From 996ea60642c5d78fc915573af0641d78bc7e2d49 Mon Sep 17 00:00:00 2001
From: sapier <Sapier at GMX dot net>
Date: Wed, 16 Jul 2014 14:04:50 +0200
Subject: [PATCH] Add video driver selection to settings menu (based uppon idea
 from webdesigner97)

---
 builtin/mainmenu/tab_settings.lua | 28 +++++++++++++++-
 doc/menu_lua_api.txt              |  3 ++
 src/main.cpp                      | 54 ++++++++++++++++---------------
 src/script/lua_api/l_mainmenu.cpp | 32 ++++++++++++++++++
 src/script/lua_api/l_mainmenu.h   |  2 ++
 5 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua
index 2311978e0..4bb3eb36c 100644
--- a/builtin/mainmenu/tab_settings.lua
+++ b/builtin/mainmenu/tab_settings.lua
@@ -110,6 +110,24 @@ local function scrollbar_to_gui_scale(value)
 end
 
 local function formspec(tabview, name, tabdata)
+	local video_drivers = core.get_video_drivers()
+	
+	local video_driver_string = ""
+	local current_video_driver_idx = 0
+	local current_video_driver = core.setting_get("video_driver")
+	for i=1, #video_drivers, 1 do
+	
+		if i ~= 1 then
+			video_driver_string = video_driver_string .. ","
+		end
+		video_driver_string = video_driver_string .. video_drivers[i]
+		
+		if current_video_driver:lower() == video_drivers[i]:lower() then
+			current_video_driver_idx = i
+		end
+	end
+	
+	
 	local tab_string =
 		"vertlabel[0,-0.25;" .. fgettext("SETTINGS") .. "]" ..
 		"box[0.75,0;3.25,4;#999999]" ..
@@ -125,6 +143,10 @@ local function formspec(tabview, name, tabdata)
 				.. dump(core.setting_getbool("preload_item_visuals"))	.. "]"..
 		"checkbox[1,2.5;cb_particles;".. fgettext("Enable Particles") .. ";"
 				.. dump(core.setting_getbool("enable_particles"))	.. "]"..
+		"dropdown[1,3.25;3;dd_video_driver;"
+			.. video_driver_string .. ";" .. current_video_driver_idx .. "]" ..
+		"tooltip[dd_video_driver;" ..
+			fgettext("Restart minetest for driver change to take effect") .. "]" ..
 		"box[4.25,0;3.25,2.5;#999999]" ..
 		"checkbox[4.5,0;cb_mipmapping;".. fgettext("Mip-Mapping") .. ";"
 				.. dump(core.setting_getbool("mip_map")) .. "]"..
@@ -284,16 +306,20 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
 		return true
 	end
 	if fields["btn_reset_singleplayer"] then
-		print("sp reset")
 		showconfirm_reset(this)
 		return true
 	end
+
 	--Note dropdowns have to be handled LAST!
 	local ddhandled = false
 	if fields["dd_touchthreshold"] then
 		core.setting_set("touchscreen_threshold",fields["dd_touchthreshold"])
 		ddhandled = true
 	end
+	if fields["dd_video_driver"] then
+		core.setting_set("video_driver",fields["dd_video_driver"])
+		ddhandled = true
+	end
 	
 	return ddhandled
 end
diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt
index 13ef45de0..20549d892 100644
--- a/doc/menu_lua_api.txt
+++ b/doc/menu_lua_api.txt
@@ -88,6 +88,9 @@ core.sound_play(spec, looped) -> handle
 ^ spec = SimpleSoundSpec (see lua-api.txt)
 ^ looped = bool
 core.sound_stop(handle)
+core.get_video_drivers()
+^ get list of video drivers supported by engine (not all modes are guaranteed to work)
+^ returns list of available video drivers e.g. { "OpenGL", "Software" }
 
 Formspec:
 core.update_formspec(formspec)
diff --git a/src/main.cpp b/src/main.cpp
index 1b91edd21..9d336825e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1365,41 +1365,43 @@ int main(int argc, char *argv[])
 	u16 fsaa = g_settings->getU16("fsaa");
 
 	// Determine driver
