--- main-win.org.c	2011-07-03 13:14:36.000000000 -0500
+++ main-win.c	2011-07-06 16:36:33.000000000 -0500
@@ -77,6 +77,7 @@
 #include "cave.h"
 #include "init.h"
 #include "files.h"
+#include "grafmode.h"
 
 #define uint unsigned int
 
@@ -85,6 +86,34 @@
 
 #define HAS_CLEANUP
 
+/* Specifications for graphics modes.  */
+/*static const struct {
+	short grafID;			// id of tile set should be >0 and unique for anything new
+	short overdrawCol;	// column in the file where tiles to the right of draw the tile above as well
+	const char *name;			// Value of ANGBAND_GRAF variable
+ 	const char *file;			// name of png file (if any)
+	const char *menuname;			// Name of the tileset in menu
+} graphics_modes[] = {
+  {  1,   0,   "old",   "8x8.png",    "&Old tiles"},
+  {  2,   0,   "new", "16x16.png",    "&Adam Bolt's tiles"},
+  {  3,   0, "david", "32x32.png",    "&David Gervais' tiles"},
+	{  4,   0, "nomad", "16x16nmd.png", "No&mad's tiles"},
+	{  6, 122, "shock", "64x64.png", "&Shockbolt's tiles"},
+	{  7,   0, "david", "32x32.png\012345678901234567890", "&Extra tiles"},
+	{  0,   0,    NULL,        NULL,    "&None"}
+};
+// want a seperate bit fo alpha blending? change overdraw to a range of rows?
+static const int graphics_mode_high_id = 7;
+*/
+#ifndef GetWindowLongPtr
+#define GetWindowLongPtr GetWindowLong
+#endif
+#ifndef SetWindowLongPtr
+#define SetWindowLongPtr SetWindowLong
+#endif
+#ifndef GWLP_USERDATA
+#define GWLP_USERDATA GWL_USERDATA
+#endif
 
 /*
  * Use HTML-Help.
@@ -184,18 +213,38 @@
 #define IDM_WINDOW_D_HGT_7		277
 
 #define IDM_OPTIONS_GRAPHICS_NONE   400
-#define IDM_OPTIONS_GRAPHICS_OLD    401
-#define IDM_OPTIONS_GRAPHICS_ADAM   402
-#define IDM_OPTIONS_GRAPHICS_DAVID  403
-#define IDM_OPTIONS_GRAPHICS_NOMAD  404
-#define IDM_OPTIONS_GRAPHICS_NICE   405
-#define IDM_OPTIONS_TRPTILE         407
-#define IDM_OPTIONS_DBLTILE         408
-#define IDM_OPTIONS_BIGTILE         409
+#define IDM_OPTIONS_GRAPHICS_NICE   445
 #define IDM_OPTIONS_LOW_PRIORITY    420
 #define IDM_OPTIONS_SAVER           430
 #define IDM_OPTIONS_MAP             440
 
+#define IDM_OPTIONS_TILE_1x1        447
+#define IDM_OPTIONS_TILE_2x1        448
+#define IDM_OPTIONS_TILE_4x2        449
+#define IDM_OPTIONS_TILE_2x2        450
+#define IDM_OPTIONS_TILE_3x1        451
+#define IDM_OPTIONS_TILE_3x3        452
+#define IDM_OPTIONS_TILE_4x4        453
+#define IDM_OPTIONS_TILE_6x3        454
+#define IDM_OPTIONS_TILE_6x6        455
+#define IDM_OPTIONS_TILE_8x4        456
+#define IDM_OPTIONS_TILE_8x8        457
+#define IDM_OPTIONS_TILE_16x8       458
+#define IDM_OPTIONS_TILE_16x16      459
+
+#define IDM_TILE_FONT 		190
+#define IDM_TILE_08X08		191
+#define IDM_TILE_16X16		192
+#define IDM_TILE_32X32		193
+#define IDM_TILE_08X16		194
+#define IDM_TILE_10X20		195
+#define IDM_TILE_16X32		196
+#define IDM_TILE_08X13		197
+#define IDM_TILE_10X17		198
+#define IDM_TILE_12X13		199
+#define IDM_TILE_12X20		188
+#define IDM_TILE_16X25		189
+
 #define IDM_HELP_GENERAL		901
 #define IDM_HELP_SPOILERS		902
 
@@ -506,6 +555,12 @@
  */
 static DIBINIT infMask;
 
+static int overdraw = 0;
+static int overdrawmax = 8;
+
+static int alphablend = 0;
+static BLENDFUNCTION blendfn;
+
 #endif /* USE_GRAPHICS */
 
 
