Index: /Daodan/build.bat
===================================================================
--- /Daodan/build.bat	(revision 296)
+++ /Daodan/build.bat	(revision 297)
@@ -1,1 +1,1 @@
-gcc -O3 -s -Wall -shared -fomit-frame-pointer -o build\binkw32.dll src\Oni_Symbols.S src\Daodan.c src\Daodan_DLLStubs.c src\Daodan_Patch.c src\Daodan_Utility.c
+gcc -O3 -s -Wall -shared -fomit-frame-pointer -o build\binkw32.dll src\Oni_Symbols.S src\Daodan.c src\Daodan_DLLStubs.c src\Daodan_Patch.c src\Daodan_Utility.c src\daodan_gl.c
Index: /Daodan/src/BFW_Motoko_Draw.h
===================================================================
--- /Daodan/src/BFW_Motoko_Draw.h	(revision 297)
+++ /Daodan/src/BFW_Motoko_Draw.h	(revision 297)
@@ -0,0 +1,15 @@
+#pragma once
+#ifndef BFW_MOTOKO_DRAW_H
+#define BFW_MOTOKO_DRAW_H
+
+#include "Daodan.h"
+
+typedef struct
+{
+	short Width;
+	short Height;
+	short Depth;
+	short __unused;
+} M3tDisplayMode;
+
+#endif
Index: /Daodan/src/Daodan.c
===================================================================
--- /Daodan/src/Daodan.c	(revision 296)
+++ /Daodan/src/Daodan.c	(revision 297)
@@ -5,4 +5,7 @@
 #include "Oni.h"
 #include "BFW_Utility.h"
+
+#include "oni_gl.h"
+#include "daodan_gl.h"
 
 HMODULE DDrDLLModule;
@@ -42,4 +45,7 @@
 	DDrPatch_Int16 (OniExe + 0x0011ab0e, 0x12c0);
 	
+	// Patch for alt-tab and the start menu
+	DDrPatch_Byte  (OniExe + 0x00026010, 0xC3);
+	
 	// Hackish fix for Konoko not kicking guns
 //	const char kickgun_patch[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0xC7, 0x05, 0x1C, 0xC9, 0x5E, 0x00, 0x70, 0xB8, 0x43, 0x00, 0xC7, 0x05, 0x20, 0xC9, 0x5E, 0x00, 0x20, 0xBE, 0x43 };
@@ -63,5 +69,8 @@
 	DDrPatch_MakeJump(UUrStartupMessage, DDrStartupMessage);
 	
-	// Test performance patch
+	// Daodan device mode enumeration function
+	DDrPatch_MakeJump(gl_enumerate_valid_display_modes, daodan_enumerate_valid_display_modes);
+	
+	// Performance patch
 	DDrPatch_MakeJump(UUrMachineTime_High, DDrMachineTime_High);
 	DDrPatch_MakeJump(UUrMachineTime_High_Frequency, DDrMachineTime_High_Frequency);
Index: /Daodan/src/Daodan_Persistence.h
===================================================================
--- /Daodan/src/Daodan_Persistence.h	(revision 297)
+++ /Daodan/src/Daodan_Persistence.h	(revision 297)
@@ -0,0 +1,7 @@
+#pragma once
+#ifndef DAODAN_PERSISTENCE_H
+#define DAODAN_PERSISTENCE_H
+
+onibool ONICALL (*DDrPersist_GetWonGame)();
+
+#endif
Index: /Daodan/src/Daodan_Utility.c
===================================================================
--- /Daodan/src/Daodan_Utility.c	(revision 296)
+++ /Daodan/src/Daodan_Utility.c	(revision 297)
@@ -28,5 +28,5 @@
 }
 
-int64_t DDrMachineTime_Sixtieths()
+int64_t ONICALL DDrMachineTime_Sixtieths()
 {
 	static int64_t LastTime, Time;
@@ -46,5 +46,5 @@
 }
 
-int64_t DDrMachineTime_High()
+int64_t ONICALL DDrMachineTime_High()
 {
 //	LARGE_INTEGER PerfCount;
@@ -57,5 +57,5 @@
 }
 
