diff --git a/game/data/keybinds/hotkeys.lua b/game/data/keybinds/hotkeys.lua
index 07c25cc47791ae64d6223d574748a305bad91bb5..c69c8fa2a1482f84727cfb48a8ab1350c3d69c8e 100644
--- a/game/data/keybinds/hotkeys.lua
+++ b/game/data/keybinds/hotkeys.lua
@@ -251,3 +251,18 @@ defineAction{
 	group = "hotkeys",
 	name = "Next Hotkey Page",
 }
+
+defineAction{
+	default = { "sym:306:false:false:false:false" },
+	type = "HOTKEY_HOTPAGE2",
+	updown = true,
+	group = "hotkeys",
+	name = "Quick switch to Hotkey Page 2",
+}
+defineAction{
+	default = { "sym:304:false:false:false:false" },
+	type = "HOTKEY_HOTPAGE3",
+	updown = true,
+	group = "hotkeys",
+	name = "Quick switch to Hotkey Page 3",
+}
diff --git a/game/engine/KeyBind.lua b/game/engine/KeyBind.lua
index 29af2dff71f5b10d65a769d5f292055128042bf0..dfdc78089635494717ee873f93ec54f3361d2c3c 100644
--- a/game/engine/KeyBind.lua
+++ b/game/engine/KeyBind.lua
@@ -167,20 +167,22 @@ end
 function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
 	self:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
 
-	if isup then return end
-
 	if self.any_key then self.any_key(sym, ctrl, shift, alt, meta, unicode, isup) end
 
 	local ks, us = self:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
 --	print("[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, us, " ?=? ", self.binds[ks], us and self.binds[us])
 	if self.binds[ks] and self.virtuals[self.binds[ks]] then
-		self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode)
+		if isup and not _M.binds_def[self.binds[ks]].updown then return end
+		self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode, isup)
 		return
 	elseif us and self.binds[us] and self.virtuals[self.binds[us]] then
-		self.virtuals[self.binds[us]](sym, ctrl, shift, alt, meta, unicode)
+		if isup and not _M.binds_def[self.binds[us]].updown then return end
+		self.virtuals[self.binds[us]](sym, ctrl, shift, alt, meta, unicode, isup)
 		return
 	end
 
+	if isup then return end
+
 	engine.KeyCommand.receiveKey(self, sym, ctrl, shift, alt, meta, unicode, isup)
 end
 