@@ -740,49 +795,26 @@
 
         if (use_graphics_nice)
           {
-            switch (use_graphics)
-              {
-              case GRAPHICS_DAVID_GERVAIS:
-                {
-                  /* Reset the tile info */
-                  td->tile_wid = 32;
-                  td->tile_hgt = 32;
-                  break;
-                }
-                
-              case GRAPHICS_ADAM_BOLT:
-                {
-                  /* Reset the tile info */
-                  td->tile_wid = 16;
-                  td->tile_hgt = 16;
-                  break;
-                }
-
-              case GRAPHICS_NOMAD:
-                {
-                  /* Reset the tile info */
-                  td->tile_wid = 8;
-                  td->tile_hgt = 16;
-                  break;
-                }
-                
-              case GRAPHICS_ORIGINAL:
-                {
-                  /* Reset the tile info */
-                  td->tile_wid = 8;
-                  td->tile_hgt = 8;
-                  break;
-                }
-                
-              case GRAPHICS_NONE:
-                {
-                  /* Reset the tile info */
-                  td->tile_wid = td->font_wid;
-                  td->tile_hgt = td->font_hgt;
-                  break;
-                }
-                
+            if (current_graphics_mode && current_graphics_mode->grafID) {
+              if (current_graphics_mode->file[0]) {
+                char *end;
+                td->tile_wid = strtol(current_graphics_mode->file,&end,10);
+                td->tile_hgt = strtol(end+1,NULL,10);
+              } else {
+                td->tile_wid = current_graphics_mode->cell_width;
+                td->tile_hgt = current_graphics_mode->cell_height;
               }
+              if ((td->tile_wid == 0) || (td->tile_hgt == 0)) {
+                td->tile_wid = current_graphics_mode->cell_width;
+                td->tile_hgt = current_graphics_mode->cell_height;
+              }
+            }
+            else
+            {
+              /* Reset the tile info */
+              td->tile_wid = td->font_wid;
+              td->tile_hgt = td->font_hgt;
+            }
             
 	    tile_width = 1;
 	    tile_height = 1;
@@ -1285,26 +1317,40 @@
 		char buf[1024];
 		int wid, hgt;
 		const char *name;
+    graphics_mode *mode = NULL;
 
-		if (arg_graphics == GRAPHICS_DAVID_GERVAIS) {
-			wid = 32;
-			hgt = 32;
-			name = "32x32.png";
-			ANGBAND_GRAF = "david";
+    if (arg_graphics) {
+      int i=0;
+      while (graphics_modes[i].grafID != 0)  {
+        if (graphics_modes[i].grafID == arg_graphics) {
+          mode = &(graphics_modes[i]);
+          break;
+        }
+        i++;
+      }; 
+    }
+    if (mode) {
+      if (!mode->name[0]) {
+			  plog_fmt("invalid tile name '%s'", mode->menuname);
+			  return FALSE;
+      }
+      wid = mode->cell_width;
+      hgt = mode->cell_height;
+      if ((wid < 2) || (hgt < 2)) {
+			  plog_fmt("invalid tile dimensions in tileset name: '%s'", mode->name);
+			  return FALSE;
+      }
+
+      name = mode->file;
+      ANGBAND_GRAF = mode->name;
 			use_transparency = FALSE;
-		} else if (arg_graphics == GRAPHICS_ADAM_BOLT){
-			wid = 16;
-			hgt = 16;
-			name = "16x16.png";
-			ANGBAND_GRAF = "new";
-			use_transparency = TRUE;
-		} else if (arg_graphics == GRAPHICS_NOMAD) {
-			wid = 16;
-			hgt = 16;
-			name = "8x16.png";
-			ANGBAND_GRAF = "nomad";
-			use_transparency = TRUE;
-		} else {
+
+      overdraw = mode->overdrawRow;
+      overdrawmax = mode->overdrawMax;
+      alphablend = mode->alphablend;
+
+      current_graphics_mode = mode;
+    } else {
 			wid = 8;
 			hgt = 8;
 			name = "8x8.png";
@@ -1315,10 +1361,17 @@
 		path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name);
 
 		/* Load the image or quit */
-		if (!ReadDIB2_PNG(data[0].w, buf, &infGraph, &infMask)) {
-			plog_fmt("Cannot read file '%s'", name);
-			return FALSE;
-		}
+    if (alphablend) {
+		  if (!ReadDIB2_PNG(data[0].w, buf, &infGraph, NULL)) {
+			  plog_fmt("Cannot read file '%s'", name);
+			  return FALSE;
+		  }
+    } else {
+		  if (!ReadDIB2_PNG(data[0].w, buf, &infGraph, &infMask)) {
+			  plog_fmt("Cannot read file '%s'", name);
+			  return FALSE;
+		  }
+    }
 
 		/* Save the new sizes */
 		infGraph.CellWidth = wid;
@@ -1640,6 +1693,8 @@
 #endif /* 0 */
 
 
+errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp);
+errr Term_pict_win_alpha(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp);
 /*
  * React to global changes
  */
@@ -1760,6 +1815,12 @@
 
 			/* Cannot enable */
 			arg_graphics = GRAPHICS_NONE;
+    } else {
+      if (overdraw) {
+        td->t.pict_hook = Term_pict_win_alpha;
+      } else {
+       	td->t.pict_hook = Term_pict_win;
+      }
 		}
 
 		/* Change setting */
@@ -2310,9 +2371,7 @@
 	hdcSrc = CreateCompatibleDC(hdc);
 	hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
 
-	if ((arg_graphics == GRAPHICS_ADAM_BOLT) ||
-		(arg_graphics == GRAPHICS_NOMAD) ||
-	    (arg_graphics == GRAPHICS_DAVID_GERVAIS))
+	if (infMask.hBitmap)
 	{
 		hdcMask = CreateCompatibleDC(hdc);
 		SelectObject(hdcMask, infMask.hBitmap);
@@ -2336,9 +2395,7 @@
 		x1 = col * w1;
 		y1 = row * h1;
 
-		if ((arg_graphics == GRAPHICS_ADAM_BOLT) ||
-			(arg_graphics == GRAPHICS_NOMAD) ||
-		    (arg_graphics == GRAPHICS_DAVID_GERVAIS))
+	  if (hdcMask)
 		{
 			x3 = (tcp[i] & 0x7F) * w1;
 			y3 = (tap[i] & 0x7F) * h1;
@@ -2405,9 +2462,7 @@
 	SelectObject(hdcSrc, hbmSrcOld);
 	DeleteDC(hdcSrc);
 
-	if ((arg_graphics == GRAPHICS_ADAM_BOLT) ||
-		(arg_graphics == GRAPHICS_NOMAD) ||
-	    (arg_graphics == GRAPHICS_DAVID_GERVAIS))
+	if (hdcMask)
 	{
 		/* Release */
 		SelectObject(hdcMask, hbmSrcOld);
@@ -2429,6 +2484,137 @@
 }
 
 
+#ifndef AC_SRC_ALPHA
+#define AC_SRC_ALPHA     0x01
+#endif
+static errr Term_pict_win_alpha(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
+{
+	term_data *td = (term_data*)(Term->data);
+
+#ifdef USE_GRAPHICS
+
+	int i;
+	int x1, y1, w1, h1;
+	int x2, y2, w2, h2, tw2, th2;
+	int x3, y3;
+
+	HDC hdc;
+	HDC hdcSrc;
+	HBITMAP hbmSrcOld;
+
+	/* Erase the grids */
+	Term_wipe_win(x, y, n);
+
+	/* Size of bitmap cell */
+	w1 = infGraph.CellWidth;
+	h1 = infGraph.CellHeight;
+
+	/* Size of window cell */
+	if (td->map_active)
+	{
+		w2 = td->map_tile_wid;
+		h2 = td->map_tile_hgt;
+		tw2 = w2;
+    th2 = h2;
+	}
+	else
+	{
+		w2 = td->tile_wid;
+		h2 = td->tile_hgt;
+
+    /* Large tile mode */
+		th2 = tile_height * h2;
+		tw2 = tile_width * w2;
+	}
+
+	/* Location of window cell */
+	x2 = x * w2 + td->size_ow1;
+	y2 = y * h2 + td->size_oh1;
+
+	/* Info */
+	hdc = GetDC(td->w);
+
+	/* More info */
+	hdcSrc = CreateCompatibleDC(hdc);
+	hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
+
+	/* Draw attr/char pairs */
+  for (i = n-1; i >= 0; i--, x2 -= w2)
+	{
+		byte a = ap[i];
+		char c = cp[i];
+
+		/* Extract picture */
+		int row = (a & 0x7F);
+		int col = (c & 0x7F);
+		int trow = (tap[i] & 0x7F);
+
+		/* Location of bitmap cell */
+		x1 = col * w1;
+		y1 = row * h1;
+
+		x3 = (tcp[i] & 0x7F) * w1;
+		y3 = trow * h1;
+ 
+		/* Set the correct mode for stretching the tiles */
+		SetStretchBltMode(hdc, COLORONCOLOR);
+
+  	/* Perfect size */
+		if ((w1 == tw2) && (h1 == th2))
+		{
+			/* Copy the terrain picture from the bitmap to the window */
+      if (overdraw && (trow >= overdraw) && (y > 2) && (trow <= overdrawmax)) {
+  			BitBlt(hdc, x2, y2-th2, tw2, th2*2, hdcSrc, x3, y3-h1, SRCCOPY);
+        /* tell the core that the top tile is different than what it thinks */
+      } else {
+  			BitBlt(hdc, x2, y2, tw2, th2, hdcSrc, x3, y3, SRCCOPY);
+      }
+    }
+    else
+    {
+		  /* Copy the terrain picture from the bitmap to the window */
+      if (overdraw && (trow >= overdraw) && (y > 2) && (trow >= overdrawmax)) {
+  		  StretchBlt(hdc, x2, y2-th2, tw2, th2*2, hdcSrc, x3, y3-h1, w1, h1*2, SRCCOPY);
+        /* tell the core that the top tile is different than what it thinks */
+      } else {
+  		  StretchBlt(hdc, x2, y2, tw2, th2, hdcSrc, x3, y3, w1, h1, SRCCOPY);
+      }
+    }
+		/* Only draw if terrain and overlay are different */
+		if ((x1 != x3) || (y1 != y3))
+		{
+		  /* Copy the picture from the bitmap to the window */
+		  //AlphaBlend(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, w1, h1, blendfn);
+      if (overdraw && (row >= overdraw) && (y > 2) && (row >= overdrawmax)) {
+  		  AlphaBlend(hdc, x2, y2-th2, tw2, th2*2, hdcSrc, x1, y1-h1, w1, h1*2, blendfn);
+        /* tell the core that the top tile is different than what it thinks */
+      } else {
+		    AlphaBlend(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, w1, h1, blendfn);
+      }
+    }
+    //if (overdraw && (col > overdraw) && (y > 2) && (row > overdrawRow)) {
+  	//	AlphaBlend(hdc, x2, y2-th2, tw2, th2, hdcSrc, x1, y1-h1, w1, h1, blendfn);
+    //}
+  }
+
+	/* Release */
+	SelectObject(hdcSrc, hbmSrcOld);
+	DeleteDC(hdcSrc);
+
+	/* Release */
+	ReleaseDC(td->w, hdc);
+
+#else /* USE_GRAPHICS */
+
+	/* Just erase this grid */
+	return (Term_wipe_win(x, y, n));
+
+#endif /* USE_GRAPHICS */
+
+	/* Success */
+	return 0;
+}
+
 static void windows_map_aux(void)
 {
 	term_data *td = &data[0];
@@ -2568,6 +2754,8 @@
 
 	char buf[1024];
 
+  MENUITEMINFO mii;
+	HMENU hm;
 
 	/* Main window */
 	td = &data[0];
@@ -2606,7 +2794,6 @@
 	/* Load prefs */
 	load_prefs();
 
-
 	/* Main window (need these before term_getsize gets called) */
 	td = &data[0];
 	td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU |
@@ -2729,6 +2916,44 @@
 	/* Create a "brush" for drawing the "cursor" */
 	hbrYellow = CreateSolidBrush(win_clr[TERM_YELLOW]);
 
+  /* Populate the graphic options sub menu with the graphics modes */
+  hm = GetMenu(data[0].w);
+  i=0;
+  mii.cbSize = sizeof(MENUITEMINFO);
+  mii.fMask = MIIM_ID | MIIM_TYPE;
+  mii.fType = MFT_STRING;
+  while (graphics_modes[i].grafID != 0) {
+    mii.wID = graphics_modes[i].grafID + IDM_OPTIONS_GRAPHICS_NONE;
+    mii.dwTypeData = graphics_modes[i].menuname;
+    mii.cch = strlen(graphics_modes[i].menuname);
+    InsertMenuItem(hm,IDM_OPTIONS_GRAPHICS_NONE, FALSE, &mii);
+
+    /* Setup the graphics mode values for the initial graphics mode
+     * which was set in load_prefs() above */
+    /*if (arg_graphics == graphics_modes[i].grafID) {
+      overdraw = graphics_modes[i].overdrawRow;
+      overdrawmax = graphics_modes[i].overdrawMax;
+      alphablend = graphics_modes[i].alphablend;
+      if (graphics_modes[i].file) {
+        strncpy(tileset,graphics_modes[i].file,32);
+      } else {
+        tileset[0] = 0;
+      }
+      if (graphics_modes[i].name) {
+        strncpy(tilegraf,graphics_modes[i].name,8);
+      } else {
+        tilegraf[0] = 0;
+      }
+    }*/
+    ++i;
+  }
+
+  /* setup the alpha blending function */
+  blendfn.BlendOp = AC_SRC_OVER;
+  blendfn.BlendFlags = 0;
+  blendfn.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA;//AC_SRC_ALPHA;
+  blendfn.SourceConstantAlpha = 255;
+
 
 	/* Process pending messages */
 	(void)Term_xtra_win_flush();
@@ -2894,24 +3119,15 @@
 	}
 
 	/* Menu "Options", disable all */
-	EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NONE,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-	EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_OLD,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-	EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_ADAM,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-	EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NOMAD,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-	EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_DAVID,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+  i=0;
+  do {
+	  EnableMenuItem(hm, graphics_modes[i].grafID + IDM_OPTIONS_GRAPHICS_NONE,
+	                 MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+  } while (graphics_modes[i++].grafID != 0); 
+
         EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NICE,
                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-        EnableMenuItem(hm, IDM_OPTIONS_TRPTILE,
-                       MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-        EnableMenuItem(hm, IDM_OPTIONS_DBLTILE,
-                       MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
-	EnableMenuItem(hm, IDM_OPTIONS_BIGTILE,
-	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+
 	EnableMenuItem(hm, IDM_OPTIONS_SAVER,
 	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
 	EnableMenuItem(hm, IDM_OPTIONS_LOW_PRIORITY,
@@ -2925,25 +3141,91 @@
 		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
 
 	/* Menu "Options", update all */
-	CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_NONE,
-	              (arg_graphics == GRAPHICS_NONE ? MF_CHECKED : MF_UNCHECKED));
-	CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_OLD,
-	              (arg_graphics == GRAPHICS_ORIGINAL ? MF_CHECKED : MF_UNCHECKED));
-	CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_ADAM,
-	              (arg_graphics == GRAPHICS_ADAM_BOLT ? MF_CHECKED : MF_UNCHECKED));
-	CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_NOMAD,
-	              (arg_graphics == GRAPHICS_NOMAD ? MF_CHECKED : MF_UNCHECKED));
-	CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_DAVID,
-	              (arg_graphics == GRAPHICS_DAVID_GERVAIS ? MF_CHECKED : MF_UNCHECKED));
+  i=0;
+  do {
+	  CheckMenuItem(hm, graphics_modes[i].grafID + IDM_OPTIONS_GRAPHICS_NONE,
+	                (arg_graphics == graphics_modes[i].grafID ? MF_CHECKED : MF_UNCHECKED));
+  } while (graphics_modes[i++].grafID != 0); 
+
 
         CheckMenuItem(hm, IDM_OPTIONS_GRAPHICS_NICE,
                       (arg_graphics_nice ? MF_CHECKED : MF_UNCHECKED));
-        CheckMenuItem(hm, IDM_OPTIONS_TRPTILE,
-                      (tile_height == 3 ? MF_CHECKED : MF_UNCHECKED));
-        CheckMenuItem(hm, IDM_OPTIONS_DBLTILE,
-                      (tile_height == 2 ? MF_CHECKED : MF_UNCHECKED));
-	CheckMenuItem(hm, IDM_OPTIONS_BIGTILE,
-	              (tile_width == (2 * tile_height) ? MF_CHECKED : MF_UNCHECKED));
+
+  if ((tile_width == 1) && (tile_height == 1))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_1x1, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_1x1, MF_UNCHECKED);
+
+  if ((tile_width == 2) && (tile_height == 1))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_2x1, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_2x1, MF_UNCHECKED);
+
+  if ((tile_width == 2) && (tile_height == 2))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_2x2, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_2x2, MF_UNCHECKED);
+
+  if ((tile_width == 3) && (tile_height == 1))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_3x1, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_3x1, MF_UNCHECKED);
+
+  if ((tile_width == 3) && (tile_height == 3))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_3x3, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_3x3, MF_UNCHECKED);
+
+  if ((tile_width == 4) && (tile_height == 2))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_4x2, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_4x2, MF_UNCHECKED);
+
+  if ((tile_width == 4) && (tile_height == 4))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_4x4, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_4x4, MF_UNCHECKED);
+
+  if ((tile_width == 6) && (tile_height == 3))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_6x3, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_6x3, MF_UNCHECKED);
+
+  if ((tile_width == 6) && (tile_height == 6))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_6x6, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_6x6, MF_UNCHECKED);
+
+  if ((tile_width == 8) && (tile_height == 4))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_8x4, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_8x4, MF_UNCHECKED);
+
+  if ((tile_width == 8) && (tile_height == 8))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_8x8, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_8x8, MF_UNCHECKED);
+
+  if ((tile_width == 16) && (tile_height == 8))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_16x8, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_16x8, MF_UNCHECKED);
+
+  if ((tile_width == 16) && (tile_height == 16))
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_16x16, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_OPTIONS_TILE_16x16, MF_UNCHECKED);
+
+  i = data[0].tile_hgt;
+  if ((data[0].tile_wid == data[0].font_wid) && (i == data[0].font_hgt))
+    CheckMenuItem(hm, IDM_TILE_FONT, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_TILE_FONT, MF_UNCHECKED);
+
+  if ((data[0].tile_wid == 8) && (i == 16))
+    CheckMenuItem(hm, IDM_TILE_08X16, MF_CHECKED);
+  else
+    CheckMenuItem(hm, IDM_TILE_08X16, MF_UNCHECKED);
 
 #ifdef USE_SAVER
 	CheckMenuItem(hm, IDM_OPTIONS_SAVER,
@@ -2957,15 +3239,35 @@
 	if (inkey_flag && initialized)
 	{
 		/* Menu "Options", Item "Graphics" */
-		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NONE, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_OLD, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_ADAM, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NOMAD, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_DAVID, MF_ENABLED);
+    i=0;
+    do {
+	    EnableMenuItem(hm, graphics_modes[i].grafID + IDM_OPTIONS_GRAPHICS_NONE,MF_ENABLED );
+    } while (graphics_modes[i++].grafID != 0); 
+
 		EnableMenuItem(hm, IDM_OPTIONS_GRAPHICS_NICE, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_TRPTILE, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_DBLTILE, MF_ENABLED);
-		EnableMenuItem(hm, IDM_OPTIONS_BIGTILE, MF_ENABLED);
+
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_1x1, MF_ENABLED);
+		EnableMenuItem(hm, IDM_OPTIONS_TILE_2x1, MF_ENABLED);
+		EnableMenuItem(hm, IDM_OPTIONS_TILE_2x2, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_3x1, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_3x3, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_4x2, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_4x4, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_6x3, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_6x6, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_8x4, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_8x8, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_16x8, MF_ENABLED);
+    EnableMenuItem(hm, IDM_OPTIONS_TILE_16x16, MF_ENABLED);
+
+    EnableMenuItem(hm, IDM_TILE_FONT, MF_ENABLED);
+		EnableMenuItem(hm, IDM_TILE_08X16, MF_ENABLED);
+		EnableMenuItem(hm, IDM_TILE_08X08, MF_ENABLED);
+    EnableMenuItem(hm, IDM_TILE_16X16, MF_ENABLED);
+    EnableMenuItem(hm, IDM_TILE_32X32, MF_ENABLED);
+    EnableMenuItem(hm, IDM_TILE_16X32, MF_ENABLED);
+    EnableMenuItem(hm, IDM_TILE_12X20, MF_ENABLED);
+    EnableMenuItem(hm, IDM_TILE_16X25, MF_ENABLED);
 	}
 #endif /* USE_GRAPHICS */
 
