Index: 1.8.0-Changes.txt
===================================================================
--- 1.8.0-Changes.txt	(revision 5536)
+++ 1.8.0-Changes.txt	(working copy)
@@ -23,6 +23,7 @@
   OT DRB: (Windows) Fixed color glitching seen before QT cutscenes.
   OT DRB: Fixed observer movement actions with motion interpolation disabled.
   OT DRB: Fixed screenshot key on mac: ctrl+f12 for regular screenshots, ctrl+shift+f12 for mega screenshots.
+  OT DRB: Fixed crash when reading old version screen preferences.
   UI DRB: New option for coop cutscenes.
   UI DRB: Fixed the position of various in game UI elements when in a nonstandard resolution (one where a full-width statusbar collection does not exist).
   UI DRB: Fixed control bar buttons disappearing after switching back from control bar inventory mode at 640x480 resolution.
Index: Myth2Code/bitmap_dialogs/bitmap_dialogs.c
===================================================================
--- Myth2Code/bitmap_dialogs/bitmap_dialogs.c	(revision 5534)
+++ Myth2Code/bitmap_dialogs/bitmap_dialogs.c	(working copy)
@@ -169,9 +169,9 @@
 static void accumulate_dirty_bounds(rectangle2d *accumulation, rectangle2d *bounds);
 static void new_control(struct dialog_data *dialog, struct file_control_data *definition, char *text,
 	short base_item_id);
-static void invalidate_one_dialog_rectangle(struct dialog_data *dialog, rectangle2d *bounds);
+static void invalidate_one_dialog_rectangle(struct dialog_data *dialog, const rectangle2d *bounds);
 static boolean dialog_has_dirty_controls(struct dialog_data *dialog);
-static void invalidate_dialog_bounds(struct dialog_data *dialog, rectangle2d *bounds);
+static void invalidate_dialog_bounds(struct dialog_data *dialog, const rectangle2d *bounds);
 static boolean dialog_indexed_item_accepts_focus(struct dialog_data *dialog, short item_index, short *item);
 
 #ifdef GENERATE_DIALOG_STRINGS
@@ -281,7 +281,6 @@
 		
 		// and make it dirty
 		set_dialog_dirty(dialog);
-		dialog->must_be_redrawn= TRUE;
 	}
 	
 	return dialog;
