Index: code/graphics/2d.cpp
===================================================================
--- code/graphics/2d.cpp	(revision 9541)
+++ code/graphics/2d.cpp	(working copy)
@@ -1464,6 +1464,28 @@
 	return *this;
 }
 
+void gr_shield_icon(coord2d coords[6], bool resize)
+{
+	if (gr_screen.mode == GR_STUB) {
+		return;
+	}
+
+	if (resize) {
+		gr_resize_screen_pos(&coords[0].x, &coords[0].y);
+		gr_resize_screen_pos(&coords[1].x, &coords[1].y);
+		gr_resize_screen_pos(&coords[2].x, &coords[2].y);
+		gr_resize_screen_pos(&coords[3].x, &coords[3].y);
+		gr_resize_screen_pos(&coords[4].x, &coords[4].y);
+		gr_resize_screen_pos(&coords[5].x, &coords[5].y);
+	}
+
+	g3_draw_2d_shield_icon(coords,
+		gr_screen.current_color.red,
+		gr_screen.current_color.green,
+		gr_screen.current_color.blue,
+		gr_screen.current_color.alpha);
+}
+
 void gr_rect(int x, int y, int w, int h, bool resize)
 {
 	if (gr_screen.mode == GR_STUB) {
Index: code/graphics/2d.h
===================================================================
--- code/graphics/2d.h	(revision 9541)
+++ code/graphics/2d.h	(working copy)
@@ -634,6 +634,7 @@
 	(*gr_screen.gf_bitmap_ex)(x, y, w, h, sx, sy, resize);
 }
 
+void gr_shield_icon(coord2d coords[6], const bool resize = true);
 void gr_rect(int x, int y, int w, int h, bool resize = true);
 void gr_shade(int x, int y, int w, int h, bool resize = true);
 
Index: code/globalincs/pstypes.h
===================================================================
--- code/globalincs/pstypes.h	(revision 9541)
+++ code/globalincs/pstypes.h	(working copy)
@@ -173,6 +173,10 @@
 	ubyte var;
 } def_list;
 
+typedef struct coord2d {
+	int x,y;
+} coord2d;
+
 //This are defined in MainWin.c
 extern void _cdecl WinAssert(char * text,char *filename, int line);
 void _cdecl WinAssert(char * text, char * filename, int linenum, const char * format, ... );
Index: code/render/3ddraw.cpp
===================================================================
--- code/render/3ddraw.cpp	(revision 9541)
+++ code/render/3ddraw.cpp	(working copy)
@@ -1547,6 +1547,106 @@
 	return 1;
 }
 