@@ -3469,126 +3771,6 @@
 			break;
 		}
 
-		case IDM_OPTIONS_GRAPHICS_NONE:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
-
-			/* Toggle "arg_graphics" */
-			if (arg_graphics != GRAPHICS_NONE)
-			{
-				arg_graphics = GRAPHICS_NONE;
-
-				/* React to changes */
-				Term_xtra_win_react();
-
-				/* Hack -- Force redraw */
-				Term_key_push(KTRL('R'));
-			}
-
-			break;
-		}
-
-		case IDM_OPTIONS_GRAPHICS_OLD:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
-
-			/* Toggle "arg_graphics" */
-			if (arg_graphics != GRAPHICS_ORIGINAL)
-			{
-				arg_graphics = GRAPHICS_ORIGINAL;
-
-				/* React to changes */
-				Term_xtra_win_react();
-
-				/* Hack -- Force redraw */
-				Term_key_push(KTRL('R'));
-			}
-
-			break;
-		}
-
-		case IDM_OPTIONS_GRAPHICS_ADAM:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
-
-			/* Toggle "arg_graphics" */
-			if (arg_graphics != GRAPHICS_ADAM_BOLT)
-			{
-				arg_graphics = GRAPHICS_ADAM_BOLT;
-
-				/* React to changes */
-				Term_xtra_win_react();
-
-				/* Hack -- Force redraw */
-				Term_key_push(KTRL('R'));
-			}
-
-			break;
-		}
-
-		case IDM_OPTIONS_GRAPHICS_NOMAD:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
-
-			/* Toggle "arg_graphics" */
-			if (arg_graphics != GRAPHICS_NOMAD)
-			{
-				arg_graphics = GRAPHICS_NOMAD;
-
-				/* React to changes */
-				Term_xtra_win_react();
-
-				/* Hack -- Force redraw */
-				Term_key_push(KTRL('R'));
-			}
-
-			break;
-		}
-
-		case IDM_OPTIONS_GRAPHICS_DAVID:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
-
-			/* Toggle "arg_graphics" */
-			if (arg_graphics != GRAPHICS_DAVID_GERVAIS)
-			{
-				arg_graphics = GRAPHICS_DAVID_GERVAIS;
-
-				/* React to changes */
-				Term_xtra_win_react();
-
-				/* Hack -- Force redraw */
-				Term_key_push(KTRL('R'));
-			}
-
-			break;
-		}
-
                 case IDM_OPTIONS_GRAPHICS_NICE:
                 {
                         /* Paranoia */
@@ -3610,108 +3792,201 @@
                         break;
                 }
 
