diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp
index 8a2cb1449..2146eaa20 100644
--- a/src/editor/editloop.cpp
+++ b/src/editor/editloop.cpp
@@ -339,13 +339,12 @@ local int CalculateUnitIcons(void)
     i = 0;
     count = 0;
     x = TheUI.ButtonPanelY + 24;
-    while (x < TheUI.ButtonPanelY + TheUI.ButtonPanel.Graphic->Height
-	    - IconHeight) {
+    while (x < TheUI.ButtonPanelEndY - IconHeight) {
 	++i;
 	x += IconHeight + 2;
     }
     x = TheUI.ButtonPanelX + 10;
-    while (x < TheUI.ButtonPanelX + 146) {
+    while (x < TheUI.ButtonPanelEndX) {
 	count += i;
 	x += IconWidth + 8;
     }
@@ -619,8 +618,7 @@ local void DrawUnitIcons(void)
     y = TheUI.ButtonPanelY + 24;
 
     i = UnitIndex;
-    while (y < TheUI.ButtonPanelY
-	    + TheUI.ButtonPanel.Graphic->Height - IconHeight) {
+    while (y < TheUI.ButtonPanelEndY - IconHeight) {
 	if (i >= MaxShownUnits) {
 	    break;
 	}
@@ -901,25 +899,13 @@ global void EditorUpdateDisplay(void)
     //
     //  Menu button
     //
-    if (TheUI.MenuButton.Graphic) {
-	VideoDrawSub(TheUI.MenuButton.Graphic, 0, 0,
-	    TheUI.MenuButton.Graphic->Width, TheUI.MenuButton.Graphic->Height,
-	    TheUI.MenuButtonX, TheUI.MenuButtonY);
-    }
-    DrawMenuButton(MBUTTON_MAIN,
+    DrawMenuButton(TheUI.MenuButton.Button,
 	    (ButtonUnderCursor == 0 ? MenuButtonActive : 0)|
 	    (GameMenuButtonClicked ? MenuButtonClicked : 0),
-	    128, 19,
-	    TheUI.MenuButtonX+24,TheUI.MenuButtonY+2,
-	    GameFont,"Menu (~<F10~>)",NULL,NULL);
+	    TheUI.MenuButton.Width, TheUI.MenuButton.Height,
+	    TheUI.MenuButton.X,TheUI.MenuButton.Y,
+	    GameFont,TheUI.MenuButton.Text,NULL,NULL);
 
-    //
-    //  Minimap border
-    //
-    if (TheUI.Minimap.Graphic) {
-	VideoDrawSub(TheUI.Minimap.Graphic, 0, 0, TheUI.Minimap.Graphic->Width,
-	    TheUI.Minimap.Graphic->Height, TheUI.MinimapX, TheUI.MinimapY);
-    }
     //
     //  Minimap
     //
@@ -936,15 +922,6 @@ global void EditorUpdateDisplay(void)
 	    TheUI.InfoPanel.Graphic->Width, TheUI.InfoPanel.Graphic->Height/4,
 	    TheUI.InfoPanelX, TheUI.InfoPanelY);
     }
-    //
-    //  Button panel
-    //
-    if (TheUI.ButtonPanel.Graphic) {
-	VideoDrawSub(TheUI.ButtonPanel.Graphic, 0, 0,
-	    TheUI.ButtonPanel.Graphic->Width,
-	    TheUI.ButtonPanel.Graphic->Height, TheUI.ButtonPanelX,
-	    TheUI.ButtonPanelY);
-    }
     DrawEditorPanel();
 
     //
@@ -962,12 +939,12 @@ global void EditorUpdateDisplay(void)
     //
     //  Fillers
     //
-    for (i = 0; i < TheUI.NumFillers; ++i) {
-	if (TheUI.Filler[i].Graphic) {
-	    VideoDrawSub(TheUI.Filler[i].Graphic, 0, 0,
-		    TheUI.Filler[i].Graphic->Width,
-		    TheUI.Filler[i].Graphic->Height,
-		    TheUI.FillerX[i], TheUI.FillerY[i]);
+    for (i = 0; i < TheUI.NumPanels; ++i) {
+	if (TheUI.Panel[i].Graphic) {
+	    VideoDrawSub(TheUI.Panel[i].Graphic, 0, 0,
+		    TheUI.Panel[i].Graphic->Width,
+		    TheUI.Panel[i].Graphic->Height,
+		    TheUI.PanelX[i], TheUI.PanelY[i]);
 	}
     }
     //
@@ -1576,8 +1553,8 @@ local void EditorCallbackMouse(int x, int y)
     //
     //	Minimap
     //
-    if (x >= TheUI.MinimapX+24 && x < TheUI.MinimapX+24+MINIMAP_W
-	    && y >= TheUI.MinimapY+2 && y < TheUI.MinimapY+2+MINIMAP_H) {
+    if (x >= TheUI.MinimapX && x < TheUI.MinimapX+TheUI.MinimapW
+	    && y >= TheUI.MinimapY && y < TheUI.MinimapY+TheUI.MinimapH) {
 	CursorOn = CursorOnMinimap;
     }
 
@@ -1609,8 +1586,7 @@ local void EditorCallbackMouse(int x, int y)
 
 	i = UnitIndex;
 	by = TheUI.ButtonPanelY + 24;
-	while (by < TheUI.ButtonPanelY
-		+ TheUI.ButtonPanel.Graphic->Height - IconHeight) {
+	while (by < TheUI.ButtonPanelEndY - IconHeight) {
 	    if (i >= MaxShownUnits || !ShownUnitTypes[i]) {
 		break;
 	    }
@@ -1713,6 +1689,7 @@ local void EditorCallbackMouse(int x, int y)
 	SetStatusLine("Tile mode");
 	return;
     }
+#if 0
     for (i = 0; i < (int)(sizeof(TheUI.Buttons)/sizeof(*TheUI.Buttons)); ++i) {
 	if (x < TheUI.Buttons[i].X
 		|| x > TheUI.Buttons[i].X + TheUI.Buttons[i].Width
@@ -1726,12 +1703,13 @@ local void EditorCallbackMouse(int x, int y)
 	ClearStatusLine();
 	return;
     }
+#endif
 
     //
     //  Minimap
     //
-    if (x >= TheUI.MinimapX + 24 && x < TheUI.MinimapX + 24 + MINIMAP_W
-	    && y >= TheUI.MinimapY + 2 && y < TheUI.MinimapY + 2 + MINIMAP_H) {
+    if (x >= TheUI.MinimapX && x < TheUI.MinimapX + TheUI.MinimapW
+	    && y >= TheUI.MinimapY && y < TheUI.MinimapY + TheUI.MinimapH) {
 	CursorOn = CursorOnMinimap;
 	return;
     }
diff --git a/src/game/campaign.cpp b/src/game/campaign.cpp
index a4550c415..b240b3560 100644
--- a/src/game/campaign.cpp
+++ b/src/game/campaign.cpp
@@ -514,22 +514,6 @@ global void CampaignCclRegister(void)
     gh_new_procedureN("briefing",CclBriefing);
 }
 
-/**
-**	FIXME: should use the names of the real fonts.
-*/
-local char *FontNames[] = {
-    "small",
-    "game",
-    "large",
-    "small-title",
-    "large-title",
-    "user1",
-    "user2",
-    "user3",
-    "user4",
-    "user5",
-};
-
 /**
 **	Save the campaign module.
 */
diff --git a/src/include/font.h b/src/include/font.h
index 8c6253651..206700f7e 100644
--- a/src/include/font.h
+++ b/src/include/font.h
@@ -129,6 +129,12 @@ enum _game_font_ {
 --	Variables
 ----------------------------------------------------------------------------*/
 
+/**
+**	Font names
+**	FIXME: should use the names of the real fonts.
+*/
+extern char *FontNames[];
+
 /*----------------------------------------------------------------------------
 --	Functions
 ----------------------------------------------------------------------------*/
diff --git a/src/include/freecraft.h b/src/include/freecraft.h
index 486ef78ca..c06883280 100644
--- a/src/include/freecraft.h
+++ b/src/include/freecraft.h
@@ -352,9 +352,6 @@ extern char NameLine[];
 #define MAXMAP_W	50		/// Maximum map width in tiles on screen
 #define MAXMAP_H	40		/// Maximum map height in tiles
 
-#define MINIMAP_W	128		/// Minimap width in pixels
-#define MINIMAP_H	128		/// Minimap height in pixels
-
     /// Scrolling area (<= 15 y)
 #define SCROLL_UP	15
     /// Scrolling area (>= VideoHeight-16 y)
diff --git a/src/include/interface.h b/src/include/interface.h
index 2e19f0246..a85f39600 100644
--- a/src/include/interface.h
+++ b/src/include/interface.h
@@ -85,6 +85,19 @@ struct _button_action_ {
     char*	UnitMask;		/// for which units is it available
 };
 
+enum _button_area_ {
+    ButtonAreaInfo,
+    ButtonAreaTraining,
+    ButtonAreaButton,
+    ButtonAreaMenu,
+};
+
+enum _button_under_ {
+    ButtonUnderMenu,
+    ButtonUnderNetworkMenu,
+    ButtonUnderNetworkDiplomacy,
+};
+
     /// current interface state
 enum _iface_state_ {
     IfaceStateNormal,			/// Normal Game state
@@ -232,10 +245,14 @@ extern enum _scroll_state_ MouseScrollState;
 extern enum _key_state_ KeyState;
     /// pointer to unit under the cursor
 extern Unit* UnitUnderCursor;
+    /// button area under the cursor
+extern int ButtonAreaUnderCursor;
     /// button number under the cursor
 extern int ButtonUnderCursor;
-    /// button 0 (Game Menu) was clicked down
+    /// menu button was clicked down
 extern char GameMenuButtonClicked;
+    /// diplomacy button was clicked down
+extern char GameDiplomacyButtonClicked;
     /// Mouse leaves windows stops scroll
 extern char LeaveStops;
     /// current CursorOn field
diff --git a/src/include/menus.h b/src/include/menus.h
index f5296bfd8..115e08e47 100644
--- a/src/include/menus.h
+++ b/src/include/menus.h
@@ -60,6 +60,7 @@ typedef int MenuButtonId;
 /// FIXME: FILL IN THIS TABLE!!!!
 
 #define MBUTTON_MAIN		 4	/// FIXME: write docu
+#define MBUTTON_NETWORK		 7
 #define MBUTTON_GM_HALF		10
 #define MBUTTON_132		13
 #define MBUTTON_GM_FULL		16
@@ -329,6 +330,9 @@ extern _MenuFuncHash MenuFuncHash;
 --	Functions
 ----------------------------------------------------------------------------*/
 
+    /// Menu button style to char*
+extern char *MenuButtonStyle(int style);
+
     /// Initialize the hash tables for the menus
 extern void InitMenuFuncHash(void);
 
diff --git a/src/include/ui.h b/src/include/ui.h
index 7e3aa1ee1..bf26ce3f5 100644
--- a/src/include/ui.h
+++ b/src/include/ui.h
@@ -53,9 +53,6 @@
 */
 #define MOUSESCALE	1
 
-    /// MACRO - HARDCODED NUMBER OF BUTTONS on screen
-#define MaxButtons	19
-
     /// typedef for buttons on screen themselves
 typedef struct _button_ Button;
 
@@ -166,11 +163,11 @@ typedef struct _ui_ {
     char*	NormalFontColor;	/// Color for normal text displayed
     char*	ReverseFontColor;	/// Color for reverse text displayed
 
-    //	Fillers
-    GraphicConfig* Filler;		/// Filler graphics
-    int*	FillerX;		/// Filler X positions
-    int*	FillerY;		/// Filler Y positions
-    int		NumFillers;		/// Number of fillers
+    //	Panels
+    GraphicConfig* Panel;		/// Panel graphics
+    int*	PanelX;			/// Panel X positions
+    int*	PanelY;			/// Panel Y positions
+    int		NumPanels;		/// Number of panels
 
     //	Resource line
     GraphicConfig Resource;		/// Resource background
@@ -198,44 +195,36 @@ typedef struct _ui_ {
 	int	IconH;			/// icon H position
 	int	TextX;			/// text X position
 	int	TextY;			/// text Y position
-    }		Resources[MaxCosts];	/// Icon+Text of all resources
-
-    GraphicConfig FoodIcon;		/// units icon image
-    int		FoodIconRow;		/// units icon image row (frame)
-    int		FoodIconX;		/// units icon X position
-    int		FoodIconY;		/// units icon Y position
-    int		FoodIconW;		/// units icon W position
-    int		FoodIconH;		/// units icon H position
-    int		FoodTextX;		/// units text X position
-    int		FoodTextY;		/// units text Y position
-
-    GraphicConfig ScoreIcon;		/// score icon image
-    int		ScoreIconRow;		/// score icon image row (frame)
-    int		ScoreIconX;		/// score icon X position
-    int		ScoreIconY;		/// score icon Y position
-    int		ScoreIconW;		/// score icon W position
-    int		ScoreIconH;		/// score icon H position
-    int		ScoreTextX;		/// score text X position
-    int		ScoreTextY;		/// score text Y position
+    }		Resources[MaxCosts+2];	/// Icon+Text of all resources
+					/// +2 for food and score
 
     // Info panel
     GraphicConfig InfoPanel;		/// Info panel background
     int		InfoPanelX;		/// Info panel screen X position
     int		InfoPanelY;		/// Info panel screen Y position
-    int		InfoPanelW;		/// Info panel width
-    int		InfoPanelH;		/// Info panel height
+    int		InfoPanelW;		/// Info panel screen width
+    int		InfoPanelH;		/// Info panel screen height
+    int		InfoPanelNeutralFrame;
+    int		InfoPanelSelectedFrame;
+    int		InfoPanelMagicFrame;
+    int		InfoPanelConstructionFrame;
 
     // Complete bar
     int		CompleteBarColor;	/// color for complete bar
     int		CompleteBarX;		/// complete bar X position
     int		CompleteBarY;		/// complete bar Y position
+    int		CompleteBarW;		/// complete bar width
+    int		CompleteBarH;		/// complete bar height
+    char*	CompleteBarText;	/// complete bar text
+    unsigned	CompleteBarFont;	/// complete bar font
     int		CompleteTextX;		/// complete text X position
     int		CompleteTextY;		/// complete text Y position
 
     // Button panel
-    GraphicConfig ButtonPanel;		/// Button panel background
     int		ButtonPanelX;		/// Button panel screen X position
     int		ButtonPanelY;		/// Button panel screen Y position
+    int		ButtonPanelEndX;	/// Button panel screen end X position
+    int		ButtonPanelEndY;	/// Button panel screen end Y position
 
     // Map area
     ViewportMode ViewportMode;		/// Current viewport mode
@@ -247,25 +236,42 @@ typedef struct _ui_ {
     Viewport	MapArea;		/// geometry of the whole map area
 
     // The menu button
-    GraphicConfig MenuButton;		/// menu button background
-    int		MenuButtonX;		/// menu button screen X position
-    int		MenuButtonY;		/// menu button screen Y position
+    struct {
+	int	X;			/// button screen X position
+	int	Y;			/// button screen Y position
+	char*	Text;			/// button caption
+	int	Width;			/// button width
+	int	Height;			/// button height
+	int	Button;			/// button style
+    }		MenuButton,
+		NetworkMenuButton,
+		NetworkDiplomacyButton;
 
     // The minimap
-    GraphicConfig Minimap;		/// minimap panel background
     int		MinimapX;		/// minimap screen X position
     int		MinimapY;		/// minimap screen Y position
-    int		ViewportCursorColor;	/// minimap cursor color
+    int		MinimapW;		/// minimap screen width
+    int		MinimapH;		/// minimap screen height
+    int		MinimapCursorColor;	/// minimap cursor color
 
     // The status line
-    GraphicConfig StatusLine;		/// Status line background
-    int		StatusLineX;		/// status line screeen X position
-    int		StatusLineY;		/// status line screeen Y position
+    int		StatusLineX;		/// Status line screen X position
+    int		StatusLineY;		/// Status line screen Y position
+    int		StatusLineW;		/// Status line screen width
+    unsigned	StatusLineFont;		/// Status line font
 
-	/// all buttons (1 Menu, 9 Group, 9 Command)
-    Button	Buttons[MaxButtons];
-	/// used for displaying unit training queues
-    Button	Buttons2[6];
+    // Message area
+    int		MessageAreaX;		/// Message screen X position
+    int		MessageAreaY;		/// Message screen Y position
+    int		MessageAreaW;		/// Message screen width
+    unsigned	MessageAreaFont;	/// Message font
+
+    Button*	InfoButtons;		/// Info buttons
+    int		NumInfoButtons;		/// Number of info buttons
+    Button*	TrainingButtons;	/// Training buttons
+    int		NumTrainingButtons;	/// Number of training buttons
+    Button*	ButtonButtons;		/// Button panel buttons
+    int		NumButtonButtons;	/// Number of button panel buttons
 
     // Offsets for 640x480 center used by menus
     int		Offset640X;		/// Offset for 640x480 X position
diff --git a/src/include/upgrade_structs.h b/src/include/upgrade_structs.h
index 3428a0f12..3cc5ea720 100644
--- a/src/include/upgrade_structs.h
+++ b/src/include/upgrade_structs.h
@@ -62,6 +62,9 @@ enum _costs_ {
     MaxCosts				/// how many different costs
 };
 
+#define FoodCost MaxCosts
+#define ScoreCost MaxCosts+1
+
 /**
 **	Speed factor for harvesting resources
 */
diff --git a/src/map/minimap.cpp b/src/map/minimap.cpp
index fec08a501..c371ac749 100644
--- a/src/map/minimap.cpp
+++ b/src/map/minimap.cpp
@@ -49,8 +49,8 @@
 
 local Graphic* MinimapTerrainGraphic;	/// generated minimap terrain
 local Graphic* MinimapGraphic;		/// generated minimap
-local int Minimap2MapX[MINIMAP_W];	/// fast conversion table
-local int Minimap2MapY[MINIMAP_H];	/// fast conversion table
+local int* Minimap2MapX;		/// fast conversion table
+local int* Minimap2MapY;		/// fast conversion table
 local int Map2MinimapX[MaxMapWidth];	/// fast conversion table
 local int Map2MinimapY[MaxMapHeight];	/// fast conversion table
 
@@ -96,6 +96,10 @@ global void UpdateMinimapXY(int tx,int ty)
     int y;
     int scale;
 
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     if( !(scale=(MinimapScale/MINIMAP_FAC)) ) {
 	scale=1;
     }
@@ -103,7 +107,7 @@ global void UpdateMinimapXY(int tx,int ty)
     //	Pixel 7,6 7,14, 15,6 15,14 are taken for the minimap picture.
     //
     ty*=TheMap.Width;
-    for( my=MinimapY; my<MINIMAP_H-MinimapY; ++my ) {
+    for( my=MinimapY; my<TheUI.MinimapH-MinimapY; ++my ) {
 	y=Minimap2MapY[my];
 	if( y<ty ) {
 	    continue;
@@ -112,7 +116,7 @@ global void UpdateMinimapXY(int tx,int ty)
 	    break;
 	}
 
-	for( mx=MinimapX; mx<MINIMAP_W-MinimapX; ++mx ) {
+	for( mx=MinimapX; mx<TheUI.MinimapW-MinimapX; ++mx ) {
 	    int tile;
 
 	    x=Minimap2MapX[mx];
@@ -124,7 +128,7 @@ global void UpdateMinimapXY(int tx,int ty)
 	    }
 
 	    tile=TheMap.Fields[x+y].Tile;
-	    ((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*MINIMAP_W]=
+	    ((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*TheUI.MinimapW]=
 		TheMap.Tiles[tile][7+(mx%scale)*8+(6+(my%scale)*8)*TileSizeX];
 	}
     }
@@ -143,6 +147,10 @@ global void UpdateMinimapTerrain(void)
     int my;
     int scale;
 
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     if( !(scale=(MinimapScale/MINIMAP_FAC)) ) {
 	scale=1;
     }
@@ -150,12 +158,12 @@ global void UpdateMinimapTerrain(void)
     //
     //	Pixel 7,6 7,14, 15,6 15,14 are taken for the minimap picture.
     //
-    for( my=MinimapY; my<MINIMAP_H-MinimapY; ++my ) {
-	for( mx=MinimapX; mx<MINIMAP_W-MinimapX; ++mx ) {
+    for( my=MinimapY; my<TheUI.MinimapH-MinimapY; ++my ) {
+	for( mx=MinimapX; mx<TheUI.MinimapW-MinimapX; ++mx ) {
 	    int tile;
 
 	    tile=TheMap.Fields[Minimap2MapX[mx]+Minimap2MapY[my]].Tile;
-	    ((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*MINIMAP_W]=
+	    ((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*TheUI.MinimapW]=
 		TheMap.Tiles[tile][7+(mx%scale)*8+(6+(my%scale)*8)*TileSizeX];
 	}
     }
@@ -170,17 +178,21 @@ global void CreateMinimap(void)
 {
     int n;
 
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     if( TheMap.Width>TheMap.Height ) {	// Scale to biggest value.
 	n=TheMap.Width;
     } else {
 	n=TheMap.Height;
     }
-    MinimapScale=(MINIMAP_W*MINIMAP_FAC)/n;
+    MinimapScale=(TheUI.MinimapW*MINIMAP_FAC)/n;
 
-    MinimapX=((MINIMAP_W*MINIMAP_FAC)/MinimapScale-TheMap.Width)/2;
-    MinimapY=((MINIMAP_H*MINIMAP_FAC)/MinimapScale-TheMap.Height)/2;
-    MinimapX=(MINIMAP_W-(TheMap.Width*MinimapScale)/MINIMAP_FAC)/2;
-    MinimapY=(MINIMAP_H-(TheMap.Height*MinimapScale)/MINIMAP_FAC)/2;
+    MinimapX=((TheUI.MinimapW*MINIMAP_FAC)/MinimapScale-TheMap.Width)/2;
+    MinimapY=((TheUI.MinimapH*MINIMAP_FAC)/MinimapScale-TheMap.Height)/2;
+    MinimapX=(TheUI.MinimapW-(TheMap.Width*MinimapScale)/MINIMAP_FAC)/2;
+    MinimapY=(TheUI.MinimapH-(TheMap.Height*MinimapScale)/MINIMAP_FAC)/2;
 
     DebugLevel0Fn("MinimapScale %d(%d), X off %d, Y off %d\n" _C_
 	    MinimapScale/MINIMAP_FAC _C_ MinimapScale _C_ MinimapX _C_ MinimapY);
@@ -190,10 +202,12 @@ global void CreateMinimap(void)
     //
     // FIXME: this needs to be recalculated during map load - the map size
     // might have changed!
-    for( n=MinimapX; n<MINIMAP_W-MinimapX; ++n ) {
+    Minimap2MapX=calloc(sizeof(int),TheUI.MinimapW*TheUI.MinimapH);
+    Minimap2MapY=calloc(sizeof(int),TheUI.MinimapW*TheUI.MinimapH);
+    for( n=MinimapX; n<TheUI.MinimapW-MinimapX; ++n ) {
 	Minimap2MapX[n]=((n-MinimapX)*MINIMAP_FAC)/MinimapScale;
     }
-    for( n=MinimapY; n<MINIMAP_H-MinimapY; ++n ) {
+    for( n=MinimapY; n<TheUI.MinimapH-MinimapY; ++n ) {
 	Minimap2MapY[n]=(((n-MinimapY)*MINIMAP_FAC)/MinimapScale)*TheMap.Width;
     }
     for( n=0; n<TheMap.Width; ++n ) {
@@ -203,11 +217,11 @@ global void CreateMinimap(void)
 	Map2MinimapY[n]=(n*MinimapScale)/MINIMAP_FAC;
     }
 
-    MinimapTerrainGraphic=NewGraphic(8,MINIMAP_W,MINIMAP_H);
-    memset(MinimapTerrainGraphic->Frames,0,MINIMAP_W*MINIMAP_H);
-    MinimapGraphic=NewGraphic(8,MINIMAP_W,MINIMAP_H);
+    MinimapTerrainGraphic=NewGraphic(8,TheUI.MinimapW,TheUI.MinimapH);
+    memset(MinimapTerrainGraphic->Frames,0,TheUI.MinimapW*TheUI.MinimapH);
+    MinimapGraphic=NewGraphic(8,TheUI.MinimapW,TheUI.MinimapH);
     MinimapGraphic->Pixels=VideoCreateNewPalette(GlobalPalette);
-    memset(MinimapGraphic->Frames,0,MINIMAP_W*MINIMAP_H);
+    memset(MinimapGraphic->Frames,0,TheUI.MinimapW*TheUI.MinimapH);
 
     UpdateMinimapTerrain();
 }
@@ -225,8 +239,10 @@ global void DestroyMinimap(void)
     }
     VideoSaveFree(MinimapGraphic);
     MinimapGraphic=NULL;
-    memset(Minimap2MapX,0,MINIMAP_W*sizeof(int));
-    memset(Minimap2MapY,0,MINIMAP_H*sizeof(int));
+    free(Minimap2MapX);
+    Minimap2MapX=NULL;
+    free(Minimap2MapY);
+    Minimap2MapY=NULL;
 }
 
 /**
@@ -246,6 +262,10 @@ global void UpdateMinimap(void)
     int h;
     int h0;
 
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     w=(FrameCounter/FRAMES_PER_SECOND)&1;
     if( (new_phase=red_phase-w) ) {
 	red_phase=w;
@@ -254,26 +274,27 @@ global void UpdateMinimap(void)
     //
     //	Draw the mini-map background.	Note draws a little too much.
     //
-    // FIXME: position of the minimap in the graphic is hardcoded (24x2)
-    for( h=0; h<MINIMAP_H; ++h ) {
-	memcpy(&((unsigned char*)MinimapGraphic->Frames)[h*MINIMAP_W],
-	    &((unsigned char*)TheUI.Minimap.Graphic->Frames)[24+(h+2)*TheUI.Minimap.Graphic->Width],
+#if 0
+    for( h=0; h<TheUI.MinimapH; ++h ) {
+	memcpy(&((unsigned char*)MinimapGraphic->Frames)[h*TheUI.MinimapW],
+	    &((unsigned char*)TheUI.Minimap.Graphic->Frames)[h*TheUI.Minimap.Graphic->Width],
 	    TheUI.Minimap.Graphic->Width);
     }
+#endif
 
     //
     //	Draw the terrain
     //
     if( MinimapWithTerrain ) {
-	for( my=0; my<MINIMAP_H; ++my ) {
-	    for( mx=0; mx<MINIMAP_W; ++mx ) {
+	for( my=0; my<TheUI.MinimapH; ++my ) {
+	    for( mx=0; mx<TheUI.MinimapW; ++mx ) {
 		if( IsMapFieldVisible(ThisPlayer,Minimap2MapX[mx],(Minimap2MapY[my]/TheMap.Width))
 			|| (IsMapFieldExplored(ThisPlayer,Minimap2MapX[mx],
 				(Minimap2MapY[my]/TheMap.Width)) &&
 				((mx&1)==(my&1)))
 			|| ReplayRevealMap ) {
-		    ((unsigned char*)MinimapGraphic->Frames)[mx+my*MINIMAP_W]=
-			((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*MINIMAP_W];
+		    ((unsigned char*)MinimapGraphic->Frames)[mx+my*TheUI.MinimapW]=
+			((unsigned char*)MinimapTerrainGraphic->Frames)[mx+my*TheUI.MinimapW];
 		}
 	    }
 	}
@@ -309,17 +330,17 @@ global void UpdateMinimap(void)
 	    mx=1+MinimapX+Map2MinimapX[(*table)->X];
 	    my=1+MinimapY+Map2MinimapY[(*table)->Y];
 	    w=Map2MinimapX[type->TileWidth];
-	    if( mx+w>=MINIMAP_W ) {	// clip right side
-		w=MINIMAP_W-mx;
+	    if( mx+w>=TheUI.MinimapW ) {	// clip right side
+		w=TheUI.MinimapW-mx;
 	    }
 	    h0=Map2MinimapY[type->TileHeight];
-	    if( my+h0>=MINIMAP_H ) {	// clip bottom side
-		h0=MINIMAP_H-my;
+	    if( my+h0>=TheUI.MinimapH ) {	// clip bottom side
+		h0=TheUI.MinimapH-my;
 	    }
 	    while( w-->=0 ) {
 		h=h0;
 		while( h-->=0 ) {
-		    ((unsigned char*)MinimapGraphic->Frames)[mx+w+(my+h)*MINIMAP_W]=color;
+		    ((unsigned char*)MinimapGraphic->Frames)[mx+w+(my+h)*TheUI.MinimapW]=color;
 		}
 	    }
 	}
@@ -375,17 +396,17 @@ global void UpdateMinimap(void)
 	mx=1+MinimapX+Map2MinimapX[unit->X];
 	my=1+MinimapY+Map2MinimapY[unit->Y];
 	w=Map2MinimapX[type->TileWidth];
-	if( mx+w>=MINIMAP_W ) {		// clip right side
-	    w=MINIMAP_W-mx;
+	if( mx+w>=TheUI.MinimapW ) {		// clip right side
+	    w=TheUI.MinimapW-mx;
 	}
 	h0=Map2MinimapY[type->TileHeight];
-	if( my+h0>=MINIMAP_H ) {	// clip bottom side
-	    h0=MINIMAP_H-my;
+	if( my+h0>=TheUI.MinimapH ) {	// clip bottom side
+	    h0=TheUI.MinimapH-my;
 	}
 	while( w-->=0 ) {
 	    h=h0;
 	    while( h-->=0 ) {
-		((unsigned char*)MinimapGraphic->Frames)[mx+w+(my+h)*MINIMAP_W]=color;
+		((unsigned char*)MinimapGraphic->Frames)[mx+w+(my+h)*TheUI.MinimapW]=color;
 	    }
 	}
     }
@@ -400,9 +421,13 @@ global void UpdateMinimap(void)
 global void DrawMinimap(int vx __attribute__((unused)),
 	int vy __attribute__((unused)))
 {
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     VideoDrawSub(MinimapGraphic,0,0
 	    ,MinimapGraphic->Width,MinimapGraphic->Height
-	    ,TheUI.MinimapX+24,TheUI.MinimapY+2);
+	    ,TheUI.MinimapX,TheUI.MinimapY);
 }
 
 /**
@@ -432,12 +457,16 @@ global void DrawMinimapCursor(int vx, int vy)
     int h;
     int i;
 
+    if( TheUI.MinimapX==-1 ) {
+	return;
+    }
+
     // Determine and save region below minimap cursor
     // FIXME: position of the minimap in the graphic is hardcoded (24x2)
     OldMinimapCursorX=x=
-	TheUI.MinimapX+24+MinimapX+(vx*MinimapScale)/MINIMAP_FAC;
+	TheUI.MinimapX+MinimapX+(vx*MinimapScale)/MINIMAP_FAC;
     OldMinimapCursorY=y=
-	TheUI.MinimapY+2+MinimapY+(vy*MinimapScale)/MINIMAP_FAC;
+	TheUI.MinimapY+MinimapY+(vy*MinimapScale)/MINIMAP_FAC;
     OldMinimapCursorW=w=
 	(TheUI.SelectedViewport->MapWidth*MinimapScale)/MINIMAP_FAC;
     OldMinimapCursorH=h=
@@ -455,7 +484,7 @@ global void DrawMinimapCursor(int vx, int vy)
     SaveCursorRectangle(OldMinimapCursorImage,x,y,w,h);
 
     // Draw cursor as rectangle (Note: unclipped, as it is always visible)
-    VideoDraw50TransRectangle(TheUI.ViewportCursorColor,x,y,w,h);
+    VideoDraw50TransRectangle(TheUI.MinimapCursorColor,x,y,w,h);
 }
 
 /**
@@ -468,7 +497,7 @@ global int ScreenMinimap2MapX(int x)
 {
     int tx;
 
-    tx=((((x)-TheUI.MinimapX-24-MinimapX)*MINIMAP_FAC)/MinimapScale);
+    tx=((((x)-TheUI.MinimapX-MinimapX)*MINIMAP_FAC)/MinimapScale);
     if( tx<0 ) {
 	return 0;
     }
@@ -485,7 +514,7 @@ global int ScreenMinimap2MapY(int y)
 {
     int ty;
 
-    ty=((((y)-TheUI.MinimapY-2-MinimapY)*MINIMAP_FAC)/MinimapScale);
+    ty=((((y)-TheUI.MinimapY-MinimapY)*MINIMAP_FAC)/MinimapScale);
     if( ty<0 ) {
 	return 0;
     }
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index fb78d076b..3acff76eb 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -254,23 +254,40 @@ global void DebugTestDisplay(void)
 /**
 **	Draw menu button area.
 **
-**	With debug it shows the used frame time and arrival of network packets.
-**
-**	@todo	Must be more configurable. Adding diplomacy menu here?
+**	With DRAW_DEBUG it shows the used frame time and arrival of network packets.
 */
 local void DrawMenuButtonArea(void)
 {
-    VideoDrawSub(TheUI.MenuButton.Graphic,0,0
-	    ,TheUI.MenuButton.Graphic->Width
-	    ,TheUI.MenuButton.Graphic->Height
-	    ,TheUI.MenuButtonX,TheUI.MenuButtonY);
-
-    DrawMenuButton(MBUTTON_MAIN,
-	    (ButtonUnderCursor == 0 ? MenuButtonActive : 0)|
-	    (GameMenuButtonClicked ? MenuButtonClicked : 0),
-	    128, 19,
-	    TheUI.MenuButtonX+24,TheUI.MenuButtonY+2,
-	    GameFont,"Menu (~<F10~>)",NULL,NULL);
+    if( NetworkFildes==-1 ) {
+	if( TheUI.MenuButton.X!=-1 ) {
+	    DrawMenuButton(TheUI.MenuButton.Button,
+		    (ButtonAreaUnderCursor==ButtonAreaMenu
+			&& ButtonUnderCursor==ButtonUnderMenu ? MenuButtonActive : 0)|
+		    (GameMenuButtonClicked ? MenuButtonClicked : 0),
+		    TheUI.MenuButton.Width, TheUI.MenuButton.Height,
+		    TheUI.MenuButton.X,TheUI.MenuButton.Y,
+		    GameFont,TheUI.MenuButton.Text,NULL,NULL);
+	}
+    } else {
+	if( TheUI.NetworkMenuButton.X!=-1 ) {
+	    DrawMenuButton(TheUI.NetworkMenuButton.Button,
+		    (ButtonAreaUnderCursor==ButtonAreaMenu
+			&& ButtonUnderCursor==ButtonUnderNetworkMenu ? MenuButtonActive : 0)|
+		    (GameMenuButtonClicked ? MenuButtonClicked : 0),
+		    TheUI.NetworkMenuButton.Width, TheUI.NetworkMenuButton.Height,
+		    TheUI.NetworkMenuButton.X,TheUI.NetworkMenuButton.Y,
+		    GameFont,TheUI.NetworkMenuButton.Text,NULL,NULL);
+	}
+	if( TheUI.NetworkDiplomacyButton.X!=-1 ) {
+	    DrawMenuButton(TheUI.NetworkDiplomacyButton.Button,
+		    (ButtonAreaUnderCursor==ButtonAreaMenu
+			&& ButtonUnderCursor==ButtonUnderNetworkDiplomacy ? MenuButtonActive : 0)|
+		    (GameMenuButtonClicked ? MenuButtonClicked : 0),
+		    TheUI.NetworkDiplomacyButton.Width, TheUI.NetworkDiplomacyButton.Height,
+		    TheUI.NetworkDiplomacyButton.X,TheUI.NetworkDiplomacyButton.Y,
+		    GameFont,TheUI.NetworkDiplomacyButton.Text,NULL,NULL);
+	}
+    }
 
 #ifdef DRAW_DEBUG
     //
@@ -508,77 +525,52 @@ global void DrawMapArea(void)
 */
 global void UpdateDisplay(void)
 {
+    int i;
+
     MustRedraw&=EnableRedraw;		// Don't redraw disabled parts
 
     VideoLockScreen();			// prepare video write
 
     HideAnyCursor();			// remove cursor (when available)
 
-    if( MustRedraw&RedrawMap ) {
+    if( GuiGameStarted ) {
 	DrawMapArea();
-    }
 
-    if( MustRedraw&(RedrawMessage|RedrawMap) ) {
 	DrawMessages();
-    }
 
-    if( MustRedraw&RedrawFillers ) {
-	int i;
 
-	for( i=0; i<TheUI.NumFillers; ++i ) {
-	    VideoDrawSub(TheUI.Filler[i].Graphic,0,0
-		    ,TheUI.Filler[i].Graphic->Width
-		    ,TheUI.Filler[i].Graphic->Height
-		    ,TheUI.FillerX[i],TheUI.FillerY[i]);
+	for( i=0; i<TheUI.NumPanels; ++i ) {
+	    VideoDraw(TheUI.Panel[i].Graphic,0,
+		    TheUI.PanelX[i],TheUI.PanelY[i]);
 	}
-    }
 
-    if( MustRedraw&RedrawMenuButton ) {
 	DrawMenuButtonArea();
-    }
-    if( MustRedraw&RedrawMinimapBorder ) {
-	VideoDrawSub(TheUI.Minimap.Graphic,0,0
-		,TheUI.Minimap.Graphic->Width,TheUI.Minimap.Graphic->Height
-		,TheUI.MinimapX,TheUI.MinimapY);
-    }
 
-    PlayerPixels(Players);		// Reset to default colors
+	PlayerPixels(Players);		// Reset to default colors
 
-    if( MustRedraw&RedrawMinimap ) {
 	// FIXME: redraw only 1* per second!
 	// HELPME: Viewpoint rectangle must be drawn faster (if implemented) ?
 	DrawMinimap(TheUI.SelectedViewport->MapX, TheUI.SelectedViewport->MapY);
 	DrawMinimapCursor(TheUI.SelectedViewport->MapX,
 		TheUI.SelectedViewport->MapY);
-    } else if (MustRedraw&RedrawMinimapCursor) {
-	HideMinimapCursor();
-	DrawMinimapCursor(TheUI.SelectedViewport->MapX,
-		TheUI.SelectedViewport->MapY);
-    }
 
-    if( MustRedraw&RedrawInfoPanel ) {
 	DrawInfoPanel();
 	PlayerPixels(Players);		// Reset to default colors
-    }
-    if( MustRedraw&RedrawButtonPanel ) {
+
 	DrawButtonPanel();
 	PlayerPixels(Players);		// Reset to default colors
-    }
-    if( MustRedraw&RedrawResources ) {
+
 	DrawResources();
-    }
-    if( MustRedraw&RedrawStatusLine ) {
+
 	DrawStatusLine();
 	MustRedraw|=RedrawCosts;
-    }
-    if( MustRedraw&RedrawCosts ) {
+
 	DrawCosts();
-    }
-    if( MustRedraw&RedrawTimer ) {
+
 	DrawTimer();
     }
 
-    if( MustRedraw&RedrawMenu ) {
+    if( CurrentMenu ) {
 	DrawMenu(CurrentMenu);
     }
 
@@ -596,59 +588,94 @@ global void UpdateDisplay(void)
 	if( MustRedraw&RedrawMap ) {
 	    // FIXME: split into small parts see RedrawTile and RedrawRow
 	    InvalidateAreaAndCheckCursor(
-		     TheUI.MapArea.X,TheUI.MapArea.Y
-		    ,TheUI.MapArea.EndX-TheUI.MapArea.X+1
-		    ,TheUI.MapArea.EndY-TheUI.MapArea.Y+1);
+		    TheUI.MapArea.X,TheUI.MapArea.Y,
+		    TheUI.MapArea.EndX-TheUI.MapArea.X+1,
+		    TheUI.MapArea.EndY-TheUI.MapArea.Y+1);
 	}
 	if( MustRedraw&RedrawFillers ) {
 	    int i;
 
-	    for( i=0; i<TheUI.NumFillers; ++i ) {
+	    for( i=0; i<TheUI.NumPanels; ++i ) {
 		InvalidateAreaAndCheckCursor(
-			 TheUI.FillerX[i],TheUI.FillerY[i]
-			,TheUI.Filler[i].Graphic->Width
-			,TheUI.Filler[i].Graphic->Height);
+			TheUI.PanelX[i],TheUI.PanelY[i],
+			TheUI.Panel[i].Graphic->Width,
+			TheUI.Panel[i].Graphic->Height);
 	    }
 	}
 	if(MustRedraw&RedrawMenuButton ) {
-	    InvalidateAreaAndCheckCursor(
-		     TheUI.MenuButtonX,TheUI.MenuButtonY
-		    ,TheUI.MenuButton.Graphic->Width
-		    ,TheUI.MenuButton.Graphic->Height);
+	    if( NetworkFildes==-1 ) {
+		if( TheUI.MenuButton.X!=-1 ) {
+		    InvalidateAreaAndCheckCursor(
+			    TheUI.MenuButton.X,TheUI.MenuButton.Y,
+			    TheUI.MenuButton.Width,
+			    TheUI.MenuButton.Height);
+		}
+	    } else {
+		if( TheUI.NetworkMenuButton.X!=-1 ) {
+		    InvalidateAreaAndCheckCursor(
+			    TheUI.NetworkMenuButton.X,
+			    TheUI.NetworkMenuButton.Y,
+			    TheUI.NetworkMenuButton.Width,
+			    TheUI.NetworkMenuButton.Height);
+		}
+		if( TheUI.NetworkDiplomacyButton.X!=-1 ) {
+		    InvalidateAreaAndCheckCursor(
+			    TheUI.NetworkDiplomacyButton.X,
+			    TheUI.NetworkDiplomacyButton.Y,
+			    TheUI.NetworkDiplomacyButton.Width,
+			    TheUI.NetworkDiplomacyButton.Height);
+		}
+	    }
 	}
 	if( MustRedraw&RedrawMinimapBorder ) {
-	    InvalidateAreaAndCheckCursor(
-		 TheUI.MinimapX,TheUI.MinimapY
-		,TheUI.Minimap.Graphic->Width,TheUI.Minimap.Graphic->Height);
+	    // Unused
+//	    InvalidateAreaAndCheckCursor(
+//		 TheUI.MinimapX,TheUI.MinimapY
+//		,TheUI.Minimap.Graphic->Width,TheUI.Minimap.Graphic->Height);
 	} else if( (MustRedraw&RedrawMinimap)
 		|| (MustRedraw&RedrawMinimapCursor) ) {
 	    // FIXME: Redraws too much of the minimap
-	    InvalidateAreaAndCheckCursor(
-		     TheUI.MinimapX+24,TheUI.MinimapY+2
-		    ,MINIMAP_W,MINIMAP_H);
+	    if( TheUI.MinimapX!=-1 ) {
+		InvalidateAreaAndCheckCursor(
+			TheUI.MinimapX,TheUI.MinimapY,
+			TheUI.MinimapW,TheUI.MinimapH);
+	    }
 	}
 	if( MustRedraw&RedrawInfoPanel ) {
-	    InvalidateAreaAndCheckCursor(
-		     TheUI.InfoPanelX,TheUI.InfoPanelY
-		    ,TheUI.InfoPanelW,TheUI.InfoPanelH);
+	    if( TheUI.InfoPanelX!=-1 ) {
+		InvalidateAreaAndCheckCursor(
+			TheUI.InfoPanelX,TheUI.InfoPanelY,
+			TheUI.InfoPanelW,TheUI.InfoPanelH);
+	    }
 	}
 	if( MustRedraw&RedrawButtonPanel ) {
 	    InvalidateAreaAndCheckCursor(
-		     TheUI.ButtonPanelX,TheUI.ButtonPanelY
-		    ,TheUI.ButtonPanel.Graphic->Width
-		    ,TheUI.ButtonPanel.Graphic->Height);
+		    TheUI.ButtonPanelX,TheUI.ButtonPanelY,
+		    TheUI.ButtonPanelEndX-TheUI.ButtonPanelX+7,
+		    TheUI.ButtonPanelEndY-TheUI.ButtonPanelY+7);
 	}
 	if( MustRedraw&RedrawResources ) {
-	    InvalidateAreaAndCheckCursor(
-		     TheUI.ResourceX,TheUI.ResourceY
-		    ,TheUI.Resource.Graphic->Width
-		    ,TheUI.Resource.Graphic->Height);
+	    for( i=0; i<MaxCosts+2; ++i ) {
+		if( TheUI.Resources[i].TextX!=-1 ) {
+		    // FIXME: width is wrong
+		    static int width=0;
+		    if( !width ) {
+			width=VideoTextLength(GameFont,"99,999");
+		    }
+		    InvalidateAreaAndCheckCursor(
+			    TheUI.Resources[i].TextX,TheUI.Resources[i].TextY,
+			    width,
+			    VideoTextHeight(GameFont));
+		}
+	    }
 	}
 	if( MustRedraw&RedrawStatusLine || MustRedraw&RedrawCosts ) {
-	    InvalidateAreaAndCheckCursor(
-		     TheUI.StatusLineX,TheUI.StatusLineY
-		    ,TheUI.StatusLine.Graphic->Width
-		    ,TheUI.StatusLine.Graphic->Height);
+	    if( TheUI.StatusLineX!=-1 ) {
+		InvalidateAreaAndCheckCursor(
+			TheUI.StatusLineX,TheUI.StatusLineY,
+			TheUI.StatusLineW,
+			VideoTextHeight(TheUI.StatusLineFont));
+	    }
 	}
 	if( MustRedraw&RedrawTimer ) {
 	    // FIXME: Invalidate timer area
@@ -842,10 +869,6 @@ global void GameMainLoop(void)
 	    if( Callbacks==&MenuCallbacks ) {
 		MustRedraw|=RedrawMenu;
 	    }
-	    if( CurrentMenu && CurrentMenu->Panel
-		    && !strcmp(CurrentMenu->Panel, ScPanel) ) {
-		MustRedraw = RedrawEverything;
-	    }
 
 	    //For debuggin only: replace UpdateDisplay by DebugTestDisplay when
 	    //			 debugging linedraw routines..
diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp
index 30e457591..66e047574 100644
--- a/src/ui/botpanel.cpp
+++ b/src/ui/botpanel.cpp
@@ -374,12 +374,9 @@ global void DrawButtonPanel(void)
     const ButtonAction* buttons;
     char buf[8];
 
-    //
-    //	Draw background
-    //
-    VideoDrawSub(TheUI.ButtonPanel.Graphic,0,0
-	    ,TheUI.ButtonPanel.Graphic->Width,TheUI.ButtonPanel.Graphic->Height
-	    ,TheUI.ButtonPanelX,TheUI.ButtonPanelY);
+    if( !TheUI.NumButtonButtons ) {
+	return;
+    }
 
     if( !(buttons=CurrentButtons) ) {	// no buttons
 	return;
@@ -388,13 +385,14 @@ global void DrawButtonPanel(void)
     // FIXME: this is unneeded DrawUnitIcon does it self
     PlayerPixels(ThisPlayer);		// could only select own units.
 
-    for( i=0; i<9; ++i ) {
+    for( i=0; i<TheUI.NumButtonButtons; ++i ) {
 	if( buttons[i].Pos!=-1 ) {
 	    int j;
 	    int action;
 
 	    // cursor is on that button
-	    if( ButtonUnderCursor==i+10 ) {
+	    if( ButtonAreaUnderCursor==ButtonAreaButton
+		    && ButtonUnderCursor==i ) {
 		v=IconActive;
 		if( MouseButtons&LeftButton ) {
 		    v=IconClicked;
@@ -493,12 +491,13 @@ global void DrawButtonPanel(void)
 	    }
 
 	    DrawUnitIcon(ThisPlayer,buttons[i].Icon.Icon
-		    ,v,TheUI.Buttons[i+10].X,TheUI.Buttons[i+10].Y);
+		    ,v,TheUI.ButtonButtons[i].X,TheUI.ButtonButtons[i].Y);
 
 	    //
 	    //	Update status line for this button
 	    //
-	    if( ButtonUnderCursor==i+10 && KeyState!=KeyStateInput ) {
+	    if( ButtonAreaUnderCursor==ButtonAreaButton
+		    && ButtonUnderCursor==i && KeyState!=KeyStateInput ) {
 		SetStatusLine(buttons[i].Hint);
 		// FIXME: Draw costs
 		v=buttons[i].Value;
@@ -539,7 +538,7 @@ global void DrawButtonPanel(void)
 	    if( ShowCommandKey ) {
 		Button* b;
 
-		b=&TheUI.Buttons[i+10];
+		b=&TheUI.ButtonButtons[i];
 		if( CurrentButtons[i].Key==27 ) {
 		    strcpy(buf,"ESC");
 		    VideoDrawText(b->X+4+b->Width-VideoTextLength(GameFont,buf),
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 84a8bf859..100eb80ff 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -94,7 +94,7 @@ local void ShowInput(void)
     sprintf(InputStatusLine,"MESSAGE:%s~!_",Input);
     input=InputStatusLine;
     // FIXME: This is slow!
-    while( VideoTextLength(GameFont,input)>TheUI.StatusLine.Graphic->Width ) {
+    while( VideoTextLength(GameFont,input)>TheUI.StatusLineW ) {
 	++input;
     }
     KeyState=KeyStateCommand;
diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp
index 599097558..9a9a2756d 100644
--- a/src/ui/mainscr.cpp
+++ b/src/ui/mainscr.cpp
@@ -133,14 +133,19 @@ local void UiDrawCompleted(int full,int ready)
 {
     int f;
 
+    if( TheUI.CompleteBarX==-1 ) {
+	return;
+    }
+
     if( !full ) {
 	return;
     }
     f=(100*ready)/full;
-    f=(f*152)/100;
-    VideoFillRectangleClip(TheUI.CompleteBarColor
-	    ,TheUI.CompleteBarX,TheUI.CompleteBarY,f,14);
-    VideoDrawText(TheUI.CompleteTextX,TheUI.CompleteTextY,GameFont,"% Complete");
+    f=(f*TheUI.CompleteBarW)/100;
+    VideoFillRectangleClip(TheUI.CompleteBarColor,
+	    TheUI.CompleteBarX,TheUI.CompleteBarY,f,TheUI.CompleteBarH);
+    VideoDrawText(TheUI.CompleteTextX,TheUI.CompleteTextY,
+	    TheUI.CompleteBarFont,TheUI.CompleteBarText);
 }
 
 /**
@@ -188,22 +193,28 @@ global void DrawUnitInfo(const Unit* unit)
     //
     //	Draw icon in upper left corner
     //
-    x=TheUI.Buttons[1].X;
-    y=TheUI.Buttons[1].Y;
-    DrawUnitIcon(unit->Player,type->Icon.Icon
-	    ,(ButtonUnderCursor==1)
-		? (IconActive|(MouseButtons&LeftButton)) : 0
-	    ,x,y);
-    UiDrawLifeBar(unit,x,y);
+    if( TheUI.NumInfoButtons>=2 ) {
+	x=TheUI.InfoButtons[0].X;
+	y=TheUI.InfoButtons[0].Y;
+	DrawUnitIcon(unit->Player,type->Icon.Icon
+		,(ButtonAreaUnderCursor==ButtonAreaInfo && ButtonUnderCursor==0)
+		    ? (IconActive|(MouseButtons&LeftButton)) : 0
+		,x,y);
+	UiDrawLifeBar(unit,x,y);
 
-    if( unit->Player==ThisPlayer ) {	// Only for own units.
-	if( unit->HP && unit->HP<10000 ) {
-	    sprintf(buf,"%d/%d",unit->HP,stats->HitPoints);
-	    VideoDrawTextCentered(x+(type->Icon.Icon->Width+7)/2
-		    ,y+type->Icon.Icon->Height+7+7+3,SmallFont,buf);
+	if( unit->Player==ThisPlayer ) {	// Only for own units.
+	    if( unit->HP && unit->HP<10000 ) {
+		sprintf(buf,"%d/%d",unit->HP,stats->HitPoints);
+		VideoDrawTextCentered(x+(type->Icon.Icon->Width+7)/2
+			,y+type->Icon.Icon->Height+7+7+3,SmallFont,buf);
+	    }
 	}
     }
 
+    if( TheUI.InfoPanelW<176 ) {
+	return;
+    }
+
     x=TheUI.InfoPanelX;
     y=TheUI.InfoPanelY;
 
@@ -313,12 +324,12 @@ global void DrawUnitInfo(const Unit* unit)
 	    } else {
 		VideoDrawTextCentered(x+114,y+8+29,GameFont,"Training...");
 
-		for( i = 0; i < unit->Data.Train.Count; i++ ) {
+		for( i=0; i<unit->Data.Train.Count; ++i ) {
 		    DrawUnitIcon(unit->Player
 			    ,unit->Data.Train.What[i]->Icon.Icon
-			    ,(ButtonUnderCursor==i+4)
+			    ,(ButtonAreaUnderCursor==ButtonAreaTraining && ButtonUnderCursor==i)
 				? (IconActive|(MouseButtons&LeftButton)) : 0
-			    ,TheUI.Buttons2[i].X,TheUI.Buttons2[i].Y);
+			    ,TheUI.TrainingButtons[i].X,TheUI.TrainingButtons[i].Y);
 		}
 
 		UiDrawCompleted(
@@ -431,16 +442,16 @@ global void DrawUnitInfo(const Unit* unit)
 	    if( unit->OnBoard[i]!=NoUnitP ) {
 		DrawUnitIcon(unit->Player
 		    ,unit->OnBoard[i]->Type->Icon.Icon
-		    ,(ButtonUnderCursor==i+4)
+		    ,(ButtonAreaUnderCursor==ButtonAreaInfo && ButtonUnderCursor==i+3)
 			? (IconActive|(MouseButtons&LeftButton)) : 0
-			    ,TheUI.Buttons[i+4].X,TheUI.Buttons[i+4].Y);
+			    ,TheUI.InfoButtons[i+3].X,TheUI.InfoButtons[i+3].Y);
 		UiDrawLifeBar(unit->OnBoard[i]
-			,TheUI.Buttons[i+4].X,TheUI.Buttons[i+4].Y);
+			,TheUI.InfoButtons[i+3].X,TheUI.InfoButtons[i+3].Y);
 		if( unit->OnBoard[i]->Type->CanCastSpell ) {
 		    UiDrawManaBar(unit->OnBoard[i]
-			    ,TheUI.Buttons[i+4].X,TheUI.Buttons[i+4].Y);
+			    ,TheUI.InfoButtons[i+3].X,TheUI.InfoButtons[i+3].Y);
 		}
-		if( ButtonUnderCursor==i+4 ) {
+		if( ButtonAreaUnderCursor==ButtonAreaInfo && ButtonUnderCursor==i+3 ) {
 		    if( unit->OnBoard[i]->Name ) {
 			char buf[128];
 
@@ -567,11 +578,6 @@ global void DrawResources(void)
     int i;
     int v;
 
-    VideoDrawSub(TheUI.Resource.Graphic,0,0
-	    ,TheUI.Resource.Graphic->Width
-	    ,TheUI.Resource.Graphic->Height
-	    ,TheUI.ResourceX,TheUI.ResourceY);
-
     if( TheUI.OriginalResources ) {
 	// FIXME: could write a sub function for this
 	VideoDrawSub(TheUI.Resources[GoldCost].Icon.Graphic,0
@@ -605,31 +611,43 @@ global void DrawResources(void)
 			,0,TheUI.Resources[i].IconRow*TheUI.Resources[i].IconH
 			,TheUI.Resources[i].IconW,TheUI.Resources[i].IconH
 			,TheUI.Resources[i].IconX,TheUI.Resources[i].IconY);
+	    }
+	    if( TheUI.Resources[i].TextX!=-1 ) {
 		v=ThisPlayer->Resources[i];
 		VideoDrawNumber(TheUI.Resources[i].TextX
 			,TheUI.Resources[i].TextY+(v>99999)*3
 			,v>99999 ? SmallFont : GameFont,v);
 	    }
 	}
-	VideoDrawSub(TheUI.FoodIcon.Graphic,0
-		,TheUI.FoodIconRow*TheUI.FoodIconH
-		,TheUI.FoodIconW,TheUI.FoodIconH
-		,TheUI.FoodIconX,TheUI.FoodIconY);
-	sprintf(tmp,"%d/%d",ThisPlayer->NumFoodUnits,ThisPlayer->Food);
-	if( ThisPlayer->Food<ThisPlayer->NumFoodUnits ) {
-	    VideoDrawReverseText(TheUI.FoodTextX,TheUI.FoodTextY,GameFont,tmp);
-	} else {
-	    VideoDrawText(TheUI.FoodTextX,TheUI.FoodTextY,GameFont,tmp);
+	if( TheUI.Resources[FoodCost].Icon.Graphic ) {
+	    VideoDrawSub(TheUI.Resources[FoodCost].Icon.Graphic,0
+		    ,TheUI.Resources[FoodCost].IconRow*TheUI.Resources[FoodCost].IconH
+		    ,TheUI.Resources[FoodCost].IconW,TheUI.Resources[FoodCost].IconH
+		    ,TheUI.Resources[FoodCost].IconX,TheUI.Resources[FoodCost].IconY);
+	}
+	if( TheUI.Resources[FoodCost].TextX!=-1 ) {
+	    sprintf(tmp,"%d/%d",ThisPlayer->NumFoodUnits,ThisPlayer->Food);
+	    if( ThisPlayer->Food<ThisPlayer->NumFoodUnits ) {
+		VideoDrawReverseText(TheUI.Resources[FoodCost].TextX,
+			TheUI.Resources[FoodCost].TextY,GameFont,tmp);
+	    } else {
+		VideoDrawText(TheUI.Resources[FoodCost].TextX,
+			TheUI.Resources[FoodCost].TextY,GameFont,tmp);
+	    }
 	}
 
-	VideoDrawSub(TheUI.ScoreIcon.Graphic,0
-		,TheUI.ScoreIconRow*TheUI.ScoreIconH
-		,TheUI.ScoreIconW,TheUI.ScoreIconH
-		,TheUI.ScoreIconX,TheUI.ScoreIconY);
-	v=ThisPlayer->Score;
-	VideoDrawNumber(TheUI.ScoreTextX
-		,TheUI.ScoreTextY+(v>99999)*3
-		,v>99999 ? SmallFont : GameFont,v);
+	if( TheUI.Resources[ScoreCost].Icon.Graphic ) {
+	    VideoDrawSub(TheUI.Resources[ScoreCost].Icon.Graphic,0
+		    ,TheUI.Resources[ScoreCost].IconRow*TheUI.Resources[ScoreCost].IconH
+		    ,TheUI.Resources[ScoreCost].IconW,TheUI.Resources[ScoreCost].IconH
+		    ,TheUI.Resources[ScoreCost].IconX,TheUI.Resources[ScoreCost].IconY);
+	}
+	if( TheUI.Resources[ScoreCost].TextX!=-1 ) {
+	    v=ThisPlayer->Score;
+	    VideoDrawNumber(TheUI.Resources[ScoreCost].TextX
+		    ,TheUI.Resources[ScoreCost].TextY+(v>99999)*3
+		    ,v>99999 ? SmallFont : GameFont,v);
+	}
     }
 }
 
@@ -704,7 +722,7 @@ global void UpdateMessages(void)
     // Scroll/remove old message line
     if (MessagesFrameTimeout < FrameCounter) {
 	++MessagesScrollY;
-	if (MessagesScrollY == VideoTextHeight(GameFont) + 1) {
+	if (MessagesScrollY == VideoTextHeight(TheUI.MessageAreaFont) + 1) {
 	    MessagesFrameTimeout = FrameCounter + MESSAGES_TIMEOUT - MessagesScrollY;
 	    MessagesScrollY = 0;
 	    ShiftMessages();
@@ -724,16 +742,20 @@ global void DrawMessages(void)
 {
     int z;
 
+    if (TheUI.MessageAreaX==-1 ) {
+	return;
+    }
+
     // Draw message line(s)
     for (z = 0; z < MessagesCount; z++) {
 	if (z == 0) {
 	    PushClipping();
-	    SetClipping(TheUI.MapArea.X + 8, TheUI.MapArea.Y + 8, VideoWidth - 1,
+	    SetClipping(TheUI.MessageAreaX, TheUI.MessageAreaY, VideoWidth - 1,
 		VideoHeight - 1);
 	}
-	VideoDrawTextClip(TheUI.MapArea.X + 8,
-	    TheUI.MapArea.Y + 8 + z * (VideoTextHeight(GameFont) + 1) - MessagesScrollY,
-	    GameFont, Messages[z]);
+	VideoDrawTextClip(TheUI.MessageAreaX,
+	    TheUI.MessageAreaY + z * (VideoTextHeight(TheUI.MessageAreaFont) + 1) - MessagesScrollY,
+	    TheUI.MessageAreaFont, Messages[z]);
 	if (z == 0) {
 	    PopClipping();
 	}
@@ -754,6 +776,10 @@ local void AddMessage(const char *msg)
     char *message;
     char *next;
 
+    if (TheUI.MessageAreaX==-1) {
+	return;
+    }
+
     if (!MessagesCount) {
 	MessagesFrameTimeout = FrameCounter + MESSAGES_TIMEOUT;
     }
@@ -788,8 +814,7 @@ local void AddMessage(const char *msg)
 	next = ptr = message + strlen(message);
     }
 
-    // FIXME: 440+(VideoWidth-640) is the wrong value.
-    while (VideoTextLength(GameFont, message) >= 440+(VideoWidth-640) ) {
+    while (VideoTextLength(TheUI.MessageAreaFont, message) >= TheUI.MessageAreaW ) {
 	while (1) {
 	    --ptr;
 	    if (*ptr == ' ') {
@@ -803,7 +828,7 @@ local void AddMessage(const char *msg)
 	// No space found, wrap in the middle of a word
 	if (ptr == message) {
 	    ptr = next-1;
-	    while (VideoTextLength(GameFont, message) >= 440+(VideoWidth-640) ) {
+	    while (VideoTextLength(TheUI.MessageAreaFont, message) >= TheUI.MessageAreaW ) {
 		*--ptr = '\0';
 	    }
 	    next = ptr+1;
@@ -946,12 +971,9 @@ local char StatusLine[STATUS_LINE_LEN];			/// status line/hints
 */
 global void DrawStatusLine(void)
 {
-    VideoDrawSub(TheUI.StatusLine.Graphic
-	    ,0,0
-	    ,TheUI.StatusLine.Graphic->Width,TheUI.StatusLine.Graphic->Height
-	    ,TheUI.StatusLineX,TheUI.StatusLineY);
-    if( StatusLine ) {
-	VideoDrawText(TheUI.StatusLineX+2,TheUI.StatusLineY+2,GameFont,StatusLine);
+    if( TheUI.StatusLineX!=-1 && StatusLine[0] ) {
+	VideoDrawText(TheUI.StatusLineX,TheUI.StatusLineY,
+		TheUI.StatusLineFont,StatusLine);
     }
 }
 
@@ -962,9 +984,9 @@ global void DrawStatusLine(void)
 */
 global void SetStatusLine(char* status)
 {
-    if( KeyState!=KeyStateInput && strcmp( StatusLine, status ) ) {
+    if( KeyState!=KeyStateInput && strcmp(StatusLine,status) ) {
 	MustRedraw|=RedrawStatusLine;
-	strncpy( StatusLine, status, STATUS_LINE_LEN-1 );
+	strncpy(StatusLine,status,STATUS_LINE_LEN-1);
 	StatusLine[STATUS_LINE_LEN-1] = 0;
     }
 }
@@ -975,7 +997,7 @@ global void SetStatusLine(char* status)
 global void ClearStatusLine(void)
 {
     if( KeyState!=KeyStateInput ) {
-	SetStatusLine( "" );
+	SetStatusLine("");
     }
 }
 
@@ -998,13 +1020,15 @@ global void DrawCosts(void)
     x=TheUI.StatusLineX+270;
     if( CostsMana ) {
 	// FIXME: hardcoded image!!!
-	VideoDrawSub(TheUI.Resources[GoldCost].Icon.Graphic
-		/* ,0,TheUI.Resources[GoldCost].IconRow
-			*TheUI.Resources[GoldCost].IconH */
-		,0,3*TheUI.Resources[GoldCost].IconH
-		,TheUI.Resources[GoldCost].IconW
-		,TheUI.Resources[GoldCost].IconH
-		,x,TheUI.StatusLineY+1);
+	if( TheUI.Resources[GoldCost].Icon.Graphic ) {
+	    VideoDrawSub(TheUI.Resources[GoldCost].Icon.Graphic
+		    /* ,0,TheUI.Resources[GoldCost].IconRow
+			    *TheUI.Resources[GoldCost].IconH */
+		    ,0,3*TheUI.Resources[GoldCost].IconH
+		    ,TheUI.Resources[GoldCost].IconW
+		    ,TheUI.Resources[GoldCost].IconH
+		    ,x,TheUI.StatusLineY+1);
+	}
 
 	VideoDrawNumber(x+15,TheUI.StatusLineY+2,GameFont,CostsMana);
 	x+=45;
@@ -1028,10 +1052,12 @@ global void DrawCosts(void)
 
     if( CostsFood ) {
 	// FIXME: hardcoded image!!!
-	VideoDrawSub(TheUI.FoodIcon.Graphic
-		,0,TheUI.FoodIconRow*TheUI.FoodIconH
-		,TheUI.FoodIconW,TheUI.FoodIconH
-		,x,TheUI.StatusLineY+1);
+	if( TheUI.Resources[FoodCost].Icon.Graphic ) {
+	    VideoDrawSub(TheUI.Resources[FoodCost].Icon.Graphic
+		    ,0,TheUI.Resources[FoodCost].IconRow*TheUI.Resources[FoodCost].IconH
+		    ,TheUI.Resources[FoodCost].IconW,TheUI.Resources[FoodCost].IconH
+		    ,x,TheUI.StatusLineY+1);
+	}
 	VideoDrawNumber(x+15,TheUI.StatusLineY+2,GameFont,CostsFood);
 	x+=45;
     }
@@ -1097,10 +1123,12 @@ global void ClearCosts(void)
 */
 local void DrawInfoPanelBackground(unsigned frame)
 {
-    VideoDrawSub(TheUI.InfoPanel.Graphic
-	    ,0,TheUI.InfoPanelH*frame
-	    ,TheUI.InfoPanelW,TheUI.InfoPanelH
-	    ,TheUI.InfoPanelX,TheUI.InfoPanelY);
+    if( TheUI.InfoPanel.Graphic ) {
+	VideoDrawSub(TheUI.InfoPanel.Graphic,
+		0,TheUI.InfoPanelH*frame,
+		TheUI.InfoPanelW,TheUI.InfoPanelH,
+		TheUI.InfoPanelX,TheUI.InfoPanelY);
+    }
 }
 
 /**
@@ -1116,20 +1144,25 @@ global void DrawInfoPanel(void)
 {
     int i;
 
+    if( TheUI.InfoPanelX==-1 ) {
+	return;
+    }
+
     if( NumSelected ) {
 	if( NumSelected>1 ) {
 	    PlayerPixels(ThisPlayer);	// can only be own!
-	    DrawInfoPanelBackground(0);
+	    DrawInfoPanelBackground(TheUI.InfoPanelNeutralFrame);
             for( i=0; i<NumSelected; ++i ) {
-	        DrawUnitIcon(ThisPlayer
-			,Selected[i]->Type->Icon.Icon
-			,(ButtonUnderCursor==i+1)
-			    ? (IconActive|(MouseButtons&LeftButton)) : 0
-				,TheUI.Buttons[i+1].X,TheUI.Buttons[i+1].Y);
+	        DrawUnitIcon(ThisPlayer,
+			Selected[i]->Type->Icon.Icon,
+			(ButtonAreaUnderCursor==ButtonAreaInfo && ButtonUnderCursor==0)
+			    ? (IconActive|(MouseButtons&LeftButton)) : 0,
+			TheUI.InfoButtons[i].X,TheUI.InfoButtons[i].Y);
 		UiDrawLifeBar(Selected[i]
-			,TheUI.Buttons[i+1].X,TheUI.Buttons[i+1].Y);
+			,TheUI.InfoButtons[i].X,TheUI.InfoButtons[i].Y);
 
-		if( ButtonUnderCursor==1+i ) {
+		if( ButtonAreaUnderCursor==ButtonAreaInfo
+			&& ButtonUnderCursor==i ) {
 		    if( Selected[i]->Name ) {
 			char buf[128];
 
@@ -1150,18 +1183,18 @@ global void DrawInfoPanel(void)
 			|| Selected[0]->Orders[0].Action==UnitActionResearch
 			|| Selected[0]->Orders[0].Action==UnitActionUpgradeTo
 			|| Selected[0]->Orders[0].Action==UnitActionTrain) ) {
-		    i=3;
+		    i=TheUI.InfoPanelConstructionFrame;
 		} else if( Selected[0]->Type->_MaxMana ) {
-		    i=2;
+		    i=TheUI.InfoPanelMagicFrame;
 		} else {
-		    i=1;
+		    i=TheUI.InfoPanelSelectedFrame;
 		}
 	    } else {
-		i=0;
+		i=TheUI.InfoPanelNeutralFrame;
 	    }
 	    DrawInfoPanelBackground(i);
 	    DrawUnitInfo(Selected[0]);
-	    if( ButtonUnderCursor==1 ) {
+	    if( ButtonAreaUnderCursor==ButtonAreaInfo && ButtonUnderCursor==0 ) {
 		if( Selected[0]->Name ) {
 		    char buf[128];
 
@@ -1178,7 +1211,7 @@ global void DrawInfoPanel(void)
 
     //	Nothing selected
 
-    DrawInfoPanelBackground(0);
+    DrawInfoPanelBackground(TheUI.InfoPanelNeutralFrame);
     if( UnitUnderCursor && UnitVisibleOnMap(UnitUnderCursor) ) {
 	// FIXME: not correct for enemies units
 	DrawUnitInfo(UnitUnderCursor);
@@ -1189,6 +1222,10 @@ global void DrawInfoPanel(void)
 	char* rc;
 	// FIXME: need some cool ideas for this.
 
+	if( TheUI.InfoPanelW<176 ) {
+	    return;
+	}
+
 	x=TheUI.InfoPanelX+16;
 	y=TheUI.InfoPanelY+8;
 
@@ -1239,23 +1276,23 @@ global void DrawTimer(void)
     int min;
     int sec;
 
-    if (!GameTimer.Init) {
+    if( !GameTimer.Init ) {
 	return;
     }
 
-    sec = GameTimer.Cycles / CYCLES_PER_SECOND % 60;
-    min = (GameTimer.Cycles / CYCLES_PER_SECOND / 60) % 60;
-    hour = (GameTimer.Cycles / CYCLES_PER_SECOND / 3600);
+    sec=GameTimer.Cycles / CYCLES_PER_SECOND % 60;
+    min=(GameTimer.Cycles / CYCLES_PER_SECOND / 60) % 60;
+    hour=(GameTimer.Cycles / CYCLES_PER_SECOND / 3600);
 
-    if (hour) {
-	sprintf(buf, "%d:%02d:%02d", hour, min, sec);
+    if( hour ) {
+	sprintf(buf,"%d:%02d:%02d",hour,min,sec);
     } else {
-	sprintf(buf, "%d:%02d", min, sec);
+	sprintf(buf,"%d:%02d",min,sec);
     }
 
     // FIXME: make this configurable
-    VideoDrawText(TheUI.SelectedViewport->EndX - 70,
-	TheUI.SelectedViewport->Y + 15, GameFont, buf);
+    VideoDrawText(TheUI.SelectedViewport->EndX-70,
+	TheUI.SelectedViewport->Y+15,GameFont,buf);
 }
 
 /**
diff --git a/src/ui/menu_defs.inc b/src/ui/menu_defs.inc
index ea45717c3..06bf88db9 100644
--- a/src/ui/menu_defs.inc
+++ b/src/ui/menu_defs.inc
@@ -157,46 +157,6 @@ local char *MenuHotKeyToStr(int key, char *buf)
     return buf;
 }
 
-local char *MenuButtonStyle(int style)
-{
-    switch (style) {
-	case MBUTTON_MAIN:
-	    return "main";
-	case MBUTTON_GM_HALF:
-	    return "gm-half";
-	case MBUTTON_132:
-	    return "132";
-	case MBUTTON_GM_FULL:
-	    return "gm-full";
-	case MBUTTON_GEM_ROUND:
-	    return "gem-round";
-	case MBUTTON_GEM_SQUARE:
-	    return "gem-square";
-	case MBUTTON_UP_ARROW:
-	    return "up-arrow";
-	case MBUTTON_DOWN_ARROW:
-	    return "down-arrow";
-	case MBUTTON_LEFT_ARROW:
-	    return "left-arrow";
-	case MBUTTON_RIGHT_ARROW:
-	    return "right-arrow";
-	case MBUTTON_S_KNOB:
-	    return "s-knob";
-	case MBUTTON_S_VCONT:
-	    return "s-vcont";
-	case MBUTTON_S_HCONT:
-	    return "s-hcont";
-	case MBUTTON_PULLDOWN:
-	    return "pulldown";
-	case MBUTTON_VTHIN:
-	    return "vthin";
-	case MBUTTON_FOLDER:
-	    return "folder";
-    }
-    fprintf(stderr,"MenuButtonStyle not found: %d\n", style);
-    return "";
-}
-
 /**
 **	Save state of units to file.
 **
diff --git a/src/ui/menu_proc.cpp b/src/ui/menu_proc.cpp
index 04b24a6a5..f5b957e0e 100644
--- a/src/ui/menu_proc.cpp
+++ b/src/ui/menu_proc.cpp
@@ -104,6 +104,51 @@ local int MenuButtonCurSel = -1;
 --	Menu operation functions
 ----------------------------------------------------------------------------*/
 
+/**
+**	FIXME: docu
+*/
+global char *MenuButtonStyle(int style)
+{
+    switch (style) {
+	case MBUTTON_MAIN:
+	    return "main";
+	case MBUTTON_NETWORK:
+	    return "network";
+	case MBUTTON_GM_HALF:
+	    return "gm-half";
+	case MBUTTON_132:
+	    return "132";
+	case MBUTTON_GM_FULL:
+	    return "gm-full";
+	case MBUTTON_GEM_ROUND:
+	    return "gem-round";
+	case MBUTTON_GEM_SQUARE:
+	    return "gem-square";
+	case MBUTTON_UP_ARROW:
+	    return "up-arrow";
+	case MBUTTON_DOWN_ARROW:
+	    return "down-arrow";
+	case MBUTTON_LEFT_ARROW:
+	    return "left-arrow";
+	case MBUTTON_RIGHT_ARROW:
+	    return "right-arrow";
+	case MBUTTON_S_KNOB:
+	    return "s-knob";
+	case MBUTTON_S_VCONT:
+	    return "s-vcont";
+	case MBUTTON_S_HCONT:
+	    return "s-hcont";
+	case MBUTTON_PULLDOWN:
+	    return "pulldown";
+	case MBUTTON_VTHIN:
+	    return "vthin";
+	case MBUTTON_FOLDER:
+	    return "folder";
+    }
+    fprintf(stderr,"MenuButtonStyle not found: %d\n", style);
+    return "";
+}
+
 /**
 **	Find a menu by ident.
 **
@@ -2343,9 +2388,6 @@ global void ProcessMenu(const char *menu_id, int loop)
 	    }
 	    DebugLevel3("MustRedraw: 0x%08x\n" _C_ MustRedraw);
 	    if (MustRedraw) {
-		if (CurrentMenu->Panel && !strcmp(CurrentMenu->Panel, ScPanel)) {
-		    MustRedraw = RedrawEverything;
-		}
 		if (MustRedraw == RedrawEverything) {
 		    InterfaceState = IfaceStateNormal;
 		    UpdateDisplay();
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index 3916d6bc0..69e71f34e 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -61,8 +61,10 @@ global enum _mouse_buttons_ MouseButtons;/// Current pressed mouse buttons
 global enum _key_modifiers_ KeyModifiers;/// Current keyboard modifiers
 
 global Unit* UnitUnderCursor;		/// Unit under cursor
+global int ButtonAreaUnderCursor=-1;	/// Button area under cursor
 global int ButtonUnderCursor=-1;	/// Button under cursor
-global char GameMenuButtonClicked;	/// Game menu button (F10) was clicked
+global char GameMenuButtonClicked;	/// Menu button was clicked
+global char GameDiplomacyButtonClicked;	/// Diplomacy button was clicked
 global char LeaveStops;			/// Mouse leaves windows stops scroll
 
 global enum _cursor_on_ CursorOn=CursorOnUnknown;	/// Cursor on field
@@ -103,31 +105,31 @@ local void DrawMouseCoordsOnMap(int x,int y)
 	return;
     }
     VideoLockScreen();
-    VideoDrawSub(TheUI.MenuButton.Graphic,0,0
-	    ,TheUI.MenuButton.Graphic->Width
-	    ,TheUI.MenuButton.Graphic->Height
-	    ,TheUI.MenuButtonX,TheUI.MenuButtonY);
+    VideoDrawSub(TheUI.MenuButton.Graphic,0,0,
+	    TheUI.MenuButton.Graphic->Width,
+	    TheUI.MenuButton.Graphic->Height,
+	    TheUI.MenuButtonX,TheUI.MenuButtonY);
     flags=TheMap.Fields[x+y*TheMap.Width].Flags;
 //  sprintf(buf,"%3d,%3d=%02X|%04X|%c%c%c%c%c%c%c%c%c",x,y
-    sprintf(buf,"%3d,%3d=%02X|%04X|%c%c%c%c%c%c%c",x,y
-	    ,TheMap.Fields[x+y*TheMap.Width].Value
-	    ,flags
+    sprintf(buf,"%3d,%3d=%02X|%04X|%c%c%c%c%c%c%c",x,y,
+	    TheMap.Fields[x+y*TheMap.Width].Value,
+	    flags,
 	    //,TheMap.Fields[x+y*TheMap.Width].Tile
-	    ,flags&MapFieldUnpassable	?'u':'-'
-	    ,flags&MapFieldNoBuilding	?'n':'-'
-	    ,flags&MapFieldForest	?'f':'-'
-	    ,flags&MapFieldWaterAllowed ?'w':'-'
-	    ,flags&MapFieldCoastAllowed ?'c':'-'
-	    ,flags&MapFieldLandAllowed	?'l':'-'
-	    ,flags&MapFieldHuman	?'h':'-'
-//	    ,flags&MapFieldExplored	?'e':'-'
-//	    ,flags&MapFieldVisible	?'v':'-'
+	    flags&MapFieldUnpassable	?'u':'-',
+	    flags&MapFieldNoBuilding	?'n':'-',
+	    flags&MapFieldForest	?'f':'-',
+	    flags&MapFieldWaterAllowed ?'w':'-',
+	    flags&MapFieldCoastAllowed ?'c':'-',
+	    flags&MapFieldLandAllowed	?'l':'-',
+	    flags&MapFieldHuman	?'h':'-'
+//	    flags&MapFieldExplored	?'e':'-'
+//	    flags&MapFieldVisible	?'v':'-'
 	);
     VideoDrawText(TheUI.MenuButtonX+3,TheUI.MenuButtonY+3,GameFont,buf);
     VideoUnlockScreen();
-    InvalidateArea(TheUI.MenuButtonX,TheUI.MenuButtonY
-	    ,TheUI.MenuButton.Graphic->Width
-	    ,TheUI.MenuButton.Graphic->Height);
+    InvalidateArea(TheUI.MenuButtonX,TheUI.MenuButtonY,
+	    TheUI.MenuButton.Graphic->Width,
+	    TheUI.MenuButton.Graphic->Height);
 }
 #endif	// } FLAG_DEBUG
 
@@ -463,46 +465,105 @@ local void HandleMouseOn(int x,int y)
     //
     //	Handle buttons
     //
-    for( i=0; i<(int)(sizeof(TheUI.Buttons)/sizeof(*TheUI.Buttons)); ++i ) {
-	if( x<TheUI.Buttons[i].X
-		|| x>TheUI.Buttons[i].X+TheUI.Buttons[i].Width
-		|| y<TheUI.Buttons[i].Y
-		|| y>TheUI.Buttons[i].Y+TheUI.Buttons[i].Height ) {
-	    continue;
-	}
-	DebugLevel3("On button %d\n" _C_ i);
-	ButtonUnderCursor=i;
-	CursorOn=CursorOnButton;
-	if( i<10 ) {
-	    if (i == 0) {		// Menu button
+    if( NetworkFildes==-1 ) {
+	if( TheUI.MenuButton.X!=-1 ) {
+	    if( x>=TheUI.MenuButton.X
+		    && x<=TheUI.MenuButton.X+TheUI.MenuButton.Width
+		    && y>TheUI.MenuButton.Y
+		    && y<=TheUI.MenuButton.Y+TheUI.MenuButton.Height ) {
+		ButtonAreaUnderCursor=ButtonAreaMenu;
+		ButtonUnderCursor=ButtonUnderMenu;
+		CursorOn=CursorOnButton;
 		MustRedraw|=RedrawMenuButton;
-	    } else {
-		MustRedraw|=RedrawInfoPanel;
+		return;
+	    }
+	}
+    } else {
+	if( TheUI.NetworkMenuButton.X!=-1 ) {
+	    if( x>=TheUI.NetworkMenuButton.X
+		    && x<=TheUI.NetworkMenuButton.X+TheUI.NetworkMenuButton.Width
+		    && y>TheUI.NetworkMenuButton.Y
+		    && y<=TheUI.NetworkMenuButton.Y+TheUI.NetworkMenuButton.Height ) {
+		ButtonAreaUnderCursor=ButtonAreaMenu;
+		ButtonUnderCursor=ButtonUnderNetworkMenu;
+		CursorOn=CursorOnButton;
+		MustRedraw|=RedrawMenuButton;
+		return;
+	    }
+	}
+	if( TheUI.NetworkDiplomacyButton.X!=-1 ) {
+	    if( x>=TheUI.NetworkDiplomacyButton.X
+		    && x<=TheUI.NetworkDiplomacyButton.X+TheUI.NetworkDiplomacyButton.Width
+		    && y>TheUI.NetworkDiplomacyButton.Y
+		    && y<=TheUI.NetworkDiplomacyButton.Y+TheUI.NetworkDiplomacyButton.Height ) {
+		ButtonAreaUnderCursor=ButtonAreaMenu;
+		ButtonUnderCursor=ButtonUnderNetworkDiplomacy;
+		CursorOn=CursorOnButton;
+		MustRedraw|=RedrawMenuButton;
+		return;
+	    }
+	}
+    }
+    for( i=0; i<TheUI.NumButtonButtons; ++i ) {
+	if( x>=TheUI.ButtonButtons[i].X
+		&& x<=TheUI.ButtonButtons[i].X+TheUI.ButtonButtons[i].Width+7
+		&& y>TheUI.ButtonButtons[i].Y
+		&& y<=TheUI.ButtonButtons[i].Y+TheUI.ButtonButtons[i].Height+7 ) {
+	    ButtonAreaUnderCursor=ButtonAreaButton;
+	    ButtonUnderCursor=i;
+	    CursorOn=CursorOnButton;
+	    MustRedraw|=RedrawButtonPanel;
+	    return;
+	}
+    }
+    if( NumSelected==1 && Selected[0]->Type->Building
+	    && Selected[0]->Orders[0].Action==UnitActionTrain
+	    && Selected[0]->Data.Train.Count>1 ) {
+	for( i=0; i<TheUI.NumTrainingButtons; ++i ) {
+	    if( x>=TheUI.TrainingButtons[i].X
+		    && x<=TheUI.TrainingButtons[i].X+TheUI.TrainingButtons[i].Width+7
+		    && y>TheUI.TrainingButtons[i].Y
+		    && y<=TheUI.TrainingButtons[i].Y+TheUI.TrainingButtons[i].Height+7 ) {
+		ButtonAreaUnderCursor=ButtonAreaTraining;
+		ButtonUnderCursor=i;
+		CursorOn=CursorOnButton;
+		MustRedraw|=RedrawButtonPanel;
+		return;
+	    }
+	}
+    } else {
+	for( i=0; i<TheUI.NumInfoButtons; ++i ) {
+	    if( x>=TheUI.InfoButtons[i].X
+		    && x<=TheUI.InfoButtons[i].X+TheUI.InfoButtons[i].Width+7
+		    && y>TheUI.InfoButtons[i].Y
+		    && y<=TheUI.InfoButtons[i].Y+TheUI.InfoButtons[i].Height+7 ) {
+		ButtonAreaUnderCursor=ButtonAreaInfo;
+		ButtonUnderCursor=i;
+		CursorOn=CursorOnButton;
+		MustRedraw|=RedrawButtonPanel;
+		return;
 	    }
-	} else {
-	    MustRedraw|=RedrawButtonPanel;
 	}
-	return;
     }
 
     if( ButtonUnderCursor!=-1 ) {	// remove old display
-	if( ButtonUnderCursor<10 ) {
-	    if (ButtonUnderCursor == 0) {	// Menu button
-		MustRedraw|=RedrawMenuButton;
-	    } else {
-		MustRedraw|=RedrawInfoPanel;
-	    }
+	if( ButtonAreaUnderCursor==ButtonAreaMenu ) {
+	    MustRedraw|=RedrawMenuButton;
+	} else if( ButtonAreaUnderCursor==ButtonAreaInfo ) {
+	    MustRedraw|=RedrawInfoPanel;
 	} else {
 	    MustRedraw|=RedrawButtonPanel;
 	}
+	ButtonAreaUnderCursor=-1;
 	ButtonUnderCursor=-1;
     }
 
     //
     //	Minimap
     //
-    if( x>=TheUI.MinimapX+24 && x<TheUI.MinimapX+24+MINIMAP_W
-	    && y>=TheUI.MinimapY+2 && y<TheUI.MinimapY+2+MINIMAP_H ) {
+    if( TheUI.MinimapX!=-1
+	    && x>=TheUI.MinimapX && x<TheUI.MinimapX+TheUI.MinimapW
+	    && y>=TheUI.MinimapY && y<TheUI.MinimapY+TheUI.MinimapH ) {
 	CursorOn=CursorOnMinimap;
 	return;
     }
@@ -596,18 +657,18 @@ global void RestrictCursorToViewport(void)
 */
 global void RestrictCursorToMinimap(void)
 {
-    if (CursorX < TheUI.MinimapX + 24) {
-	CursorStartX = TheUI.MinimapX + 24;
-    } else if (CursorX >= TheUI.MinimapX + 24 + MINIMAP_W) {
-	CursorStartX = TheUI.MinimapX + 24 + MINIMAP_W - 1;
+    if (CursorX < TheUI.MinimapX) {
+	CursorStartX = TheUI.MinimapX;
+    } else if (CursorX >= TheUI.MinimapX + TheUI.MinimapW) {
+	CursorStartX = TheUI.MinimapX + TheUI.MinimapW - 1;
     } else {
 	CursorStartX = CursorX;
     }
 
-    if (CursorY < TheUI.MinimapY + 2) {
-	CursorStartY = TheUI.MinimapY + 2;
-    } else if (CursorY >= TheUI.MinimapY + 2 + MINIMAP_H) {
-	CursorStartY = TheUI.MinimapY + 2 + MINIMAP_H - 1;
+    if (CursorY < TheUI.MinimapY) {
+	CursorStartY = TheUI.MinimapY;
+    } else if (CursorY >= TheUI.MinimapY + TheUI.MinimapH) {
+	CursorStartY = TheUI.MinimapY + TheUI.MinimapH - 1;
     } else {
 	CursorStartY = CursorY;
     }
@@ -694,7 +755,7 @@ global void UIHandleMouseMove(int x,int y)
     //
     //	User may be draging with button pressed.
     //
-    if( GameMenuButtonClicked ) {
+    if( GameMenuButtonClicked || GameDiplomacyButtonClicked ) {
 	return;
     }
 
@@ -1215,11 +1276,11 @@ local void UISelectStateButtonDown(unsigned button __attribute__((unused)))
 	sx = CursorX - vp->X + TileSizeX * vp->MapX;
 	sy = CursorY - vp->Y + TileSizeY * vp->MapY;
 	if( MouseButtons&LeftButton ) {
-	    MakeLocalMissile(MissileTypeGreenCross
-		    ,vp->MapX*TileSizeX+CursorX - vp->X
-		    ,vp->MapY*TileSizeY+CursorY - vp->Y
-		    ,vp->MapX*TileSizeX+CursorX - vp->X
-		    ,vp->MapY*TileSizeY+CursorY - vp->Y);
+	    MakeLocalMissile(MissileTypeGreenCross,
+		    vp->MapX*TileSizeX+CursorX - vp->X,
+		    vp->MapY*TileSizeY+CursorY - vp->Y,
+		    vp->MapX*TileSizeX+CursorX - vp->X,
+		    vp->MapY*TileSizeY+CursorY - vp->Y);
 	    SendCommand(sx, sy);
 	}
 	return;
@@ -1244,8 +1305,8 @@ local void UISelectStateButtonDown(unsigned button __attribute__((unused)))
 	    CurrentButtonLevel = 0; // reset unit buttons to normal
 	    UpdateButtonPanel();
 	    MustRedraw|=RedrawButtonPanel|RedrawCursor;
-	    MakeLocalMissile(MissileTypeGreenCross
-		    ,sx+TileSizeX/2,sy+TileSizeY/2,0,0);
+	    MakeLocalMissile(MissileTypeGreenCross,
+		    sx+TileSizeX/2,sy+TileSizeY/2,0,0);
 	    SendCommand(sx,sy);
 	} else {
 	    ViewportCenterViewpoint(TheUI.SelectedViewport, mx, my);
@@ -1255,8 +1316,8 @@ local void UISelectStateButtonDown(unsigned button __attribute__((unused)))
 
     if( CursorOn==CursorOnButton ) {
 	// FIXME: other buttons?
-	if( ButtonUnderCursor>9 ) {
-	    DoButtonButtonClicked(ButtonUnderCursor-10);
+	if( ButtonAreaUnderCursor==ButtonAreaButton ) {
+	    DoButtonButtonClicked(ButtonUnderCursor);
 	    return;
 	}
     }
@@ -1363,16 +1424,16 @@ global void UIHandleButtonDown(unsigned button)
 		}
 		if( CanBuildUnitType(Selected[0],CursorBuilding,x,y)
 			&& (explored || ReplayRevealMap) ) {
-		    PlayGameSound(GameSounds.PlacementSuccess.Sound
-			    ,MaxSampleVolume);
-		    SendCommandBuildBuilding(Selected[0],x,y,CursorBuilding
-			    ,!(KeyModifiers&ModifierShift));
+		    PlayGameSound(GameSounds.PlacementSuccess.Sound,
+			    MaxSampleVolume);
+		    SendCommandBuildBuilding(Selected[0],x,y,CursorBuilding,
+			    !(KeyModifiers&ModifierShift));
 		    if( !(KeyModifiers&ModifierAlt) ) {
 			CancelBuildingMode();
 		    }
 		} else {
-		    PlayGameSound(GameSounds.PlacementError.Sound
-			    ,MaxSampleVolume);
+		    PlayGameSound(GameSounds.PlacementError.Sound,
+			    MaxSampleVolume);
 		}
 	    } else {
 		CancelBuildingMode();
@@ -1418,10 +1479,10 @@ global void UIHandleButtonDown(unsigned button)
 		if( UnitUnderCursor && (unit=UnitOnScreenMapPosition(x,y)) ) {
 		    unit->Blink=4;	// if right click on building -- blink
 		} else {	// if not not click on building -- green cross
-		    MakeLocalMissile(MissileTypeGreenCross
-			,TheUI.MouseViewport->MapX*TileSizeX
-			    +CursorX-TheUI.MouseViewport->X
-			,TheUI.MouseViewport->MapY*TileSizeY
+		    MakeLocalMissile(MissileTypeGreenCross,
+			TheUI.MouseViewport->MapX*TileSizeX
+			    +CursorX-TheUI.MouseViewport->X,
+			TheUI.MouseViewport->MapY*TileSizeY
 			    +CursorY-TheUI.MouseViewport->Y,0,0);
 		}
 		DoRightButton(x,y);
@@ -1436,9 +1497,9 @@ global void UIHandleButtonDown(unsigned button)
 		ScreenMinimap2MapX(CursorX), ScreenMinimap2MapY(CursorY));
 	} else if( MouseButtons&RightButton ) {
 	    if( !GameObserve && !GamePaused ) {
-		MakeLocalMissile(MissileTypeGreenCross
-			,ScreenMinimap2MapX(CursorX)*TileSizeX+TileSizeX/2
-			,ScreenMinimap2MapY(CursorY)*TileSizeY+TileSizeY/2,0,0);
+		MakeLocalMissile(MissileTypeGreenCross,
+			ScreenMinimap2MapX(CursorX)*TileSizeX+TileSizeX/2,
+			ScreenMinimap2MapY(CursorY)*TileSizeY+TileSizeY/2,0,0);
 		// DoRightButton() takes screen map coordinates
 		DoRightButton(ScreenMinimap2MapX(CursorX) * TileSizeX,
 			ScreenMinimap2MapY(CursorY) * TileSizeY);
@@ -1451,75 +1512,82 @@ global void UIHandleButtonDown(unsigned button)
 	//
 	//	clicked on info panel - selection shown
 	//
-	if( NumSelected>1 && ButtonUnderCursor && ButtonUnderCursor<10 ) {
+	if( NumSelected>1 && ButtonAreaUnderCursor==ButtonAreaInfo ) {
 	    if( !GameObserve && !GamePaused ) {
-		DoSelectionButtons(ButtonUnderCursor-1,button);
+		DoSelectionButtons(ButtonUnderCursor,button);
 	    }
 	} else if( (MouseButtons&LeftButton) ) {
 	    //
 	    //	clicked on menu button
 	    //
-	    if( ButtonUnderCursor==0 && !GameMenuButtonClicked ) {
-		PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
-		GameMenuButtonClicked = 1;
-		MustRedraw|=RedrawMenuButton;
+	    if( ButtonAreaUnderCursor==ButtonAreaMenu ) {
+		if( (ButtonUnderCursor==ButtonUnderMenu
+			    || ButtonUnderCursor==ButtonUnderNetworkMenu)
+			&& !GameMenuButtonClicked ) {
+		    PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
+		    GameMenuButtonClicked=1;
+		    MustRedraw|=RedrawMenuButton;
+		} else if( ButtonUnderCursor==ButtonUnderNetworkDiplomacy
+			&& !GameDiplomacyButtonClicked ) {
+		    PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
+		    GameDiplomacyButtonClicked=1;
+		    MustRedraw|=RedrawMenuButton;
+		}
 	    //
-	    //	clicked on info panel - single unit shown
+	    //	clicked on info panel
 	    //
-	    } else if( ButtonUnderCursor==1 && NumSelected==1 ) {
-		PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
-		ViewportCenterViewpoint(TheUI.SelectedViewport, Selected[0]->X,
-			Selected[0]->Y);
-	    //
-	    //	clicked on info panel - single unit shown
-	    //		for transporter - training queues
-	    //
-	    } else if( ButtonUnderCursor>3 && ButtonUnderCursor<10 ) {
-		if( NumSelected==1 && Selected[0]->Type->Transporter ) {
-		    if( !GameObserve && !GamePaused ) {
-			if( Selected[0]->OnBoard[ButtonUnderCursor-4] ) {
-			    // FIXME: should check if valid here.
-			    SendCommandUnload(Selected[0]
-				    ,Selected[0]->X,Selected[0]->Y
-				    ,Selected[0]->OnBoard[ButtonUnderCursor-4]
-				    ,!(KeyModifiers&ModifierShift));
+	    } else if( ButtonAreaUnderCursor==ButtonAreaInfo ) {
+		//
+		//  clicked on single unit shown
+		//
+		if( ButtonUnderCursor==0 && NumSelected==1 ) {
+		    PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
+		    ViewportCenterViewpoint(TheUI.SelectedViewport, Selected[0]->X,
+			    Selected[0]->Y);
+		//
+		//  for transporter
+		//
+		} else if( ButtonUnderCursor>2 && ButtonUnderCursor<9 ) {
+		    if( NumSelected==1 && Selected[0]->Type->Transporter ) {
+			if( !GameObserve && !GamePaused ) {
+			    if( Selected[0]->OnBoard[ButtonUnderCursor-3] ) {
+				// FIXME: should check if valid here.
+				SendCommandUnload(Selected[0],
+					Selected[0]->X,Selected[0]->Y,
+					Selected[0]->OnBoard[ButtonUnderCursor-3],
+					!(KeyModifiers&ModifierShift));
+			    }
 			}
 		    }
 		}
-		else if( NumSelected==1 && Selected[0]->Type->Building &&
-		         Selected[0]->Orders[0].Action==UnitActionTrain) {
-		    if( !GameObserve && !GamePaused ) {
-			int slotid = ButtonUnderCursor-4;
-			if ( Selected[0]->Data.Train.Count == 1 ) {
-			    // FIXME: ignore clicks that did not hit
-			    // FIXME: with only one unit being built, this
-			    // unit is displayed between two slots.
-			    slotid = 0;
-			}
-			if ( slotid < Selected[0]->Data.Train.Count ) {
-			    DebugLevel0Fn("Cancel slot %d %s\n" _C_
-				slotid _C_
-				Selected[0]->Data.Train.What[slotid]
-				    ->Ident);
-			    SendCommandCancelTraining(Selected[0],
-				slotid,
-				Selected[0]->Data.Train.What[slotid]);
-			}
+	    //
+	    //	clicked on training button
+	    //
+	    } else if( ButtonAreaUnderCursor==ButtonAreaTraining ) {
+		if( !GameObserve && !GamePaused ) {
+		    if( ButtonUnderCursor<Selected[0]->Data.Train.Count ) {
+			DebugLevel0Fn("Cancel slot %d %s\n" _C_
+			    ButtonUnderCursor _C_
+			    Selected[0]->Data.Train.What[ButtonUnderCursor]->Ident);
+			SendCommandCancelTraining(Selected[0],
+			    ButtonUnderCursor,
+			    Selected[0]->Data.Train.What[ButtonUnderCursor]);
 		    }
 		}
 	    //
 	    //	clicked on button panel
 	    //
-	    } else if( ButtonUnderCursor>9 ) {
+	    } else if( ButtonAreaUnderCursor==ButtonAreaButton ) {
 		if( !GameObserve && !GamePaused ) {
-		    DoButtonButtonClicked(ButtonUnderCursor-10);
+		    DoButtonButtonClicked(ButtonUnderCursor);
 		}
 	    }
 	} else if( (MouseButtons&MiddleButton) ) {
 	    //
 	    //	clicked on info panel - single unit shown
 	    //
-	    if( ButtonUnderCursor==1 && NumSelected==1 ) {
+	    if( ButtonAreaUnderCursor==ButtonAreaInfo
+		    && ButtonUnderCursor==0 && NumSelected==1 ) {
 		PlayGameSound(GameSounds.Click.Sound,MaxSampleVolume);
 		if( TheUI.SelectedViewport->Unit == Selected[0] ) {
 		    TheUI.SelectedViewport->Unit = NULL;
@@ -1553,7 +1621,9 @@ global void UIHandleButtonUp(unsigned button)
     if( (1<<button) == LeftButton && GameMenuButtonClicked == 1 ) {
 	GameMenuButtonClicked = 0;
 	MustRedraw|=RedrawMenuButton;
-	if( ButtonUnderCursor == 0 ) {
+	if( ButtonAreaUnderCursor==ButtonAreaMenu
+		&& (ButtonUnderCursor==ButtonUnderMenu
+		    || ButtonUnderCursor==ButtonUnderNetworkMenu) ) {
 	    // FIXME: Not if, in input mode.
 	    if( NetworkFildes==-1 ) {
 		GamePaused=1;
@@ -1564,6 +1634,20 @@ global void UIHandleButtonUp(unsigned button)
 	}
     }
 
+    //
+    //	Diplomacy button
+    //
+    if( (1<<button) == LeftButton && GameDiplomacyButtonClicked == 1 ) {
+	GameDiplomacyButtonClicked = 0;
+	MustRedraw|=RedrawMenuButton;
+	if( ButtonAreaUnderCursor==ButtonAreaMenu
+		&& ButtonUnderCursor==ButtonUnderNetworkDiplomacy) {
+	    // FIXME: Not if, in input mode.
+	    ProcessMenu("menu-diplomacy",0);
+	    return;
+	}
+    }
+
     // FIXME: should be completly rewritten
     // FIXME: must selecting!  (lokh: what does this mean? is this done now?)
 
@@ -1637,10 +1721,10 @@ global void UIHandleButtonUp(unsigned button)
 	    if( IsMapFieldVisible(ThisPlayer,
 			Viewport2MapX(TheUI.MouseViewport,CursorX),
 			Viewport2MapY(TheUI.MouseViewport,CursorY)) || ReplayRevealMap ) {
-		unit=UnitOnScreen(unit
-		    ,CursorX-TheUI.MouseViewport->X+
-			TheUI.MouseViewport->MapX*TileSizeX
-		    ,CursorY-TheUI.MouseViewport->Y+
+		unit=UnitOnScreen(unit,
+		    CursorX-TheUI.MouseViewport->X+
+			TheUI.MouseViewport->MapX*TileSizeX,
+		    CursorY-TheUI.MouseViewport->Y+
 			TheUI.MouseViewport->MapY*TileSizeY);
 	    }
 	    if( unit ) {
diff --git a/src/ui/script_ui.cpp b/src/ui/script_ui.cpp
index 578d16fe8..04b3aecb1 100644
--- a/src/ui/script_ui.cpp
+++ b/src/ui/script_ui.cpp
@@ -530,753 +530,83 @@ local SCM CclSetGameCursor(SCM ident)
 }
 
 /**
-**	Define the look+feel of the user interface.
+**	Define a menu item
 **
 **	FIXME: need some general data structure to make this parsing easier.
-**	FIXME: use the new tagged config format.
+**
+**	@param value	Button type.
 */
-local SCM CclDefineUI(SCM list)
+local MenuButtonId scm2buttonid(SCM value)
 {
-    SCM value;
-    SCM temp;
-    char* str;
-    int	x;
-    int	y;
-    int i;
-    UI* ui;
-    void* v;
-    MenuPanel** menupanel;
+    MenuButtonId id;
 
-    //	Get identifier
-    value=gh_car(list);
-    list=gh_cdr(list);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(list);
-    list=gh_cdr(list);
-    x=gh_scm2int(value);
-    value=gh_car(list);
-    list=gh_cdr(list);
-    y=gh_scm2int(value);
-
-    // Find slot: new or redefinition
-    ui=NULL;
-    i=0;
-    if( UI_Table ) {
-	for( ; UI_Table[i]; ++i ) {
-	    if( UI_Table[i]->Width==x && UI_Table[i]->Height==y
-		    && !strcmp(UI_Table[i]->Name,str) ) {
-		ui=UI_Table[i];
-		break;
-	    }
-	}
+    if ( gh_eq_p(value, gh_symbol2scm("main")) ) {
+        id=MBUTTON_MAIN;
+    } else if ( gh_eq_p(value, gh_symbol2scm("network")) ) {
+        id=MBUTTON_NETWORK;
+    } else if ( gh_eq_p(value, gh_symbol2scm("gm-half")) ) {
+        id=MBUTTON_GM_HALF;
+    } else if ( gh_eq_p(value, gh_symbol2scm("132")) ) {
+        id=MBUTTON_132;
+    } else if ( gh_eq_p(value, gh_symbol2scm("gm-full")) ) {
+        id=MBUTTON_GM_FULL;
+    } else if ( gh_eq_p(value, gh_symbol2scm("gem-round")) ) {
+        id=MBUTTON_GEM_ROUND;
+    } else if ( gh_eq_p(value, gh_symbol2scm("gem-square")) ) {
+        id=MBUTTON_GEM_SQUARE;
+    } else if ( gh_eq_p(value, gh_symbol2scm("up-arrow")) ) {
+        id=MBUTTON_UP_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("down-arrow")) ) {
+        id=MBUTTON_DOWN_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("left-arrow")) ) {
+        id=MBUTTON_LEFT_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("right-arrow")) ) {
+        id=MBUTTON_RIGHT_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("s-knob")) ) {
+        id=MBUTTON_S_KNOB;
+    } else if ( gh_eq_p(value, gh_symbol2scm("s-vcont")) ) {
+        id=MBUTTON_S_VCONT;
+    } else if ( gh_eq_p(value, gh_symbol2scm("s-hcont")) ) {
+        id=MBUTTON_S_HCONT;
+    } else if ( gh_eq_p(value, gh_symbol2scm("pulldown")) ) {
+        id=MBUTTON_PULLDOWN;
+    } else if ( gh_eq_p(value, gh_symbol2scm("vthin")) ) {
+        id=MBUTTON_VTHIN;
+    } else if ( gh_eq_p(value, gh_symbol2scm("folder")) ) {
+        id=MBUTTON_FOLDER;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-gem-round")) ) {
+        id=MBUTTON_SC_GEM_ROUND;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-gem-square")) ) {
+        id=MBUTTON_SC_GEM_SQUARE;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-up-arrow")) ) {
+        id=MBUTTON_SC_UP_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-down-arrow")) ) {
+        id=MBUTTON_SC_DOWN_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-left-arrow")) ) {
+        id=MBUTTON_SC_LEFT_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-right-arrow")) ) {
+        id=MBUTTON_SC_RIGHT_ARROW;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-knob")) ) {
+        id=MBUTTON_SC_S_KNOB;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-vcont")) ) {
+        id=MBUTTON_SC_S_VCONT;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-hcont")) ) {
+        id=MBUTTON_SC_S_HCONT;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-pulldown")) ) {
+        id=MBUTTON_SC_PULLDOWN;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button-left")) ) {
+        id=MBUTTON_SC_BUTTON_LEFT;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button")) ) {
+        id=MBUTTON_SC_BUTTON;
+    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button-right")) ) {
+        id=MBUTTON_SC_BUTTON_RIGHT;
+    } else {
+	char *s1=gh_scm2newstr(value, NULL);
+        fprintf(stderr, "Unsupported button %s\n", s1);
+        free(s1);
+	return 0;
     }
-    if( !ui ) {
-	ui=calloc(1,sizeof(UI));
-	v=malloc(sizeof(UI*)*(i+2));
-	memcpy(v,UI_Table,i*sizeof(UI*));
-	free(UI_Table);
-	UI_Table=v;
-	UI_Table[i]=ui;
-	UI_Table[i+1]=NULL;
-    }
-
-    free(ui->Name);
-    ui->Name=str;
-    ui->Width=x;
-    ui->Height=y;
-
-    //
-    //	Some value defaults
-    //
-
-    // This save the setup values FIXME: They are set by CCL.
-
-    ui->Contrast=TheUI.Contrast;
-    ui->Brightness=TheUI.Brightness;
-    ui->Saturation=TheUI.Saturation;
-
-    ui->MouseScroll=TheUI.MouseScroll;
-    ui->KeyScroll=TheUI.KeyScroll;
-    ui->ReverseMouseMove=TheUI.ReverseMouseMove;
-
-    ui->WarpX=-1;
-    ui->WarpY=-1;
-
-    ui->MouseAdjust=TheUI.MouseAdjust;
-    ui->MouseScale=TheUI.MouseScale;
-
-    ui->OriginalResources=TheUI.OriginalResources;
-
-    //
-    //	Now the real values.
-    //
-
-    //	Filler 1
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    for( i=0; i<ui->NumFillers; ++i ) {
-	free(ui->Filler[i].File);
-    }
-    free(ui->Filler);
-    free(ui->FillerX);
-    free(ui->FillerY);
-
-    ui->NumFillers=1;
-    ui->Filler=malloc(ui->NumFillers*sizeof(*ui->Filler));
-    ui->FillerX=malloc(ui->NumFillers*sizeof(*ui->FillerX));
-    ui->FillerY=malloc(ui->NumFillers*sizeof(*ui->FillerY));
-
-    ui->Filler[0].File=str;
-    ui->FillerX[0]=x;
-    ui->FillerY[0]=y;
-
-    //	Resource
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->Resource.File);
-    ui->Resource.File=str;
-    ui->ResourceX=x;
-    ui->ResourceY=y;
-
-    //
-    //	Parse icons
-    //
-    for( i=1; i<MaxCosts; ++i ) {
-	// icon
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( gh_null_p(temp) ) {
-	    free(ui->Resources[i].Icon.File);
-	    ui->Resources[i].Icon.File=NULL;
-	    ui->Resources[i].Icon.Graphic=NULL;
-	    ui->Resources[i].IconRow=0;
-	    ui->Resources[i].IconX=0;
-	    ui->Resources[i].IconY=0;
-	    ui->Resources[i].IconW=0;
-	    ui->Resources[i].IconH=0;
-	    ui->Resources[i].TextX=0;
-	    ui->Resources[i].TextY=0;
-	    continue;
-	}
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	str=gh_scm2newstr(value,NULL);
-	free(ui->Resources[i].Icon.File);
-	ui->Resources[i].Icon.File=str;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconRow=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconX=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].IconY=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconW=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].IconH=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].TextX=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].TextY=y;
-    }
-
-    //	Food icon
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->FoodIcon.File);
-    ui->FoodIcon.File=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->FoodIconRow=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodIconX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodIconY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodIconW=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodIconH=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodTextX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodTextY=y;
-
-    //	Score icon
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ScoreIcon.File);
-    ui->ScoreIcon.File=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->ScoreIconRow=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreIconX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreIconY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreIconW=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreIconH=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreTextX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreTextY=y;
-
-    //	InfoPanel
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->InfoPanel.File);
-    ui->InfoPanel.File=str;
-    ui->InfoPanelX=x;
-    ui->InfoPanelY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->InfoPanelW=x;
-    ui->InfoPanelH=y;
-
-    // Completed bar
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->CompleteBarColor=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->CompleteBarX=x;
-    ui->CompleteBarY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->CompleteTextX=x;
-    ui->CompleteTextY=y;
-
-    //	ButtonPanel
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->ButtonPanel.File);
-    ui->ButtonPanel.File=str;
-    ui->ButtonPanelX=x;
-    ui->ButtonPanelY=y;
-
-    // The map
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->MapArea.X=x;
-    ui->MapArea.Y=y;
-    if ( ui->MapArea.X < 0 || ui->MapArea.Y < 0 ) {
-	fprintf(stderr,"map top-left point expected\n");
-	return SCM_UNSPECIFIED;
-    }
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    //StephanR: note that the bottom-right point is one pixel off
-    ui->MapArea.EndX = x-1;
-    ui->MapArea.EndY = y-1;
-    if ( x < 1 || y < 1 || ui->MapArea.EndX < ui->MapArea.X ||
-				ui->MapArea.EndY < ui->MapArea.Y ) {
-	fprintf(stderr,"map bottom-right point expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    //	MenuButton
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->MenuButton.File);
-    ui->MenuButton.File=str;
-    ui->MenuButtonX=x;
-    ui->MenuButtonY=y;
-
-    //	Minimap
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->Minimap.File);
-    ui->Minimap.File=str;
-    ui->MinimapX=x;
-    ui->MinimapY=y;
-
-    //	StatusLine
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->StatusLine.File);
-    ui->StatusLine.File=str;
-    ui->StatusLineX=x;
-    ui->StatusLineY=y;
-
-    // Buttons
-    for( i=0; i<MaxButtons; ++i ) {
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons[i].X=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons[i].Y=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons[i].Width=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons[i].Height=y;
-    }
-    for( i=0; i<6; ++i ) {
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons2[i].X=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons2[i].Y=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons2[i].Width=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons2[i].Height=y;
-    }
-
-    //
-    //	Get the cursors definitions.
-    //
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Point.Name);
-    ui->Point.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Glass.Name);
-    ui->Glass.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Cross.Name);
-    ui->Cross.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->YellowHair.Name);
-    ui->YellowHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->GreenHair.Name);
-    ui->GreenHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->RedHair.Name);
-    ui->RedHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Scroll.Name);
-    ui->Scroll.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowE.Name);
-    ui->ArrowE.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowNE.Name);
-    ui->ArrowNE.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowN.Name);
-    ui->ArrowN.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowNW.Name);
-    ui->ArrowNW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowW.Name);
-    ui->ArrowW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowSW.Name);
-    ui->ArrowSW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowS.Name);
-    ui->ArrowS.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowSE.Name);
-    ui->ArrowSE.Name=str;
-
-    //
-    //	Panels
-    //
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    menupanel=&ui->MenuPanels;
-    while( *menupanel ) {
-	menupanel=&(*menupanel)->Next;
-    }
-    (*menupanel)=calloc(1,sizeof(**menupanel));
-    (*menupanel)->Ident=strdup("panel1");
-    (*menupanel)->Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    while( *menupanel ) {
-	menupanel=&(*menupanel)->Next;
-    }
-    (*menupanel)=calloc(1,sizeof(**menupanel));
-    (*menupanel)->Ident=strdup("panel2");
-    (*menupanel)->Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    while( *menupanel ) {
-	menupanel=&(*menupanel)->Next;
-    }
-    (*menupanel)=calloc(1,sizeof(**menupanel));
-    (*menupanel)->Ident=strdup("panel3");
-    (*menupanel)->Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    while( *menupanel ) {
-	menupanel=&(*menupanel)->Next;
-    }
-    (*menupanel)=calloc(1,sizeof(**menupanel));
-    (*menupanel)->Ident=strdup("panel4");
-    (*menupanel)->Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    while( *menupanel ) {
-	menupanel=&(*menupanel)->Next;
-    }
-    (*menupanel)=calloc(1,sizeof(**menupanel));
-    (*menupanel)->Ident=strdup("panel5");
-    (*menupanel)->Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->VictoryBackground.File);
-    ui->VictoryBackground.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->DefeatBackground.File);
-    ui->DefeatBackground.File=str;
-
-    return SCM_UNSPECIFIED;
+    return id;
 }
 
 /**
@@ -1284,10 +614,10 @@ local SCM CclDefineUI(SCM list)
 **
 **	@param list	Tagged list of the user interface configuration.
 */
-local SCM CclDefineNewUI(SCM list)
+local SCM CclDefineUI(SCM list)
 {
     SCM value;
-    //SCM temp;
+    SCM sublist;
     char* str;
     int	x;
     int	y;
@@ -1357,6 +687,20 @@ local SCM CclDefineNewUI(SCM list)
 
     ui->OriginalResources=TheUI.OriginalResources;
 
+    ui->MenuButton.X=-1;
+    ui->NetworkMenuButton.X=-1;
+    ui->NetworkDiplomacyButton.X=-1;
+    ui->MinimapX=-1;
+    ui->StatusLineX=-1;
+    ui->InfoPanelX=-1;
+    ui->InfoPanelW=-1;
+    ui->CompleteBarX=-1;
+    ui->ButtonPanelX=-1;
+    ui->MessageAreaX=-1;
+    for( i=0; i<MaxCosts+2; ++i ) {
+	ui->Resources[i].TextX=-1;
+    }
+
     //
     //	Now the real values.
     //
@@ -1371,664 +715,623 @@ local SCM CclDefineNewUI(SCM list)
 	    value=gh_car(list);
 	    list=gh_cdr(list);
 	    ui->ReverseFontColor=gh_scm2newstr(value,NULL);
-	} else if( gh_eq_p(value,gh_symbol2scm("filler")) ) {
-	    value=gh_car(list);
+	} else if( gh_eq_p(value,gh_symbol2scm("panel")) ) {
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
+	    ui->NumPanels++;
+	    ui->Panel=realloc(ui->Panel,ui->NumPanels*sizeof(*ui->Panel));
+	    ui->PanelX=realloc(ui->PanelX,ui->NumPanels*sizeof(*ui->PanelX));
+	    ui->PanelY=realloc(ui->PanelY,ui->NumPanels*sizeof(*ui->PanelY));
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("file")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->Panel[ui->NumPanels-1].File=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->PanelX[ui->NumPanels-1]=gh_scm2int(gh_car(value));
+		    ui->PanelY[ui->NumPanels-1]=gh_scm2int(gh_car(gh_cdr(value)));
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
 	} else if( gh_eq_p(value,gh_symbol2scm("resources")) ) {
-	    value=gh_car(list);
-	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("info-panel")) ) {
-	    value=gh_car(list);
-	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("button-panel")) ) {
-	    value=gh_car(list);
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		SCM slist;
+		int res;
+		char* name;
+
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		name=gh_scm2newstr(value,NULL);
+		for( res=0; res<MaxCosts; ++res ) {
+		    if( !strcmp(name,DefaultResourceNames[res]) ) {
+			break;
+		    }
+		}
+		if( res==MaxCosts ) {
+		    if( !strcmp(name,"food") ) {
+			res=FoodCost;
+		    } else if( !strcmp(name,"score") ) {
+			res=ScoreCost;
+		    } else {
+			errl("Resource not found",value);
+		    }
+		}
+		free(name);
+		slist=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		while( !gh_null_p(slist) ) {
+		    value=gh_car(slist);
+		    slist=gh_cdr(slist);
+		    if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->Resources[res].IconX=gh_scm2int(gh_car(value));
+			ui->Resources[res].IconY=gh_scm2int(gh_car(gh_cdr(value)));
+		    } else if( gh_eq_p(value,gh_symbol2scm("file")) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->Resources[res].Icon.File=gh_scm2newstr(value,NULL);
+		    } else if( gh_eq_p(value,gh_symbol2scm("row")) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->Resources[res].IconRow=gh_scm2int(value);
+		    } else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->Resources[res].IconW=gh_scm2int(gh_car(value));
+			ui->Resources[res].IconH=gh_scm2int(gh_car(gh_cdr(value)));
+		    } else if( gh_eq_p(value,gh_symbol2scm("text-pos")) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->Resources[res].TextX=gh_scm2int(gh_car(value));
+			ui->Resources[res].TextY=gh_scm2int(gh_car(gh_cdr(value)));
+		    } else {
+			errl("Unsupported tag",value);
+		    }
+		}
+	    }
 	} else if( gh_eq_p(value,gh_symbol2scm("map-area")) ) {
-	    value=gh_car(list);
+	    int w;
+	    int h;
+
+	    w=0;
+	    h=0;
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("menu-button")) ) {
-	    value=gh_car(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MapArea.X=gh_scm2int(gh_car(value));
+		    ui->MapArea.Y=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    w=gh_scm2int(gh_car(value));
+		    h=gh_scm2int(gh_car(gh_cdr(value)));
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	    ui->MapArea.EndX=ui->MapArea.X+w-1;
+	    ui->MapArea.EndY=ui->MapArea.Y+h-1;
+	} else if( gh_eq_p(value,gh_symbol2scm("info-area")) ) {
+	    int minx;
+	    int miny;
+	    int maxx;
+	    int maxy;
+
+	    minx=miny=9999;
+	    maxx=maxy=0;
+
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("minimap")) ) {
-	    value=gh_car(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->InfoPanelX=gh_scm2int(gh_car(value));
+		    ui->InfoPanelY=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("panel")) ) {
+		    SCM slist;
+
+		    slist=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    while( !gh_null_p(slist) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			if( gh_eq_p(value,gh_symbol2scm("file")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->InfoPanel.File=gh_scm2newstr(value,NULL);
+			} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->InfoPanelW=gh_scm2int(gh_car(value));
+			    ui->InfoPanelH=gh_scm2int(gh_car(gh_cdr(value)));
+			} else {
+			    errl("Unsupported tag",value);
+			}
+		    }
+		} else if( gh_eq_p(value,gh_symbol2scm("neutral-frame")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->InfoPanelNeutralFrame=gh_scm2int(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("selected-frame")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->InfoPanelSelectedFrame=gh_scm2int(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("magic-frame")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->InfoPanelMagicFrame=gh_scm2int(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("construction-frame")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->InfoPanelConstructionFrame=gh_scm2int(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("completed-bar")) ) {
+		    SCM slist;
+
+		    slist=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    while( !gh_null_p(slist) ) {
+			value=gh_car(slist);
+			slist=gh_cdr(slist);
+			if( gh_eq_p(value,gh_symbol2scm("color")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteBarColor=gh_scm2int(value);
+			} else if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteBarX=gh_scm2int(gh_car(value));
+			    ui->CompleteBarY=gh_scm2int(gh_car(gh_cdr(value)));
+			} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteBarW=gh_scm2int(gh_car(value));
+			    ui->CompleteBarH=gh_scm2int(gh_car(gh_cdr(value)));
+			} else if( gh_eq_p(value,gh_symbol2scm("text")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteBarText=gh_scm2newstr(value,NULL);
+			} else if( gh_eq_p(value,gh_symbol2scm("font")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteBarFont=CclFontByIdentifier(value);
+			} else if( gh_eq_p(value,gh_symbol2scm("text-pos")) ) {
+			    value=gh_car(slist);
+			    slist=gh_cdr(slist);
+			    ui->CompleteTextX=gh_scm2int(gh_car(value));
+			    ui->CompleteTextY=gh_scm2int(gh_car(gh_cdr(value)));
+			} else {
+			    errl("Unsupported tag",value);
+			}
+		    }
+		} else if( gh_eq_p(value,gh_symbol2scm("buttons")) ) {
+		    SCM slist;
+		    SCM sslist;
+		    Button* b;
+
+		    slist=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    while( !gh_null_p(slist) ) {
+			sslist=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->NumInfoButtons++;
+			ui->InfoButtons=realloc(ui->InfoButtons,
+				ui->NumInfoButtons*sizeof(*ui->InfoButtons));
+			b=&ui->InfoButtons[ui->NumInfoButtons-1];
+			while( !gh_null_p(sslist) ) {
+			    value=gh_car(sslist);
+			    sslist=gh_cdr(sslist);
+			    if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->X=gh_scm2int(gh_car(value));
+				b->Y=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->Width=gh_scm2int(gh_car(value));
+				b->Height=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else {
+				errl("Unsupported tag",value);
+			    }
+			}
+			if( b->X<minx ) {
+			    minx=b->X;
+			}
+			if( b->Y<miny ) {
+			    miny=b->Y;
+			}
+			if( b->X+b->Width>maxx ) {
+			    maxx=b->X+b->Width;
+			}
+			if( b->Y+b->Height>maxy ) {
+			    maxy=b->Y+b->Height;
+			}
+		    }
+		} else if( gh_eq_p(value,gh_symbol2scm("training-buttons")) ) {
+		    SCM slist;
+		    SCM sslist;
+		    Button* b;
+
+		    slist=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    while( !gh_null_p(slist) ) {
+			sslist=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->NumTrainingButtons++;
+			ui->TrainingButtons=realloc(ui->TrainingButtons,
+				ui->NumTrainingButtons*sizeof(*ui->TrainingButtons));
+			b=&ui->TrainingButtons[ui->NumTrainingButtons-1];
+			while( !gh_null_p(sslist) ) {
+			    value=gh_car(sslist);
+			    sslist=gh_cdr(sslist);
+			    if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->X=gh_scm2int(gh_car(value));
+				b->Y=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->Width=gh_scm2int(gh_car(value));
+				b->Height=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else {
+				errl("Unsupported tag",value);
+			    }
+			}
+			if( b->X<minx ) {
+			    minx=b->X;
+			}
+			if( b->Y<miny ) {
+			    miny=b->Y;
+			}
+			if( b->X+b->Width>maxx ) {
+			    maxx=b->X+b->Width;
+			}
+			if( b->Y+b->Height>maxy ) {
+			    maxy=b->Y+b->Height;
+			}
+		    }
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	    if( ui->InfoPanelX==-1 ) {
+		ui->InfoPanelX=minx;
+		ui->InfoPanelY=miny;
+	    }
+	    if( ui->InfoPanelW==-1 ) {
+		ui->InfoPanelW=maxx-ui->InfoPanelX;
+		ui->InfoPanelH=maxy-ui->InfoPanelY;
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("button-area")) ) {
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("buttons")) ) {
+		    SCM slist;
+		    SCM sslist;
+		    Button* b;
+
+		    slist=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    while( !gh_null_p(slist) ) {
+			sslist=gh_car(slist);
+			slist=gh_cdr(slist);
+			ui->NumButtonButtons++;
+			ui->ButtonButtons=realloc(ui->ButtonButtons,
+				ui->NumButtonButtons*sizeof(*ui->ButtonButtons));
+			b=&ui->ButtonButtons[ui->NumButtonButtons-1];
+			while( !gh_null_p(sslist) ) {
+			    value=gh_car(sslist);
+			    sslist=gh_cdr(sslist);
+			    if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->X=gh_scm2int(gh_car(value));
+				b->Y=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+				value=gh_car(sslist);
+				sslist=gh_cdr(sslist);
+				b->Width=gh_scm2int(gh_car(value));
+				b->Height=gh_scm2int(gh_car(gh_cdr(value)));
+			    } else {
+				errl("Unsupported tag",value);
+			    }
+			}
+			if( ui->NumButtonButtons==1
+				|| b->X<ui->ButtonPanelX ) {
+			    ui->ButtonPanelX=b->X;
+			}
+			if( ui->NumButtonButtons==1
+				|| b->X+b->Width>ui->ButtonPanelEndX ) {
+			    ui->ButtonPanelEndX=b->X+b->Width;
+			}
+			if( ui->NumButtonButtons==1
+				|| b->Y<ui->ButtonPanelY ) {
+			    ui->ButtonPanelY=b->Y;
+			}
+			if( ui->NumButtonButtons==1
+				|| b->Y+b->Height>ui->ButtonPanelEndY ) {
+			    ui->ButtonPanelEndY=b->Y+b->Height;
+			}
+		    }
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("minimap-area")) ) {
+	    sublist=gh_car(list);
+	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MinimapX=gh_scm2int(gh_car(value));
+		    ui->MinimapY=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MinimapW=gh_scm2int(gh_car(value));
+		    ui->MinimapH=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("cursor-color")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MinimapCursorColor=gh_scm2int(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
 	} else if( gh_eq_p(value,gh_symbol2scm("status-line")) ) {
-	    value=gh_car(list);
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("buttons")) ) {
-	    value=gh_car(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("font")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->StatusLineFont=CclFontByIdentifier(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->StatusLineX=gh_scm2int(gh_car(value));
+		    ui->StatusLineY=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("width")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->StatusLineW=gh_scm2int(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("menu-button")) ) {
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("buttons-2")) ) {
-	    value=gh_car(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MenuButton.X=gh_scm2int(gh_car(value));
+		    ui->MenuButton.Y=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MenuButton.Width=gh_scm2int(gh_car(value));
+		    ui->MenuButton.Height=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("caption")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MenuButton.Text=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("style")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MenuButton.Button=scm2buttonid(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("network-menu-button")) ) {
+	    sublist=gh_car(list);
 	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkMenuButton.X=gh_scm2int(gh_car(value));
+		    ui->NetworkMenuButton.Y=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkMenuButton.Width=gh_scm2int(gh_car(value));
+		    ui->NetworkMenuButton.Height=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("caption")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkMenuButton.Text=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("style")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkMenuButton.Button=scm2buttonid(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("network-diplomacy-button")) ) {
+	    sublist=gh_car(list);
+	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkDiplomacyButton.X=gh_scm2int(gh_car(value));
+		    ui->NetworkDiplomacyButton.Y=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("size")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkDiplomacyButton.Width=gh_scm2int(gh_car(value));
+		    ui->NetworkDiplomacyButton.Height=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("caption")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkDiplomacyButton.Text=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("style")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->NetworkDiplomacyButton.Button=scm2buttonid(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("message-area")) ) {
+	    sublist=gh_car(list);
+	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("font")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MessageAreaFont=CclFontByIdentifier(value);
+		} else if( gh_eq_p(value,gh_symbol2scm("pos")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MessageAreaX=gh_scm2int(gh_car(value));
+		    ui->MessageAreaY=gh_scm2int(gh_car(gh_cdr(value)));
+		} else if( gh_eq_p(value,gh_symbol2scm("width")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->MessageAreaW=gh_scm2int(value);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
 	} else if( gh_eq_p(value,gh_symbol2scm("cursors")) ) {
+	    sublist=gh_car(list);
+	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		if( gh_eq_p(value,gh_symbol2scm("point")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->Point.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("glass")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->Glass.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("cross")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->Cross.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("yellow")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->YellowHair.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("green")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->GreenHair.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("red")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->RedHair.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("scroll")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->Scroll.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-e")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowE.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-ne")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowNE.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-n")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowN.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-nw")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowNW.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-w")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowW.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-sw")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowSW.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-s")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowS.Name=gh_scm2newstr(value,NULL);
+		} else if( gh_eq_p(value,gh_symbol2scm("arrow-se")) ) {
+		    value=gh_car(sublist);
+		    sublist=gh_cdr(sublist);
+		    ui->ArrowSE.Name=gh_scm2newstr(value,NULL);
+		} else {
+		    errl("Unsupported tag",value);
+		}
+	    }
+	} else if( gh_eq_p(value,gh_symbol2scm("victory-background")) ) {
 	    value=gh_car(list);
 	    list=gh_cdr(list);
-	} else if( gh_eq_p(value,gh_symbol2scm("panels")) ) {
+	    ui->VictoryBackground.File=gh_scm2newstr(value,NULL);
+	} else if( gh_eq_p(value,gh_symbol2scm("defeat-background")) ) {
 	    value=gh_car(list);
 	    list=gh_cdr(list);
+	    ui->DefeatBackground.File=gh_scm2newstr(value,NULL);
+	} else if( gh_eq_p(value,gh_symbol2scm("menu-panels")) ) {
+	    sublist=gh_car(list);
+	    list=gh_cdr(list);
+	    while( !gh_null_p(sublist) ) {
+		MenuPanel** menupanel;
+
+		menupanel=&ui->MenuPanels;
+		while( *menupanel ) {
+		    menupanel=&(*menupanel)->Next;
+		}
+		*menupanel=calloc(1,sizeof(**menupanel));
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		(*menupanel)->Ident=gh_scm2newstr(value,NULL);
+		value=gh_car(sublist);
+		sublist=gh_cdr(sublist);
+		(*menupanel)->Panel.File=gh_scm2newstr(value,NULL);
+	    }
 	} else {
 	    errl("Unsupported tag",value);
 	}
     }
 
-#if 0
-    //	Filler 1
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->Filler1.File);
-    ui->Filler1.File=str;
-    ui->Filler1X=x;
-    ui->Filler1Y=y;
-
-    //	Resource
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->Resource.File);
-    ui->Resource.File=str;
-    ui->ResourceX=x;
-    ui->ResourceY=y;
-
-    //
-    //	Parse icons
-    //
-    for( i=1; i<MaxCosts; ++i ) {
-	// icon
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( gh_null_p(temp) ) {
-	    free(ui->Resources[i].Icon.File);
-	    ui->Resources[i].Icon.File=NULL;
-	    ui->Resources[i].Icon.Graphic=NULL;
-	    ui->Resources[i].IconRow=0;
-	    ui->Resources[i].IconX=0;
-	    ui->Resources[i].IconY=0;
-	    ui->Resources[i].IconW=0;
-	    ui->Resources[i].IconH=0;
-	    ui->Resources[i].TextX=0;
-	    ui->Resources[i].TextY=0;
-	    continue;
-	}
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	str=gh_scm2newstr(value,NULL);
-	free(ui->Resources[i].Icon.File);
-	ui->Resources[i].Icon.File=str;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconRow=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconX=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].IconY=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].IconW=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].IconH=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Resources[i].TextX=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Resources[i].TextY=y;
-    }
-
-    //	Food icon
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->FoodIcon.File);
-    ui->FoodIcon.File=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->FoodIconRow=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodIconX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodIconY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodIconW=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodIconH=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->FoodTextX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->FoodTextY=y;
-
-    //	Score icon
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ScoreIcon.File);
-    ui->ScoreIcon.File=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->ScoreIconRow=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreIconX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreIconY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreIconW=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreIconH=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    ui->ScoreTextX=x;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->ScoreTextY=y;
-
-    //	InfoPanel
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->InfoPanel.File);
-    ui->InfoPanel.File=str;
-    ui->InfoPanelX=x;
-    ui->InfoPanelY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->InfoPanelW=x;
-    ui->InfoPanelH=y;
-
-    // Completed bar
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    i=gh_scm2int(value);
-    ui->CompleteBarColor=i;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->CompleteBarX=x;
-    ui->CompleteBarY=y;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->CompleteTextX=x;
-    ui->CompleteTextY=y;
-
-    //	ButtonPanel
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->ButtonPanel.File);
-    ui->ButtonPanel.File=str;
-    ui->ButtonPanelX=x;
-    ui->ButtonPanelY=y;
-
-    // The map
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    ui->MapArea.X=x;
-    ui->MapArea.Y=y;
-    if ( ui->MapArea.X < 0 || ui->MapArea.Y < 0 ) {
-	fprintf(stderr,"map top-left point expected\n");
-	return SCM_UNSPECIFIED;
-    }
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-    //StephanR: note that the bottom-right point is one pixel off
-    ui->MapArea.EndX = x-1;
-    ui->MapArea.EndY = y-1;
-    if ( x < 1 || y < 1 || ui->MapArea.EndX < ui->MapArea.X ||
-				ui->MapArea.EndY < ui->MapArea.Y ) {
-	fprintf(stderr,"map bottom-right point expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    //	MenuButton
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->MenuButton.File);
-    ui->MenuButton.File=str;
-    ui->MenuButtonX=x;
-    ui->MenuButtonY=y;
-
-    //	Minimap
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->Minimap.File);
-    ui->Minimap.File=str;
-    ui->MinimapX=x;
-    ui->MinimapY=y;
-
-    //	StatusLine
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    if( !gh_list_p(temp) ) {
-	fprintf(stderr,"list expected\n");
-	return SCM_UNSPECIFIED;
-    }
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    x=gh_scm2int(value);
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    y=gh_scm2int(value);
-
-    free(ui->StatusLine.File);
-    ui->StatusLine.File=str;
-    ui->StatusLineX=x;
-    ui->StatusLineY=y;
-
-    // Buttons
-    for( i=0; i<MaxButtons; ++i ) {
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons[i].X=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons[i].Y=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons[i].Width=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons[i].Height=y;
-    }
-    for( i=0; i<6; ++i ) {
-	temp=gh_car(list);
-	list=gh_cdr(list);
-
-	if( !gh_list_p(temp) ) {
-	    fprintf(stderr,"list expected\n");
-	    return SCM_UNSPECIFIED;
-	}
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons2[i].X=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons2[i].Y=y;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	x=gh_scm2int(value);
-	ui->Buttons2[i].Width=x;
-
-	value=gh_car(temp);
-	temp=gh_cdr(temp);
-	y=gh_scm2int(value);
-	ui->Buttons2[i].Height=y;
-    }
-
-    //
-    //	Get the cursors definitions.
-    //
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Point.Name);
-    ui->Point.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Glass.Name);
-    ui->Glass.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Cross.Name);
-    ui->Cross.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->YellowHair.Name);
-    ui->YellowHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->GreenHair.Name);
-    ui->GreenHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->RedHair.Name);
-    ui->RedHair.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Scroll.Name);
-    ui->Scroll.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowE.Name);
-    ui->ArrowE.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowNE.Name);
-    ui->ArrowNE.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowN.Name);
-    ui->ArrowN.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowNW.Name);
-    ui->ArrowNW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowW.Name);
-    ui->ArrowW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowSW.Name);
-    ui->ArrowSW.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowS.Name);
-    ui->ArrowS.Name=str;
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ArrowSE.Name);
-    ui->ArrowSE.Name=str;
-
-    //
-    //	Panels
-    //
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->GameMenuPanel.File);
-    ui->GameMenuPanel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Menu1Panel.File);
-    ui->Menu1Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->Menu2Panel.File);
-    ui->Menu2Panel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->VictoryPanel.File);
-    ui->VictoryPanel.File=str;
-
-    temp=gh_car(list);
-    list=gh_cdr(list);
-
-    value=gh_car(temp);
-    temp=gh_cdr(temp);
-    str=gh_scm2newstr(value,NULL);
-    free(ui->ScenarioPanel.File);
-    ui->ScenarioPanel.File=str;
-#endif
-
     return SCM_UNSPECIFIED;
 }
 