-double DDrMachineTime_High_Frequency()
+double ONICALL DDrMachineTime_High_Frequency()
 {
 //	LARGE_INTEGER Frequency;
Index: /Daodan/src/Oni_Symbols.S
===================================================================
--- /Daodan/src/Oni_Symbols.S	(revision 296)
+++ /Daodan/src/Oni_Symbols.S	(revision 297)
@@ -2,19 +2,22 @@
 
 // MSVC6.0 stdlib
-symbol ( _oni_malloc                      , 0x0011fc24 )
-symbol ( _oni_free                        , 0x0011fbf5 )
+symbol ( _oni_malloc                         , 0x0011fc24 )
+symbol ( _oni_free                           , 0x0011fbf5 )
 
-symbol ( _oni_fopen                       , 0x0011ea9f )
-symbol ( _oni_fflush                      , 0x0011eab2 )
-symbol ( _oni_fprintf                     , 0x0011ebbf )
-symbol ( _oni_vsprintf                    , 0x0011e860 )
+symbol ( _oni_fopen                          , 0x0011ea9f )
+symbol ( _oni_fflush                         , 0x0011eab2 )
+symbol ( _oni_fprintf                        , 0x0011ebbf )
+symbol ( _oni_vsprintf                       , 0x0011e860 )
 
 // Oni Engine
-symbol ( _ONiMain                         , 0x000d3280 )
+symbol ( _ONiMain                            , 0x000d3280 )
 
 // BFW_Utility
-symbol ( _UUrStartupMessage               , 0x00024860 )
-symbol ( @UUrMachineTime_High@0           , 0x00026480 )
-symbol ( @UUrMachineTime_High_Frequency@0 , 0x000264b0 )
-symbol ( @UUrMachineTime_Sixtieths@0      , 0x000263e0 )
-symbol ( _ONgFileStartup                  , 0x001711b8 )
+symbol ( _UUrStartupMessage                  , 0x00024860 )
+symbol ( @UUrMachineTime_High@0              , 0x00026480 )
+symbol ( @UUrMachineTime_High_Frequency@0    , 0x000264b0 )
+symbol ( @UUrMachineTime_Sixtieths@0         , 0x000263e0 )
+symbol ( _ONgFileStartup                     , 0x001711b8 )
+
+// OpenGL
+symbol ( @gl_enumerate_valid_display_modes@4 , 0x000083a0 )
Index: /Daodan/src/daodan_gl.c
===================================================================
--- /Daodan/src/daodan_gl.c	(revision 297)
+++ /Daodan/src/daodan_gl.c	(revision 297)
@@ -0,0 +1,46 @@
+#include "daodan_gl.h"
+
+#define maxmodes (104) // Dirty hack to add more resolutions, it really should only be 16 ^_^
+
+const M3tDisplayMode daodan_reslist[] = {
+	{ 640,  480,  0, 0 },
+	{ 800,  600,  0, 0 },
+	{ 1024, 768,  0, 0 },
+	{ 1280, 1024, 0, 0 },
+	{ 1600, 1200, 0, 0 },
+	{ 1920, 1080, 0, 0 },
+};
+
+const short daodan_resmodes[] = { 16, 32 };
+
+unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[maxmodes])
+{
+	unsigned int vmodes = 0;
+	unsigned int screen_x = GetSystemMetrics(SM_CXSCREEN);
+	unsigned int screen_y = GetSystemMetrics(SM_CYSCREEN);
+	
+	int i, j;
+	
+	for (i = 0; i < sizeof(daodan_resmodes) / sizeof(short); i ++)
+	{
+		for (j = 0; j < sizeof(daodan_reslist) / sizeof(M3tDisplayMode); j ++)
+			if (modes[vmodes].Width != screen_x && modes[vmodes].Height != screen_y)
+			{
+				modes[vmodes].Width  = daodan_reslist[j].Width;
+				modes[vmodes].Height = daodan_reslist[j].Height;
+				modes[vmodes].Depth  = daodan_resmodes[i];
+				
+				if (++vmodes == maxmodes - sizeof(daodan_reslist) / sizeof(M3tDisplayMode) + i)
+					goto modesfull;
+			}
+		
+		modes[vmodes].Width  = GetSystemMetrics(SM_CXSCREEN);
+		modes[vmodes].Height = GetSystemMetrics(SM_CYSCREEN);
+		modes[vmodes].Depth  = daodan_resmodes[i];
+		if (++vmodes == maxmodes - sizeof(daodan_reslist) / sizeof(M3tDisplayMode) + i)
+			goto modesfull;
+	}
+	
+	modesfull:
+	return vmodes;
+}
Index: /Daodan/src/daodan_gl.h
===================================================================
--- /Daodan/src/daodan_gl.h	(revision 297)
+++ /Daodan/src/daodan_gl.h	(revision 297)
@@ -0,0 +1,10 @@
+#pragma once
+#ifndef DAODAN_GL_H
+#define DAODAN_GL_H
+
+#include "Daodan.h"
+#include "BFW_Motoko_Draw.h"
+
+unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[16]);
+
+#endif
Index: /Daodan/src/oni_gl.h
===================================================================
--- /Daodan/src/oni_gl.h	(revision 297)
+++ /Daodan/src/oni_gl.h	(revision 297)
@@ -0,0 +1,10 @@
+#pragma once
+#ifndef ONI_GL_H
+#define ONI_GL_H
+
+#include "Daodan.h"
+#include "BFW_Motoko_Draw.h"
+
+unsigned int ONICALL gl_enumerate_valid_display_modes(M3tDisplayMode modes[16]);
+
+#endif