-
-	video::E_DRIVER_TYPE driverType;
-
-	std::string driverstring = g_settings->get("video_driver");
-
-	if (driverstring == "null")
-		driverType = video::EDT_NULL;
-	else if (driverstring == "software")
-		driverType = video::EDT_SOFTWARE;
-	else if (driverstring == "burningsvideo")
-		driverType = video::EDT_BURNINGSVIDEO;
-	else if (driverstring == "direct3d8")
-		driverType = video::EDT_DIRECT3D8;
-	else if (driverstring == "direct3d9")
-		driverType = video::EDT_DIRECT3D9;
-	else if (driverstring == "opengl")
-		driverType = video::EDT_OPENGL;
+	video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
+	static const char* driverids[] = {
+		"null",
+		"software",
+		"burningsvideo",
+		"direct3d8",
+		"direct3d9",
+		"opengl"
 #ifdef _IRR_COMPILE_WITH_OGLES1_
-	else if (driverstring == "ogles1")
-		driverType = video::EDT_OGLES1;
+		,"ogles1"
 #endif
 #ifdef _IRR_COMPILE_WITH_OGLES2_
-	else if (driverstring == "ogles2")
-		driverType = video::EDT_OGLES2;
+		,"ogles2"
 #endif
-	else {
-		errorstream << "WARNING: Invalid video_driver specified; defaulting "
-			<< "to opengl" << std::endl;
-		driverType = video::EDT_OPENGL;
+		,"invalid"
+	};
+
+	std::string driverstring = g_settings->get("video_driver");
+	for (unsigned int i = 0;
+			i < (sizeof(driverids)/sizeof(driverids[0]));
+			i++)
+	{
+		if (strcasecmp(driverstring.c_str(), driverids[i]) == 0) {
+			driverType = (video::E_DRIVER_TYPE) i;
+			break;
+		}
+
+		if (strcasecmp("invalid", driverids[i]) == 0) {
+			errorstream << "WARNING: Invalid video_driver specified; defaulting "
+				<< "to opengl" << std::endl;
+			break;
+		}
 	}
 
 	/*
 		List video modes if requested
 	*/
-
 	MyEventReceiver* receiver = new MyEventReceiver();
 
 	if (cmd_args.getFlag("videomodes")) {
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index ae2fddf6d..1760d2794 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "sound.h"
 #include "settings.h"
 #include "main.h" // for g_settings
+#include "EDriverTypes.h"
 
 #include <IFileArchive.h>
 #include <IFileSystem.h>
@@ -1001,6 +1002,36 @@ int ModApiMainMenu::l_download_file(lua_State *L)
 	return 1;
 }
 
+/******************************************************************************/
+int ModApiMainMenu::l_get_video_drivers(lua_State *L)
+{
+	static const char* drivernames[] = {
+		"NULL Driver",
+		"Software",
+		"Burningsvideo",
+		"Direct3D 8",
+		"Direct3D 9",
+		"OpenGL",
+		"OGLES1",
+		"OGLES2"
+	};
+	unsigned int index = 1;
+	lua_newtable(L);
+	int top = lua_gettop(L);
+
+	for (unsigned int i = irr::video::EDT_SOFTWARE;
+			i < MYMIN(irr::video::EDT_COUNT, (sizeof(drivernames)/sizeof(drivernames[0])));
+			i++) {
+		if (irr::IrrlichtDevice::isDriverSupported((irr::video::E_DRIVER_TYPE) i)) {
+			lua_pushnumber(L,index++);
+			lua_pushstring(L,drivernames[i]);
+			lua_settable(L, top);
+		}
+	}
+
+	return 1;
+}
+
 /******************************************************************************/
 int ModApiMainMenu::l_gettext(lua_State *L)
 {
@@ -1094,6 +1125,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
 	API_FCT(sound_play);
 	API_FCT(sound_stop);
 	API_FCT(gettext);
+	API_FCT(get_video_drivers);
 	API_FCT(get_screen_info);
 	API_FCT(do_async_callback);
 }
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
index 7a9cafd1f..1783a3f7f 100644
--- a/src/script/lua_api/l_mainmenu.h
+++ b/src/script/lua_api/l_mainmenu.h
@@ -133,6 +133,8 @@ class ModApiMainMenu : public ModApiBase {
 
 	static int l_download_file(lua_State *L);
 
+	static int l_get_video_drivers(lua_State *L);
+
 	// async
 	static int l_do_async_callback(lua_State *L);
 
-- 
GitLab