-                case IDM_OPTIONS_TRPTILE:
-                {
-                        /* Paranoia */
-                        if (!inkey_flag || !initialized)
-                        {
-                                plog("You may not do that right now.");
-                                break;
-                        }
-
-                        /* Reduce... */
-			if (tile_height == 3)
-			{
-			        tile_width /= 3;
-			        tile_height /= 3;
-			}
-
-                        /* ...or increase */
-			else
-			{
-			        tile_width /= tile_height;
-			        tile_width *= 3;
-			        tile_height = 3;
-			}
-
-
-                        /* Set flag */
-                        change_tilesize = TRUE;
-
-                        /* React to changes */
-                        Term_xtra_win_react();
-
-                        /* Hack -- Force redraw */
-                        Term_key_push(KTRL('R'));
-
-                        break;
-                        }
-
-                case IDM_OPTIONS_DBLTILE:
-                                {
-                        /* Paranoia */
-                        if (!inkey_flag || !initialized)
-                                        {
-                                plog("You may not do that right now.");
-                                break;
-                                }
-
-                        /* Reduce... */
-			if (tile_height == 2)
-			{
-			        tile_width /= 2;
-			        tile_height /= 2;
-			}
-
-                        /* ...or increase */
-			else
-			{
-			        tile_width /= tile_height;
-			        tile_height = 2;
-			        tile_width *= tile_height;
-			}
-
-                        /* Set flag */
-                        change_tilesize = TRUE;
-
-                        /* React to changes */
-                        Term_xtra_win_react();
-
-                        /* Hack -- Force redraw */
-                        Term_key_push(KTRL('R'));
+    case IDM_OPTIONS_TILE_1x1:
+    case IDM_OPTIONS_TILE_2x1:
+    case IDM_OPTIONS_TILE_2x2:
+    case IDM_OPTIONS_TILE_3x1:
+    case IDM_OPTIONS_TILE_3x3:
+    case IDM_OPTIONS_TILE_4x2:
+    case IDM_OPTIONS_TILE_4x4:
+    case IDM_OPTIONS_TILE_6x3:
+    case IDM_OPTIONS_TILE_6x6:
+    case IDM_OPTIONS_TILE_8x4:
+    case IDM_OPTIONS_TILE_8x8:
+    case IDM_OPTIONS_TILE_16x8:
+    case IDM_OPTIONS_TILE_16x16:
+    {
+      /* Paranoia */
+      if (!inkey_flag || !initialized)
+      {
+              plog("You may not do that right now.");
+              break;
+      }
+	    switch (wCmd)
+	    {
+        case IDM_OPTIONS_TILE_1x1:
+          {
+			      tile_width = 1;
+			      tile_height = 1;
+            break;
+          }
+        case IDM_OPTIONS_TILE_2x1:
+          {
+			      tile_width = 2;
+			      tile_height = 1;
+            break;
+          }
+        case IDM_OPTIONS_TILE_2x2:
+          {
+			      tile_width = 2;
+			      tile_height = 2;
+            break;
+          }
+        case IDM_OPTIONS_TILE_3x1:
+          {
+			      tile_width = 3;
+			      tile_height = 1;
+            break;
+          }
+        case IDM_OPTIONS_TILE_3x3:
+          {
+			      tile_width = 3;
+			      tile_height = 3;
+            break;
+          }
+        case IDM_OPTIONS_TILE_4x2:
+          {
+			      tile_width = 4;
+			      tile_height = 2;
+            break;
+          }
+        case IDM_OPTIONS_TILE_4x4:
+          {
+			      tile_width = 4;
+			      tile_height = 4;
+            break;
+          }
+        case IDM_OPTIONS_TILE_6x3:
+          {
+			      tile_width = 6;
+			      tile_height = 3;
+            break;
+          }
+        case IDM_OPTIONS_TILE_6x6:
+          {
+			      tile_width = 6;
+			      tile_height = 6;
+            break;
+          }
+        case IDM_OPTIONS_TILE_8x4:
+          {
+			      tile_width = 8;
+			      tile_height = 4;
+            break;
+          }
+        case IDM_OPTIONS_TILE_8x8:
+          {
+			      tile_width = 8;
+			      tile_height = 8;
+            break;
+          }
+        case IDM_OPTIONS_TILE_16x8:
+          {
+			      tile_width = 16;
+			      tile_height = 8;
+            break;
+          }
+        case IDM_OPTIONS_TILE_16x16:
+          {
+			      tile_width = 16;
+			      tile_height = 16;
+            break;
+          }
+      }
 
-                        break;
-                                                }
+      /* Set flag */
+      change_tilesize = TRUE;
 
-		case IDM_OPTIONS_BIGTILE:
-		{
-			/* Paranoia */
-			if (!inkey_flag || !initialized)
-			{
-				plog("You may not do that right now.");
-				break;
-			}
+      /* React to changes */
+      Term_xtra_win_react();
 
-                        /* Reduce... */
-			if (tile_height != tile_width)
-			{
-			        tile_width = tile_height;
-			}
+      /* Hack -- Force redraw */
+      Term_key_push(KTRL('R'));
 
-                        /* ...or increase */
-			else
-			{
-			        tile_width *= 2;
-			}
+			break;
+		}
 
-                       /* Set flag */
-                        change_tilesize = TRUE;
+    case IDM_TILE_FONT:
+    case IDM_TILE_08X08:
+    case IDM_TILE_16X16:
+    case IDM_TILE_32X32:
+    case IDM_TILE_08X16:
+    case IDM_TILE_10X20:
+    case IDM_TILE_16X32:
+    case IDM_TILE_08X13:
+    case IDM_TILE_10X17:
+    case IDM_TILE_16X25:
+    case IDM_TILE_12X20:
+    {
+      /* Paranoia */
+      if (!inkey_flag || !initialized)
+      {
+        plog("You may not do that right now.");
+        break;
+      }
+			td = &data[0];
+	    switch (wCmd)
+	    {
+        case IDM_TILE_FONT:
+        {
+			    td->tile_wid = td->font_wid;
+			    td->tile_hgt = td->font_hgt;
+          break;
+        }
+        case IDM_TILE_08X16:
+        {
+			    td->tile_wid = 8;
+			    td->tile_hgt = 16;
+          break;
+        }
+        case IDM_TILE_08X08:
+        {
+			    td->tile_wid = 8;
+			    td->tile_hgt = 8;
+          break;
+        }
+        case IDM_TILE_16X16:
+        {
+			    td->tile_wid = 16;
+			    td->tile_hgt = 16;
+          break;
+        }
+        case IDM_TILE_32X32:
+        {
+			    td->tile_wid = 32;
+			    td->tile_hgt = 32;
+          break;
+        }
+        case IDM_TILE_10X20:
+        {
+			    td->tile_wid = 10;
+			    td->tile_hgt = 20;
+          break;
+        }
+        case IDM_TILE_16X32:
+        {
+			    td->tile_wid = 16;
+			    td->tile_hgt = 32;
+          break;
+        }
+        case IDM_TILE_12X20:
+        {
+			    td->tile_wid = 12;
+			    td->tile_hgt = 20;
+          break;
+        }
+        case IDM_TILE_16X25:
+        {
+			    td->tile_wid = 16;
+			    td->tile_hgt = 25;
+          break;
+        }
+      }
 
-                        /* React to changes */
-                        Term_xtra_win_react();
+      /* React to changes */
+			term_getsize(td);
 
- 			/* Mega-Hack : Redraw screen */
-			Term_key_push(KTRL('R'));
+			term_window_resize(td);
 
 			break;
 		}
@@ -3829,7 +4104,54 @@
 			display_help(HELP_SPOILERS);
 			break;
 		}