@@ -2404,84 +1707,6 @@ local SCM CclDefineMenu(SCM list)
     return SCM_UNSPECIFIED;
 }
 
-/**
-**	Define a menu item
-**
-**	FIXME: need some general data structure to make this parsing easier.
-**
-**	@param value	Button type.
-*/
-local MenuButtonId scm2buttonid(SCM value)
-{
-    MenuButtonId id;
-
-    if ( gh_eq_p(value, gh_symbol2scm("main")) ) {
-        id=MBUTTON_MAIN;
-    } else if ( gh_eq_p(value, gh_symbol2scm("gm-half")) ) {
-        id=MBUTTON_GM_HALF;
-    } else if ( gh_eq_p(value, gh_symbol2scm("132")) ) {
-        id=MBUTTON_132;
-    } else if ( gh_eq_p(value, gh_symbol2scm("gm-full")) ) {
-        id=MBUTTON_GM_FULL;
-    } else if ( gh_eq_p(value, gh_symbol2scm("gem-round")) ) {
-        id=MBUTTON_GEM_ROUND;
-    } else if ( gh_eq_p(value, gh_symbol2scm("gem-square")) ) {
-        id=MBUTTON_GEM_SQUARE;
-    } else if ( gh_eq_p(value, gh_symbol2scm("up-arrow")) ) {
-        id=MBUTTON_UP_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("down-arrow")) ) {
-        id=MBUTTON_DOWN_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("left-arrow")) ) {
-        id=MBUTTON_LEFT_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("right-arrow")) ) {
-        id=MBUTTON_RIGHT_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("s-knob")) ) {
-        id=MBUTTON_S_KNOB;
-    } else if ( gh_eq_p(value, gh_symbol2scm("s-vcont")) ) {
-        id=MBUTTON_S_VCONT;
-    } else if ( gh_eq_p(value, gh_symbol2scm("s-hcont")) ) {
-        id=MBUTTON_S_HCONT;
-    } else if ( gh_eq_p(value, gh_symbol2scm("pulldown")) ) {
-        id=MBUTTON_PULLDOWN;
-    } else if ( gh_eq_p(value, gh_symbol2scm("vthin")) ) {
-        id=MBUTTON_VTHIN;
-    } else if ( gh_eq_p(value, gh_symbol2scm("folder")) ) {
-        id=MBUTTON_FOLDER;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-gem-round")) ) {
-        id=MBUTTON_SC_GEM_ROUND;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-gem-square")) ) {
-        id=MBUTTON_SC_GEM_SQUARE;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-up-arrow")) ) {
-        id=MBUTTON_SC_UP_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-down-arrow")) ) {
-        id=MBUTTON_SC_DOWN_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-left-arrow")) ) {
-        id=MBUTTON_SC_LEFT_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-right-arrow")) ) {
-        id=MBUTTON_SC_RIGHT_ARROW;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-knob")) ) {
-        id=MBUTTON_SC_S_KNOB;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-vcont")) ) {
-        id=MBUTTON_SC_S_VCONT;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-s-hcont")) ) {
-        id=MBUTTON_SC_S_HCONT;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-pulldown")) ) {
-        id=MBUTTON_SC_PULLDOWN;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button-left")) ) {
-        id=MBUTTON_SC_BUTTON_LEFT;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button")) ) {
-        id=MBUTTON_SC_BUTTON;
-    } else if ( gh_eq_p(value, gh_symbol2scm("sc-button-right")) ) {
-        id=MBUTTON_SC_BUTTON_RIGHT;
-    } else {
-	char *s1=gh_scm2newstr(value, NULL);
-        fprintf(stderr, "Unsupported button %s\n", s1);
-        free(s1);
-	return 0;
-    }
-    return id;
-}
-
 local int scm2hotkey(SCM value)
 {
     char *s;
@@ -3701,7 +2926,6 @@ global void UserInterfaceCclRegister(void)
     gh_new_procedureN("define-cursor",CclDefineCursor);
     gh_new_procedure1_0("set-game-cursor!",CclSetGameCursor);
     gh_new_procedureN("define-ui",CclDefineUI);
-    gh_new_procedureN("define-new-ui",CclDefineNewUI);
     gh_new_procedureN("define-viewports",CclDefineViewports);
 
     gh_new_procedure1_0("set-grab-mouse!", CclSetGrabMouse);
diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp
index 163b5589e..5acf69159 100644
--- a/src/ui/ui.cpp
+++ b/src/ui/ui.cpp
@@ -39,6 +39,7 @@
 #include "interface.h"
 #include "map.h"
 #include "ui.h"
+#include "menus.h"
 
 /*----------------------------------------------------------------------------
 --	Variables
@@ -69,7 +70,6 @@ global UI** UI_Table;
 local void ClipViewport(Viewport* vp, int ClipX, int ClipY);
 local void FinishViewportModeConfiguration(Viewport new_vps[], int num_vps);
 
-
 /**
 **	Initialize the user interface.
 **
@@ -146,16 +146,6 @@ global void InitUserInterface(const char *race_name)
     } else {
 	SetViewportMode(VIEWPORT_SINGLE);
     }
-
-    // FIXME: Can be removed after new config is working
-    if( !strcmp(race_name,"human") || !strcmp(race_name,"alliance") ) {
-	TheUI.NormalFontColor=strdup(FontWhite);
-	TheUI.ReverseFontColor=strdup(FontYellow);
-    } else {
-	TheUI.NormalFontColor=strdup(FontYellow);
-	TheUI.ReverseFontColor=strdup(FontWhite);
-    }
-    TheUI.ViewportCursorColor=ColorWhite;
 }
 
 /**
@@ -173,11 +163,11 @@ global void LoadUserInterface(void)
     //
     //	Load graphics
     //
-    for( i=0; i<TheUI.NumFillers; ++i ) {
-	if( TheUI.Filler[i].File ) {
-	    TheUI.Filler[i].Graphic=LoadGraphic(TheUI.Filler[i].File);
+    for( i=0; i<TheUI.NumPanels; ++i ) {
+	if( TheUI.Panel[i].File ) {
+	    TheUI.Panel[i].Graphic=LoadSprite(TheUI.Panel[i].File,0,0);
 #ifdef USE_OPENGL
-	    MakeTexture(TheUI.Filler[i].Graphic,TheUI.Filler[i].Graphic->Width,TheUI.Filler[i].Graphic->Height);
+	    MakeTexture(TheUI.Panel[i].Graphic,TheUI.Panel[i].Graphic->Width,TheUI.Panel[i].Graphic->Height);
 #endif
 	}
     }
@@ -200,17 +190,17 @@ global void LoadUserInterface(void)
     }
 
     // FIXME: reuse same graphics?
-    if( TheUI.FoodIcon.File ) {
-	TheUI.FoodIcon.Graphic=LoadGraphic(TheUI.FoodIcon.File);
+    if( TheUI.Resources[FoodCost].Icon.File ) {
+	TheUI.Resources[FoodCost].Icon.Graphic=LoadGraphic(TheUI.Resources[FoodCost].Icon.File);
 #ifdef USE_OPENGL
-	MakeTexture(TheUI.FoodIcon.Graphic,TheUI.FoodIcon.Graphic->Width,TheUI.FoodIcon.Graphic->Height);
+	MakeTexture(TheUI.Resources[FoodCost].Icon.Graphic,TheUI.Resources[FoodCost].Icon.Graphic->Width,TheUI.Resources[FoodCost].Icon.Graphic->Height);
 #endif
     }
     // FIXME: reuse same graphics?
-    if( TheUI.ScoreIcon.File ) {
-	TheUI.ScoreIcon.Graphic=LoadGraphic(TheUI.ScoreIcon.File);
+    if( TheUI.Resources[ScoreCost].Icon.File ) {
+	TheUI.Resources[ScoreCost].Icon.Graphic=LoadGraphic(TheUI.Resources[ScoreCost].Icon.File);
 #ifdef USE_OPENGL
-	MakeTexture(TheUI.ScoreIcon.Graphic,TheUI.ScoreIcon.Graphic->Width,TheUI.ScoreIcon.Graphic->Height);
+	MakeTexture(TheUI.Resources[ScoreCost].Icon.Graphic,TheUI.Resources[ScoreCost].Icon.Graphic->Width,TheUI.Resources[ScoreCost].Icon.Graphic->Height);
 #endif
     }
 
@@ -220,30 +210,6 @@ global void LoadUserInterface(void)
 	MakeTexture(TheUI.InfoPanel.Graphic,TheUI.InfoPanel.Graphic->Width,TheUI.InfoPanel.Graphic->Height);
 #endif
     }
-    if( TheUI.ButtonPanel.File ) {
-	TheUI.ButtonPanel.Graphic=LoadGraphic(TheUI.ButtonPanel.File);
-#ifdef USE_OPENGL
-	MakeTexture(TheUI.ButtonPanel.Graphic,TheUI.ButtonPanel.Graphic->Width,TheUI.ButtonPanel.Graphic->Height);
-#endif
-    }
-    if( TheUI.MenuButton.File ) {
-	TheUI.MenuButton.Graphic=LoadGraphic(TheUI.MenuButton.File);
-#ifdef USE_OPENGL
-	MakeTexture(TheUI.MenuButton.Graphic,TheUI.MenuButton.Graphic->Width,TheUI.MenuButton.Graphic->Height);
-#endif
-    }
-    if( TheUI.Minimap.File ) {
-	TheUI.Minimap.Graphic=LoadGraphic(TheUI.Minimap.File);
-#ifdef USE_OPENGL
-	MakeTexture(TheUI.Minimap.Graphic,TheUI.Minimap.Graphic->Width,TheUI.Minimap.Graphic->Height);
-#endif
-    }
-    if( TheUI.StatusLine.File ) {
-	TheUI.StatusLine.Graphic=LoadGraphic(TheUI.StatusLine.File);
-#ifdef USE_OPENGL
-	MakeTexture(TheUI.StatusLine.Graphic,TheUI.StatusLine.Graphic->Width,TheUI.StatusLine.Graphic->Height);
-#endif
-    }
 
     //
     //	Resolve cursors
@@ -285,235 +251,226 @@ global void LoadUserInterface(void)
 **	@param file	Save file handle
 **	@param ui	User interface to save
 */
-local void OldSaveUi(FILE* file,const UI* ui)
+local void SaveUi(FILE * file, const UI * ui)
 {
     int i;
     MenuPanel* menupanel;
 
-    fprintf(file,"(define-old-ui '%s %d %d\t; Selector\n",
-	    ui->Name,ui->Width,ui->Height);
-    fprintf(file,"  ; Filler 1\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->Filler[0].File,ui->FillerX[0],ui->FillerY[0]);
-    fprintf(file,"  ; Resource line\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->Resource.File,ui->ResourceX,ui->ResourceY);
-
-    for( i=1; i<MaxCosts; ++i ) {
-	fprintf(file,"  ; Resource %s\n",DefaultResourceNames[i]);
-	fprintf(file,"  (list \"%s\" %d\n    %d %d %d %d  %d %d)\n",
-		ui->Resources[i].Icon.File,ui->Resources[i].IconRow,
-		ui->Resources[i].IconX,ui->Resources[i].IconY,
-		ui->Resources[i].IconW,ui->Resources[i].IconH,
-		ui->Resources[i].TextX,ui->Resources[i].TextY);
-    }
-    fprintf(file,"  ; Food\n");
-    fprintf(file,"  (list \"%s\" %d\n    %d %d %d %d  %d %d)\n",
-	    ui->FoodIcon.File,ui->FoodIconRow,
-	    ui->FoodIconX,ui->FoodIconY,
-	    ui->FoodIconW,ui->FoodIconH,
-	    ui->FoodTextX,ui->FoodTextY);
-    fprintf(file,"  ; Score\n");
-    fprintf(file,"  (list \"%s\" %d\n    %d %d %d %d  %d %d)\n",
-	    ui->ScoreIcon.File,ui->ScoreIconRow,
-	    ui->ScoreIconX,ui->ScoreIconY,
-	    ui->ScoreIconW,ui->ScoreIconH,
-	    ui->ScoreTextX,ui->ScoreTextY);
-
-    fprintf(file,"  ; Info panel\n");
-    fprintf(file,"  (list \"%s\" %d %d %d %d)\n",
-	    ui->InfoPanel.File,
-	    ui->InfoPanelX,ui->InfoPanelY,
-	    ui->InfoPanelW,ui->InfoPanelH);
-
-    fprintf(file,"  ; Complete bar\n");
-    fprintf(file,"  (list %d %d %d %d %d)\n",
-	    ui->CompleteBarColor,
-	    ui->CompleteBarX,ui->CompleteBarY,
-	    ui->CompleteTextX,ui->CompleteTextY);
-
-    fprintf(file,"  ; Button panel\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->ButtonPanel.File,ui->ButtonPanelX,ui->ButtonPanelY);
-
-    fprintf(file,"  ; The map area\n");
-    fprintf(file,"  (list %d %d %d %d)\n",
-	    ui->MapArea.X, ui->MapArea.Y,
-	    ui->MapArea.EndX+1,ui->MapArea.EndY+1);
-
-    fprintf(file,"  ; Menu button background\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->MenuButton.File,ui->MenuButtonX,ui->MenuButtonY);
-
-    fprintf(file,"  ; Minimap background\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->Minimap.File,ui->MinimapX,ui->MinimapY);
-
-    fprintf(file,"  ; Status line\n");
-    fprintf(file,"  (list \"%s\" %d %d)\n",
-	    ui->StatusLine.File,ui->StatusLineX,ui->StatusLineY);
-
-    fprintf(file,"  ; Buttons\n");
-    for( i=0; i<MaxButtons; ++i ) {
-	fprintf(file,"  (list %3d %3d %4d %3d)\n",
-		ui->Buttons[i].X,ui->Buttons[i].Y,
-		ui->Buttons[i].Width,ui->Buttons[i].Height);
-    }
-
-    fprintf(file,"  ; Buttons II\n");
-    for( i=0; i<6; ++i ) {
-	fprintf(file,"  (list %3d %3d %4d %3d)\n",
-		ui->Buttons2[i].X,ui->Buttons2[i].Y,
-		ui->Buttons2[i].Width,ui->Buttons2[i].Height);
-    }
-
-    fprintf(file,"  ; Cursors\n");
-    fprintf(file,"  (list");
-    fprintf(file," '%s",ui->Point.Name);
-    fprintf(file," '%s",ui->Glass.Name);
-    fprintf(file," '%s\n",ui->Cross.Name);
-    fprintf(file,"    '%s",ui->YellowHair.Name);
-    fprintf(file," '%s",ui->GreenHair.Name);
-    fprintf(file,"    '%s\n",ui->RedHair.Name);
-    fprintf(file,"    '%s\n",ui->Scroll.Name);
-
-    fprintf(file,"    '%s",ui->ArrowE.Name);
-    fprintf(file," '%s",ui->ArrowNE.Name);
-    fprintf(file," '%s",ui->ArrowN.Name);
-    fprintf(file," '%s\n",ui->ArrowNW.Name);
-    fprintf(file,"    '%s",ui->ArrowW.Name);
-    fprintf(file," '%s",ui->ArrowSW.Name);
-    fprintf(file," '%s",ui->ArrowS.Name);
-    fprintf(file," '%s)\n",ui->ArrowSE.Name);
-
-    menupanel=ui->MenuPanels;
-    while( menupanel ) {
-	fprintf(file,"  (list \"%s\")\n",menupanel->Panel.File);
-	menupanel=menupanel->Next;
-    }
-
-    fprintf(file,"  (list \"%s\")\n",ui->VictoryBackground.File);
-    fprintf(file,"  (list \"%s\")",ui->DefeatBackground.File);
-
-    fprintf(file," )\n\n");
-}
-
-#if 0
-/**
-**	Save the UI structure.
-**
-**	@param file	Save file handle
-**	@param ui	User interface to save
-*/
-local void NewSaveUi(FILE * file, const UI * ui)
-{
-    int i;
-
-    fprintf(file, "(define-ui '%s %d %d\t; Selector\n",
+    fprintf(file, "(define-ui '%s %d %d",
 	ui->Name, ui->Width, ui->Height);
 
-    fprintf(file, "  'normal-font-color '%s 'reverse-font-color '%s\n",
+    fprintf(file, "\n  'normal-font-color '%s\n  'reverse-font-color '%s",
 	ui->NormalFontColor, ui->ReverseFontColor);
 
-    for( i=0; i<TheUI.NumFillers; ++i ) {
-	fprintf(file, "  'filler '(pos (%d %d) image \"%s\")\n",
-	    ui->FillerX[i], ui->FillerY[i], ui->Filler[i].File);
+    fprintf(file, "\n");
+    for( i=0; i<TheUI.NumPanels; ++i ) {
+	fprintf(file, "\n  'panel '(file \"%s\" pos (%d %d))",
+	    ui->Panel[i].File, ui->PanelX[i], ui->PanelY[i]);
     }
 
-    fprintf(file, "  'resources '(pos (%d %d) image \"%s\"",
-	ui->ResourceX, ui->ResourceY, ui->Resource.File);
-    for (i = 1; i < MaxCosts; ++i) {
+    fprintf(file, "\n");
+    fprintf(file, "\n  'resources '(");
+    for (i=1; i<MaxCosts; ++i) {
 	// FIXME: use slot 0 for time displays!
-	fprintf(file, "\n    %s (icon-pos (%d %d) icon-file \"%s\"\n",
-	    DefaultResourceNames[i],
-	    ui->Resources[i].IconX, ui->Resources[i].IconY,
-	    ui->Resources[i].Icon.File);
-	fprintf(file,"      icon-frame %d icon-size (%d %d) text-pos (%d %d))",
-	    ui->Resources[i].IconRow,
-	    ui->Resources[i].IconW, ui->Resources[i].IconH,
-	    ui->Resources[i].TextX, ui->Resources[i].TextY);
+	if( DefaultResourceNames[i] ) {
+	    fprintf(file, "\n    %s (", DefaultResourceNames[i]);
+	    if( ui->Resources[i].Icon.File ) {
+		fprintf(file, "\n      pos (%d %d) file \"%s\" row %d size (%d %d)",
+		    ui->Resources[i].IconX, ui->Resources[i].IconY,
+		    ui->Resources[i].Icon.File,
+		    ui->Resources[i].IconRow,
+		    ui->Resources[i].IconW, ui->Resources[i].IconH);
+	    }
+	    if( ui->Resources[i].TextX!=-1 ) {
+		fprintf(file, "\n      text-pos (%d %d)",
+		    ui->Resources[i].TextX, ui->Resources[i].TextY);
+	    }
+	    fprintf(file, ")");
+	}
+    }
+    if( ui->Resources[FoodCost].Icon.File ) {
+	fprintf(file, "\n    food (");
+	fprintf(file, "\n      pos (%d %d) file \"%s\" row %d size (%d %d)",
+	    ui->Resources[FoodCost].IconX, ui->Resources[FoodCost].IconY,
+	    ui->Resources[FoodCost].Icon.File,
+	    ui->Resources[FoodCost].IconRow,
+	    ui->Resources[FoodCost].IconW, ui->Resources[FoodCost].IconH);
+	if( ui->Resources[FoodCost].TextX!=-1 ) {
+	    fprintf(file, "\n      text-pos (%d %d)",
+		ui->Resources[FoodCost].TextX, ui->Resources[FoodCost].TextY);
+	}
+	fprintf(file, ")");
+    }
+    if( ui->Resources[ScoreCost].Icon.File ) {
+	fprintf(file, "\n    score (");
+	fprintf(file, "\n      pos (%d %d) file \"%s\" row %d size (%d %d)",
+	    ui->Resources[ScoreCost].IconX, ui->Resources[ScoreCost].IconY,
+	    ui->Resources[ScoreCost].Icon.File,
+	    ui->Resources[ScoreCost].IconRow,
+	    ui->Resources[ScoreCost].IconW, ui->Resources[ScoreCost].IconH);
+	if( ui->Resources[ScoreCost].TextX!=-1 ) {
+	    fprintf(file, "\n      text-pos (%d %d)",
+		ui->Resources[ScoreCost].TextX, ui->Resources[ScoreCost].TextY);
+	}
+	fprintf(file, ")");
     }
-    fprintf(file, "\n    food (icon-pos (%d %d) icon-file \"%s\"\n",
-	ui->FoodIconX, ui->FoodIconY, ui->FoodIcon.File);
-    fprintf(file,"      icon-frame %d icon-size (%d %d) text-pos (%d %d))",
-	ui->FoodIconRow,
-	ui->FoodIconW, ui->FoodIconH, ui->FoodTextX, ui->FoodTextY);
-    fprintf(file, "\n    score (icon-pos (%d %d) icon-file \"%s\"\n",
-	ui->ScoreIconX, ui->ScoreIconY, ui->ScoreIcon.File);
-    fprintf(file,"      icon-frame %d icon-size (%d %d) text-pos (%d %d))",
-	ui->ScoreIconRow,
-	ui->ScoreIconW, ui->ScoreIconH, ui->ScoreTextX, ui->ScoreTextY);
     fprintf(file, ")\n");
 
-    fprintf(file, "  'info-panel '(pos (%d %d) image \"%s\"\n",
-	ui->InfoPanelX, ui->InfoPanelY,
-	ui->InfoPanel.File);
-    fprintf(file, "    size (%d %d)\n",
-	ui->InfoPanelW, ui->InfoPanelH);
-
-    fprintf(file, "    complete-bar (color %d pos (%d %d) text-pos (%d %d)))\n",
-	ui->CompleteBarColor,
-	ui->CompleteBarX, ui->CompleteBarY,
-	ui->CompleteTextX, ui->CompleteTextY);
-
-    fprintf(file, "  'button-panel '(pos (%d %d) image \"%s\")\n",
-	ui->ButtonPanelX, ui->ButtonPanelY, ui->ButtonPanel.File);
-
-    fprintf(file, "  'map-area '(pos (%d %d) size (%d %d))\n",
+    fprintf(file, "\n  'map-area '(pos (%d %d) size (%d %d))",
 	ui->MapArea.X, ui->MapArea.Y,
 	ui->MapArea.EndX + 1, ui->MapArea.EndY + 1);
 
-    fprintf(file, "  'menu-button '(pos (%d %d) image \"%s\")\n",
-	ui->MenuButtonX, ui->MenuButtonY, ui->MenuButton.File);
-
-    fprintf(file, "  'minimap '(pos (%d %d) image \"%s\" 'viewport-color %d)\n",
-	ui->MinimapX, ui->MinimapY, ui->Minimap.File, ui->ViewportCursorColor);
-
-    fprintf(file, "  'status-line '(pos (%d %d) image \"%s\")\n",
-	ui->StatusLineX, ui->StatusLineY, ui->StatusLine.File);
-
-    fprintf(file, "; 0 Menu 1-9 Info 10-19 Button\n");
-    fprintf(file, "  'buttons '(");
-    for (i = 0; i < MaxButtons; ++i) {
-	fprintf(file, "\n    (pos (%3d %3d) size (%4d %3d))",
-	    ui->Buttons[i].X, ui->Buttons[i].Y,
-	    ui->Buttons[i].Width, ui->Buttons[i].Height);
+    fprintf(file, "\n");
+    fprintf(file, "\n  'info-area '(");
+    fprintf(file, "\n    pos (%d %d)",
+	ui->InfoPanelX, ui->InfoPanelY);
+    if( ui->InfoPanel.File ) {
+	fprintf(file, "\n    panel (file \"%s\" size (%d %d))",
+	    ui->InfoPanel.File, ui->InfoPanelW, ui->InfoPanelH);
     }
-
-    fprintf(file, ")\n; 0-5 Training\n");
-    fprintf(file, "  'buttons-2 '(");
-    for (i = 0; i < 6; ++i) {
-	fprintf(file, "\n    (pos (%3d %3d) size (%4d %3d))",
-	    ui->Buttons2[i].X, ui->Buttons2[i].Y,
-	    ui->Buttons2[i].Width, ui->Buttons2[i].Height);
+    fprintf(file, "\n    neutral-frame %d",
+	ui->InfoPanelNeutralFrame);
+    fprintf(file, "\n    selected-frame %d",
+	ui->InfoPanelSelectedFrame);
+    fprintf(file, "\n    magic-frame %d",
+	ui->InfoPanelMagicFrame);
+    fprintf(file, "\n    construction-frame %d",
+	ui->InfoPanelConstructionFrame);
+    fprintf(file, "\n    completed-bar (");
+    fprintf(file, "\n      color %d", ui->CompleteBarColor);
+    fprintf(file, "\n      pos (%d %d)", ui->CompleteBarX, ui->CompleteBarY);
+    fprintf(file, "\n      size (%d %d)", ui->CompleteBarW, ui->CompleteBarH);
+    fprintf(file, "\n      text \"%s\"", ui->CompleteBarText);
+    fprintf(file, "\n      font %s", FontNames[ui->CompleteBarFont]);
+    fprintf(file, "\n      text-pos (%d %d)",
+	ui->CompleteTextX, ui->CompleteTextY);
+    fprintf(file, ")");
+    if( ui->NumInfoButtons ) {
+	fprintf(file, "\n    buttons (");
+	for( i=0; i<ui->NumInfoButtons; ++i ) {
+	    fprintf(file, "\n      (pos (%3d %3d) size (%3d %3d))",
+		ui->InfoButtons[i].X, ui->InfoButtons[i].Y,
+		ui->InfoButtons[i].Width, ui->InfoButtons[i].Height);
+	}
+	fprintf(file, ")");
     }
+    if( ui->NumTrainingButtons ) {
+	fprintf(file, "\n    buttons (");
+	for( i=0; i<ui->NumTrainingButtons; ++i ) {
+	    fprintf(file, "\n      (pos (%3d %3d) size (%3d %3d))",
+		ui->TrainingButtons[i].X, ui->TrainingButtons[i].Y,
+		ui->TrainingButtons[i].Width, ui->TrainingButtons[i].Height);
+	}
+	fprintf(file, ")");
+    }
+    fprintf(file, ")\n");
 
-    fprintf(file, ")\n  'cursors '(point %s\n", ui->Point.Name);
-    fprintf(file, "    glass %s\n", ui->Glass.Name);
-    fprintf(file, "    cross %s\n", ui->Cross.Name);
-    fprintf(file, "    yellow %s\n", ui->YellowHair.Name);
-    fprintf(file, "    green %s\n", ui->GreenHair.Name);
-    fprintf(file, "    red %s\n", ui->RedHair.Name);
-    fprintf(file, "    scroll %s\n", ui->Scroll.Name);
+    fprintf(file, "\n  'button-area '(");
+    if( ui->NumButtonButtons ) {
+	fprintf(file, "\n    buttons (");
+	for( i=0; i<ui->NumButtonButtons; ++i ) {
+	    fprintf(file, "\n      (pos (%3d %3d) size (%3d %3d))",
+		ui->ButtonButtons[i].X, ui->ButtonButtons[i].Y,
+		ui->ButtonButtons[i].Width, ui->ButtonButtons[i].Height);
+	}
+	fprintf(file, ")");
+    }
+    fprintf(file, ")\n");
 
-    fprintf(file, "    arrow-e %s\n", ui->ArrowE.Name);
-    fprintf(file, "    arrow-ne %s\n", ui->ArrowNE.Name);
-    fprintf(file, "    arrow-n %s\n", ui->ArrowN.Name);
-    fprintf(file, "    arrow-nw %s\n", ui->ArrowNW.Name);
-    fprintf(file, "    arrow-w %s\n", ui->ArrowW.Name);
-    fprintf(file, "    arrow-sw %s\n", ui->ArrowSW.Name);
-    fprintf(file, "    arrow-s %s\n", ui->ArrowS.Name);
-    fprintf(file, "    arrow-se %s)\n", ui->ArrowSE.Name);
+    fprintf(file, "\n  'minimap-area '(");
+    fprintf(file, "\n    pos (%d %d)",
+	ui->MinimapX, ui->MinimapY);
+    fprintf(file, "\n    size (%d %d)",
+	ui->MinimapW, ui->MinimapH);
+    fprintf(file, "\n    cursor-color %d",
+	ui->MinimapCursorColor);
+    fprintf(file, ")\n");
 
-    fprintf(file, "  'panels '(game-menu \"%s\"\n", ui->GameMenuPanel.File);
-    fprintf(file, "    menu-1 \"%s\"\n", ui->Menu1Panel.File);
-    fprintf(file, "    menu-2 \"%s\"\n", ui->Menu2Panel.File);
-    fprintf(file, "    victory \"%s\"\n", ui->VictoryPanel.File);
-    fprintf(file, "    scenario \"%s\")", ui->ScenarioPanel.File);
+    fprintf(file, "\n  'status-line '(");
+    fprintf(file, "\n    font %s",
+	FontNames[ui->StatusLineFont]);
+    fprintf(file, "\n    pos (%d %d)",
+	ui->StatusLineX, ui->StatusLineY);
+    fprintf(file, "\n    width %d",
+	ui->StatusLineW);
+    fprintf(file, ")\n");
+
+    fprintf(file, "\n  'menu-button '(");
+    fprintf(file, "\n    pos (%d %d)",
+	ui->MenuButton.X, ui->MenuButton.Y);
+    fprintf(file, "\n    size (%d %d)",
+	ui->MenuButton.Width, ui->MenuButton.Height);
+    fprintf(file, "\n    caption \"%s\"",
+	ui->MenuButton.Text);
+    fprintf(file, "\n    style %s",
+	MenuButtonStyle(ui->MenuButton.Button));
+    fprintf(file, ")");
+
+    fprintf(file, "\n  'network-menu-button '(");
+    fprintf(file, "\n    pos (%d %d)",
+	ui->NetworkMenuButton.X, ui->NetworkMenuButton.Y);
+    fprintf(file, "\n    size (%d %d)",
+	ui->NetworkMenuButton.Width, ui->NetworkMenuButton.Height);
+    fprintf(file, "\n    caption \"%s\"",
+	ui->NetworkMenuButton.Text);
+    fprintf(file, "\n    style %s",
+	MenuButtonStyle(ui->NetworkMenuButton.Button));
+    fprintf(file, ")");
+
+    fprintf(file, "\n  'network-diplomacy-button '(");
+    fprintf(file, "\n    pos (%d %d)",
+	ui->NetworkDiplomacyButton.X, ui->NetworkDiplomacyButton.Y);
+    fprintf(file, "\n    size (%d %d)",
+	ui->NetworkDiplomacyButton.Width, ui->NetworkDiplomacyButton.Height);
+    fprintf(file, "\n    caption \"%s\"",
+	ui->NetworkDiplomacyButton.Text);
+    fprintf(file, "\n    style %s",
+	MenuButtonStyle(ui->NetworkDiplomacyButton.Button));
+    fprintf(file, ")\n");
+
+    fprintf(file, "\n  'message-area '(");
+    fprintf(file, "\n    font %s", FontNames[ui->MessageAreaFont]);
+    fprintf(file, "\n    pos (%d %d)",
+	ui->MessageAreaX, ui->MessageAreaY);
+    fprintf(file, "\n    width %d", ui->MessageAreaW);
+    fprintf(file, ")\n");
+
+    fprintf(file, "\n  'cursors '(");
+    fprintf(file, "\n    point %s", ui->Point.Name);
+    fprintf(file, "\n    glass %s", ui->Glass.Name);
+    fprintf(file, "\n    cross %s", ui->Cross.Name);
+    fprintf(file, "\n    yellow %s", ui->YellowHair.Name);
+    fprintf(file, "\n    green %s", ui->GreenHair.Name);
+    fprintf(file, "\n    red %s", ui->RedHair.Name);
+    fprintf(file, "\n    scroll %s", ui->Scroll.Name);
+
+    fprintf(file, "\n    arrow-e %s", ui->ArrowE.Name);
+    fprintf(file, "\n    arrow-ne %s", ui->ArrowNE.Name);
+    fprintf(file, "\n    arrow-n %s", ui->ArrowN.Name);
+    fprintf(file, "\n    arrow-nw %s", ui->ArrowNW.Name);
+    fprintf(file, "\n    arrow-w %s", ui->ArrowW.Name);
+    fprintf(file, "\n    arrow-sw %s", ui->ArrowSW.Name);
+    fprintf(file, "\n    arrow-s %s", ui->ArrowS.Name);
+    fprintf(file, "\n    arrow-se %s", ui->ArrowSE.Name);
+    fprintf(file, ")\n");
+
+    fprintf(file, "\n  'victory-background \"%s\"",
+	ui->VictoryBackground.File);
+    fprintf(file, "\n  'defeat-background \"%s\"",
+	ui->DefeatBackground.File);
+    fprintf(file, "\n");
+
+    fprintf(file, "\n  'menu-panels '(");
+    menupanel=ui->MenuPanels;
+    while( menupanel ) {
+	fprintf(file,"\n    %s \"%s\"",
+		menupanel->Ident, menupanel->Panel.File);
+	menupanel=menupanel->Next;
+    }
+    fprintf(file, ")");
 
     fprintf(file, " )\n\n");
 }
-#endif
 
 /**
 **	Save the viewports.
@@ -563,8 +520,7 @@ global void SaveUserInterface(FILE* file)
 	    TheUI.OriginalResources ? "#t" : "#f");
 
     // Save the current UI
-    OldSaveUi(file,&TheUI);
-    // NewSaveUi(file,&TheUI);
+    SaveUi(file,&TheUI);
     SaveViewports(file,&TheUI);
 }
 
@@ -581,8 +537,8 @@ global void CleanUserInterface(void)
     //
     //	Free the graphics. FIXME: if they are shared this will crash.
     //
-    for( i=0; i<TheUI.NumFillers; ++i ) {
-	VideoSaveFree(TheUI.Filler[i].Graphic);
+    for( i=0; i<TheUI.NumPanels; ++i ) {
+	VideoSaveFree(TheUI.Panel[i].Graphic);
     }
     VideoSaveFree(TheUI.Resource.Graphic);
 
@@ -590,13 +546,9 @@ global void CleanUserInterface(void)
 	VideoSaveFree(TheUI.Resources[i].Icon.Graphic);
     }
 
-    VideoSaveFree(TheUI.FoodIcon.Graphic);
-    VideoSaveFree(TheUI.ScoreIcon.Graphic);
+    VideoSaveFree(TheUI.Resources[FoodCost].Icon.Graphic);
+    VideoSaveFree(TheUI.Resources[ScoreCost].Icon.Graphic);
     VideoSaveFree(TheUI.InfoPanel.Graphic);
-    VideoSaveFree(TheUI.ButtonPanel.Graphic);
-    VideoSaveFree(TheUI.MenuButton.Graphic);
-    VideoSaveFree(TheUI.Minimap.Graphic);
-    VideoSaveFree(TheUI.StatusLine.Graphic);
 
     menupanel=TheUI.MenuPanels;
     while( menupanel ) {
diff --git a/src/video/font.cpp b/src/video/font.cpp
index b13aae11e..06a65f89c 100644
--- a/src/video/font.cpp
+++ b/src/video/font.cpp
@@ -97,6 +97,22 @@ local int FontBitmapWidths[MaxFonts];
 local int CurrentFont;
 #endif
 
+/**
+**	FIXME: should use the names of the real fonts.
+*/
+global char *FontNames[] = {
+    "small",
+    "game",
+    "large",
+    "small-title",
+    "large-title",
+    "user1",
+    "user2",
+    "user3",
+    "user4",
+    "user5",
+};
+
 /*----------------------------------------------------------------------------
 --	Functions
 ----------------------------------------------------------------------------*/