From 90c47a9c8d738001e9d60849dbeef78873e3a10e Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Wed, 25 May 2016 18:28:50 +0200
Subject: [PATCH] load shaders from files, so we can use the libretro shaders

---
 src/include/shaders.h       |    2 +-
 src/stratagus/stratagus.cpp | 1606 +++++++++++++++++------------------
 src/video/sdl.cpp           |   15 +-
 src/video/shaders.cpp       |  425 ++-------
 4 files changed, 881 insertions(+), 1167 deletions(-)

diff --git a/src/include/shaders.h b/src/include/shaders.h
index 94dcfe6d0..63ba7b26b 100644
--- a/src/include/shaders.h
+++ b/src/include/shaders.h
@@ -10,7 +10,7 @@ extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer;
 #endif
 extern GLuint fullscreenFramebuffer;
 extern unsigned ShaderIndex;
-extern bool LoadShaders();
+extern bool LoadShaders(char* shadernameOut);
 extern bool LoadShaderExtensions();
 extern void SetupFramebuffer();
 extern void RenderFramebufferToScreen();
diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp
index 5ced197a7..c4c7b0d13 100644
--- a/src/stratagus/stratagus.cpp
+++ b/src/stratagus/stratagus.cpp
@@ -1,803 +1,803 @@
-//       _________ __                 __
-//      /   _____//  |_____________ _/  |______     ____  __ __  ______
-//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
-//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
-//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
-//             \/                  \/          \//_____/            \/
-//  ______________________                           ______________________
-//                        T H E   W A R   B E G I N S
-//         Stratagus - A free fantasy real time strategy game engine
-//
-/**@name stratagus.cpp - The main file. */
-//
-//      (c) Copyright 1998-2015 by Lutz Sammer, Francois Beerten,
-//                                 Jimmy Salmon, Pali Rohár and cybermind
-//
-//      This program is free software; you can redistribute it and/or modify
-//      it under the terms of the GNU General Public License as published by
-//      the Free Software Foundation; only version 2 of the License.
-//
-//      This program is distributed in the hope that it will be useful,
-//      but WITHOUT ANY WARRANTY; without even the implied warranty of
-//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//      GNU General Public License for more details.
-//
-//      You should have received a copy of the GNU General Public License
-//      along with this program; if not, write to the Free Software
-//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-//      02111-1307, USA.
-//
-
-//@{
-
-/**
-** @mainpage
-**
-** @section Introduction Introduction
-**
-** Welcome to the source code documentation of the Stratagus engine.
-** Extract the source documentation with doxygen (http://www.doxygen.org) tool.
-**
-** Any help to improve this documention is welcome. If you didn't
-** understand something or you found an error or a wrong spelling
-** or wrong grammar please write an email (including a patch :).
-**
-** @section Information Information
-**
-** Visit the https://github.com/Wargus/stratagus web page for the latest news and
-** <A HREF="../index.html">Stratagus Info</A> for other documentation.
-**
-** @section Modules Modules
-**
-** This are the main modules of the Stratagus engine.
-**
-** @subsection Map Map
-**
-** Handles the map. A map is made from tiles.
-**
-** @see map.h @see map.cpp @see tileset.h @see tileset.cpp
-**
-** @subsection Unit Unit
-**
-** Handles units. Units are ships, flyers, buildings, creatures,
-** machines.
-**
-** @see unit.h @see unit.cpp @see unittype.h @see unittype.cpp
-**
-** @subsection Missile Missile
-**
-** Handles missiles. Missiles are all other sprites on map
-** which are no unit.
-**
-** @see missile.h @see missile.cpp
-**
-** @subsection Player Player
-**
-** Handles players, all units are owned by a player. A player
-** could be controlled by a human or a computer.
-**
-** @see player.h @see player.cpp @see ::CPlayer
-**
-** @subsection Sound Sound
-**
-** Handles the high and low level of the sound. There are the
-** background music support, voices and sound effects.
-** Following low level backends are supported: OSS and SDL.
-**
-** @todo adpcm file format support for sound effects
-** @todo better separation of low and high level, assembler mixing
-** support.
-** @todo Streaming support of ogg/mp3 files.
-**
-** @see sound.h @see sound.cpp
-** @see script_sound.cpp @see sound_id.cpp @see sound_server.cpp
-** @see unitsound.cpp
-** @see sdl_audio.cpp
-** @see ogg.cpp @see wav.cpp
-**
-** @subsection Video Video
-**
-** Handles the high and low level of the graphics.
-** This also contains the sprite and linedrawing routines.
-**
-** See page @ref VideoModule for more information upon supported
-** features and video platforms.
-**
-** @see video.h @see video.cpp
-**
-** @subsection Network Network
-**
-** Handles the high and low level of the network protocol.
-** The network protocol is needed for multiplayer games.
-**
-** See page @ref NetworkModule for more information upon supported
-** features and API.
-**
-** @see network.h @see network.cpp
-**
-** @subsection Pathfinder Pathfinder
-**
-** @see pathfinder.h @see pathfinder.cpp
-**
-** @subsection AI AI
-**
-** There are currently two AI's. The old one is very hardcoded,
-** but does things like placing buildings better than the new.
-** The old AI shouldn't be used.  The new is very flexible, but
-** very basic. It includes none optimations.
-**
-** See page @ref AiModule for more information upon supported
-** features and API.
-**
-** @see ai_local.h
-** @see ai.h @see ai.cpp
-**
-** @subsection CCL CCL
-**
-** CCL is Craft Configuration Language, which is used to
-** configure and customize Stratagus.
-**
-** @see script.h @see script.cpp
-**
-** @subsection Icon Icon
-**
-** @see icons.h @see icons.cpp
-**
-** @subsection Editor Editor
-**
-** This is the integrated editor, it shouldn't be a perfect
-** editor. It is used to test new features of the engine.
-**
-** See page @ref EditorModule for more information upon supported
-** features and API.
-**
-** @see editor.h @see editor.cpp
-*/
-
-/*----------------------------------------------------------------------------
---  Includes
-----------------------------------------------------------------------------*/
-
-#include <ctype.h>
-
-#ifdef USE_BEOS
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-extern void beos_init(int argc, char **argv);
-
-#endif
-
-#ifdef MAC_BUNDLE
-#define Button ButtonOSX
-#include <Carbon/Carbon.h>
-#undef Button
-#endif
-
-#include "SDL.h"
-
-#include "stratagus.h"
-
-#include "ai.h"
-#include "editor.h"
-#include "game.h"
-#include "guichan.h"
-#include "interface.h"
-#include "iocompat.h"
-#include "iolib.h"
-#include "map.h"
-#include "netconnect.h"
-#include "network.h"
-#include "parameters.h"
-#include "player.h"
-#include "replay.h"
-#include "results.h"
-#include "settings.h"
-#include "sound_server.h"
-#include "title.h"
-#include "translate.h"
-#include "ui.h"
-#include "unit_manager.h"
-#include "version.h"
-#include "video.h"
-#include "widgets.h"
-#include "util.h"
-
-#include "missile.h" //for FreeBurningBuildingFrames
-
-#ifdef USE_STACKTRACE
-#include <stdexcept>
-#include <stacktrace/call_stack.hpp>
-#include <stacktrace/stack_exception.hpp>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef USE_WIN32
-#include <windows.h>
-#include <dbghelp.h>
-#endif
-
-#if defined(USE_WIN32) && ! defined(NO_STDIO_REDIRECT)
-#include "windows.h"
-#define REDIRECT_OUTPUT
-#endif
-
-#if defined(USE_WIN32) && ! defined(REDIRECT_OUTPUT)
-#include "SetupConsole_win32.h"
-#endif
-
-/*----------------------------------------------------------------------------
---  Variables
-----------------------------------------------------------------------------*/
-
-std::string StratagusLibPath;        /// Path for data directory
-
-/// Name, Version, Copyright
-const char NameLine[] = NAME " v" VERSION ", " COPYRIGHT;
-
-std::string CliMapName;          /// Filename of the map given on the command line
-std::string MenuRace;
-
-bool EnableDebugPrint;           /// if enabled, print the debug messages
-bool EnableAssert;               /// if enabled, halt on assertion failures
-bool EnableUnitDebug;            /// if enabled, a unit info dump will be created
-
-/*============================================================================
-==  MAIN
-============================================================================*/
-
-/**
-**  Pre menu setup.
-*/
-void PreMenuSetup()
-{
-	//
-	//  Initial menus require some gfx.
-	//
-	SetDefaultTextColors(FontYellow, FontWhite);
-
-	LoadFonts();
-
-	InitVideoCursors();
-
-	if (MenuRace.empty()) {
-		LoadCursors(PlayerRaces.Name[0]);
-	} else {
-		LoadCursors(MenuRace);
-	}
-
-	InitSettings();
-
-	InitUserInterface();
-	UI.Load();
-}
-
-/**
-**  Run the guichan main menus loop.
-**
-**  @return          0 for success, else exit.
-*/
-static int MenuLoop()
-{
-	int status;
-
-	initGuichan();
-	InterfaceState = IfaceStateMenu;
-	//  Clear screen
-	Video.ClearScreen();
-	Invalidate();
-
-	ButtonUnderCursor = -1;
-	OldButtonUnderCursor = -1;
-	CursorState = CursorStatePoint;
-	GameCursor = UI.Point.Cursor;
-
-	// FIXME delete this when switching to full guichan GUI
-	const std::string filename = LibraryFileName("scripts/guichan.lua");
-	status = LuaLoadFile(filename);
-
-	// We clean up later in Exit
-	return status;
-}
-
-//----------------------------------------------------------------------------
-
-/**
-**  Print headerline, copyright, ...
-*/
-static void PrintHeader()
-{
-	std::string CompileOptions =
-#ifdef DEBUG
-		"DEBUG "
-#endif
-#ifdef USE_ZLIB
-		"ZLIB "
-#endif
-#ifdef USE_BZ2LIB
-		"BZ2LIB "
-#endif
-#ifdef USE_VORBIS
-		"VORBIS "
-#endif
-#ifdef USE_THEORA
-		"THEORA "
-#endif
-#ifdef USE_FLUIDSYNTH
-		"FLUIDSYNTH "
-#endif
-#ifdef USE_MIKMOD
-		"MIKMOD "
-#endif
-#ifdef USE_MNG
-		"MNG "
-#endif
-#ifdef USE_OPENGL
-		"OPENGL "
-#endif
-#ifdef USE_GLES
-		"GLES "
-#endif
-#ifdef USE_WIN32
-		"WIN32 "
-#endif
-#ifdef USE_LINUX
-		"LINUX "
-#endif
-#ifdef USE_BSD
-		"BSD "
-#endif
-#ifdef USE_BEOS
-		"BEOS "
-#endif
-#ifdef USE_MAC
-		"MAC "
-#endif
-#ifdef USE_X11
-		"X11 "
-#endif
-#ifdef USE_TOUCHSCREEN
-		"TOUCHSCREEN "
-#endif
-		"";
-
-	fprintf(stdout,
-			"%s\n  written by Lutz Sammer, Fabrice Rossi, Vladi Shabanski, Patrice Fortier,\n"
-			"  Jon Gabrielson, Andreas Arens, Nehal Mistry, Jimmy Salmon, Pali Rohar,\n"
-			"  cybermind and others.\n"
-			"\t" HOMEPAGE "\n"
-			"Compile options %s",
-			NameLine, CompileOptions.c_str());
-}
-
-void PrintLicense()
-{
-	printf("\n"
-		   "\n"
-		   "Stratagus may be copied only under the terms of the GNU General Public License\n"
-		   "which may be found in the Stratagus source kit.\n"
-		   "\n"
-		   "DISCLAIMER:\n"
-		   "This software is provided as-is.  The author(s) can not be held liable for any\n"
-		   "damage that might arise from the use of this software.\n"
-		   "Use it at your own risk.\n"
-		   "\n");
-}
-
-
-/**
-**  Exit the game.
-**
-**  @param err  Error code to pass to shell.
-*/
-void Exit(int err)
-{
-	if (GameRunning) {
-		StopGame(GameExit);
-		return;
-	}
-
-	StopMusic();
-	QuitSound();
-	NetworkQuitGame();
-
-	ExitNetwork1();
-	CleanModules();
-	FreeBurningBuildingFrames();
-	FreeSounds();
-	FreeGraphics();
-	FreePlayerColors();
-	FreeButtonStyles();
-	FreeAllContainers();
-	freeGuichan();
-	DebugPrint("Frames %lu, Slow frames %d = %ld%%\n" _C_
-			   FrameCounter _C_ SlowFrameCounter _C_
-			   (SlowFrameCounter * 100) / (FrameCounter ? FrameCounter : 1));
-	lua_settop(Lua, 0);
-	lua_close(Lua);
-	DeInitVideo();
-
-	fprintf(stdout, "%s", _("Thanks for playing Stratagus.\n"));
-	exit(err);
-}
-
-/**
-**  Do a fatal exit.
-**  Called on out of memory or crash.
-**
-**  @param err  Error code to pass to shell.
-*/
-void ExitFatal(int err)
-{
-#ifdef USE_STACKTRACE
-	throw stacktrace::stack_runtime_error((const char*)err);
-#endif
-	exit(err);
-}
-
-/**
-**  Display the usage.
-*/
-static void Usage()
-{
-	PrintHeader();
-	printf(
-		"\n\nUsage: %s [OPTIONS] [map.smp|map.smp.gz]\n"
-		"\t-a\t\tEnables asserts check in engine code (for debugging)\n"
-		"\t-c file.lua\tConfiguration start file (default stratagus.lua)\n"
-		"\t-d datapath\tPath to stratagus data (default current directory)\n"
-		"\t-D depth\tVideo mode depth = pixel per point\n"
-		"\t-e\t\tStart editor (instead of game)\n"
-		"\t-E file.lua\tEditor configuration start file (default editor.lua)\n"
-		"\t-F\t\tFull screen video mode\n"
-		"\t-G \"options\"\tGame options (passed to game scripts)\n"
-		"\t-h\t\tHelp shows this page\n"
-		"\t-i\t\tEnables unit info dumping into log (for debugging)\n"
-		"\t-I addr\t\tNetwork address to use\n"
-		"\t-l\t\tDisable command log\n"
-		"\t-N name\t\tName of the player\n"
-#if defined(USE_OPENGL) || defined(USE_GLES)
-		"\t-o\t\tDo not use OpenGL or OpenGL ES 1.1\n"
-		"\t-O\t\tUse OpenGL or OpenGL ES 1.1\n"
-#endif
-		"\t-p\t\tEnables debug messages printing in console\n"
-		"\t-P port\t\tNetwork port to use\n"
-		"\t-s sleep\tNumber of frames for the AI to sleep before it starts\n"
-		"\t-S speed\tSync speed (100 = 30 frames/s)\n"
-		"\t-u userpath\tPath where stratagus saves preferences, log and savegame\n"
-		"\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n"
-		"\t-W\t\tWindowed video mode\n"
-#if defined(USE_OPENGL) || defined(USE_GLES)
-		"\t-x idx\t\tControls fullscreen scaling if your graphics card supports shaders.\n"\
-		"\t  \t\tPass 1 for nearest-neigubour, 2 for EPX/AdvMame, 3 for HQx, 4 for SAL, 5 for SuperEagle\n"\
-		"\t  \t\tYou can also use Ctrl+Alt+/ to cycle between these scaling algorithms at runtime.\n"
-		"\t  \t\tPass -1 to force old-school nearest neighbour scaling without shaders\n"\
-		"\t-Z\t\tUse OpenGL to scale the screen to the viewport (retro-style). Implies -O.\n"
-#endif
-		"map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n",
-		Parameters::Instance.applicationName.c_str());
-}
-
-#ifdef REDIRECT_OUTPUT
-
-static std::string stdoutFile;
-static std::string stderrFile;
-
-static void CleanupOutput()
-{
-	fclose(stdout);
-	fclose(stderr);
-
-	struct stat st;
-	if (stat(stdoutFile.c_str(), &st) == 0 && st.st_size == 0) {
-		unlink(stdoutFile.c_str());
-	}
-	if (stat(stderrFile.c_str(), &st) == 0 && st.st_size == 0) {
-		unlink(stderrFile.c_str());
-	}
-}
-
-static void RedirectOutput()
-{
-	std::string path = Parameters::Instance.GetUserDirectory();
-
-	makedir(path.c_str(), 0777);
-
-	stdoutFile = path + "\\stdout.txt";
-	stderrFile = path + "\\stderr.txt";
-
-	if (!freopen(stdoutFile.c_str(), "w", stdout)) {
-		printf("freopen stdout failed");
-	}
-	if (!freopen(stderrFile.c_str(), "w", stderr)) {
-		printf("freopen stderr failed");
-	}
-	atexit(CleanupOutput);
-}
-#endif
-
-void ParseCommandLine(int argc, char **argv, Parameters &parameters)
-{
-	for (;;) {
-		switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z?-")) {
-			case 'a':
-				EnableAssert = true;
-				continue;
-			case 'c':
-				parameters.luaStartFilename = optarg;
-				if (strlen(optarg) > 4 &&
-				    !(strstr(optarg, ".lua") == optarg + strlen(optarg) - 4)) {
-					parameters.luaStartFilename += ".lua";
-				}
-				continue;
-			case 'd': {
-				StratagusLibPath = optarg;
-				size_t index;
-				while ((index = StratagusLibPath.find('\\')) != std::string::npos) {
-					StratagusLibPath[index] = '/';
-				}
-				continue;
-			}
-			case 'D':
-				Video.Depth = atoi(optarg);
-				continue;
-			case 'e':
-				Editor.Running = EditorCommandLine;
-				continue;
-			case 'E':
-				parameters.luaEditorStartFilename = optarg;
-				continue;
-			case 'F':
-				VideoForceFullScreen = 1;
-				Video.FullScreen = 1;
-				continue;
-			case 'G':
-				parameters.luaScriptArguments = optarg;
-				continue;
-			case 'i':
-				EnableUnitDebug = true;
-				continue;
-			case 'I':
-				CNetworkParameter::Instance.localHost = optarg;
-				continue;
-			case 'l':
-				CommandLogDisabled = true;
-				continue;
-			case 'N':
-				parameters.LocalPlayerName = optarg;
-				continue;
-#if defined(USE_OPENGL) || defined(USE_GLES)
-			case 'o':
-				ForceUseOpenGL = 1;
-				UseOpenGL = 0;
-				if (ZoomNoResize) {
-					fprintf(stderr, "Error: -Z only works with OpenGL enabled\n");
-					Usage();
-					ExitFatal(-1);
-				}
-				continue;
-			case 'O':
-				ForceUseOpenGL = 1;
-				UseOpenGL = 1;
-				continue;
-#endif
-			case 'P':
-				CNetworkParameter::Instance.localPort = atoi(optarg);
-				continue;
-			case 'p':
-				EnableDebugPrint = true;
-				continue;
-			case 's':
-				AiSleepCycles = atoi(optarg);
-				continue;
-			case 'S':
-				VideoSyncSpeed = atoi(optarg);
-				continue;
-			case 'u':
-				Parameters::Instance.SetUserDirectory(optarg);
-				continue;
-			case 'v': {
-				char *sep = strchr(optarg, 'x');
-				if (!sep || !*(sep + 1)) {
-					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
-					Usage();
-					ExitFatal(-1);
-				}
-				Video.Height = atoi(sep + 1);
-				*sep = 0;
-				Video.Width = atoi(optarg);
-				if (!Video.Height || !Video.Width) {
-					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%sx%s'\n", argv[0], optarg, sep + 1);
-					Usage();
-					ExitFatal(-1);
-				}
-#if defined(USE_OPENGL) || defined(USE_GLES)
-				if (ZoomNoResize) {
-					Video.ViewportHeight = Video.Height;
-					Video.ViewportWidth = Video.Width;
-					Video.Height = 0;
-					Video.Width = 0;
-				}
-#endif
-				continue;
-			}
-			case 'W':
-				VideoForceFullScreen = 1;
-				Video.FullScreen = 0;
-				continue;
-#if defined(USE_OPENGL) || defined(USE_GLES)
-			case 'x':
-				ShaderIndex = atoi(optarg) % MAX_SHADERS;
-				if (atoi(optarg) == -1) {
-					GLShaderPipelineSupported = false;
-				}
-				continue;
-			case 'Z':
-				ForceUseOpenGL = 1;
-				UseOpenGL = 1;
-				ZoomNoResize = 1;
-				Video.ViewportHeight = Video.Height;
-				Video.ViewportWidth = Video.Width;
-				Video.Height = 0;
-				Video.Width = 0;
-				continue;
-#endif
-			case -1:
-				break;
-			case '?':
-			case 'h':
-			default:
-				Usage();
-				ExitFatal(-1);
-		}
-		break;
-	}
-
-	if (argc - optind > 1) {
-		fprintf(stderr, "too many map files. if you meant to pass game arguments, these go after '--'\n");
-		Usage();
-		ExitFatal(-1);
-	}
-
-	if (argc - optind) {
-		size_t index;
-		CliMapName = argv[optind];
-		while ((index = CliMapName.find('\\')) != std::string::npos) {
-			CliMapName[index] = '/';
-		}
-	}
-}
-
-#ifdef USE_WIN32
-static LONG WINAPI CreateDumpFile(EXCEPTION_POINTERS *ExceptionInfo)
-{
-	HANDLE hFile = CreateFile("crash.dmp", GENERIC_READ | GENERIC_WRITE,	FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
-		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,	NULL);
-	MINIDUMP_EXCEPTION_INFORMATION mei;
-	mei.ThreadId = GetCurrentThreadId();
-	mei.ClientPointers = TRUE;
-	mei.ExceptionPointers = ExceptionInfo;
-	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mei, NULL, NULL);
-	fprintf(stderr, "Stratagus crashed!\n");
-	fprintf(stderr, "A mini dump file \"crash.dmp\" has been created in the Stratagus folder.\n");
-	fprintf(stderr, "Please send it to our bug tracker: https://github.com/Wargus/stratagus/issues\n");
-	fprintf(stderr, "and tell us what caused this bug to occur.\n");
-	return EXCEPTION_EXECUTE_HANDLER;
-}
-#endif
-
-/**
-**  The main program: initialise, parse options and arguments.
-**
-**  @param argc  Number of arguments.
-**  @param argv  Vector of arguments.
-*/
-int stratagusMain(int argc, char **argv)
-{
-#ifdef USE_BEOS
-	//  Parse arguments for BeOS
-	beos_init(argc, argv);
-#endif
-#ifdef USE_WIN32
-	SetUnhandledExceptionFilter(CreateDumpFile);
-#endif
-#if defined(USE_WIN32) && ! defined(REDIRECT_OUTPUT)
-	SetupConsole();
-#endif
-	//  Setup some defaults.
-#ifndef MAC_BUNDLE
-	StratagusLibPath = ".";
-#else
-	freopen("/tmp/stdout.txt", "w", stdout);
-	freopen("/tmp/stderr.txt", "w", stderr);
-	// Look for the specified data set inside the application bundle
-	// This should be a subdir of the Resources directory
-	CFURLRef pluginRef = CFBundleCopyResourceURL(CFBundleGetMainBundle(),
-												 CFSTR(MAC_BUNDLE_DATADIR), NULL, NULL);
-	CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef,  kCFURLPOSIXPathStyle);
-	const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding());
-	Assert(pathPtr);
-	StratagusLibPath = pathPtr;
-#endif
-#ifdef USE_STACKTRACE
-	try {
-#endif
-	Parameters &parameters = Parameters::Instance;
-	parameters.SetDefaultValues();
-	parameters.SetLocalPlayerNameFromEnv();
-
-#ifdef REDIRECT_OUTPUT
-	RedirectOutput();
-#endif
-
-	if (argc > 0) {
-		parameters.applicationName = argv[0];
-	}
-
-	// FIXME: Parse options before or after scripts?
-	ParseCommandLine(argc, argv, parameters);
-	// Init the random number generator.
-	InitSyncRand();
-
-	makedir(parameters.GetUserDirectory().c_str(), 0777);
-
-	// Init Lua and register lua functions!
-	InitLua();
-	LuaRegisterModules();
-
-	// Initialise AI module
-	InitAiModule();
-
-	LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
-
-	PrintHeader();
-	PrintLicense();
-
-	// Setup video display
-	InitVideo();
-
-	// Setup sound card
-	if (!InitSound()) {
-		InitMusic();
-	}
-
-#ifndef DEBUG           // For debug it's better not to have:
-	srand(time(NULL));  // Random counter = random each start
-#endif
-
-	//  Show title screens.
-	SetDefaultTextColors(FontYellow, FontWhite);
-	LoadFonts();
-	SetClipping(0, 0, Video.Width - 1, Video.Height - 1);
-	Video.ClearScreen();
-	ShowTitleScreens();
-
-	// Init player data
-	ThisPlayer = NULL;
-	//Don't clear the Players structure as it would erase the allowed units.
-	// memset(Players, 0, sizeof(Players));
-	NumPlayers = 0;
-
-	UnitManager.Init(); // Units memory management
-	PreMenuSetup();     // Load everything needed for menus
-
-	MenuLoop();
-
-	Exit(0);
-#ifdef USE_STACKTRACE
-	} catch (const std::exception &e) {
-		fprintf(stderr, "Stratagus crashed!\n");
-		fprintf(stderr, "Please send this call stack to our bug tracker: https://github.com/Wargus/stratagus/issues\n");
-		fprintf(stderr, "and tell us what caused this bug to occur.\n");
-		fprintf(stderr, " === exception state traceback === \n");
-		fprintf(stderr, "%s", e.what());
-		exit(1);
-	}
-#endif
-	return 0;
-}
-
-//@}
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name stratagus.cpp - The main file. */
+//
+//      (c) Copyright 1998-2015 by Lutz Sammer, Francois Beerten,
+//                                 Jimmy Salmon, Pali Rohár and cybermind
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; only version 2 of the License.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+//@{
+
+/**
+** @mainpage
+**
+** @section Introduction Introduction
+**
+** Welcome to the source code documentation of the Stratagus engine.
+** Extract the source documentation with doxygen (http://www.doxygen.org) tool.
+**
+** Any help to improve this documention is welcome. If you didn't
+** understand something or you found an error or a wrong spelling
+** or wrong grammar please write an email (including a patch :).
+**
+** @section Information Information
+**
+** Visit the https://github.com/Wargus/stratagus web page for the latest news and
+** <A HREF="../index.html">Stratagus Info</A> for other documentation.
+**
+** @section Modules Modules
+**
+** This are the main modules of the Stratagus engine.
+**
+** @subsection Map Map
+**
+** Handles the map. A map is made from tiles.
+**
+** @see map.h @see map.cpp @see tileset.h @see tileset.cpp
+**
+** @subsection Unit Unit
+**
+** Handles units. Units are ships, flyers, buildings, creatures,
+** machines.
+**
+** @see unit.h @see unit.cpp @see unittype.h @see unittype.cpp
+**
+** @subsection Missile Missile
+**
+** Handles missiles. Missiles are all other sprites on map
+** which are no unit.
+**
+** @see missile.h @see missile.cpp
+**
+** @subsection Player Player
+**
+** Handles players, all units are owned by a player. A player
+** could be controlled by a human or a computer.
+**
+** @see player.h @see player.cpp @see ::CPlayer
+**
+** @subsection Sound Sound
+**
+** Handles the high and low level of the sound. There are the
+** background music support, voices and sound effects.
+** Following low level backends are supported: OSS and SDL.
+**
+** @todo adpcm file format support for sound effects
+** @todo better separation of low and high level, assembler mixing
+** support.
+** @todo Streaming support of ogg/mp3 files.
+**
+** @see sound.h @see sound.cpp
+** @see script_sound.cpp @see sound_id.cpp @see sound_server.cpp
+** @see unitsound.cpp
+** @see sdl_audio.cpp
+** @see ogg.cpp @see wav.cpp
+**
+** @subsection Video Video
+**
+** Handles the high and low level of the graphics.
+** This also contains the sprite and linedrawing routines.
+**
+** See page @ref VideoModule for more information upon supported
+** features and video platforms.
+**
+** @see video.h @see video.cpp
+**
+** @subsection Network Network
+**
+** Handles the high and low level of the network protocol.
+** The network protocol is needed for multiplayer games.
+**
+** See page @ref NetworkModule for more information upon supported
+** features and API.
+**
+** @see network.h @see network.cpp
+**
+** @subsection Pathfinder Pathfinder
+**
+** @see pathfinder.h @see pathfinder.cpp
+**
+** @subsection AI AI
+**
+** There are currently two AI's. The old one is very hardcoded,
+** but does things like placing buildings better than the new.
+** The old AI shouldn't be used.  The new is very flexible, but
+** very basic. It includes none optimations.
+**
+** See page @ref AiModule for more information upon supported
+** features and API.
+**
+** @see ai_local.h
+** @see ai.h @see ai.cpp
+**
+** @subsection CCL CCL
+**
+** CCL is Craft Configuration Language, which is used to
+** configure and customize Stratagus.
+**
+** @see script.h @see script.cpp
+**
+** @subsection Icon Icon
+**
+** @see icons.h @see icons.cpp
+**
+** @subsection Editor Editor
+**
+** This is the integrated editor, it shouldn't be a perfect
+** editor. It is used to test new features of the engine.
+**
+** See page @ref EditorModule for more information upon supported
+** features and API.
+**
+** @see editor.h @see editor.cpp
+*/
+
+/*----------------------------------------------------------------------------
+--  Includes
+----------------------------------------------------------------------------*/
+
+#include <ctype.h>
+
+#ifdef USE_BEOS
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern void beos_init(int argc, char **argv);
+
+#endif
+
+#ifdef MAC_BUNDLE
+#define Button ButtonOSX
+#include <Carbon/Carbon.h>
+#undef Button
+#endif
+
+#include "SDL.h"
+
+#include "stratagus.h"
+
+#include "ai.h"
+#include "editor.h"
+#include "game.h"
+#include "guichan.h"
+#include "interface.h"
+#include "iocompat.h"
+#include "iolib.h"
+#include "map.h"
+#include "netconnect.h"
+#include "network.h"
+#include "parameters.h"
+#include "player.h"
+#include "replay.h"
+#include "results.h"
+#include "settings.h"
+#include "sound_server.h"
+#include "title.h"
+#include "translate.h"
+#include "ui.h"
+#include "unit_manager.h"
+#include "version.h"
+#include "video.h"
+#include "widgets.h"
+#include "util.h"
+
+#include "missile.h" //for FreeBurningBuildingFrames
+
+#ifdef USE_STACKTRACE
+#include <stdexcept>
+#include <stacktrace/call_stack.hpp>
+#include <stacktrace/stack_exception.hpp>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef USE_WIN32
+#include <windows.h>
+#include <dbghelp.h>
+#endif
+
+#if defined(USE_WIN32) && ! defined(NO_STDIO_REDIRECT)
+#include "windows.h"
+#define REDIRECT_OUTPUT
+#endif
+
+#if defined(USE_WIN32) && ! defined(REDIRECT_OUTPUT)
+#include "SetupConsole_win32.h"
+#endif
+
+/*----------------------------------------------------------------------------
+--  Variables
+----------------------------------------------------------------------------*/
+
+std::string StratagusLibPath;        /// Path for data directory
+
+/// Name, Version, Copyright
+const char NameLine[] = NAME " v" VERSION ", " COPYRIGHT;
+
+std::string CliMapName;          /// Filename of the map given on the command line
+std::string MenuRace;
+
+bool EnableDebugPrint;           /// if enabled, print the debug messages
+bool EnableAssert;               /// if enabled, halt on assertion failures
+bool EnableUnitDebug;            /// if enabled, a unit info dump will be created
+
+/*============================================================================
+==  MAIN
+============================================================================*/
+
+/**
+**  Pre menu setup.
+*/
+void PreMenuSetup()
+{
+	//
+	//  Initial menus require some gfx.
+	//
+	SetDefaultTextColors(FontYellow, FontWhite);
+
+	LoadFonts();
+
+	InitVideoCursors();
+
+	if (MenuRace.empty()) {
+		LoadCursors(PlayerRaces.Name[0]);
+	} else {
+		LoadCursors(MenuRace);
+	}
+
+	InitSettings();
+
+	InitUserInterface();
+	UI.Load();
+}
+
+/**
+**  Run the guichan main menus loop.
+**
+**  @return          0 for success, else exit.
+*/
+static int MenuLoop()
+{
+	int status;
+
+	initGuichan();
+	InterfaceState = IfaceStateMenu;
+	//  Clear screen
+	Video.ClearScreen();
+	Invalidate();
+
+	ButtonUnderCursor = -1;
+	OldButtonUnderCursor = -1;
+	CursorState = CursorStatePoint;
+	GameCursor = UI.Point.Cursor;
+
+	// FIXME delete this when switching to full guichan GUI
+	const std::string filename = LibraryFileName("scripts/guichan.lua");
+	status = LuaLoadFile(filename);
+
+	// We clean up later in Exit
+	return status;
+}
+
+//----------------------------------------------------------------------------
+
+/**
+**  Print headerline, copyright, ...
+*/
+static void PrintHeader()
+{
+	std::string CompileOptions =
+#ifdef DEBUG
+		"DEBUG "
+#endif
+#ifdef USE_ZLIB
+		"ZLIB "
+#endif
+#ifdef USE_BZ2LIB
+		"BZ2LIB "
+#endif
+#ifdef USE_VORBIS
+		"VORBIS "
+#endif
+#ifdef USE_THEORA
+		"THEORA "
+#endif
+#ifdef USE_FLUIDSYNTH
+		"FLUIDSYNTH "
+#endif
+#ifdef USE_MIKMOD
+		"MIKMOD "
+#endif
+#ifdef USE_MNG
+		"MNG "
+#endif
+#ifdef USE_OPENGL
+		"OPENGL "
+#endif
+#ifdef USE_GLES
+		"GLES "
+#endif
+#ifdef USE_WIN32
+		"WIN32 "
+#endif
+#ifdef USE_LINUX
+		"LINUX "
+#endif
+#ifdef USE_BSD
+		"BSD "
+#endif
+#ifdef USE_BEOS
+		"BEOS "
+#endif
+#ifdef USE_MAC
+		"MAC "
+#endif
+#ifdef USE_X11
+		"X11 "
+#endif
+#ifdef USE_TOUCHSCREEN
+		"TOUCHSCREEN "
+#endif
+		"";
+
+	fprintf(stdout,
+			"%s\n  written by Lutz Sammer, Fabrice Rossi, Vladi Shabanski, Patrice Fortier,\n"
+			"  Jon Gabrielson, Andreas Arens, Nehal Mistry, Jimmy Salmon, Pali Rohar,\n"
+			"  cybermind and others.\n"
+			"\t" HOMEPAGE "\n"
+			"Compile options %s",
+			NameLine, CompileOptions.c_str());
+}
+
+void PrintLicense()
+{
+	printf("\n"
+		   "\n"
+		   "Stratagus may be copied only under the terms of the GNU General Public License\n"
+		   "which may be found in the Stratagus source kit.\n"
+		   "\n"
+		   "DISCLAIMER:\n"
+		   "This software is provided as-is.  The author(s) can not be held liable for any\n"
+		   "damage that might arise from the use of this software.\n"
+		   "Use it at your own risk.\n"
+		   "\n");
+}
+
+
+/**
+**  Exit the game.
+**
+**  @param err  Error code to pass to shell.
+*/
+void Exit(int err)
+{
+	if (GameRunning) {
+		StopGame(GameExit);
+		return;
+	}
+
+	StopMusic();
+	QuitSound();
+	NetworkQuitGame();
+
+	ExitNetwork1();
+	CleanModules();
+	FreeBurningBuildingFrames();
+	FreeSounds();
+	FreeGraphics();
+	FreePlayerColors();
+	FreeButtonStyles();
+	FreeAllContainers();
+	freeGuichan();
+	DebugPrint("Frames %lu, Slow frames %d = %ld%%\n" _C_
+			   FrameCounter _C_ SlowFrameCounter _C_
+			   (SlowFrameCounter * 100) / (FrameCounter ? FrameCounter : 1));
+	lua_settop(Lua, 0);
+	lua_close(Lua);
+	DeInitVideo();
+
+	fprintf(stdout, "%s", _("Thanks for playing Stratagus.\n"));
+	exit(err);
+}
+
+/**
+**  Do a fatal exit.
+**  Called on out of memory or crash.
+**
+**  @param err  Error code to pass to shell.
+*/
+void ExitFatal(int err)
+{
+#ifdef USE_STACKTRACE
+	throw stacktrace::stack_runtime_error((const char*)err);
+#endif
+	exit(err);
+}
+
+/**
+**  Display the usage.
+*/
+static void Usage()
+{
+	PrintHeader();
+	printf(
+		"\n\nUsage: %s [OPTIONS] [map.smp|map.smp.gz]\n"
+		"\t-a\t\tEnables asserts check in engine code (for debugging)\n"
+		"\t-c file.lua\tConfiguration start file (default stratagus.lua)\n"
+		"\t-d datapath\tPath to stratagus data (default current directory)\n"
+		"\t-D depth\tVideo mode depth = pixel per point\n"
+		"\t-e\t\tStart editor (instead of game)\n"
+		"\t-E file.lua\tEditor configuration start file (default editor.lua)\n"
+		"\t-F\t\tFull screen video mode\n"
+		"\t-G \"options\"\tGame options (passed to game scripts)\n"
+		"\t-h\t\tHelp shows this page\n"
+		"\t-i\t\tEnables unit info dumping into log (for debugging)\n"
+		"\t-I addr\t\tNetwork address to use\n"
+		"\t-l\t\tDisable command log\n"
+		"\t-N name\t\tName of the player\n"
+#if defined(USE_OPENGL) || defined(USE_GLES)
+		"\t-o\t\tDo not use OpenGL or OpenGL ES 1.1\n"
+		"\t-O\t\tUse OpenGL or OpenGL ES 1.1\n"
+#endif
+		"\t-p\t\tEnables debug messages printing in console\n"
+		"\t-P port\t\tNetwork port to use\n"
+		"\t-s sleep\tNumber of frames for the AI to sleep before it starts\n"
+		"\t-S speed\tSync speed (100 = 30 frames/s)\n"
+		"\t-u userpath\tPath where stratagus saves preferences, log and savegame\n"
+		"\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n"
+		"\t-W\t\tWindowed video mode\n"
+#if defined(USE_OPENGL) || defined(USE_GLES)
+		"\t-x idx\t\tControls fullscreen scaling if your graphics card supports shaders.\n"\
+		"\t  \t\tPass 1 for nearest-neigubour, 2 for EPX/AdvMame, 3 for HQx, 4 for SAL, 5 for SuperEagle\n"\
+		"\t  \t\tYou can also use Ctrl+Alt+/ to cycle between these scaling algorithms at runtime.\n"
+		"\t  \t\tPass -1 to force old-school nearest neighbour scaling without shaders\n"\
+		"\t-Z\t\tUse OpenGL to scale the screen to the viewport (retro-style). Implies -O.\n"
+#endif
+		"map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n",
+		Parameters::Instance.applicationName.c_str());
+}
+
+#ifdef REDIRECT_OUTPUT
+
+static std::string stdoutFile;
+static std::string stderrFile;
+
+static void CleanupOutput()
+{
+	fclose(stdout);
+	fclose(stderr);
+
+	struct stat st;
+	if (stat(stdoutFile.c_str(), &st) == 0 && st.st_size == 0) {
+		unlink(stdoutFile.c_str());
+	}
+	if (stat(stderrFile.c_str(), &st) == 0 && st.st_size == 0) {
+		unlink(stderrFile.c_str());
+	}
+}
+
+static void RedirectOutput()
+{
+	std::string path = Parameters::Instance.GetUserDirectory();
+
+	makedir(path.c_str(), 0777);
+
+	stdoutFile = path + "\\stdout.txt";
+	stderrFile = path + "\\stderr.txt";
+
+	if (!freopen(stdoutFile.c_str(), "w", stdout)) {
+		printf("freopen stdout failed");
+	}
+	if (!freopen(stderrFile.c_str(), "w", stderr)) {
+		printf("freopen stderr failed");
+	}
+	atexit(CleanupOutput);
+}
+#endif
+
+void ParseCommandLine(int argc, char **argv, Parameters &parameters)
+{
+	for (;;) {
+		switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z?-")) {
+			case 'a':
+				EnableAssert = true;
+				continue;
+			case 'c':
+				parameters.luaStartFilename = optarg;
+				if (strlen(optarg) > 4 &&
+				    !(strstr(optarg, ".lua") == optarg + strlen(optarg) - 4)) {
+					parameters.luaStartFilename += ".lua";
+				}
+				continue;
+			case 'd': {
+				StratagusLibPath = optarg;
+				size_t index;
+				while ((index = StratagusLibPath.find('\\')) != std::string::npos) {
+					StratagusLibPath[index] = '/';
+				}
+				continue;
+			}
+			case 'D':
+				Video.Depth = atoi(optarg);
+				continue;
+			case 'e':
+				Editor.Running = EditorCommandLine;
+				continue;
+			case 'E':
+				parameters.luaEditorStartFilename = optarg;
+				continue;
+			case 'F':
+				VideoForceFullScreen = 1;
+				Video.FullScreen = 1;
+				continue;
+			case 'G':
+				parameters.luaScriptArguments = optarg;
+				continue;
+			case 'i':
+				EnableUnitDebug = true;
+				continue;
+			case 'I':
+				CNetworkParameter::Instance.localHost = optarg;
+				continue;
+			case 'l':
+				CommandLogDisabled = true;
+				continue;
+			case 'N':
+				parameters.LocalPlayerName = optarg;
+				continue;
+#if defined(USE_OPENGL) || defined(USE_GLES)
+			case 'o':
+				ForceUseOpenGL = 1;
+				UseOpenGL = 0;
+				if (ZoomNoResize) {
+					fprintf(stderr, "Error: -Z only works with OpenGL enabled\n");
+					Usage();
+					ExitFatal(-1);
+				}
+				continue;
+			case 'O':
+				ForceUseOpenGL = 1;
+				UseOpenGL = 1;
+				continue;
+#endif
+			case 'P':
+				CNetworkParameter::Instance.localPort = atoi(optarg);
+				continue;
+			case 'p':
+				EnableDebugPrint = true;
+				continue;
+			case 's':
+				AiSleepCycles = atoi(optarg);
+				continue;
+			case 'S':
+				VideoSyncSpeed = atoi(optarg);
+				continue;
+			case 'u':
+				Parameters::Instance.SetUserDirectory(optarg);
+				continue;
+			case 'v': {
+				char *sep = strchr(optarg, 'x');
+				if (!sep || !*(sep + 1)) {
+					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
+					Usage();
+					ExitFatal(-1);
+				}
+				Video.Height = atoi(sep + 1);
+				*sep = 0;
+				Video.Width = atoi(optarg);
+				if (!Video.Height || !Video.Width) {
+					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%sx%s'\n", argv[0], optarg, sep + 1);
+					Usage();
+					ExitFatal(-1);
+				}
+#if defined(USE_OPENGL) || defined(USE_GLES)
+				if (ZoomNoResize) {
+					Video.ViewportHeight = Video.Height;
+					Video.ViewportWidth = Video.Width;
+					Video.Height = 0;
+					Video.Width = 0;
+				}
+#endif
+				continue;
+			}
+			case 'W':
+				VideoForceFullScreen = 1;
+				Video.FullScreen = 0;
+				continue;
+#if defined(USE_OPENGL) || defined(USE_GLES)
+			case 'x':
+				ShaderIndex = atoi(optarg) % MAX_SHADERS;
+				if (atoi(optarg) == -1) {
+					GLShaderPipelineSupported = false;
+				}
+				continue;
+			case 'Z':
+				ForceUseOpenGL = 1;
+				UseOpenGL = 1;
+				ZoomNoResize = 1;
+				Video.ViewportHeight = Video.Height;
+				Video.ViewportWidth = Video.Width;
+				Video.Height = 0;
+				Video.Width = 0;
+				continue;
+#endif
+			case -1:
+				break;
+			case '?':
+			case 'h':
+			default:
+				Usage();
+				ExitFatal(-1);
+		}
+		break;
+	}
+
+	if (argc - optind > 1) {
+		fprintf(stderr, "too many map files. if you meant to pass game arguments, these go after '--'\n");
+		Usage();
+		ExitFatal(-1);
+	}
+
+	if (argc - optind) {
+		size_t index;
+		CliMapName = argv[optind];
+		while ((index = CliMapName.find('\\')) != std::string::npos) {
+			CliMapName[index] = '/';
+		}
+	}
+}
+
+#ifdef USE_WIN32
+static LONG WINAPI CreateDumpFile(EXCEPTION_POINTERS *ExceptionInfo)
+{
+	HANDLE hFile = CreateFile("crash.dmp", GENERIC_READ | GENERIC_WRITE,	FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,	NULL);
+	MINIDUMP_EXCEPTION_INFORMATION mei;
+	mei.ThreadId = GetCurrentThreadId();
+	mei.ClientPointers = TRUE;
+	mei.ExceptionPointers = ExceptionInfo;
+	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mei, NULL, NULL);
+	fprintf(stderr, "Stratagus crashed!\n");
+	fprintf(stderr, "A mini dump file \"crash.dmp\" has been created in the Stratagus folder.\n");
+	fprintf(stderr, "Please send it to our bug tracker: https://github.com/Wargus/stratagus/issues\n");
+	fprintf(stderr, "and tell us what caused this bug to occur.\n");
+	return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+/**
+**  The main program: initialise, parse options and arguments.
+**
+**  @param argc  Number of arguments.
+**  @param argv  Vector of arguments.
+*/
+int stratagusMain(int argc, char **argv)
+{
+#ifdef USE_BEOS
+	//  Parse arguments for BeOS
+	beos_init(argc, argv);
+#endif
+#ifdef USE_WIN32
+	SetUnhandledExceptionFilter(CreateDumpFile);
+#endif
+#if defined(USE_WIN32) && ! defined(REDIRECT_OUTPUT)
+	SetupConsole();
+#endif
+	//  Setup some defaults.
+#ifndef MAC_BUNDLE
+	StratagusLibPath = ".";
+#else
+	freopen("/tmp/stdout.txt", "w", stdout);
+	freopen("/tmp/stderr.txt", "w", stderr);
+	// Look for the specified data set inside the application bundle
+	// This should be a subdir of the Resources directory
+	CFURLRef pluginRef = CFBundleCopyResourceURL(CFBundleGetMainBundle(),
+												 CFSTR(MAC_BUNDLE_DATADIR), NULL, NULL);
+	CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef,  kCFURLPOSIXPathStyle);
+	const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding());
+	Assert(pathPtr);
+	StratagusLibPath = pathPtr;
+#endif
+#ifdef USE_STACKTRACE
+	try {
+#endif
+	Parameters &parameters = Parameters::Instance;
+	parameters.SetDefaultValues();
+	parameters.SetLocalPlayerNameFromEnv();
+
+#ifdef REDIRECT_OUTPUT
+	RedirectOutput();
+#endif
+
+	if (argc > 0) {
+		parameters.applicationName = argv[0];
+	}
+
+	// FIXME: Parse options before or after scripts?
+	ParseCommandLine(argc, argv, parameters);
+	// Init the random number generator.
+	InitSyncRand();
+
+	makedir(parameters.GetUserDirectory().c_str(), 0777);
+
+	// Init Lua and register lua functions!
+	InitLua();
+	LuaRegisterModules();
+
+	// Initialise AI module
+	InitAiModule();
+
+	LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
+
+	PrintHeader();
+	PrintLicense();
+
+	// Setup video display
+	InitVideo();
+
+	// Setup sound card
+	if (!InitSound()) {
+		InitMusic();
+	}
+
+#ifndef DEBUG           // For debug it's better not to have:
+	srand(time(NULL));  // Random counter = random each start
+#endif
+
+	//  Show title screens.
+	SetDefaultTextColors(FontYellow, FontWhite);
+	LoadFonts();
+	SetClipping(0, 0, Video.Width - 1, Video.Height - 1);
+	Video.ClearScreen();
+	ShowTitleScreens();
+
+	// Init player data
+	ThisPlayer = NULL;
+	//Don't clear the Players structure as it would erase the allowed units.
+	// memset(Players, 0, sizeof(Players));
+	NumPlayers = 0;
+
+	UnitManager.Init(); // Units memory management
+	PreMenuSetup();     // Load everything needed for menus
+
+	MenuLoop();
+
+	Exit(0);
+#ifdef USE_STACKTRACE
+	} catch (const std::exception &e) {
+		fprintf(stderr, "Stratagus crashed!\n");
+		fprintf(stderr, "Please send this call stack to our bug tracker: https://github.com/Wargus/stratagus/issues\n");
+		fprintf(stderr, "and tell us what caused this bug to occur.\n");
+		fprintf(stderr, " === exception state traceback === \n");
+		fprintf(stderr, "%s", e.what());
+		exit(1);
+	}
+#endif
+	return 0;
+}
+
+//@}
diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp
index 8500d74f4..675ae3c28 100644
--- a/src/video/sdl.cpp
+++ b/src/video/sdl.cpp
@@ -284,6 +284,9 @@ static void InitOpenGL()
 	}
 #endif
 