diff --git a/game/engine/Shader.lua b/game/engine/Shader.lua
index 1c3899949de9aceccdd91dab7d2f58c4cbce0556..479209a4ca2b6def0a005a4c3ba483b91ef84643 100644
--- a/game/engine/Shader.lua
+++ b/game/engine/Shader.lua
@@ -69,7 +69,7 @@ function _M:getVertex(name)
 		code[#code+1] = l
 	end
 	f:close()
-	self.verts[name] = core.shader.newShader(table.concat(code, "\n"))
+	self.verts[name] = core.shader.newShader(table.concat(code, "\n"), true)
 	print("[SHADER] created vertex shader from /data/gfx/shaders/"..name..".vert")
 	return self.verts[name]
 end
diff --git a/game/engine/interface/PlayerHotkeys.lua b/game/engine/interface/PlayerHotkeys.lua
index 60f991dc6c3e0abfd619f88261bd2d389dd0c2cd..f7ce06bfb15ac0fa773745cf4c79df4415f1728f 100644
--- a/game/engine/interface/PlayerHotkeys.lua
+++ b/game/engine/interface/PlayerHotkeys.lua
@@ -59,6 +59,11 @@ function _M:nextHotkeyPage()
 	self.hotkey_page = util.boundWrap(self.hotkey_page + 1, 1, 3)
 	self.changed = true
 end
+--- Switch to hotkey page
+function _M:setHotkeyPage(v)
+	self.hotkey_page = v
+	self.changed = true
+end
 
 -- Autoadd talents to hotkeys
 function _M:hotkeyAutoTalents()
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index c0c9fa6d806b6782377b314b535d75a3b8036513..92827ae2e7c03d72b3621bcfbb16940ac0552316 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -590,6 +590,8 @@ function _M:setupCommands()
 		HOTKEY_THIRD_12 = not_wild(function() self.player:activateHotkey(36) end),
 		HOTKEY_PREV_PAGE = not_wild(function() self.player:prevHotkeyPage() end),
 		HOTKEY_NEXT_PAGE = not_wild(function() self.player:nextHotkeyPage() end),
+		HOTKEY_HOTPAGE2 = function(sym, ctrl, shift, alt, meta, unicode, isup) self.player:setHotkeyPage(isup and 1 or 2) end,
+		HOTKEY_HOTPAGE3 = function(sym, ctrl, shift, alt, meta, unicode, isup) self.player:setHotkeyPage(isup and 1 or 3) end,
 
 		-- Actions
 		CHANGE_LEVEL = function()
diff --git a/game/modules/tome/data/gfx/shaders/water.frag b/game/modules/tome/data/gfx/shaders/water.frag
index cd6f9dd27f6ae0cc15db98daa5feebbd41ce0d88..9de2b68632fe1a05dafb20d6310f6fac2bb06c78 100644
--- a/game/modules/tome/data/gfx/shaders/water.frag
+++ b/game/modules/tome/data/gfx/shaders/water.frag
@@ -1,7 +1,8 @@
-uniform int tick;
-uniform sampler3D noisevol;
+varying vec2 texCoord;
+
+//uniform int tick;
+//uniform sampler3D noisevol;
 uniform sampler2D noise2d;
-uniform float red;
 
 void main(void)
 {
@@ -15,12 +16,18 @@ void main(void)
 //	gl_FragColor.xyz = (1.0-bump.xyz)*vec3(0.3,0.3,1.0)+(bump.xyz)*vec3(0.0,0.0,0.0);
 //	gl_FragColor = bump;
 
-	vec4 n = texture2D(noise2d, gl_TexCoord[0].xy);
-	n.x = 1;
-	gl_FragColor = n;
+//	vec4 n = texture2D(noise2d, texCoord.xy);
+//	n.x = 1;
+//	gl_FragColor = n;
+	gl_FragColor = texture2D(noise2d, texCoord.xy);
+	gl_FragColor.r = 1;
+	gl_FragColor.a = 1.0;
 
 //	int i = (tick / 30) % 255;
 //	float t = (float)i;
 //	t = t / 255;
 //	gl_FragColor = vec4(red, 0, t, 1);
+
+//	gl_FragColor.xy = gl_TexCoord[0].xy;
 }
+
diff --git a/game/modules/tome/data/gfx/shaders/water.lua b/game/modules/tome/data/gfx/shaders/water.lua
index 58b7ce3507d0807bf4c2dc5a3f631c0461d6d39c..e5ca3eb8ace0f3a051f65bd398bfc34cc76bb76e 100644
--- a/game/modules/tome/data/gfx/shaders/water.lua
+++ b/game/modules/tome/data/gfx/shaders/water.lua
@@ -19,9 +19,11 @@
 
 local noise = core.noise.new(2)
 local tex = noise:makeTexture2D("simplex", 128, 128, 4, 0, 0)
+tex = core.display.loadImage("/data/gfx/terrain/tree.png"):glTexture()
 
 return {
 	frag = "water",
+	vert = "default",
 	args = {
 		noise2d = { texture = tex },
 	},
diff --git a/src/main.c b/src/main.c
index c84df8418faada45ff8f4cedb518c16532a00ec5..31cfcc3ef1dba280ed3a01bcdf15d785a9d43b90 100644
--- a/src/main.c
+++ b/src/main.c
@@ -366,7 +366,7 @@ int initGL()
 //	glShadeModel( GL_SMOOTH );
 
 	/* Set the background black */
-	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+	glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
 
 	/* Depth buffer setup */
 //	glClearDepth( 1.0f );
@@ -403,7 +403,11 @@ int resizeWindow(int width, int height)
 
 	ratio = ( GLfloat )width / ( GLfloat )height;
 
+	glActiveTexture(GL_TEXTURE0);
 	glEnable( GL_TEXTURE_2D );
+	glActiveTexture(GL_TEXTURE1);
+	glEnable(GL_TEXTURE_2D);
+	glActiveTexture(GL_TEXTURE0);
 
 	/* Setup our viewport. */
 	glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height );
diff --git a/src/shaders.c b/src/shaders.c
index 92e15ad7a50839677ac3c686b747194635079578..d2774b619f7f56f4b533826749c40a55d60fbea6 100644
--- a/src/shaders.c
+++ b/src/shaders.c
@@ -42,6 +42,8 @@ void useShader(GLuint p, int x, int y)
 	CHECKGL(glUniform1ivARB(glGetUniformLocationARB(p, "mapx"), 1, &i));
 	i = y;
 	CHECKGL(glUniform1ivARB(glGetUniformLocationARB(p, "mapy"), 1, &i));
+
+	CHECKGLSLVALID(p);
 }
 
 static GLuint loadShader(const char* code, GLuint type)
@@ -178,7 +180,7 @@ static int program_set_uniform_texture(lua_State *L)
 	CHECKGL(glBindTexture(is3d ? GL_TEXTURE_3D : GL_TEXTURE_2D, *t));
 	CHECKGL(glUniform1ivARB(glGetUniformLocationARB(*p, var), 1, &i));
 	CHECKGL(glUseProgramObjectARB(0));
-//	CHECKGL(glActiveTexture(GL_TEXTURE0));
+	CHECKGL(glActiveTexture(GL_TEXTURE0));
 	return 0;
 }