-	}
+    default:
+    {
+      if ((wCmd >= IDM_OPTIONS_GRAPHICS_NONE) && (wCmd <= IDM_OPTIONS_GRAPHICS_NONE+graphics_mode_high_id))
+		  {
+        int selected_mode = 0;
+        int desired_mode = wCmd - IDM_OPTIONS_GRAPHICS_NONE;
+			  /* Paranoia */
+			  if (!inkey_flag || !initialized)
+			  {
+				  plog("You may not do that right now.");
+				  break;
+			  }
+        i=0;
+        do {
+          if (graphics_modes[i].grafID == desired_mode) {
+			      selected_mode = desired_mode;
+            /*overdraw = graphics_modes[i].overdrawRow;
+            overdrawmax = graphics_modes[i].overdrawMax;
+            alphablend = graphics_modes[i].alphablend;
+            if (graphics_modes[i].file) {
+              strncpy(tileset,graphics_modes[i].file,32);
+            } else {
+              tileset[0] = 0;
+            }
+            if (graphics_modes[i].name) {
+              strncpy(tilegraf,graphics_modes[i].name,8);
+            } else {
+              tilegraf[0] = 0;
+            }*/
+            break;
+          }
+        } while (graphics_modes[i++].grafID != 0); 
+
+			  /* Toggle "arg_graphics" */
+			  if (arg_graphics != selected_mode)
+			  {
+				  arg_graphics = selected_mode;
+
+				  /* React to changes */
+				  Term_xtra_win_react();
+
+				  /* Hack -- Force redraw */
+				  Term_key_push(KTRL('R'));
+			  }
+		  }
+      break;
+    }
+  }
 }
 
 