+
+	glMatrixMode(GL_TEXTURE);
+	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 	glLoadIdentity();
 
@@ -299,8 +302,8 @@ static void InitOpenGL()
 
 #ifdef USE_OPENGL
 	glClearDepth(1.0f);
-
-	if (GLShaderPipelineSupported) {
+
+	if (GLShaderPipelineSupported) {
 		SetupFramebuffer();
 	}
 #endif
@@ -848,7 +851,9 @@ static void SdlDoEvent(const EventCallback &callbacks, SDL_Event &event)
 				&& event.key.keysym.sym == SDLK_SLASH
 				&& event.key.keysym.mod & KMOD_ALT
 				&& event.key.keysym.mod & KMOD_CTRL) {
-				LoadShaders();
+				char shadername[1024] = { '\0' };
+				LoadShaders(shadername);
+				SetMessage(shadername);
 				break;
 			}
 			InputKeyButtonPress(callbacks, SDL_GetTicks(),
@@ -968,11 +973,11 @@ void RealizeVideoMemory()
 		eglSwapBuffers(eglDisplay, eglSurface);
 #endif
 #if defined(USE_OPENGL) || defined(USE_GLES_NATIVE)
-		if (GLShaderPipelineSupported) {
+		if (GLShaderPipelineSupported) {
 			RenderFramebufferToScreen();
 		} else {
 			SDL_GL_SwapBuffers();
-		}
+		}
 #endif
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	} else
diff --git a/src/video/shaders.cpp b/src/video/shaders.cpp
index d568a5c53..488a94ff6 100644
--- a/src/video/shaders.cpp
+++ b/src/video/shaders.cpp
@@ -1,323 +1,10 @@
 #include "stratagus.h"
 #include "video.h"