@@ -357,7 +356,33 @@
 	void)
 {
 	struct dialog_data *dialog;
+	rectangle2d screen_bounds;
 
+	get_screen_bounds(&screen_bounds);
+
+	// Build 409 - DRB - since our resolution can change now, keep dialogs recentered at all times.
+	for (dialog= first_dialog; dialog != NULL; dialog= dialog->next)
+	{
+		if (DIALOG_IS_VISIBLE(dialog) && 
+			(dialog->flags & (_dialog_is_centered_flag | _dialog_is_hcentered_flag | _dialog_is_vcentered_flag)))
+		{
+			int both_flags = _dialog_is_hcentered_flag|_dialog_is_vcentered_flag;
+			rectangle2d new_bounds= dialog->bounds, old_bounds= dialog->bounds;
+			adjust_rectangle2d(&screen_bounds, &new_bounds, &new_bounds,
+				(dialog->flags & both_flags) == _dialog_is_hcentered_flag ? _adjust_rectangle_hcenter :
+				(dialog->flags & both_flags) == _dialog_is_vcentered_flag ? _adjust_rectangle_vcenter :
+				_adjust_rectangle_center);
+			assert(dialog->bounds.left >= 0 && dialog->bounds.top >= 0);
+			if(memcmp(&new_bounds, &old_bounds, sizeof(rectangle2d)))
+			{
+				dialog->bounds= new_bounds; // move
+				set_dialog_dirty(dialog); // invalidate bounds
+				invalidate_dialog_rectangle(&old_bounds); // redraw old bounds
+			}
+		}
+	}
+	// Build 409 - DRB - end change
+
 	if (the_modal_dialog)
 	{
 		give_dialog_items_time(the_modal_dialog);
@@ -378,33 +403,9 @@
 {
 	struct dialog_data *dialog;
 	boolean need_fullscreen_redraw= FALSE;
-	rectangle2d screen_bounds;
 
-	get_game_screen_bounds(&screen_bounds);
-
-	// Build 409 - DRB - since our resolution can change now, keep dialogs recentered at all times.
 	for (dialog= first_dialog; dialog != NULL; dialog= dialog->next)
 	{
-		if (DIALOG_IS_VISIBLE(dialog) && 
-			(dialog->flags & (_dialog_is_centered_flag | _dialog_is_hcentered_flag | _dialog_is_vcentered_flag)))
-		{
-			int both_flags = _dialog_is_hcentered_flag|_dialog_is_vcentered_flag;
-			rectangle2d old_bounds= dialog->bounds;
-			adjust_rectangle2d(&screen_bounds, &dialog->bounds, &dialog->bounds,
-				(dialog->flags & both_flags) == _dialog_is_hcentered_flag ? _adjust_rectangle_hcenter :
-				(dialog->flags & both_flags) == _dialog_is_vcentered_flag ? _adjust_rectangle_vcenter :
-				_adjust_rectangle_center);
-			assert(dialog->bounds.left >= 0 && dialog->bounds.top >= 0);
-			if(memcmp(&dialog->bounds, &old_bounds, sizeof(rectangle2d)))
-			{
-				set_dialog_dirty(dialog);
-			}
-		}
-	}
-	// Build 409 - DRB - end change
-
-	for (dialog= first_dialog; dialog != NULL; dialog= dialog->next)
-	{
 		if (!DIALOG_IS_VISIBLE(dialog))
 		{
 			continue;
@@ -425,7 +426,7 @@
 			{
 				rectangle2d bounds;
 
-				get_game_screen_bounds(&bounds);
+				get_screen_bounds(&bounds);
 				fill_rectangle(screen, &black, &bounds, 0, NULL);
 				// Clear the erase screen flag
 				dialog->flags&= ~_dialog_erases_screen_flag;
@@ -456,7 +457,8 @@
 		{
 			if (((!the_modal_dialog) && (dialog->flags & _dialog_is_transparent_flag)) || dialog_has_dirty_controls(dialog) || dialog_is_dirty(dialog))
 			{
-				accumulate_dirty_bounds(dirty_bounds, &dialog->bounds);
+				//accumulate_dirty_bounds(dirty_bounds, &dialog->bounds);
+				accumulate_dirty_bounds(dirty_bounds, &dialog->dirty_bounds);
 				dirty= TRUE;
 	 		}
 	 		*erase_to_black |= ((dialog->flags & _dialog_draws_black_backdrop_flag) ? TRUE : FALSE);
@@ -614,7 +616,7 @@
 
 			/* Convert the coordinate to local... */
 			local_point= action->pointer;
-			get_game_screen_bounds(&screen_bounds);
+			get_screen_bounds(&screen_bounds);
 			local_point.x-= screen_bounds.left + dialog_bounds.left;
 			local_point.y-= screen_bounds.top + dialog_bounds.top;
 
@@ -733,13 +735,6 @@
 
 			if (control->handler(_control_click_verb, dialog, item_index, &param))
 			{
-				// Build 306 - ALS - this is most gross.
-				// Build 363 - ALS - even grosser - status bar too
-				if (dialog == get_control_bar_dialog() || dialog == get_status_bar_dialog())
-				{
-					dialog->must_be_redrawn = TRUE;
-				}
-				// Build 306 - ALS - end change
 				press_item_with_delay(dialog, item_index, TICKS_FOR_VISIBLE_OFF+TICKS_FOR_VISIBLE_HOLD, &local_action);
 				handled= TRUE;
 			}
@@ -908,28 +903,21 @@
 	control= find_control(dialog, item);
 	if (control)
 	{
-		rectangle2d bounds, dialog_bounds;
 		struct dialog_data *dialog_in_front;
-		
-		bounds= control->bounds;
-		offset_rectangle2d(&bounds, dialog->bounds.left, dialog->bounds.top);
-	
+			
 		dialog->private_flags |= _dialog_has_dirty_background_controls_flag;
 		control->flags |= (_control_background_dirty_flag | _control_dirty_flag);
 
 		// Build 360 - ALS - invalidate the rectangle on this dialog - to invalidate any overlapping controls (i.e. metaserver room popup)
 		// Build 362 - ALS - invalidate the complete dialog bounds, in order to prevent transparent controls being drawn multiple times without
 		//                   the background being redrawn (i.e. multiplayer postgame stats dialog buttons)
-		dialog_bounds= dialog->bounds;
-		invalidate_one_dialog_rectangle(dialog, &dialog_bounds);
+		invalidate_one_dialog_rectangle(dialog, &dialog->bounds);
 		// Build 360 - ALS - end change
 
-		bounds= dialog->bounds; // Build 363 - ALS - ugh this is now necessary to invalidate the dialogs in front of it properly...
-		// easier than clip regions
 		dialog_in_front= dialog->next;
 		if (dialog_in_front && DIALOG_IS_VISIBLE(dialog))
 		{
-			invalidate_dialog_bounds(dialog_in_front, &bounds);
+			invalidate_dialog_bounds(dialog_in_front, &dialog->bounds);
 		}
 	}
 	assert(control);
@@ -979,7 +967,7 @@
 	{
 		rectangle2d clipped_bounds;
 	
-		if (DIALOG_IS_VISIBLE(dialog) && union_rectangles2d(bounds, &dialog->bounds, &clipped_bounds))
+		if (DIALOG_IS_VISIBLE(dialog) && intersect_rectangles2d(bounds, &dialog->bounds, &clipped_bounds))
 		{
 			dialog_in_bounds= TRUE;
  		}
@@ -990,7 +978,7 @@
 }
 
 void invalidate_dialog_rectangle(
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	if (first_dialog)
 	{
@@ -1413,7 +1401,6 @@
 		else if (dialog_has_dirty_controls(dialog))
 		{
 			draw_controls(destination, dialog);
-			dialog->must_be_redrawn= TRUE;
 		}
 
 		// no longer dirty. (set to be invalid, negative rectangle)
@@ -1821,7 +1808,7 @@
 		/* Convert the coordinate to local... */
 		local_point= action->pointer;
 			
-		get_game_screen_bounds(&screen_bounds);
+		get_screen_bounds(&screen_bounds);
 		
 		dialog_bounds= dialog->bounds;
 		local_point.x-= screen_bounds.left + dialog->bounds.left;
@@ -1879,7 +1866,7 @@
 		/* Convert the coordinate to local... */
 		local_point= action->pointer;
 			
-		get_game_screen_bounds(&screen_bounds);
+		get_screen_bounds(&screen_bounds);
 		
 		dialog_bounds= dialog->bounds;
 		local_point.x-= screen_bounds.left + dialog->bounds.left;
@@ -2205,7 +2192,6 @@
 					dialog->delay= 0;
 				}
 			}
-			dialog->must_be_redrawn= TRUE;
 		}
 		else
 		{
@@ -2387,7 +2373,7 @@
 // easier than doing clip regions....
 static void invalidate_dialog_bounds(
 	struct dialog_data *dialog,
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	while (dialog)
 	{
@@ -2400,13 +2386,13 @@
 
 static void invalidate_one_dialog_rectangle(
 	struct dialog_data *dialog,
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	rectangle2d clipped_bounds;
 
 	assert(dialog);
 
-	if (DIALOG_IS_VISIBLE(dialog) && union_rectangles2d(bounds, &dialog->bounds, &clipped_bounds))
+	if (DIALOG_IS_VISIBLE(dialog) && intersect_rectangles2d(bounds, &dialog->bounds, &clipped_bounds))
 	{
 		struct control_data *control;
 		rectangle2d dialog_space_dirty_rectangle;
@@ -2432,7 +2418,7 @@
 					{
 						rectangle2d control_dirty_rect;
 					
-						if (union_rectangles2d(&dialog_space_dirty_rectangle, &control->bounds, &control_dirty_rect))
+						if (intersect_rectangles2d(&dialog_space_dirty_rectangle, &control->bounds, &control_dirty_rect))
 						{
 							// set this control as dirty...
 							control->flags |= _control_dirty_flag;
@@ -2453,14 +2439,6 @@
 		// now save it in the dialog...
 		offset_rectangle2d(&dialog_space_dirty_rectangle, dialog->bounds.left, dialog->bounds.top);
 		dialog->dirty_bounds= dialog_space_dirty_rectangle;
-		// Build 341 - ALS - grow the dirty bounds to contain this dialog's dirty bounds
-		//                   so that we dirty the bounds of overlapping dialogs correctly
-		// Build 361 - ALS - moved into this function
-		bounds->left= MIN(bounds->left, dialog->dirty_bounds.left);
-		bounds->right= MAX(bounds->right, dialog->dirty_bounds.right);
-		bounds->top= MIN(bounds->top, dialog->dirty_bounds.top);
-		bounds->bottom= MAX(bounds->bottom, dialog->dirty_bounds.bottom);
-		// Build 341 - ALS - end change
 	}
 	
 	return;
Index: Myth2Code/bitmap_dialogs/bitmap_dialogs.h
===================================================================
--- Myth2Code/bitmap_dialogs/bitmap_dialogs.h	(revision 5534)
+++ Myth2Code/bitmap_dialogs/bitmap_dialogs.h	(working copy)
@@ -115,7 +115,6 @@
 	struct rgb_color text_color;
 	struct bitmap_data *internal_bitmap;
 
-	boolean must_be_redrawn;
 	boolean delay_was_set; // Build 326 - ALS
 	struct action_data click_action; // Build 326 - ALS
 };
@@ -150,7 +149,7 @@
 	int sequence_index);
 void set_dialog_background_color(struct dialog_data *dialog, struct rgb_color *color);
 
-void invalidate_dialog_rectangle(rectangle2d *bounds); // invalidates all dialogs that union this..
+void invalidate_dialog_rectangle(const rectangle2d *bounds); // invalidates all dialogs that union this..
 boolean dialog_exists_in_rectangle(rectangle2d *bounds);
 
 void set_dialog_item_keyboard_equivalent(struct dialog_data *dialog, short item, 
Index: Myth2Code/bitmap_dialogs/button_control.c
===================================================================
--- Myth2Code/bitmap_dialogs/button_control.c	(revision 5522)
+++ Myth2Code/bitmap_dialogs/button_control.c	(working copy)
@@ -340,8 +340,11 @@
 {
 	struct button_control_data *data= get_button_control_data(dialog, item_index);
 
-	data->flags= flags;
-	set_dialog_item_dirty(dialog, item_index);
+	if(data->flags != flags)
+	{
+		data->flags= flags;
+		set_dialog_item_dirty(dialog, item_index);
+	}
 	
 	return;
 }
@@ -353,8 +356,11 @@
 {
 	struct button_control_data *data= get_button_control_data(dialog, item_index);
 
-	data->transparency= transparency;
-	set_dialog_item_dirty(dialog, item_index);
+	if(data->transparency != transparency)
+	{
+		data->transparency= transparency;
+		set_dialog_item_dirty(dialog, item_index);
+	}
 	
 	return;
 }
@@ -366,7 +372,11 @@
 {
 	struct button_control_data *data= get_button_control_data(dialog, item_index);
 	
-	data->text_color= *color;
+	if(memcmp(&data->text_color, color, sizeof(struct rgb_color)))
+	{
+		data->text_color= *color;
+		set_dialog_item_dirty(dialog, item_index);
+	}
 	
 	return;
 }
Index: Myth2Code/bitmap_dialogs/private_lists.c
===================================================================
--- Myth2Code/bitmap_dialogs/private_lists.c	(revision 5522)
+++ Myth2Code/bitmap_dialogs/private_lists.c	(working copy)
@@ -763,7 +763,7 @@
 			current_row_rect.top= list->rows[index].height_in_list;
 			current_row_rect.bottom= current_row_rect.top+ list->rows[index].height;
 			
-			if (union_rectangles2d(&current_row_rect, &visible_bounds, &clip_rect))
+			if (intersect_rectangles2d(&current_row_rect, &visible_bounds, &clip_rect))
 			{
 				int horizontal_offset= list_bounds.left;
 				int vertical_offset= list_bounds.top + list->vertical_gutter -
@@ -1481,7 +1481,7 @@
 		{
 			rectangle2d bounds;
 			
-			union_rectangles2d(scroll_bounds, thumb_bounds, &bounds);
+			intersect_rectangles2d(scroll_bounds, thumb_bounds, &bounds);
 			warn(equal_rectangle2d(thumb_bounds, &bounds));
 		}
 #endif
Index: Myth2Code/bitmap_drawing.c
===================================================================
--- Myth2Code/bitmap_drawing.c	(revision 5535)
+++ Myth2Code/bitmap_drawing.c	(working copy)
@@ -132,7 +132,7 @@
 	return destination;
 }
 
-boolean union_rectangles2d(
+boolean intersect_rectangles2d(
 	const rectangle2d *r1,
 	const rectangle2d *r2,
 	rectangle2d *intersection)
@@ -161,6 +161,17 @@
 	return intersected;
 }
 
+void union_rectangles2d(
+	const rectangle2d *r1,
+	const rectangle2d *r2,
+	rectangle2d *union_rect)
+{
+	union_rect->left= MIN(r1->left, r2->left);
+	union_rect->right= MAX(r1->right, r2->right);
+	union_rect->top= MIN(r1->top, r2->top);
+	union_rect->bottom= MAX(r1->bottom, r2->bottom);
+}
+
 boolean point2d_in_rectangle2d(
 	const rectangle2d *rectangle,
 	const point2d *point)
Index: Myth2Code/bitmap_drawing.h
===================================================================
--- Myth2Code/bitmap_drawing.h	(revision 5529)
+++ Myth2Code/bitmap_drawing.h	(working copy)
@@ -100,13 +100,13 @@
 // geometry
 
 C_INLINE int rectangle2d_width(
-	rectangle2d *rectangle)
+	const rectangle2d *rectangle)
 {
 	return rectangle->right - rectangle->left;
 }
 
 C_INLINE int rectangle2d_height(
-	rectangle2d *rectangle)
+	const rectangle2d *rectangle)
 {
 	return rectangle->bottom - rectangle->top;
 }
@@ -116,8 +116,8 @@
 rectangle2d *offset_rectangle2d(rectangle2d *rectangle, short dx, short dy);
 rectangle2d *adjust_rectangle2d(rectangle2d *bounds, rectangle2d *source, rectangle2d *destination, short mode);
 
-#define intersect_rectangles2d(r1, r2, intersection) union_rectangles2d(r1, r2, intersection)
-boolean union_rectangles2d(const rectangle2d *r1, const rectangle2d *r2, rectangle2d *intersection);
+boolean intersect_rectangles2d(const rectangle2d *r1, const rectangle2d *r2, rectangle2d *intersection); // Build 409 - DRB - was union_rectangles2d. somebody doesn't know what union means!
+void union_rectangles2d(const rectangle2d *r1, const rectangle2d *r2, rectangle2d *union_rect); // Build 409 - DRB - new function
 boolean point2d_in_rectangle2d(const rectangle2d *rectangle, const point2d *point);
 
 boolean interior_rectangle2d(const rectangle2d *outer, const rectangle2d *inner);
Index: Myth2Code/console/console.c
===================================================================
--- Myth2Code/console/console.c	(revision 5531)
+++ Myth2Code/console/console.c	(working copy)
@@ -707,7 +707,7 @@
 	char txt[CONSOLE_LINE_BUFFER_SIZE];
 	rectangle2d screen_bounds;
 	
-	get_game_screen_bounds(&screen_bounds);
+	get_screen_bounds(&screen_bounds);
 	maximum_width = RECTANGLE_WIDTH(&screen_bounds);
 	if (owner_player_index != NONE)
 	{
Index: Myth2Code/control_bar.c
===================================================================
--- Myth2Code/control_bar.c	(revision 5536)
+++ Myth2Code/control_bar.c	(working copy)
@@ -75,17 +75,17 @@
 
 struct control_bar_data {
 	struct dialog_data *dialog;
-	short visible;
-	short inv_visible;
+	byte visible;
+	byte inv_visible;
+	byte visibility_before_toggle;
+	byte number_of_buttons;
 	short button_width;
-	short padding;
 	short collection_index;
-	short number_of_buttons;
 	struct mapping *button_mappings;
 	int string_list_index;
 };
 
-static struct control_bar_data control_bar= { NULL, TRUE, NONE};
+static struct control_bar_data control_bar;
 
 /* ---------- local prototypes */
 
@@ -100,7 +100,7 @@
 	NUMBER_OF_BUTTONS_1024x768= 20
 };
 
-static struct mapping button_mappings_640x480[]= 
+static struct mapping button_mappings_640x480[]=
 	{
 	{_button_chat, _control_bar_elements_sequence_generic_button},
 	{_button_stop, _control_bar_elements_sequence_generic_button},
@@ -113,11 +113,11 @@
 	{_button_formation_staggered_line, _control_bar_elements_sequence_formation3},
 	{_button_formation_box, _control_bar_elements_sequence_formation4},
 	{_button_formation_deep_encirclement, _control_bar_elements_sequence_formation5},
-	{_button_formation_vanguard, _control_bar_elements_sequence_formation6},	
+	{_button_formation_vanguard, _control_bar_elements_sequence_formation6},
 	{_button_formation_circle, _control_bar_elements_sequence_formation7}
 	};
 
-static struct mapping button_mappings_800x600[]= 
+static struct mapping button_mappings_800x600[]=
 	{
 	{_button_chat, _control_bar_elements_sequence_generic_button},
 	{_button_stop, _control_bar_elements_sequence_generic_button},
@@ -138,7 +138,7 @@
 	{_button_formation_circle, _control_bar_elements_sequence_formation10}
 	};
 
-static struct mapping button_mappings_1024x768[]= 
+static struct mapping button_mappings_1024x768[]=
 	{
 	{_button_chat, _control_bar_elements_sequence_generic_button},
 	{_button_empty, _control_bar_elements_sequence_generic_button},
@@ -216,7 +216,7 @@
 
 	if (control_bar.dialog)
 	{
-		short index;
+		int index;
 
 		move_control_bar();
 
@@ -236,7 +236,7 @@
 						(get_team_data(get_local_player_team_index())->number_of_players == 1)) &&
 						(control_bar.string_list_index != NONE))
 					{
-						set_button_control_name(control_bar.dialog, index, get_string_from_list(control_bar.string_list_index, _button_string_yell));	
+						set_button_control_name(control_bar.dialog, index, get_string_from_list(control_bar.string_list_index, _button_string_yell));
 					}
 					break;
 					
@@ -267,7 +267,9 @@
 					set_rectangle2d(&bounds, 0, 0, control_bar.button_width, 16);
 					offset_rectangle2d(&bounds, (78+((control_bar.button_width+16) * (index - (_button_inv_none + 1)))), 8);
 				}
+
 				new_unpressed_control(control_bar.dialog, DIALOG_BUTTON_TAG, index, &bounds, "");
+
 				if (index != _button_inv_none) // Build 258 - ALS
 				{
 					if (control_bar.button_width < 65)
@@ -280,30 +282,6 @@
 					}
 				}
 
-				switch (index)
-				{
-					case _button_inv_none:
-						set_button_control_name(control_bar.dialog, index, "None"); break;
-					case _button_inv_1:
-						set_button_control_name(control_bar.dialog, index, "Item 1"); break;
-					case _button_inv_2:
-						set_button_control_name(control_bar.dialog, index, "Item 2"); break;
-					case _button_inv_3:
-						set_button_control_name(control_bar.dialog, index, "Item 3"); break;
-					case _button_inv_4:
-						set_button_control_name(control_bar.dialog, index, "Item 4"); break;
-					case _button_inv_5:
-						set_button_control_name(control_bar.dialog, index, "Item 5"); break;
-					case _button_inv_6:
-						set_button_control_name(control_bar.dialog, index, "Item 6"); break;
-					case _button_inv_7:
-						set_button_control_name(control_bar.dialog, index, "Item 7"); break;
-					case _button_inv_8:
-						set_button_control_name(control_bar.dialog, index, "Item 8"); break;
-					case _button_inv_9:
-						set_button_control_name(control_bar.dialog, index, "Item 9"); break;
-				}
-
 				set_button_transparency(control_bar.dialog, index, 0);
 				find_control(control_bar.dialog, index)->flags|= _control_has_no_delay_flag; // Build 327 - ALS - instant control bar now!
 				bitmap_set_item_enabled(control_bar.dialog, index, TRUE);
@@ -314,7 +292,6 @@
 		set_dialog_background(control_bar.dialog, control_bar.collection_index, _control_bar_elements_sequence_background);
 		
 		set_dialog_visible(control_bar.dialog, control_bar.visible);
-		control_bar.dialog->must_be_redrawn= TRUE; // Build 306 - ALS - set must_be_redrawn on the dialog correctly
 	}
 	
 	return;
@@ -327,102 +304,61 @@
 	{
 		dispose_dialog(control_bar.dialog);
 		control_bar.dialog= NULL;
+		control_bar.visible= FALSE;
 	}
 
 	return;
 }
 
-void update_control_bar( // called at frame time....
+void update_control_bar_buttons(
 	void)
 {
-	if (control_bar.dialog &&
-		control_bar.visible)
+	boolean shift_down= key_down(_key_shift);
+
+	int index;
+	for (index= 1; index<=control_bar.number_of_buttons; ++index)
 	{
-		if (!control_bar.inv_visible)
+		int button_type= control_bar.button_mappings[index-1].button_type;
+		// handle switching between whisper and yell
+		if (button_type== _button_chat)
 		{
-		boolean must_be_redrawn= FALSE;
-
-		if (get_game_type()== _game_type_networked &&
-			get_local_player_team_index() != NONE)
-		{
-			struct team_data *player_team= get_team_data(get_local_player_team_index());
-
-			if (player_team->number_of_players > 1 &&
-				get_console_input_state() != _console_input_active)
+			if(control_bar.string_list_index != NONE &&
+				get_game_type()== _game_type_networked &&
+				get_local_player_team_index() != NONE)
 			{
-				static boolean last_chat_button_state= NONE;
-				boolean chat_button_state= key_down(_key_shift);
+				struct team_data *player_team= get_team_data(get_local_player_team_index());
 
-				if (chat_button_state!= last_chat_button_state)
+				if (player_team->number_of_players > 1 &&
+					get_console_input_state() != _console_input_active)
 				{
-					short index;
-
-					for (index= 1; index<=control_bar.number_of_buttons; ++index)
-					{
-						if ((control_bar.button_mappings[index-1].button_type== _button_chat) &&
-							(control_bar.string_list_index != NONE))
-						{
-							set_button_control_name(control_bar.dialog, index,
-								get_string_from_list(control_bar.string_list_index, chat_button_state ? _button_string_yell : _button_string_whisper));
-							must_be_redrawn= TRUE;
-							break;
-						}
-					}
-					last_chat_button_state= chat_button_state;
+					set_button_control_name(control_bar.dialog, index,
+						get_string_from_list(control_bar.string_list_index, shift_down ? _button_string_yell : _button_string_whisper));
 				}
 			}
 		}
-		
+		// handle ally button enable state
+		else if (button_type== _button_ally)
 		{
-			static boolean last_ally_button_state= NONE;
-			boolean enable_ally_button= ally_button_is_valid();
-
-			if (enable_ally_button!= last_ally_button_state)
-			{
-				short index;
-
-				for (index= 1; index<=control_bar.number_of_buttons; ++index)
-				{
-					if (control_bar.button_mappings[index-1].button_type== _button_ally)
-					{
-						bitmap_set_item_enabled(control_bar.dialog, index, enable_ally_button);
-						must_be_redrawn= TRUE;
-						break;
-					}
-				}
-				last_ally_button_state= enable_ally_button;
-			}
+			bitmap_set_item_enabled(control_bar.dialog, index, ally_button_is_valid());
 		}
+	}
+}
 
-		// Build 306 - ALS - set must_be_redrawn on the dialog correctly
-		if (control_bar.visible && must_be_redrawn)
+// called at frame time....
+void update_control_bar(
+	void)
+{
+	if (control_bar.dialog &&
+		control_bar.visible)
+	{
+		if (control_bar.inv_visible && (get_input_definition()->flags&_input_definition_control_bar_inventory_flag))
 		{
-			control_bar.dialog->must_be_redrawn= must_be_redrawn;
+			update_inventory_buttons();
 		}
-		// Build 306 - ALS - end change
-		}
-		else if (get_input_definition()->flags&_input_definition_control_bar_inventory_flag)
+		else
 		{
-			if (update_inventory_buttons())
-			{
-				control_bar.dialog->must_be_redrawn = TRUE; // Build 306 - ALS - set must_be_redrawn on the dialog correctly
-				set_dialog_dirty(control_bar.dialog);
-			}
+			update_control_bar_buttons();
 		}
-
-		// Builod 361 - ALS - simplified this logic
-		if (active_screen.rasterizer_code == _rasterizer_software)
-		{
-			static boolean use_transparency= FALSE;
-	
-			if (use_transparency != USE_TRANSPARENCY())
-			{
-				control_bar.dialog->must_be_redrawn= TRUE; // Build 306 - ALS - set must_be_redrawn on the dialog correctly
-				set_dialog_dirty(control_bar.dialog);
-				use_transparency= USE_TRANSPARENCY();
-			}
-		}
-		// Build 361 - ALS - end change
 	}
 
 	return;
@@ -445,125 +381,81 @@
 	}
 }
 
-short update_inventory_buttons(void)
+void update_inventory_buttons(void)
 {
 	short *projectile_types;
-	short index, count = 0, change = 0;
-	static short old_selected = NONE, old_count = NONE;
 
-	if (!control_bar.inv_visible) return 0;
+	if (!control_bar.inv_visible)
+	{
+		return;
+	}
 
 	// get a list of projectile types currently held by selected monster(s)
 	projectile_types = get_selection_inventory_types();
 
 	if (projectile_types)
 	{
-		short selected = get_selection_inventory_selected();
+		short selected_index = get_selection_inventory_selected();
 		struct rgb_color yellow = {0xffff, 0xffff, 0x7777};
 		
 		// see how many in list
-		count = get_selection_inventory_count();
+		int index, count = get_selection_inventory_count();
 
-		if (old_count != count || old_selected != selected)
+		if (count > _button_inv_count - (_button_inv_none-1))
 		{
-			change = 1;
+			count = _button_inv_count - (_button_inv_none-1);
 		}
-		old_count = count;
-		old_selected = selected;
 
-		if (count > _button_inv_count - (_button_inv_none-1))
-			count = _button_inv_count - (_button_inv_none-1);
-
 		if (!count)
-			return change;
-
-		// make sure we can see the None button
-		if (!bitmap_get_item_visible(control_bar.dialog, _button_inv_none))
 		{
-			change = 1;
+			return;
 		}
-		bitmap_set_item_visible(control_bar.dialog, _button_inv_none, TRUE);
-		bitmap_set_item_enabled(control_bar.dialog, _button_inv_none, TRUE);
-		if (selected == NONE)
-		{
-			set_button_control_text_color(control_bar.dialog, _button_inv_none, &yellow);
-		}
-		else
-		{
-			set_button_control_text_color(control_bar.dialog, _button_inv_none, &white);
-		}
 
 		// set status of the other buttons, adjust labels etc appropriately
-		for (index=0; index<count; index++)
+		for (index=NONE; index<count; index++)
 		{
-			struct projectile_definition *definition = get_projectile_definition(projectile_types[index]);
-			char *label = NULL, old_label[256], tmp[256];
+			int dialog_item= _button_inv_none + index + 1;
+			char *label = get_selection_inventory_string(index);
+			char tmp[256];
 
-			// set the label on the button
-			if (definition &&
-					definition->artifact_index != NONE)
-			{
-				label = get_string_from_list(get_artifact_definition(definition->artifact_index)->special_ability_string_list_index, 0);
-				//set_button_control_shape(control_bar.dialog, index, control_bar.collection_index, control_bar.button_mappings[index-1].sequence_index);
-			}
-
 			if (!label || !strlen(label))
 			{
 				sprintf(tmp, "Item %d", index);
 				label = tmp;
 			}
-			get_button_control_name(control_bar.dialog, _button_inv_none+1+index, old_label, sizeof(old_label)); // Build 310 - ALS - sizeof(old_label)
-			if (strcmp(label, old_label))
-			{
-				change = 1;
-			}
 
 			// display the button
-			if (!bitmap_get_item_visible(control_bar.dialog, _button_inv_none+1+index))
-			{
-				change = 1;
-			}
-			set_button_control_name(control_bar.dialog, _button_inv_none + 1 + index, label);
-			bitmap_set_item_visible(control_bar.dialog, _button_inv_none + 1 + index, TRUE);
-			bitmap_set_item_enabled(control_bar.dialog, _button_inv_none + 1 + index, TRUE);
+			set_button_control_name(control_bar.dialog, dialog_item, label);
+			bitmap_set_item_visible(control_bar.dialog, dialog_item, TRUE);
+			bitmap_set_item_enabled(control_bar.dialog, dialog_item, TRUE);
+			set_button_control_text_color(control_bar.dialog, dialog_item, index == selected_index ? &yellow : &white);
+		}
 
-			if (index == selected)
-			{
-				set_button_control_text_color(control_bar.dialog, _button_inv_none + 1 + index, &yellow);
-			}	
-			else
-			{
-				set_button_control_text_color(control_bar.dialog, _button_inv_none + 1 + index, &white);
-			}
-		}
 		// make extra buttons invisible
 		for (index=count + 1 + _button_inv_none; index<_button_inv_count; index++)
 		{
-			if (bitmap_get_item_visible(control_bar.dialog, index))
-			{
-				change = 1;
-			}
 			bitmap_set_item_visible(control_bar.dialog, index, FALSE);
 		}
 	}
 	else
 	{
 		// no items in selection - make all buttons invisible
+		int index;
 		for (index=_button_inv_none; index<_button_inv_count; index++)
 		{
-			if (bitmap_get_item_visible(control_bar.dialog, index))
-			{
-				change = 1;
-			}
 			bitmap_set_item_visible(control_bar.dialog, index, FALSE);
 		}
 	}
-	
-	set_dialog_dirty(control_bar.dialog);
-	control_bar.dialog->must_be_redrawn= TRUE; // Build 306 - ALS - set must_be_redrawn on the dialog correctly
-	return change;
 }
 
+void toggle_control_bar_inventory(
+	void)
+{
+	int visibility_before_toggle = control_bar.visible;
+	set_control_bar_visibility(control_bar.visible == 2 ? control_bar.visibility_before_toggle : 2);
+	control_bar.visibility_before_toggle = visibility_before_toggle;
+}
+
 void set_control_bar_visibility(
 	boolean visible)
 {
@@ -571,14 +463,12 @@
 		get_local_player_team_index()!= NONE && // observers
 		control_bar.visible != visible)
 	{
-		short index;
-		short inv_was_visible = control_bar.inv_visible;
+		int index, inv_was_visible = control_bar.inv_visible;
 
 		set_dialog_visible(control_bar.dialog, visible);
 		control_bar.visible= visible;
 
 		SET_FLAG(get_game_preferences()->flags, _game_pref_control_bar_visible_bit, visible);
-//		write_game_preferences();
 
 		if (get_input_definition()->flags&_input_definition_control_bar_inventory_flag)
 		{
@@ -610,8 +500,14 @@
 			}
 		}
 	}
-	
-	return;	
+
+	if(active_screen.rasterizer_code== _rasterizer_software)
+	{
+		// mark us as dirty here so that set_control_bar_visibility(control_bar_visible(NULL)) handles a transparency switch.
+		set_dialog_dirty(control_bar.dialog);
+	}
+
+	return;
 }
 
 short control_bar_visible(
@@ -622,16 +518,9 @@
 		calculate_control_bar_bounds(bounds);
 	}
 	
-	return control_bar.visible;	
+	return control_bar.visible;
 }
 
-short control_inventory_visible(void)
-{
-	if (control_bar.visible && control_bar.inv_visible)
-		return TRUE;
-	return FALSE;
-}
-
 struct dialog_data *get_control_bar_dialog(
 	void)
 {
@@ -641,65 +530,25 @@
 /* ---------- local code */
 
 static void control_bar_dialog_handler_proc(
-	struct dialog_data *dialog, 
+	struct dialog_data *dialog,
 	short item,
 	struct action_data *action)
 {
-	short button_type= control_bar.button_mappings[item-1].button_type;
+	int button_type= control_bar.button_mappings[item-1].button_type;
+	boolean shift_down= test_action_flag(action, _shift_down_bit);
 	
 	UNUSED_PARAMETER(dialog);
 
-	if (control_bar.visible)
-	{
-		control_bar.dialog->must_be_redrawn= TRUE; // Build 306 - ALS - set must_be_redrawn on the dialog correctly
-	}
-
 	if (control_bar.visible && control_bar.inv_visible &&
 		(get_input_definition()->flags&_input_definition_control_bar_inventory_flag))
 	{
-		switch (item)
+		if (_button_inv_none <= item && item <= _button_inv_9)
 		{
-			case _button_inv_none:
-				set_selection_inventory(9, FALSE);
-				update_inventory_buttons();
-				break;
-			case _button_inv_1:
-				set_selection_inventory(0, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_2:
-				set_selection_inventory(1, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_3:
-				set_selection_inventory(2, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_4:
-				set_selection_inventory(3, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_5:
-				set_selection_inventory(4, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_6:
-				set_selection_inventory(5, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_7:
-				set_selection_inventory(6, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_8:
-				set_selection_inventory(7, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
-			case _button_inv_9:
-				set_selection_inventory(8, key_down(_key_shift)); 
-				update_inventory_buttons();
-				break;
+			int inventory_index= item== _button_inv_none ? 9 : item-_button_inv_1;
+			set_selection_inventory(inventory_index, shift_down);
+			update_inventory_buttons();
 		}
+
 		return;
 	}
 
@@ -743,7 +592,7 @@
 		case _button_formation_deep_encirclement:
 		case _button_formation_vanguard:
 		case _button_formation_circle:
-			assign_formation_to_selection(button_type - _button_formation_short_line, test_action_flag(action, _shift_down_bit));
+			assign_formation_to_selection(button_type - _button_formation_short_line, shift_down);
 			break;
 	}
 	
@@ -755,7 +604,7 @@
 {
 	rectangle2d game_bounds;
 
-	get_game_screen_bounds(&game_bounds);
+	get_screen_bounds(&game_bounds);
 	
 	if (control_bar.dialog)
 	{
@@ -778,7 +627,7 @@
 {
 	rectangle2d game_bounds;
 
-	get_game_screen_bounds(&game_bounds);	// Build 205 - PAB - Set the dialog bounds correctly now
+	get_screen_bounds(&game_bounds);	// Build 205 - PAB - Set the dialog bounds correctly now
 
 	control_bar.dialog->bounds.top = game_bounds.bottom - CONTROL_BAR_HEIGHT;
 	control_bar.dialog->bounds.bottom= control_bar.dialog->bounds.top + CONTROL_BAR_HEIGHT;
@@ -816,7 +665,7 @@
 			if (valid_team_count > 1)
 			{
 				enable_ally_button= TRUE;
-			}				
+			}
 		}
 	}
 	
Index: Myth2Code/control_bar.h
===================================================================
--- Myth2Code/control_bar.h	(revision 5531)
+++ Myth2Code/control_bar.h	(working copy)
@@ -29,8 +29,8 @@
 void update_control_bar_for_new_resolution(boolean new_gui_res);
 
 int is_control_bar(struct dialog_data *);
+void toggle_control_bar_inventory(void); // Build 409 - DRB
 void set_control_bar_visibility(boolean visible);
 short control_bar_visible(rectangle2d *bounds);
 #define CTRL_BAR_HEIGHT 32    // I know, shoot me.
-short control_inventory_visible(void);
 struct dialog_data *get_control_bar_dialog(void);
Index: Myth2Code/cutscenes/cutscenes.c
===================================================================
--- Myth2Code/cutscenes/cutscenes.c	(revision 5522)
+++ Myth2Code/cutscenes/cutscenes.c	(working copy)
@@ -459,15 +459,13 @@
 		// Modal Update
 
 		struct bitmap_data *viewport;
-		rectangle2d source, destination;
-		get_game_screen_bounds(&source);
-		offset_rectangle2d(&source, -source.left, -source.top);
-		get_game_screen_bounds(&destination);
-		viewport = get_linear_backbuffer(&source);
+		rectangle2d screen_bounds;
+		get_screen_bounds(&screen_bounds);
+		viewport = get_linear_backbuffer(&screen_bounds);
 		movie_player_set_viewport(player, viewport);
 		player->done = !movie_player_advance(player);
 		release_linear_backbuffer(viewport);
-		display_backbuffer(&source, &destination);
+		display_backbuffer(&screen_bounds);
 	}
 
 	return player->done;
Index: Myth2Code/hardware/3DFX/utilities_3dfx.c
===================================================================
--- Myth2Code/hardware/3DFX/utilities_3dfx.c	(revision 5522)
+++ Myth2Code/hardware/3DFX/utilities_3dfx.c	(working copy)
@@ -465,7 +465,7 @@
 	// The status and control bars need to adjust the size of the texture pages based on the width
 	// of the screen, because not all screens are an even multiple of 64 across.  Besides,
 	// we might as well compute the true number of pages we'll need.
-	get_game_screen_bounds(&screen_bounds);
+	get_screen_bounds(&screen_bounds);
 	screen_width= RECTANGLE_WIDTH(&screen_bounds);
 
 	if (screen_width%128== 0)
Index: Myth2Code/hardware/Direct3D/render_d3d.c
===================================================================
--- Myth2Code/hardware/Direct3D/render_d3d.c	(revision 5522)
+++ Myth2Code/hardware/Direct3D/render_d3d.c	(working copy)
@@ -328,7 +328,7 @@
 	short piece_height;
 	int panel_index= 0;
 	int x0, x1, y0, y1;
-	D3DTLVERTEX	vertices[4];
+	D3DTLVERTEX vertices[4];
 
 	D3DCOLOR color= RGBA_MAKE(255, 255, 255, INTERFACE_ALPHA());
 
Index: Myth2Code/hardware/Direct3D/utilities_d3d.c
===================================================================
--- Myth2Code/hardware/Direct3D/utilities_d3d.c	(revision 5522)
+++ Myth2Code/hardware/Direct3D/utilities_d3d.c	(working copy)
@@ -920,7 +920,7 @@
 	// The status and control bars need to adjust the size of the texture pages based on the width
 	// of the screen, because not all screens are an even multiple of 64 across.  Besides,
 	// we might as well compute the true number of pages we'll need.
-	get_game_screen_bounds( &screen_bounds );
+	get_screen_bounds( &screen_bounds );
 	screen_width = RECTANGLE_WIDTH(&screen_bounds);
 
 	if (screen_width%128 == 0)
Index: Myth2Code/hardware/hardware_rasterizers.c
===================================================================
--- Myth2Code/hardware/hardware_rasterizers.c	(revision 5522)
+++ Myth2Code/hardware/hardware_rasterizers.c	(working copy)
@@ -190,7 +190,7 @@
 }
 
 struct bitmap_data *initialize_render_bitmap_hardware(
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	struct bitmap_data *bitmap= active_screen.offscreen_pixels_structure;
 
@@ -487,7 +487,6 @@
 #endif
 
 	}
-
 }
 // Build 366 - ALS - end change
 
Index: Myth2Code/hardware/hardware_rasterizers.h
===================================================================
--- Myth2Code/hardware/hardware_rasterizers.h	(revision 5522)
+++ Myth2Code/hardware/hardware_rasterizers.h	(working copy)
@@ -99,7 +99,7 @@
 
 void preload_bitmap_into_cache_hardware(struct bitmap_data *bitmap);
 
-struct bitmap_data *initialize_render_bitmap_hardware(rectangle2d *bounds);
+struct bitmap_data *initialize_render_bitmap_hardware(const rectangle2d *bounds);
 void release_render_bitmap_hardware(void);
 
 struct bitmap_data *get_linear_backbuffer_hardware(rectangle2d *bounds);
Index: Myth2Code/hardware/OpenGL/render_opengl.c
===================================================================
--- Myth2Code/hardware/OpenGL/render_opengl.c	(revision 5532)
+++ Myth2Code/hardware/OpenGL/render_opengl.c	(working copy)
@@ -1112,7 +1112,7 @@
 	current_projection_mode = _projection_mode_none;
 
 	{
-		get_active_screen_bounds(&window);
+		get_screen_bounds(&window);
 		window_width = window.right - window.left;
 		window_height = window.bottom - window.top;
 	}
Index: Myth2Code/main.c
===================================================================
--- Myth2Code/main.c	(revision 5530)
+++ Myth2Code/main.c	(working copy)
@@ -334,7 +334,7 @@
 static boolean rasterize_dialogs(rectangle2d *fullscreen_bounds, rectangle2d *dirty_bounds, boolean must_redraw);
 
 static boolean exit_myth_on_game_quit(void);
-static void rasterize_myth(int ticks_elapsed, rectangle2d *bounds);
+static void rasterize_myth(int ticks_elapsed, const rectangle2d *bounds);
 static void adjust_landscape_filtering(void);
 static boolean warn_no_networking(boolean warn);
 
@@ -1210,14 +1210,9 @@
 	boolean dialogs_only)
 {
 	struct game_data *game= get_game();
-	rectangle2d render_bounds;
-	rectangle2d destination_bounds;
 	boolean game_in_progress= FALSE;
 	int render_ticks_elapsed= ticks_elapsed;
 
-	calculate_source_frame(&render_bounds);
-	calculate_destination_frame(&destination_bounds);
-
 	// update and rasterize the game if it is running and time passed...
 	if (!dialogs_only)
 	{
@@ -1255,6 +1250,10 @@
 	if (myth_is_visible() && // if not visible, don't bother rendering
 		game->state != _game_state_modal_draw_loop)
 	{
+		// Initialize to empty rect, and accumulate bounds as we go.
+		rectangle2d redraw_bounds;
+		set_rectangle2d(&redraw_bounds, SHORT_MAX, SHORT_MAX, SHORT_MIN, SHORT_MIN);
+
 		if (active_screen.rasterizer_code != _rasterizer_software)
 		{
 			render_begin_hardware();
@@ -1267,24 +1266,24 @@
 		}
 		// Build 344 - ALS - end change
 
- 		if (!dialogs_only && game_in_progress)
+		if (!dialogs_only && game_in_progress)
 		{
 			// Build 311 - Melekor - free at last from the laggy shackles of 30 FPS oppression!
 			handle_camera_control(game->game_ticks_since_last_frame);
-			rasterize_myth(render_ticks_elapsed, &render_bounds);
+			calculate_destination_frame(&redraw_bounds);
+			rasterize_myth(render_ticks_elapsed, &redraw_bounds);
 		}
 
 		// display any dialogs, and finish displaying the screen.
 		{
 			boolean dialogs_were_drawn;
-			rectangle2d dialog_dirty_bounds, fullscreen_bounds, game_screen_bounds;
-			get_game_screen_bounds(&game_screen_bounds);
-			set_rectangle2d(&fullscreen_bounds, 0, 0, rectangle2d_width(&game_screen_bounds), rectangle2d_height(&game_screen_bounds));
-			dialogs_were_drawn = rasterize_dialogs(&fullscreen_bounds, &dialog_dirty_bounds, dialogs_only || game_in_progress);
+			boolean redraw_dialogs= active_screen.rasterizer_code != _rasterizer_software; // always redraw dialogs every frame in hardware modes.
+			rectangle2d dialog_dirty_bounds, screen_bounds;
+			get_screen_bounds(&screen_bounds);
+			dialogs_were_drawn = rasterize_dialogs(&screen_bounds, &dialog_dirty_bounds, redraw_dialogs);
 			if(dialogs_were_drawn)
 			{
-				destination_bounds= game_screen_bounds;
-				render_bounds= fullscreen_bounds;
+				union_rectangles2d(&redraw_bounds, &dialog_dirty_bounds, &redraw_bounds);
 			}
 
 #if !defined(macosx) && !defined(linux)
@@ -1292,9 +1291,7 @@
 			if (active_screen.rasterizer_code == _rasterizer_3dfx &&
 				!has_hardware_cursor_3dfx())
 			{
-				struct bitmap_data *fullscreen_bitmap_data;
-
-				fullscreen_bitmap_data= get_render_destination(&fullscreen_bounds);
+				struct bitmap_data *fullscreen_bitmap_data= get_render_destination(&screen_bounds);
 				rasterize_mouse_cursor(fullscreen_bitmap_data);
 				release_render_destination(fullscreen_bitmap_data);
 			}
@@ -1304,9 +1301,13 @@
 		if (active_screen.rasterizer_code != _rasterizer_software)
 		{
 			render_end_hardware(TRUE);
+			update_screen_hardware();
 		}
-
-		display_backbuffer(&render_bounds, &destination_bounds);
+		else if (redraw_bounds.left < redraw_bounds.right &&
+			redraw_bounds.top < redraw_bounds.bottom)
+		{
+			display_backbuffer(&redraw_bounds);
+		}
 	}
 
 	if(screenshot_requested)
@@ -1322,7 +1323,7 @@
 
 static void rasterize_myth(
 	int ticks_elapsed,
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	struct view_data view;
 	memset(&view, 0, sizeof(view));
@@ -1412,21 +1413,17 @@
 				// Build 366 - ALS - refactored the below code
 				if (dialog_rasterization.dialog == status_bar_dialog)
 				{
-					if (status_bar_visible(NULL) &&
-						(must_redraw || status_bar_dialog->must_be_redrawn))
+					if (status_bar_visible(NULL))
 					{
 						draw_status_bar_hardware(&dialog_rasterization);
-						status_bar_dialog->must_be_redrawn= FALSE;
 						dialogs_were_drawn= TRUE;
 					}
 				}
 				else if (dialog_rasterization.dialog == control_bar_dialog)
 				{
-					if (control_bar_visible(NULL) &&
-						(must_redraw || control_bar_dialog->must_be_redrawn))
+					if (control_bar_visible(NULL))
 					{
 						draw_control_bar_hardware(&dialog_rasterization);
-						control_bar_dialog->must_be_redrawn= FALSE;
 						dialogs_were_drawn= TRUE;
 					}
 				}
@@ -2766,33 +2763,6 @@
 			break;
 	}
 
-#ifdef NEW_INVENTORY
-	// Build 256 - ACS
-	if (get_game_state()==_game_state_running &&
-		(get_input_definition()->flags&_input_definition_control_bar_inventory_flag) &&
-		test_action_flag(action, _selection_inventory_bit) && 
-		get_console_input_state() != _console_input_active && // not when chatting
-		!test_action_flag(action, _option_down_bit) && 
-		!shift_down)
-	{
-		static short control_bar_was_visible = 0;
-		static short inventory_was_visible = 0;
-
-		if (!inventory_was_visible)
-		{
-			control_bar_was_visible = control_bar_visible(NULL);
-			inventory_was_visible = TRUE;
-			set_control_bar_visibility(2);
-		}
-		else
-		{
-			inventory_was_visible = FALSE;
-			set_control_bar_visibility(control_bar_was_visible);
-		}
-	}
-	// Build 256 - end change
-#endif
-	
 	return handled;
 }
 
Index: Myth2Code/myth_networking/myth_networking.c
===================================================================
--- Myth2Code/myth_networking/myth_networking.c	(revision 5522)
+++ Myth2Code/myth_networking/myth_networking.c	(working copy)
@@ -2315,8 +2315,6 @@
 		for (i = 0; i < missing_plugins_count; i++)
 			add_missing_plugin_to_list(dialog, iMISSING_PLUGINS_LIST, missing_plugins + i);
 
-		dialog->must_be_redrawn = TRUE;
-
 		missing_plugins_dialog = dialog; // Build 331 - ALS
 		while (!done)
 		{
@@ -2391,7 +2389,6 @@
 				for (i = 0; i < missing_plugins_count; i++)
 					add_missing_plugin_to_list(missing_plugins_dialog, iMISSING_PLUGINS_LIST, missing_plugins + i);
 				set_dialog_item_dirty(missing_plugins_dialog, iMISSING_PLUGINS_LIST);
-				missing_plugins_dialog->must_be_redrawn = TRUE;
 				return TRUE; // "recovered" because the existing missing plugins dialog will return the real value
 			}
 			// Build 331 - ALS - end change
Index: Myth2Code/observer.c
===================================================================
--- Myth2Code/observer.c	(revision 5522)
+++ Myth2Code/observer.c	(working copy)
@@ -930,7 +930,7 @@
 				{
 					struct rectangle2d bounds;
 					short cx, cy;
-					get_game_screen_bounds(&bounds);
+					get_screen_bounds(&bounds);
 					cx = (bounds.left+bounds.right)/2;
 					cy = (bounds.top+bounds.bottom)/2;
 					set_mouse_position(cx, cy);
@@ -961,7 +961,7 @@
 				short x, y;
 				short cx, cy;
 				get_mouse_position(&x, &y);
-				get_game_screen_bounds(&bounds);
+				get_screen_bounds(&bounds);
 				cx = (bounds.left+bounds.right)/2;
 				cy = (bounds.top+bounds.bottom)/2;
 				set_mouse_position(cx, cy);
Index: Myth2Code/render/render.c
===================================================================
--- Myth2Code/render/render.c	(revision 5522)
+++ Myth2Code/render/render.c	(working copy)
@@ -8,7 +8,7 @@
 
 #include "cseries.h"
 
-#include "screen.h" // for get_game_screen_bounds()
+#include "screen.h" // for get_screen_bounds()
 #include "render_private.h"
 #include "render_sort.h"
 #include "error_manager.h"
@@ -169,9 +169,9 @@
 	}
 	else
 	{
-		rectangle2d fullscreen_bounds;
-		set_rectangle2d(&fullscreen_bounds, 0, 0, active_screen.width, active_screen.height);
-		screenshot = copy_bits_from_render_view_hardware(&fullscreen_bounds);
+		rectangle2d screen_bounds;
+		get_screen_bounds(&screen_bounds);
+		screenshot = copy_bits_from_render_view_hardware(&screen_bounds);
 	}
 
 	return screenshot;
@@ -604,7 +604,7 @@
 	rectangle2d window;
 
 	{
-		get_active_screen_bounds(&window);
+		get_screen_bounds(&window);
 		window_width = window.right - window.left;
 		window_height = window.bottom - window.top;
 	}
Index: Myth2Code/render/render_rasterize.c
===================================================================
--- Myth2Code/render/render_rasterize.c	(revision 5522)
+++ Myth2Code/render/render_rasterize.c	(working copy)
@@ -490,7 +490,7 @@
 		{
 			render_begin_hardware();
 		}
-		get_game_screen_bounds(&bounds);
+		get_screen_bounds(&bounds);
 		offset_rectangle2d(&bounds, -bounds.left, -bounds.top);
 
 		bitmap= get_linear_backbuffer(&bounds);
Index: Myth2Code/screen.c
===================================================================
--- Myth2Code/screen.c	(revision 5531)
+++ Myth2Code/screen.c	(working copy)
@@ -389,45 +389,17 @@
 	}
 }
 
-#if defined(windows) || defined(USE_SDL)
-void get_active_screen_bounds(
+void get_screen_bounds(
 	rectangle2d *bounds)
 {
 	assert(active_screen.screen_initialized);
 	set_rectangle2d(bounds, 0, 0, active_screen.width, active_screen.height);
-	
-	return;
-}
-#endif
 
-// will be smaller than active_screen bounds if the machine doesn't support resolution switching (a la powerbooks)
-void get_game_screen_bounds(
-	rectangle2d *bounds)
-{
-	rectangle2d screen_bounds;
-
-	assert(active_screen.screen_initialized);
-
-	get_active_screen_bounds(&screen_bounds);
-
-	// Notice that this doesn't really support monitors which can't support < 640x480 (like
-	// the PowerBook540c w/ PPC upgrade.
-//	set_rectangle2d(bounds, 0, 0, active_screen.screen_parameters->width, active_screen.screen_parameters->height);
-	/* offsets should only matter for screens that can't resolution switch, a la 3400c's */
-
-	bounds->left= 0;
-	bounds->top= 0;
-	bounds->right = active_screen.resolution_width;
-	bounds->bottom = active_screen.resolution_height;
-
-	/* Now center it */
-	adjust_rectangle2d(&screen_bounds, bounds, bounds, _adjust_rectangle_center);
-
 	return;
 }
 
 struct bitmap_data *get_render_destination(
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	struct bitmap_data *bitmap= NULL;
 
@@ -495,33 +467,30 @@
 	struct rgb_color *color)
 {
 	struct bitmap_data *linear_backbuffer;
-	rectangle2d source, destination;
+	rectangle2d screen;
 
-	get_game_screen_bounds(&source);
-	offset_rectangle2d(&source, -source.left, -source.top);
-	get_game_screen_bounds(&destination);
+	set_rectangle2d(&screen, 0, 0, active_screen.width, active_screen.height);
 
-	linear_backbuffer= get_linear_backbuffer(&source);
+	linear_backbuffer= get_linear_backbuffer(&screen);
 	if (linear_backbuffer)
 	{
-		fill_rectangle(linear_backbuffer, color, &source, 0, NULL);
+		fill_rectangle(linear_backbuffer, color, &screen, 0, NULL);
 		release_linear_backbuffer(linear_backbuffer);
 	}
 
-	display_backbuffer(&source, &destination);
+	display_backbuffer(&screen);
 
 	return;
 }
 
 void display_backbuffer(
-	rectangle2d *source_bounds,
-	rectangle2d *destination_bounds)
+	const rectangle2d *rect)
 {
 	perf_push("display_backbuffer", _perf_category_graphics_gpu);
 
 	if (active_screen.rasterizer_code== _rasterizer_software)
 	{
-		copy_offscreen_world_to_screen(source_bounds, destination_bounds);
+		copy_offscreen_world_to_screen(rect);
 	}
 	else
 	{
@@ -544,10 +513,12 @@
 		active_screen.rasterizer_code == _rasterizer_3dfx;
 }
 
+// The destination frame is the sub-rect of the game screen
+// which should be drawn to by rasterize_myth.
 void calculate_destination_frame(
 	rectangle2d *frame)
 {
-	get_game_screen_bounds(frame);
+	get_screen_bounds(frame);
 
 	if (!gui_overlaps_screen_bitmap())
 	{
@@ -567,29 +538,6 @@
 	return;
 }
 
-void calculate_source_frame(
-	rectangle2d *frame)
-{
-	short width, height;
-	rectangle2d screen_bounds;
-
-	calculate_destination_frame(frame);
-
-	height= RECTANGLE_HEIGHT(frame);
-	width= RECTANGLE_WIDTH(frame);
-
-	// put into gworld coordinate system.
-	get_game_screen_bounds(&screen_bounds);
-	offset_rectangle2d(frame, -screen_bounds.left, -screen_bounds.top);
-
-	/* Into the lower right corner of the destination, so we can pixel double in place. */
-	set_rectangle2d(frame, frame->left+RECTANGLE_WIDTH(frame)-width, frame->top+RECTANGLE_HEIGHT(frame)-height, 
-		frame->right, frame->bottom);
-	
-	return;
-}
-
-
 #include "spatial_groups.h"
 #include "monster_definitions.h"
 #include "attack_ai.h"
@@ -838,7 +786,7 @@
 }
 
 struct bitmap_data *initialize_offscreen_bitmap_with_data(
-	rectangle2d *bounds,
+	const rectangle2d *bounds,
 	void *data,
 	int bytes_per_row)
 {
Index: Myth2Code/screen.h
===================================================================
--- Myth2Code/screen.h	(revision 5530)
+++ Myth2Code/screen.h	(working copy)
@@ -170,7 +170,7 @@
 
 /* ------ prototypes/SCREEN.C */
 // this is only for rendering- ie triangles, and rectangles. (hardware uses this as well)
-struct bitmap_data *get_render_destination(rectangle2d *bounds);
+struct bitmap_data *get_render_destination(const rectangle2d *bounds);
 void release_render_destination(struct bitmap_data *bitmap);
 
 struct bitmap_data *get_linear_backbuffer(rectangle2d *bounds);
@@ -178,19 +178,17 @@
 
 void erase_and_display_backbuffer(struct rgb_color *color);
 
-void display_backbuffer(rectangle2d *source, rectangle2d *destination);
+void display_backbuffer(const rectangle2d *rect);
 
 // true if status or control bars draw on top of the game screen, e.g. with transparency on
 boolean gui_overlaps_screen_bitmap(void);
 
 void calculate_destination_frame(rectangle2d *frame);
-void calculate_source_frame(rectangle2d *frame);
 
-void calculate_mouse_movement_frame(rectangle2d *mouse_bounds);
+void calculate_mouse_movement_frame(rectangle2d *mouse_bounds); // Build 409 - DRB - TODO - scrap this function.
 
-void get_active_screen_bounds(rectangle2d *bounds);
-void get_game_screen_bounds(rectangle2d *bounds);
-void get_true_screen_dimensions(short *width, short *height);
+void get_screen_bounds(rectangle2d *bounds);
+void get_true_screen_dimensions(short *width, short *height); // Build 409 - DRB - TODO - scrap this function.
 
 void update_fps_only(void);	// Build 236 - PAB
 
@@ -201,7 +199,7 @@
 
 int get_pixel_upshift_for_bit_depth(int bit_depth);
 struct bitmap_data *initialize_offscreen_bitmap_with_data(
-	rectangle2d *bounds, void *data, int bytes_per_row);
+	const rectangle2d *bounds, void *data, int bytes_per_row);
 
 //#define get_active_screen_bit_depth() (active_screen.bit_depth)
 #define get_active_screen_encoding() (active_screen.encoding)
@@ -218,7 +216,7 @@
 boolean is_windowed_now(void);
 
 // should be in hardware.h? screen_xx.h? 
-struct bitmap_data *initialize_offscreen_bitmap(rectangle2d *bounds);
+struct bitmap_data *initialize_offscreen_bitmap(const rectangle2d *bounds);
 void release_offscreen_bitmap(struct bitmap_data *bitmap);
 
 const struct resolution_data *get_resolution_data(int width);
Index: Myth2Code/screen_private.h
===================================================================
--- Myth2Code/screen_private.h	(revision 5522)
+++ Myth2Code/screen_private.h	(working copy)
@@ -37,4 +37,4 @@
 short allocate_drawing_buffers(short device_index, short mode_index, boolean change_screen);
 void dispose_drawing_buffers(void);
 
-void copy_offscreen_world_to_screen(rectangle2d *source, rectangle2d *destination);
+void copy_offscreen_world_to_screen(const rectangle2d *rect);
Index: Myth2Code/screen_sdl.c
===================================================================
--- Myth2Code/screen_sdl.c	(revision 5522)
+++ Myth2Code/screen_sdl.c	(working copy)
@@ -327,7 +327,7 @@
 void calculate_mouse_movement_frame(
 	rectangle2d *mouse_bounds)
 {
-	get_active_screen_bounds(mouse_bounds);
+	get_screen_bounds(mouse_bounds);
 }
 
 void get_true_screen_dimensions(
Index: Myth2Code/screen_windows.c
===================================================================
--- Myth2Code/screen_windows.c	(revision 5531)
+++ Myth2Code/screen_windows.c	(working copy)
@@ -1036,7 +1036,7 @@
 void calculate_mouse_movement_frame(
 	rectangle2d *mouse_bounds)
 {
-	get_game_screen_bounds(mouse_bounds);
+	get_screen_bounds(mouse_bounds);
 
 	return;
 }
Index: Myth2Code/selection.c
===================================================================
--- Myth2Code/selection.c	(revision 5522)
+++ Myth2Code/selection.c	(working copy)
@@ -27,6 +27,7 @@
 #include "collection_references.h"
 #include "interface.h"
 #include "status_bar.h"
+#include "control_bar.h"
 #include "media_definitions.h"
 #include "mouse_cursor.h"
 
@@ -1972,7 +1973,9 @@
 		// Build 252 - ACS - cycle inventory keystroke
 		else if (test_action_flag(action, _option_down_bit))
 			change_selection_mode(_selection_mode_inventory_next);
-		else if (!(get_input_definition()->flags&_input_definition_control_bar_inventory_flag))
+		else if (get_input_definition()->flags&_input_definition_control_bar_inventory_flag)
+			toggle_control_bar_inventory();
+		else
 			change_selection_mode(_selection_mode_inventory);
 	}
 
Index: Myth2Code/selection.h
===================================================================
--- Myth2Code/selection.h	(revision 5522)
+++ Myth2Code/selection.h	(working copy)
@@ -98,7 +98,7 @@
 
 #define NEW_INVENTORY
 #ifdef NEW_INVENTORY
-short update_inventory_buttons(void);
+void update_inventory_buttons(void);
 short *get_selection_inventory_types(void);
 void set_selection_inventory(short, boolean);
 #endif
Index: Myth2Code/setup_software_windows.c
===================================================================
--- Myth2Code/setup_software_windows.c	(revision 5530)
+++ Myth2Code/setup_software_windows.c	(working copy)
@@ -157,7 +157,7 @@
 }
 
 struct bitmap_data *initialize_offscreen_bitmap(
-	rectangle2d *bounds)
+	const rectangle2d *bounds)
 {
 	return initialize_offscreen_bitmap_with_data(bounds, screen_pixels, screen_pixels_width_bytes);
 }
@@ -171,16 +171,17 @@
 }
 
 void copy_offscreen_world_to_screen(
-	rectangle2d *source_bounds,
-	rectangle2d *destination_bounds)
+	const rectangle2d *rect)
 {
 	// blit the bitmap from memory to the window
+
 	if(memory_bitmap)
 	{
-		BitBlt(window_dc, source_bounds->left, source_bounds->top,
-			source_bounds->right-source_bounds->left,
-			source_bounds->bottom-source_bounds->top,
-			memory_dc, destination_bounds->left, destination_bounds->top,
-			SRCCOPY);
+		//RECT client;
+		//GetClientRect(screen_window, &client);
+		//FillRect(window_dc, &client, (HBRUSH)GetStockObject(BLACK_BRUSH));
+		BitBlt(window_dc, rect->left, rect->top,
+			RECTANGLE_WIDTH(rect), RECTANGLE_HEIGHT(rect),
+			memory_dc, rect->left, rect->top, SRCCOPY);
 	}
 }
Index: Myth2Code/status_bar.c
===================================================================
--- Myth2Code/status_bar.c	(revision 5534)
+++ Myth2Code/status_bar.c	(working copy)
@@ -114,7 +114,6 @@
 	status_bar.map_visible= FALSE;
 	status_bar.map_initially_opened= FALSE;
 	status_bar.force_update= TRUE;
-	status_bar.status_bar->must_be_redrawn= TRUE;
 
 	if (status_bar.status_bar)
 	{
@@ -132,7 +131,6 @@
 	status_bar.height= new_height==NONE ? DEFAULT_STATUS_BAR_HEIGHT : new_height;
 	calculate_status_bar_bounds(&bounds);
 	move_dialog(status_bar.status_bar, &bounds);
-	status_bar.status_bar->must_be_redrawn= TRUE;
 	
 	return;
 }
@@ -150,6 +148,7 @@
 	{
 		dispose_dialog(status_bar.status_bar);
 		status_bar.status_bar= NULL;
+		status_bar.visible= FALSE;
 	}
 
 	return;
@@ -169,10 +168,6 @@
 	{
 		char buffer[1024];
 		
-		if (status_bar.visible)
-		{
-			status_bar.status_bar->must_be_redrawn= TRUE;
-		}
 		set_status_data_random_seed(status_bar.status_bar, _name_item, get_selection_random_seed());
 		
 		get_selection_name_string(buffer, sizeof(buffer));
@@ -295,7 +290,6 @@
 		dispose_dialog(old_bar);
 
 		status_bar.force_update= TRUE;
-		status_bar.status_bar->must_be_redrawn= TRUE;
 		update_status_bar();
 	}
 }
@@ -310,8 +304,6 @@
 		status_bar.force_update= visible;
 		SET_FLAG(get_game_preferences()->flags, _game_pref_status_bar_visible_bit, visible);
 	}
-
-	status_bar.status_bar->must_be_redrawn= TRUE;
 	
 	return;
 }
@@ -554,7 +546,7 @@
 {
 	rectangle2d game_bounds;
 
-	get_game_screen_bounds(&game_bounds);
+	get_screen_bounds(&game_bounds);
 
 	// Build 400 - ALS - lifted logic from control bar code - don't resize it (for now)
 	if (status_bar.status_bar)
Index: Myth2Code/unit_trading_dialog.c
===================================================================
--- Myth2Code/unit_trading_dialog.c	(revision 5534)
+++ Myth2Code/unit_trading_dialog.c	(working copy)
@@ -333,7 +333,7 @@
 		rectangle2d game_bounds;
 		rectangle2d bounds;
 	
-		get_game_screen_bounds(&game_bounds);
+		get_screen_bounds(&game_bounds);
 		offset_rectangle2d(&game_bounds, -game_bounds.left, -game_bounds.top);
 		get_dialog_bounds(dialog, &bounds);
 		