+void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a)
+{
+	int saved_zbuf;
+	vertex v[6];
+	vertex *verts[6] = {&v[0], &v[1], &v[2], &v[3], &v[4], &v[5]};
+
+	memset(v,0,sizeof(vertex)*6);
+	saved_zbuf = gr_zbuffer_get();
+
+	// start the frame, no zbuffering, no culling
+	if (!Fred_running)
+		g3_start_frame(1);
+
+	gr_zbuffer_set(GR_ZBUFF_NONE);
+	int cull = gr_set_cull(0);
+
+	// stuff coords
+	v[0].screen.xyw.x = i2fl(coords[0].x);
+	v[0].screen.xyw.y = i2fl(coords[0].y);
+	v[0].screen.xyw.w = 0.0f;
+	v[0].texture_position.u = 0.0f;
+	v[0].texture_position.v = 0.0f;
+	v[0].flags = PF_PROJECTED;
+	v[0].codes = 0;
+	v[0].r = (ubyte)r;
+	v[0].g = (ubyte)g;
+	v[0].b = (ubyte)b;
+	v[0].a = 0;
+
+	v[1].screen.xyw.x = i2fl(coords[1].x);
+	v[1].screen.xyw.y = i2fl(coords[1].y);
+	v[1].screen.xyw.w = 0.0f;
+	v[1].texture_position.u = 0.0f;
+	v[1].texture_position.v = 0.0f;
+	v[1].flags = PF_PROJECTED;
+	v[1].codes = 0;
+	v[1].r = (ubyte)r;
+	v[1].g = (ubyte)g;
+	v[1].b = (ubyte)b;
+	v[1].a = (ubyte)a;
+
+	v[2].screen.xyw.x = i2fl(coords[2].x);
+	v[2].screen.xyw.y = i2fl(coords[2].y);
+	v[2].screen.xyw.w = 0.0f;
+	v[2].texture_position.u = 0.0f;
+	v[2].texture_position.v = 0.0f;
+	v[2].flags = PF_PROJECTED;
+	v[2].codes = 0;
+	v[2].r = (ubyte)r;
+	v[2].g = (ubyte)g;
+	v[2].b = (ubyte)b;
+	v[2].a = 0;
+
+	v[3].screen.xyw.x = i2fl(coords[3].x);
+	v[3].screen.xyw.y = i2fl(coords[3].y);
+	v[3].screen.xyw.w = 0.0f;
+	v[3].texture_position.u = 0.0f;
+	v[3].texture_position.v = 0.0f;
+	v[3].flags = PF_PROJECTED;
+	v[3].codes = 0;
+	v[3].r = (ubyte)r;
+	v[3].g = (ubyte)g;
+	v[3].b = (ubyte)b;
+	v[3].a = (ubyte)a;
+
+	v[4].screen.xyw.x = i2fl(coords[4].x);
+	v[4].screen.xyw.y = i2fl(coords[4].y);
+	v[4].screen.xyw.w = 0.0f;
+	v[4].texture_position.u = 0.0f;
+	v[4].texture_position.v = 0.0f;
+	v[4].flags = PF_PROJECTED;
+	v[4].codes = 0;
+	v[4].r = (ubyte)r;
+	v[4].g = (ubyte)g;
+	v[4].b = (ubyte)b;
+	v[4].a = 0;
+
+	v[5].screen.xyw.x = i2fl(coords[5].x);
+	v[5].screen.xyw.y = i2fl(coords[5].y);
+	v[5].screen.xyw.w = 0.0f;
+	v[5].texture_position.u = 0.0f;
+	v[5].texture_position.v = 0.0f;
+	v[5].flags = PF_PROJECTED;
+	v[5].codes = 0;
+	v[5].r = (ubyte)r;
+	v[5].g = (ubyte)g;
+	v[5].b = (ubyte)b;
+	v[5].a = 0;
+
+	// draw the polys
+	g3_draw_poly_constant_sw(6, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_ALPHA | TMAP_FLAG_TRISTRIP, 0.1f);
+
+	if (!Fred_running)
+		g3_end_frame();
+
+	// restore zbuffer and culling
+	gr_zbuffer_set(saved_zbuf);
+	gr_set_cull(cull);
+}
+
 void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a)
 {
 	int saved_zbuf;
Index: code/render/3d.h
===================================================================
--- code/render/3d.h	(revision 9541)
+++ code/render/3d.h	(working copy)
@@ -316,6 +316,11 @@
 int g3_draw_perspective_bitmap(angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags);
 
 /**
+ * Draw a 2D shield icon w/ 6 points
+ */
+void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a);
+
+/**
  * Draw a 2D rectangle
  */
 void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a);
Index: code/hud/hudshield.h
===================================================================
--- code/hud/hudshield.h	(revision 9541)
+++ code/hud/hudshield.h	(working copy)
@@ -60,6 +60,7 @@
 	virtual void render(float frametime);
 	void showShields(object *objp, int mode);
 	int maybeFlashShield(int target_index, int shield_offset);
+	void renderShieldIcon(coord2d coords[6]);
 };
 
 class HudGaugeShieldPlayer: public HudGaugeShield
Index: code/hud/hudshield.cpp
===================================================================
--- code/hud/hudshield.cpp	(revision 9541)
+++ code/hud/hudshield.cpp	(working copy)
@@ -691,9 +691,9 @@
 	//
 	// Draw shield quadrants at one of NUM_SHIELD_LEVELS
 	max_shield = get_max_shield_quad(objp);
-	
-	int j, x_val, y_val, mid_val;
 