-#ifdef USE_OPENGL
-const char* vertex_shader = "#version 130\n\
-\n\
-uniform sampler2D u_texture;\n\
-\n\
-void main()\n\
-{\n\
-    gl_TexCoord[0] = gl_MultiTexCoord0;\n\
-	gl_Position = ftransform();\n\
-}";
+#include "iolib.h"
+#include <iostream>
+#include <fstream>
 
-const char* fragment_shaders[MAX_SHADERS] = {
-	// Nearest-neighbour
-	"#version 130\n\
-	\n\
-	uniform sampler2D u_texture;\n\
-	uniform float u_width;\n\
-	uniform float u_height;\n\
-	uniform float u_widthrel;\n\
-	uniform float u_heightrel;\n\
-	void main()\n\
-	{\n\
-		vec4 myColor = texture2D(u_texture, gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel));\n\
-		gl_FragColor = myColor;\n\
-	}",
-	// Scale2x
-	"#version 110\n\
-	\n\
-	uniform sampler2D u_texture;\n\
-	uniform float u_width;\n\
-	uniform float u_height;\n\
-	uniform float u_widthrel;\n\
-	uniform float u_heightrel;\n\
-	\n\
-	void main() {\n\
-		// o = offset, the width of a pixel\n\
-        vec2 texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
-        vec2 textureDimensions = vec2(u_width, u_height);\n\
-		vec2 o = 1.0 / textureDimensions;\n\
-		// texel arrangement\n\
-		// A B C\n\
-		// D E F\n\
-		// G H I\n\
-		vec4 A = texture2D(u_texture, texCoord + vec2( -o.x,  o.y));\n\
-		vec4 B = texture2D(u_texture, texCoord + vec2(    0,  o.y));\n\
-		vec4 C = texture2D(u_texture, texCoord + vec2(  o.x,  o.y));\n\
-		vec4 D = texture2D(u_texture, texCoord + vec2( -o.x,    0));\n\
-		vec4 E = texture2D(u_texture, texCoord + vec2(    0,    0));\n\
-		vec4 F = texture2D(u_texture, texCoord + vec2(  o.x,    0));\n\
-		vec4 G = texture2D(u_texture, texCoord + vec2( -o.x, -o.y));\n\
-		vec4 H = texture2D(u_texture, texCoord + vec2(    0, -o.y));\n\
-		vec4 I = texture2D(u_texture, texCoord + vec2(  o.x, -o.y));\n\
-		vec2 p = texCoord * textureDimensions;\n\
-		// p = the position within a pixel [0...1]\n\
-		p = p - floor(p);\n\
-		if (p.x > .5) {\n\
-			if (p.y > .5) {\n\
-				// Top Right\n\
-				gl_FragColor = B == F && B != D && F != H ? F : E;\n\
-			} else {\n\
-				// Bottom Right\n\
-				gl_FragColor = H == F && D != H && B != F ? F : E;\n\
-			}\n\
-		} else {\n\
-			if (p.y > .5) {\n\
-				// Top Left\n\
-				gl_FragColor = D == B && B != F && D != H ? D : E;\n\
-			} else {\n\
-				// Bottom Left\n\
-				gl_FragColor = D == H && D != B && H != F ? D : E;\n\
-			}\n\
-		}\n\
-	}",
-	// HQX
-	"#version 130\n\
-	\n\
-	uniform sampler2D u_texture;\n\
-	uniform float u_width;\n\
-	uniform float u_height;\n\
-	uniform float u_widthrel;\n\
-	uniform float u_heightrel;\n\
-	\n\
-	const float mx = 0.325;      // start smoothing wt.\n\
-	const float k = -0.250;      // wt. decrease factor\n\
-	const float max_w = 0.25;    // max filter weigth\n\
-	const float min_w =-0.05;    // min filter weigth\n\
-	const float lum_add = 0.25;  // effects smoothing \n\
-	\n\
-	void main()\n\
-	{\n\
-	   vec2 v_texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
-	\n\
-	   // hq2x\n\
-	   float x = 0.5 * (1.0 / u_width);\n\
-	   float y = 0.5 * (1.0 / u_height);\n\
-	   vec2 dg1 = vec2( x, y);\n\
-	   vec2 dg2 = vec2(-x, y);\n\
-	   vec2 dx = vec2(x, 0.0);\n\
-	   vec2 dy = vec2(0.0, y);\n\
-	\n\
-	   vec4 TexCoord[5];\n\
-	   TexCoord[0] = vec4(v_texCoord, 0.0, 0.0);\n\
-	   TexCoord[1].xy = TexCoord[0].xy - dg1;\n\
-	   TexCoord[1].zw = TexCoord[0].xy - dy;\n\
-	   TexCoord[2].xy = TexCoord[0].xy - dg2;\n\
-	   TexCoord[2].zw = TexCoord[0].xy + dx;\n\
-	   TexCoord[3].xy = TexCoord[0].xy + dg1;\n\
-	   TexCoord[3].zw = TexCoord[0].xy + dy;\n\
-	   TexCoord[4].xy = TexCoord[0].xy + dg2;\n\
-	   TexCoord[4].zw = TexCoord[0].xy - dx;\n\
-	\n\
-	   vec3 c00 = texture2D(u_texture, TexCoord[1].xy).xyz; \n\
-	   vec3 c10 = texture2D(u_texture, TexCoord[1].zw).xyz; \n\
-	   vec3 c20 = texture2D(u_texture, TexCoord[2].xy).xyz; \n\
-	   vec3 c01 = texture2D(u_texture, TexCoord[4].zw).xyz; \n\
-	   vec3 c11 = texture2D(u_texture, TexCoord[0].xy).xyz; \n\
-	   vec3 c21 = texture2D(u_texture, TexCoord[2].zw).xyz; \n\
-	   vec3 c02 = texture2D(u_texture, TexCoord[4].xy).xyz; \n\
-	   vec3 c12 = texture2D(u_texture, TexCoord[3].zw).xyz; \n\
-	   vec3 c22 = texture2D(u_texture, TexCoord[3].xy).xyz; \n\
-	   vec3 dt = vec3(1.0, 1.0, 1.0);\n\
-	\n\
-	   float md1 = dot(abs(c00 - c22), dt);\n\
-	   float md2 = dot(abs(c02 - c20), dt);\n\
-	\n\
-	   float w1 = dot(abs(c22 - c11), dt) * md2;\n\
-	   float w2 = dot(abs(c02 - c11), dt) * md1;\n\
-	   float w3 = dot(abs(c00 - c11), dt) * md2;\n\
-	   float w4 = dot(abs(c20 - c11), dt) * md1;\n\
-	\n\
-	   float t1 = w1 + w3;\n\
-	   float t2 = w2 + w4;\n\
-	   float ww = max(t1, t2) + 0.0001;\n\
-	\n\
-	   c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);\n\
-	\n\
-	   float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);\n\
-	   float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);\n\
-	\n\
-	   w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);\n\
-	   w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);\n\
-	   w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);\n\
-	   w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);\n\
-	   \n\
-	   gl_FragColor = vec4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1);\n\
-	}",
-	// 2xSAL
-	"#version 130\n\
-	\n\
-	uniform sampler2D u_texture;\n\
-	uniform float u_width;\n\
-	uniform float u_height;\n\
-	uniform float u_widthrel;\n\
-	uniform float u_heightrel;\n\
-	\n\
-	void main()\n\
-	{\n\
-	   vec2 texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
-	   vec2 UL, UR, DL, DR;\n\
-	   float dx = pow(u_width, -1.0) * 0.25;\n\
-	   float dy = pow(u_height, -1.0) * 0.25;\n\
-	   vec3 dt = vec3(1.0, 1.0, 1.0);\n\
-	   UL = texCoord + vec2(-dx, -dy);\n\
-	   UR = texCoord + vec2(dx, -dy);\n\
-	   DL = texCoord + vec2(-dx, dy);\n\
-	   DR = texCoord + vec2(dx, dy);\n\
-	   vec3 c00 = texture2D(u_texture, UL).xyz;\n\
-	   vec3 c20 = texture2D(u_texture, UR).xyz;\n\
-	   vec3 c02 = texture2D(u_texture, DL).xyz;\n\
-	   vec3 c22 = texture2D(u_texture, DR).xyz;\n\
-	   float m1=dot(abs(c00-c22),dt)+0.001;\n\
-	   float m2=dot(abs(c02-c20),dt)+0.001;\n\
-	   gl_FragColor = vec4((m1*(c02+c20)+m2*(c22+c00))/(2.0*(m1+m2)),1.0); \n\
-	}",
-	// SuperEagle
-	"#version 130\n\
-	\n\
-	uniform sampler2D u_texture;\n\
-	uniform float u_width;\n\
-	uniform float u_height;\n\
-	uniform float u_widthrel;\n\
-	uniform float u_heightrel;\n\
-	\n\
-	int GET_RESULT(float A, float B, float C, float D)\n\
-	{\n\
-		int x = 0; int y = 0; int r = 0;\n\
-		if (A == C) x+=1; else if (B == C) y+=1;\n\
-		if (A == D) x+=1; else if (B == D) y+=1;\n\
-		if (x <= 1) r+=1; \n\
-		if (y <= 1) r-=1;\n\
-		return r;\n\
-	} \n\
-	\n\
-	const vec3 dtt = vec3(65536.0,255.0,1.0);\n\
-	\n\
-	float reduce(vec3 color)\n\
-	{ \n\
-		return dot(color, dtt);\n\
-	}\n\
-	\n\
-	void main()\n\
-	{\n\
-	   // get texel size   	\n\
-		vec2 ps = vec2(0.999/u_width, 0.999/u_height);\n\
-	\n\
-		vec2 v_texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
-	\n\
-		// calculating offsets, coordinates\n\
-		vec2 dx = vec2( ps.x, 0.0); \n\
-		vec2 dy = vec2( 0.0, ps.y);\n\
-		vec2 g1 = vec2( ps.x,ps.y);\n\
-		vec2 g2 = vec2(-ps.x,ps.y);	\n\
-		\n\
-		vec2 pixcoord  = v_texCoord/ps;	//VAR.CT\n\
-		vec2 fp        = fract(pixcoord);\n\
-		vec2 pC4       = v_texCoord-fp*ps;\n\
-		vec2 pC8       = pC4+g1;		//VAR.CT\n\
-	\n\
-		// Reading the texels\n\
-		vec3 C0 = texture2D(u_texture,pC4-g1).xyz; \n\
-		vec3 C1 = texture2D(u_texture,pC4-dy).xyz;\n\
-		vec3 C2 = texture2D(u_texture,pC4-g2).xyz;\n\
-		vec3 D3 = texture2D(u_texture,pC4-g2+dx).xyz;\n\
-		vec3 C3 = texture2D(u_texture,pC4-dx).xyz;\n\
-		vec3 C4 = texture2D(u_texture,pC4   ).xyz;\n\
-		vec3 C5 = texture2D(u_texture,pC4+dx).xyz;\n\
-		vec3 D4 = texture2D(u_texture,pC8-g2).xyz;\n\
-		vec3 C6 = texture2D(u_texture,pC4+g2).xyz;\n\
-		vec3 C7 = texture2D(u_texture,pC4+dy).xyz;\n\
-		vec3 C8 = texture2D(u_texture,pC4+g1).xyz;\n\
-		vec3 D5 = texture2D(u_texture,pC8+dx).xyz;\n\
-		vec3 D0 = texture2D(u_texture,pC4+g2+dy).xyz;\n\
-		vec3 D1 = texture2D(u_texture,pC8+g2).xyz;\n\
-		vec3 D2 = texture2D(u_texture,pC8+dy).xyz;\n\
-		vec3 D6 = texture2D(u_texture,pC8+g1).xyz;\n\
-	\n\
-		vec3 p00,p10,p01,p11;\n\
-	\n\
-		// reducing vec3 to float	\n\
-		float c0 = reduce(C0);float c1 = reduce(C1);\n\
-		float c2 = reduce(C2);float c3 = reduce(C3);\n\
-		float c4 = reduce(C4);float c5 = reduce(C5);\n\
-		float c6 = reduce(C6);float c7 = reduce(C7);\n\
-		float c8 = reduce(C8);float d0 = reduce(D0);\n\
-		float d1 = reduce(D1);float d2 = reduce(D2);\n\
-		float d3 = reduce(D3);float d4 = reduce(D4);\n\
-		float d5 = reduce(D5);float d6 = reduce(D6);\n\
-	\n\
-		/*              SuperEagle code               */\n\
-		/*  Copied from the Dosbox source code        */\n\
-		/*  Copyright (C) 2002-2007  The DOSBox Team  */\n\
-		/*  License: GNU-GPL                          */\n\
-		/*  Adapted by guest(r) on 16.4.2007          */       \n\
-		if (c4 != c8) {\n\
-			if (c7 == c5) {\n\
-				p01 = p10 = C7;\n\
-				if ((c6 == c7) || (c5 == c2)) {\n\
-						p00 = 0.25*(3.0*C7+C4);\n\
-				} else {\n\
-						p00 = 0.5*(C4+C5);\n\
-				}\n\
-	\n\
-				if ((c5 == d4) || (c7 == d1)) {\n\
-						p11 = 0.25*(3.0*C7+C8);\n\
-				} else {\n\
-						p11 = 0.5*(C7+C8);\n\
-				}\n\
-			} else {\n\
-				p11 = 0.125*(6.0*C8+C7+C5);\n\
-				p00 = 0.125*(6.0*C4+C7+C5);\n\
-	\n\
-				p10 = 0.125*(6.0*C7+C4+C8);\n\
-				p01 = 0.125*(6.0*C5+C4+C8);\n\
-			}\n\
-		} else {\n\
-			if (c7 != c5) {\n\
-				p11 = p00 = C4;\n\
-	\n\
-				if ((c1 == c4) || (c8 == d5)) {\n\
-						p01 = 0.25*(3.0*C4+C5);\n\
-				} else {\n\
-						p01 = 0.5*(C4+C5);\n\
-				}\n\
-	\n\
-				if ((c8 == d2) || (c3 == c4)) {\n\
-						p10 = 0.25*(3.0*C4+C7);\n\
-				} else {\n\
-						p10 = 0.5*(C7+C8);\n\
-				}\n\
-			} else {\n\
-				int r = 0;\n\
-				r += GET_RESULT(c5,c4,c6,d1);\n\
-				r += GET_RESULT(c5,c4,c3,c1);\n\
-				r += GET_RESULT(c5,c4,d2,d5);\n\
-				r += GET_RESULT(c5,c4,c2,d4);\n\
-	\n\
-				if (r > 0) {\n\
-						p01 = p10 = C7;\n\
-						p00 = p11 = 0.5*(C4+C5);\n\
-				} else if (r < 0) {\n\
-						p11 = p00 = C4;\n\
-						p01 = p10 = 0.5*(C4+C5);\n\
-				} else {\n\
-						p11 = p00 = C4;\n\
-						p01 = p10 = C7;\n\
-				}\n\
-			}\n\
-		}\n\
-	\n\
-		// Distributing the four products	\n\
-		if (fp.x < 0.50)\n\
-			{ if (fp.y < 0.50) p10 = p00;}\n\
-		else\n\
-			{ if (fp.y < 0.50) p10 = p01; else p10 = p11;}\n\
-	\n\
-		gl_FragColor = vec4(p10, 1);\n\
-	}"
-};
+#ifdef USE_OPENGL
 
 #ifndef __APPLE__
 PFNGLCREATESHADERPROC glCreateShader;
