From 96256f45ce10f8cc03f4fbdeccf89b905d00a9e7 Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
Date: Fri, 25 Jan 2013 11:38:58 +0000
Subject: [PATCH] build: use our own main() wrapper in addition to SDL's, and
 only in that case. Currently only works with GCC.

---
 configure.ac                |  3 ++-
 src/core.h                  |  9 +++++++--
 src/platform/sdl/sdlapp.cpp | 31 +++++++++++++++++++++++++++++++
 test/math/Makefile.am       |  2 +-
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1ebda4f4..2cf4b717 100644
--- a/configure.ac
+++ b/configure.ac
@@ -197,7 +197,8 @@ AC_MSG_CHECKING(for -mwindows -mwin32)
 AC_TRY_LINK([], [],
  [AC_MSG_RESULT(yes)
   CXXFLAGS="${CXXFLAGS} -mwindows -mwin32"
-  LOL_LIBS="${LOL_LIBS} -uWinMain -u_WinMain@16"],
+  dnl  If we come across these symbols, try to link them
+  LOL_LIBS="${LOL_LIBS} -uWinMain -u_WinMain@16 -u_SDL_main"],
  [AC_MSG_RESULT(no)])
 LIBS="$LIBS_save"
 
diff --git a/src/core.h b/src/core.h
index c56fd78a..b0a8e522 100644
--- a/src/core.h
+++ b/src/core.h
@@ -68,9 +68,14 @@ static inline int isnan(float f)
 #   define main lol_android_main
 #endif
 
-/* If using SDL on Windows or OS X, let it override main() */
-#if defined USE_SDL && (defined _WIN32 || defined __APPLE__)
+/* If using SDL, let it override main() but immediately replace
+ * the override with ours. */
+#if defined USE_SDL
 #   include <SDL_main.h>
+#   if defined main && !LOL_DONT_DIVERT_MAIN
+#       undef main
+#       define main lol_sdl_main
+#   endif
 #endif
 
 // Base types
diff --git a/src/platform/sdl/sdlapp.cpp b/src/platform/sdl/sdlapp.cpp
index 83d8a095..6bcfba6f 100644
--- a/src/platform/sdl/sdlapp.cpp
+++ b/src/platform/sdl/sdlapp.cpp
@@ -12,6 +12,10 @@
 #   include "config.h"
 #endif
 
+/* This instructs our headers to let SDL override the "main"
+ * symbol using its macros. */
+#define LOL_DONT_DIVERT_MAIN 1
+
 #if defined USE_SDL
 #   if defined HAVE_SDL_SDL_H
 #      include <SDL/SDL.h>
@@ -37,6 +41,33 @@ HWND g_hwnd = NULL;
 extern IDirect3DDevice9 *g_d3ddevice;
 #endif
 
+#if defined main
+#   if defined _MSC_VER
+#       pragma comment(linker, "/alternatename:_lol_sdl_main=_lol_sdl_main_msvc")
+#       define WRAPPER lol_sdl_main_msvc
+#   else
+int lol_sdl_main() __attribute__((weak));
+int lol_sdl_main(int argc, char **argv) __attribute__((weak));
+int lol_sdl_main(int argc, char **argv, char **envp) __attribute__((weak));
+#       define WRAPPER lol_sdl_main
+#   endif
+
+/* One of these wrappers will be overridden by the user's version */
+int WRAPPER() { return 0; }
+int WRAPPER(int argc, char **argv) { return 0; }
+int WRAPPER(int argc, char **argv, char **envp) { return 0; }
+
+int main(int argc, char *argv[])
+{
+printf("LOL OK\n");
+    int ret = 0;
+    ret += lol_sdl_main();
+    ret += lol_sdl_main(argc, argv);
+    ret += lol_sdl_main(argc, argv, NULL);
+    return ret;
+}
+#endif
+
 namespace lol
 {
 
diff --git a/test/math/Makefile.am b/test/math/Makefile.am
index 9cac90db..1cb4295c 100644
--- a/test/math/Makefile.am
+++ b/test/math/Makefile.am
@@ -9,7 +9,7 @@ noinst_PROGRAMS = pi poly remez
 
 pi_SOURCES = pi.cpp
 pi_CPPFLAGS = @LOL_CFLAGS@
-pi_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@
+pi_LDFLAGS = -u_SDL_main -uSDL_main $(top_builddir)/src/liblol.a @LOL_LIBS@
 pi_DEPENDENCIES = $(top_builddir)/src/liblol.a
 
 poly_SOURCES = poly.cpp