+	coord2d shield_icon_coords[6];
+	
 	for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
 
 		if ( objp->flags & OF_NO_SHIELDS ) {
@@ -731,126 +731,62 @@
 			else
 			{
 				//Ugh, draw four shield quadrants
+				static const int TRI_EDGE = 6;
+				static const int BAR_LENGTH = 112;
+				static const int BAR_HEIGHT = 54;
+				static const int BAR_WIDTH = 6;
+				static const int SHIELD_OFFSET = BAR_WIDTH + TRI_EDGE + 3;
+
 				switch(i)
 				{
 					//Top
 					case 0:
-						sy += 3;
-						for(j = 0; j < 6; j++)
-						{
-							y_val = sy + 10;
-							renderGradientLine(sx + j,
-										sy,
-										sx + j,
-										y_val - j);
-						}
-						mid_val = sy + 5;
-						for(; j < 106; j++)
-						{
-							renderGradientLine(sx + j,
-										sy,
-										sx + j,
-										mid_val);
-						}
-						for(; j < 112; j++)
-						{
-							renderGradientLine(sx + j,
-										sy,
-										sx + j,
-										sy + (j - 101));
-						}
-						y_val = sy - 1;
-						sy -= 3;
-						for(j = 0; j < 112; j++)
-							renderGradientLine(sx + j, y_val, sx + j, sy);
+						shield_icon_coords[0].x = sx;                     shield_icon_coords[0].y = sy+BAR_WIDTH+TRI_EDGE;
+						shield_icon_coords[1].x = sx;                     shield_icon_coords[1].y = sy;
+						shield_icon_coords[2].x = sx+TRI_EDGE;            shield_icon_coords[2].y = sy+BAR_WIDTH;
+						shield_icon_coords[3].x = sx+BAR_LENGTH;          shield_icon_coords[3].y = sy;
+						shield_icon_coords[4].x = sx+BAR_LENGTH-TRI_EDGE; shield_icon_coords[4].y = sy+BAR_WIDTH;
+						shield_icon_coords[5].x = sx+BAR_LENGTH;          shield_icon_coords[5].y = sy+BAR_WIDTH+TRI_EDGE;
+						renderShieldIcon(shield_icon_coords);
 						break;
 					//Left
 					case 3:
-						sx += 1;
-						x_val = sx + 10;
-						y_val = sy + 15;
-						for(j = 0; j < 6; j++)
-						{
-							renderGradientLine(sx,
-										y_val + j,
-										x_val - j,
-										y_val + j);
-						}
-						mid_val = sx + 5;
-						for(; j < 48; j++)
-						{
-							renderGradientLine(sx,
-										y_val + j,
-										mid_val,
-										y_val + j);
-						}
-						for(; j < 54; j++)
-						{
-							renderGradientLine(sx,
-										y_val + j,
-										sx + (j - 43),
-										y_val + j);
-						}
-						x_val = sx;
-						sx -= 3;
-						for(j = 0; j < 54; j++)
-							renderGradientLine(x_val, y_val + j, sx, y_val + j);
-						sx += 2;
+						sy += SHIELD_OFFSET;
+						shield_icon_coords[0].x = sx+BAR_WIDTH+TRI_EDGE; shield_icon_coords[0].y = sy+BAR_HEIGHT;
+						shield_icon_coords[1].x = sx;                    shield_icon_coords[1].y = sy+BAR_HEIGHT;
+						shield_icon_coords[2].x = sx+BAR_WIDTH;          shield_icon_coords[2].y = sy+BAR_HEIGHT-TRI_EDGE;
+						shield_icon_coords[3].x = sx;                    shield_icon_coords[3].y = sy;
+						shield_icon_coords[4].x = sx+BAR_WIDTH;          shield_icon_coords[4].y = sy+TRI_EDGE;
+						shield_icon_coords[5].x = sx+BAR_WIDTH+TRI_EDGE; shield_icon_coords[5].y = sy;
+						renderShieldIcon(shield_icon_coords);
+						sy -= SHIELD_OFFSET + BAR_WIDTH + TRI_EDGE;
 						break;
 					//Right
 					case 1:
-						x_val = sx + 109;	//-3 for border
-						y_val = sy + 15;
-						for(j = 0; j < 6; j++)
-						{
-							renderGradientLine(x_val,
-										y_val + j,
-										x_val - (10 - j),
-										y_val + j);
-						}
-						mid_val = x_val - 5;
-						for(; j < 48; j++)
-						{
-							renderGradientLine(x_val,
-										y_val + j,
-										mid_val,
-										y_val + j);
-						}
-						for(; j < 54; j++)
-						{
-							renderGradientLine(x_val,
-										y_val + j,
-										x_val - (j - 43),
-										y_val + j);
-						}
-						mid_val = x_val;
-						x_val += 3;
-						for(j = 0; j < 54; j++)
-							renderGradientLine(mid_val, y_val + j, x_val, y_val + j);
+						sx += BAR_LENGTH;
+						sy += SHIELD_OFFSET;
+						shield_icon_coords[0].x = sx-BAR_WIDTH-TRI_EDGE; shield_icon_coords[0].y = sy;
+						shield_icon_coords[1].x = sx;                    shield_icon_coords[1].y = sy;
+						shield_icon_coords[2].x = sx-BAR_WIDTH;          shield_icon_coords[2].y = sy+TRI_EDGE;
+						shield_icon_coords[3].x = sx;                    shield_icon_coords[3].y = sy+BAR_HEIGHT;
+						shield_icon_coords[4].x = sx-BAR_WIDTH;          shield_icon_coords[4].y = sy+BAR_HEIGHT-TRI_EDGE;
+						shield_icon_coords[5].x = sx-BAR_WIDTH-TRI_EDGE; shield_icon_coords[5].y = sy+BAR_HEIGHT;
+						renderShieldIcon(shield_icon_coords);
+						sx -= BAR_LENGTH;
+						sy -= SHIELD_OFFSET;
 						break;
 					//Bottom
 					case 2:
-						y_val = sy + 80; //-3 for border
-						for(j = 0; j < 6; j++)
-							renderGradientLine(sx + j,
-										y_val,
-										sx + j,
-										y_val - (10 - j));
-						mid_val = y_val - 5;
-						for(; j < 106; j++)
-							renderGradientLine(sx + j,
-										y_val,
-										sx + j,
-										mid_val);
-						for(; j < 112; j++)
-							renderGradientLine(sx + j,
-										y_val,
-										sx + j,
-										y_val - (j - 101));
-						mid_val = y_val + 1;
-						y_val += 3;
-						for(j = 0; j < 112; j++)
-							renderGradientLine(sx + j, mid_val, sx + j, y_val);
+						sy += BAR_HEIGHT + SHIELD_OFFSET*2 - BAR_WIDTH - TRI_EDGE;
+						shield_icon_coords[0].x = sx+BAR_LENGTH;          shield_icon_coords[0].y = sy;
+						shield_icon_coords[1].x = sx+BAR_LENGTH;          shield_icon_coords[1].y = sy+BAR_WIDTH+TRI_EDGE;
+						shield_icon_coords[2].x = sx+BAR_LENGTH-TRI_EDGE; shield_icon_coords[2].y = sy+TRI_EDGE;
+						shield_icon_coords[3].x = sx;                     shield_icon_coords[3].y = sy+BAR_WIDTH+TRI_EDGE;
+						shield_icon_coords[4].x = sx+TRI_EDGE;            shield_icon_coords[4].y = sy+TRI_EDGE;
+						shield_icon_coords[5].x = sx;                     shield_icon_coords[5].y = sy;
+						shield_icon_coords[6].x = sx; shield_icon_coords[6].y = sy;
+						renderShieldIcon(shield_icon_coords);
+						sy -= BAR_HEIGHT + SHIELD_OFFSET*2 - BAR_WIDTH - TRI_EDGE;
 						break;
 					//Whoops?
 					default:
@@ -864,6 +800,46 @@
 	// hud_set_default_color();
 }
 
+/*
+ * Render a shield icon - basic shape is:
+ *   1                             3
+ *     ***************************
+ *     ***************************
+ *     ** 2                   4 **
+ *     *                         *
+ *     0                         5
+ *
+ * Defined by 6 points, must be passed in the order show above (i.e. a valid triangle strip)
+ *
+ */
+void HudGaugeShield::renderShieldIcon(coord2d coords[6])
+{
+	int nx = 0, ny = 0, i;
+
+	if ( gr_screen.rendering_to_texture != -1 ) {
+		gr_set_screen_scale(canvas_w, canvas_h, target_w, target_h);
+	} else {
+		if ( reticle_follow ) {
+			nx = HUD_nose_x;
+			ny = HUD_nose_y;
+
+			gr_resize_screen_pos(&nx, &ny);
+			gr_set_screen_scale(base_w, base_h);
+			gr_unsize_screen_pos(&nx, &ny);
+		} else {
+			gr_set_screen_scale(base_w, base_h);
+		}
+	}
+
+	for (i = 0; i < 6; ++i) {
+		coords[i].x += nx;
+		coords[i].y += ny;
+	}
+
+	gr_shield_icon(coords);
+	gr_reset_screen_scale();
+}
+
 int HudGaugeShield::maybeFlashShield(int target_index, int shield_offset)
 {
 	int	flashed = 0;