@@ -3943,6 +4265,21 @@
 		case VK_MULTIPLY: ch = '*'; kp = TRUE; break;
 		case VK_DIVIDE: ch = '/'; kp = TRUE; break;
 		case VK_DECIMAL: ch = '.'; kp = TRUE; break;
+
+    case VK_NUMPAD0: if (mc||ma||ms) {ch = KC_INSERT; kp = TRUE;} break;
+		case VK_NUMPAD1: if (mc||ma||ms) {ch = KC_END; kp = TRUE;} break;
+		case VK_NUMPAD2: if (mc||ma||ms) {ch = ARROW_DOWN; kp = TRUE;} break;
+		case VK_NUMPAD3: if (mc||ma||ms) {ch = KC_PGDOWN; kp = TRUE;} break;
+		case VK_NUMPAD4: if (mc||ma||ms) {ch = ARROW_LEFT; kp = TRUE;} break;
+		case VK_NUMPAD5: if (mc||ma||ms) {ch = '5'; kp = TRUE;} break;
+		case VK_NUMPAD6: if (mc||ma||ms) {ch = ARROW_RIGHT; kp = TRUE;} break;
+		case VK_NUMPAD7: if (mc||ma||ms) {ch = KC_HOME; kp = TRUE;} break;
+		case VK_NUMPAD8: if (mc||ma||ms) {ch = ARROW_UP; kp = TRUE;} break;
+		case VK_NUMPAD9: if (mc||ma||ms) {ch = KC_PGUP; kp = TRUE;} break;
+    // the "||ms" above probably are not used, since for me, when
+    // num lock is on, and shift-numpad is pressed, the key where numlock
+    // is not on is sent here, without the shift
+
 	}
 
 	/* we could fall back on using the scancode */
@@ -4711,6 +5048,8 @@
 	FreeDIB(&infMask);
 #endif /* USE_GRAPHICS */
 
+  close_graphics_modes();
+
 #ifdef USE_SOUND
 	/* Free the sound names */
 	for (i = 0; i < MSG_MAX; i++)
@@ -5013,7 +5352,12 @@
 		angband_color_table[i][0] = win_pal[i];
 	}
 
-	/* Prepare the windows */
+  /* load the possible graphics modes */
+  if (!init_graphics_modes("graphics.txt")) {
+    i=i;
+  }
+
+  /* Prepare the windows */
 	init_windows();
 
 	/* Activate hooks */