@@ -337,7 +24,9 @@ PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
 PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
 PFNGLACTIVETEXTUREPROC glActiveTextureProc;
 PFNGLUNIFORM1FPROC glUniform1f;
+PFNGLUNIFORM2FPROC glUniform2f;
 PFNGLUNIFORM1IPROC glUniform1i;
+PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
 PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffers;
 PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer;
 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture;
@@ -359,11 +48,6 @@ GLuint fullscreenShader;
 GLuint fullscreenFramebuffer = 0;
 GLuint fullscreenTexture;
 
-#ifdef SHADERDEBUG
-#include <iostream>
-#include <fstream>
-#endif
-
 void printShaderInfoLog(GLuint obj, const char* prefix)
 {
 	int infologLength = 0;
@@ -399,48 +83,60 @@ void printProgramInfoLog(GLuint obj, const char* prefix)
 
 unsigned ShaderIndex = 0;
 
-extern bool LoadShaders() {
+extern bool LoadShaders(char* shadernameOut) {
 	GLuint vs, fs;
 	GLint params;
 	fs = glCreateShader(GL_FRAGMENT_SHADER);
 	if (fs == 0) {
 	    return false;
 	}
-#ifdef SHADERDEBUG
-	std::ifstream myfile("fragment.txt");
+
+	std::vector<FileList> flp;
+	int n = ReadDataDirectory(".", flp);
+	int numShaderFiles = 0;
+	int shaderFileToIdx[1024];
+	for (int i = 0; i < n; ++i) {
+		int pos = flp[i].name.find(".glsl");
+		if (pos > 0) {
+			shaderFileToIdx[numShaderFiles] = i;
+			numShaderFiles++;
+		}
+	}
+	if (numShaderFiles <= 0) return false;
+	if (numShaderFiles <= ShaderIndex) {
+		ShaderIndex = ShaderIndex % numShaderFiles;
+	}
+
+	if (shadernameOut) {
+		strncpy(shadernameOut, flp[shaderFileToIdx[ShaderIndex]].name.c_str(), 1023);
+	}
+	std::ifstream myfile(flp[shaderFileToIdx[ShaderIndex]].name);
 	std::string contents((std::istreambuf_iterator<char>(myfile)),
 						  std::istreambuf_iterator<char>());
-	const char* f = contents.c_str();
-	glShaderSource(fs, 1, &f, NULL);
 	myfile.close();
-#else
-	glShaderSource(fs, 1, (const char**)&(fragment_shaders[ShaderIndex]), NULL);
-#endif
+	ShaderIndex++;
+
+	const char *fragmentSrc[2] = { "#define FRAGMENT\n", contents.c_str() };
+	const char *vertexSrc[2] = { "#define VERTEX\n", contents.c_str() };
+
+	glShaderSource(fs, 2, fragmentSrc, NULL);
 	glCompileShader(fs);
 	glGetShaderiv(fs, GL_COMPILE_STATUS, &params);
 	if (params == GL_FALSE) {
-#ifdef SHADERDEBUG
 		printShaderInfoLog(fs, "Fragment Shader");
-#endif
 		glDeleteShader(fs);
 		return false;
 	}
-	ShaderIndex = (ShaderIndex + 1) % MAX_SHADERS;
 	vs = glCreateShader(GL_VERTEX_SHADER);
 	if (fs == 0) {
-#ifdef SHADERDEBUG
-		printShaderInfoLog(fs, "Fragment Shader");
-#endif
 		glDeleteShader(fs);
 		return false;
 	}
-	glShaderSource(vs, 1, (const char**)&vertex_shader, NULL);
+	glShaderSource(vs, 2, vertexSrc, NULL);
 	glCompileShader(vs);
 	glGetShaderiv(fs, GL_COMPILE_STATUS, &params);
 	if (params == GL_FALSE) {
-#ifdef SHADERDEBUG
 		printShaderInfoLog(vs, "Vertex Shader");
-#endif
 		glDeleteShader(fs);
 		glDeleteShader(vs);
 		return false;
@@ -459,9 +155,7 @@ extern bool LoadShaders() {
 	glLinkProgram(fullscreenShader);
 	glGetProgramiv(fullscreenShader, GL_LINK_STATUS, &params);
 	if (params == GL_FALSE) {
-#ifdef SHADERDEBUG
 		printProgramInfoLog(fullscreenShader, "Shader Program");
-#endif
 		glDeleteShader(fs);
 		glDeleteShader(vs);
 		glDeleteProgram(fullscreenShader);
@@ -492,7 +186,9 @@ extern bool LoadShaderExtensions() {
 	glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetUniformLocation");
 	glActiveTextureProc = (PFNGLACTIVETEXTUREPROC)(uintptr_t)SDL_GL_GetProcAddress("glActiveTexture");
 	glUniform1f = (PFNGLUNIFORM1FPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniform1f");
+	glUniform2f = (PFNGLUNIFORM2FPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniform2f");
 	glUniform1i = (PFNGLUNIFORM1IPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniform1i");
+	glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniformMatrix4fv");
 
 	glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glGenFramebuffers");
 	glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glBindFramebuffer");
@@ -504,7 +200,7 @@ extern bool LoadShaderExtensions() {
 	glDrawBuffers = (PFNGLDRAWBUFFERSPROC)(uintptr_t)SDL_GL_GetProcAddress("glDrawBuffers");
 	glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glCheckFramebufferStatus");
 	if (glCreateShader && glGenFramebuffers && glGetUniformLocation && glActiveTextureProc) {
-		return LoadShaders();
+		return LoadShaders(NULL);
 	} else {
 		return false;
 	}
@@ -536,27 +232,40 @@ extern void RenderFramebufferToScreen() {
 	glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
 	// setup our shader program
 	glUseProgram(fullscreenShader);
-	GLint textureloc = glGetUniformLocation(fullscreenShader, "u_texture");
-	GLint widthloc = glGetUniformLocation(fullscreenShader, "u_width");
-	GLint heightloc = glGetUniformLocation(fullscreenShader, "u_height");
-	GLint widthrelloc = glGetUniformLocation(fullscreenShader, "u_widthrel");
-	GLint heightrelloc = glGetUniformLocation(fullscreenShader, "u_heightrel");
-	glUniform1f(widthloc, Video.ViewportWidth);
-	glUniform1f(heightloc, Video.ViewportHeight);
-	glUniform1f(widthrelloc, (float)Video.Width / (float)Video.ViewportWidth);
-	glUniform1f(heightrelloc, (float)Video.Height / (float)Video.ViewportHeight);
-	glUniform1i(textureloc, 0);
+
+	// These are the default uniforms for glsl converted libretro shaders
+	GLint Texture = glGetUniformLocation(fullscreenShader, "Texture");
+	GLint MVPMatrix = glGetUniformLocation(fullscreenShader, "MVPMatrix");
+	GLint FrameDirection = glGetUniformLocation(fullscreenShader, "FrameDirection");
+	GLint FrameCount = glGetUniformLocation(fullscreenShader, "FrameCount");
+	GLint OutputSize = glGetUniformLocation(fullscreenShader, "OutputSize");
+	GLint TextureSize = glGetUniformLocation(fullscreenShader, "TextureSize");
+	GLint InputSize = glGetUniformLocation(fullscreenShader, "InputSize");
+
+	glUniform1i(Texture, 0);
+	GLfloat matrix[4 * 4];
+	glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
+	glUniformMatrix4fv(MVPMatrix, 1, GL_FALSE, matrix);
+	glUniform1f(FrameDirection, 1);
+	glUniform1f(FrameCount, 1);
+	glUniform2f(OutputSize, (float)Video.ViewportWidth, (float)Video.ViewportHeight);
+	glUniform2f(TextureSize, (float)Video.ViewportWidth, (float)Video.ViewportHeight);
+	glUniform2f(InputSize, (float)Video.Width, (float)Video.Height);
+
+	float widthRel = (float)Video.Width / Video.ViewportWidth;
+	float heightRel = (float)Video.Height / Video.ViewportHeight;
+
 	glActiveTextureProc(GL_TEXTURE0);
 	// render the framebuffer texture to a fullscreen quad on the real display
 	glBindTexture(GL_TEXTURE_2D, fullscreenTexture);
 	glBegin(GL_QUADS);
-	glTexCoord2f(0, 0);
-	glVertex2i(0, 0);
-	glTexCoord2f(1, 0);
-	glVertex2i(Video.ViewportWidth, 0);
-	glTexCoord2f(1, 1);
-	glVertex2i(Video.ViewportWidth, Video.ViewportHeight);
 	glTexCoord2f(0, 1);
+	glVertex2i(0, 0);
+	glTexCoord2f(widthRel, 1);
+	glVertex2i(Video.ViewportWidth, 0);
+	glTexCoord2f(widthRel, 1 - heightRel);
+	glVertex2i(Video.ViewportWidth, Video.ViewportHeight);
+	glTexCoord2f(0, 1 - heightRel);
 	glVertex2i(0, Video.ViewportHeight);
 	glEnd();
 	SDL_GL_SwapBuffers();