Index: Daodan/src/BFW_Motoko_Draw.h
===================================================================
--- Daodan/src/BFW_Motoko_Draw.h	(revision 694)
+++ Daodan/src/BFW_Motoko_Draw.h	(revision 705)
@@ -2,5 +2,5 @@
 #define BFW_MOTOKO_DRAW_H
 
-typedef struct
+typedef struct M3tDisplayMode
 {
 	unsigned short Width;
@@ -8,16 +8,24 @@
 	unsigned short Depth;
 	unsigned short __unused;
-} M3tDisplayMode;
+} M3tDisplayMode;						// 0x0010: (size).
 
-typedef struct
+typedef struct M3tDisplayDevice
 {
-	int Type;
-	char Name[64];
-	char a[64];
-	int b, c, d;
-	short DisplayModeCount;
-	M3tDisplayMode DisplayModes[12];
-	char e[990];
-} M3tDrawEngineCaps;
+	unsigned int __unknown;				// 
+	unsigned short NumModes;			// 0x0004: number of valid display modes on this device.
+	M3tDisplayMode Modes[16];			// 0x0006: list of supported display modes.
+	unsigned short __padding;			// 0x0086: padding (not used).
+} M3tDisplayDevice;						// 0x0088: (size).
+ 
+typedef struct M3tDrawEngineCaps
+{
+	int Type;							// 0x0000:
+	char Name[64];						// 0x0004: draw engine name (eg. "OpenGL").
+	char Driver[64];					// 0x0044: driver name (always NULL string).
+	unsigned int Version;				// 0x0084: draw engine version (1 for OpenGL).
+	unsigned int NumDevices;			// 0x0088: number of valid DisplayDevice-s.
+	M3tDisplayDevice DisplayDevices[8];	// 0x008c: 1 or more display devices.
+	int __unknown;						// 0x04cc:
+} M3tDrawEngineCaps;					// 0x04d0: (size).
 
 typedef struct
Index: Daodan/src/BFW_ScriptLang.h
===================================================================
--- Daodan/src/BFW_ScriptLang.h	(revision 694)
+++ Daodan/src/BFW_ScriptLang.h	(revision 705)
@@ -19,5 +19,5 @@
 		char*   value_str32;
 		float   value_float;
-		bool    value_bool;
+		char    value_bool;
 	} val;
 } sl_arg;
Index: Daodan/src/Daodan.c
===================================================================
--- Daodan/src/Daodan.c	(revision 694)
+++ Daodan/src/Daodan.c	(revision 705)
@@ -10,5 +10,4 @@
 #include "Daodan_BSL.h"
 #include "Daodan_Console.h"
-#include "Daodan_WindowHack.h"
 
 #include "Oni.h"
@@ -42,10 +41,11 @@
 bool patch_optionsvisible = true;
 
+bool patch_binkplay = true;
 bool patch_safeprintf = true;
 bool patch_daodandisplayenum = true;
 bool patch_usegettickcount = true;
 bool patch_cheatsenabled = true;
-bool patch_usedaodangl = false;
-bool patch_windowhack = true;
+bool patch_usedaodangl = true;
+bool patch_clipcursor = true;
 bool patch_daodaninit = true;
 bool patch_bsl = true;
@@ -55,11 +55,19 @@
 bool opt_border = true;
 bool opt_topmost = false;
-
-typedef int (__cdecl *CHINESEPROC)(DWORD WINAPI); 
-bool patch_chinese = false;
-
-
-
-void ONICALL DDrShowResumeButton(int window, int visibility)
+bool opt_gamma = true;
+
+typedef int (__cdecl *CHINESEPROC)(DWORD ThreadId); 
+bool patch_chinese = true;
+
+
+// Hooked WMrSlider_SetRange() in ONiOGU_Options_InitDialog. Disables a gamma
+// slider in windowed mode.
+static void ONICALL DD_ONiOGU_GammaSlider_SetRange(WMtWindow* window, int min_value, int max_value)
+{
+	WMrWindow_SetEnabled(window, M3gResolutionSwitch && opt_gamma);
+	WMrSlider_SetRange(window, min_value, max_value);
+}
+ 
+void ONICALL DDrShowResumeButton(WMtWindow* window, int visibility)
 {
 	if (visibility)
@@ -70,5 +78,5 @@
 
 /* Options always visible patch */
-void ONICALL DDrShowOptionsButton(int window, int visibility)
+void ONICALL DDrShowOptionsButton(WMtWindow* window, int visibility)
 {
 	WMrWindow_SetVisible(window, 1);
@@ -255,8 +263,10 @@
 	if(patch_chinese)
 	{
-		DDrStartupMessage("Loading chinese DLL");
-		HMODULE dll = LoadLibrary("xfhsm_oni.dll");
-		DWORD err = GetLastError();
-		DDrStartupMessage(" - Module loading returned error %i", err);
+		HMODULE dll;
+		DWORD err;
+
+ 		DDrStartupMessage("Loading chinese DLL");
+		dll = LoadLibrary("xfhsm_oni.dll");
+		err = GetLastError();
 		if( dll )
 		{
@@ -266,4 +276,8 @@
 				((CHINESEPROC)proc)(GetCurrentThreadId());
 			}
+		} else {
+			char msg[100];
+			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, msg, 100, NULL);
+			DDrStartupMessage(" - Module loading failed with error %i: %s", err, msg);
 		}
 	}
@@ -311,4 +325,21 @@
 		DDrPatch_MakeCall((void*)(OniExe + 0x000d2d43), DDrShowResumeButton);
 	}
+
+	// Fix BinkBufferInit() call in BKrMovie_Play() to use GDI (DIB) blitting
+	// instead of DirectDraw; patch ONiRunGame to use the same method to play
+	// outro (ie., BKrMovie_Play() instead of ONrMovie_Play_Hardware() as the
+	// latter has problems on WINE).
+	if (patch_binkplay)
+	{
+		// push BINKBUFFERAUTO -> push BINKBUFFERDIBSECTION.
+		DDrPatch_Byte((void*)(OniExe + 0x0008829b + 1), 0x02);
+		// call ONrMovie_Play_Hardware -> call ONrMovie_Play
+		DDrPatch_MakeCall((void*)(OniExe + 0x000d496f), ONrMovie_Play);
+	}
+
+	// Patch a gamma slider in Options dialog (unconditionally).
+	// ONiOGU_Options_InitDialog: replace WMrSlider_SetRange(gammaSliderWindow, ...)
+	// call with our hook function.
+	DDrPatch_MakeCall((void*)(OniExe + 0x000d262c), (void*)DD_ONiOGU_GammaSlider_SetRange);
 
 	return true;
@@ -360,4 +391,6 @@
 			else if (!_stricmp(name, "switch"))
 				M3gResolutionSwitch = !_stricmp(inifile_cleanstr(value), "true");
+			else if (!_stricmp(name, "gamma"))
+				opt_gamma = !_stricmp(inifile_cleanstr(value), "true");
 			else
 				DDrStartupMessage("unrecognised option \"%s\"", name);
@@ -410,6 +443,6 @@
 			else if (!_stricmp(name, "usedaodangl"))
 				patch_usedaodangl = !_stricmp(inifile_cleanstr(value), "true");
-			else if (!_stricmp(name, "windowhack"))
-				patch_windowhack = !_stricmp(inifile_cleanstr(value), "true");
+			else if (!_stricmp(name, "clipcursor"))
+				patch_clipcursor = !_stricmp(inifile_cleanstr(value), "true");
 			else if (!_stricmp(name, "daodaninit"))
 				patch_daodaninit = !_stricmp(inifile_cleanstr(value), "true");
@@ -422,4 +455,6 @@
 			else if (!_stricmp(name, "optionsvisible"))
 				patch_optionsvisible = !_stricmp(inifile_cleanstr(value), "true");
+			else if (!_stricmp(name, "binkplay"))
+				patch_binkplay = !_stricmp(inifile_cleanstr(value), "true");
 			else
 				DDrStartupMessage("unrecognised patch \"%s\"", name);
@@ -666,5 +701,5 @@
 	// Daodan device mode enumeration function
 	if (patch_daodandisplayenum)
-		DDrPatch_MakeJump((void*)gl_enumerate_valid_display_modes, (void*)daodan_enumerate_valid_display_modes);
+		DDrPatch_MakeJump((void*)gl_enumerate_valid_display_modes, (void*)DD_GLrEnumerateDisplayModes);
 	
 	// Performance patch
@@ -680,18 +715,53 @@
 		DDrPatch_MakeJump((void*)ONrPersist_GetWonGame, (void*)DDrPersist_GetWonGame);
 
-	// Windowed mode
+	// DaodanGL with windowed mode support.
 	if (patch_usedaodangl)
 	{
-		DDrPatch_NOOP((char*)(OniExe + 0x000032B7), 6);
-		DDrPatch_MakeCall((void*)(OniExe + 0x000032B7), (void*)LIiP_SetCursorPosHook);
-	
-		DDrPatch_NOOP((char*)(OniExe + 0x00003349), 6);
-		DDrPatch_MakeCall((void*)(OniExe + 0x00003349), (void*)LIiP_SetCursorPosHook);
-		DDrPatch_MakeJump((void*)ONrPlatform_Initialize, (void*)DDrPlatform_Initialize);
-		DDrPatch_MakeJump((void*)gl_platform_initialize, (void*)daodangl_platform_initialize);
-	}
-	// Hacked windowed mode (for when daodangl isn't working properly)
-	else if (patch_windowhack)
-		DDrWindowHack_Install();
+		// LIrPlatform_Mode_Set: GetWindowRect -> GetClientRect.
+		DDrPatch_NOOP((char*) OniExe + 0x00002dd6, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x00002dd6, (void*) GetClientRect);
+
+		// UUrWindow_GetSize: GetWindowRect -> GetClientRect.
+		DDrPatch_NOOP((char*) OniExe + 0x0002651c, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x0002651c, (void*) GetClientRect);
+
+		// LIrPlatform_PollInputForAction: fix GetCursorPos call to return client coordinates.
+		DDrPatch_NOOP((char*) OniExe + 0x000032cc, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x000032cc, (void*) DD_GetCursorPos);
+
+		// LIrPlatform_InputEvent_GetMouse: fix GetCursorPos call to return client coordinates.
+		DDrPatch_NOOP((char*) OniExe + 0x00002cc2, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x00002cc2, (void*) DD_GetCursorPos);
+
+		// LIrPlatform_PollInputForAction: translate SetCursorPos position to screen coordinates.
+		DDrPatch_NOOP((char*) OniExe + 0x000032b7, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x000032b7, (void*) DD_SetCursorPos);
+
+		// LIrPlatform_PollInputForAction: translate SetCursorPos position to screen coordinates.
+		DDrPatch_NOOP((char*) OniExe + 0x00003349, 6);
+		DDrPatch_MakeCall((char*) OniExe + 0x00003349, (void*) DD_SetCursorPos);
+
+		// Replace ONrPlatformInitialize.
+		DDrPatch_MakeJump((void*) ONrPlatform_Initialize, (void*) DD_ONrPlatform_Initialize);
+
+		// Replace gl_platform_initialize.
+		DDrPatch_MakeJump((void*) gl_platform_initialize, (void*) DD_GLrPlatform_Initialize);
+
+		// Replace gl_platform_dispose.
+		DDrPatch_MakeJump((void *) gl_platform_dispose, (void*) DD_GLrPlatform_Dispose);
+ 	}
+
+	if (patch_clipcursor)
+	{
+		// LIrMode_Set: replace LIrPlatform_Mode_Set call with our hook.
+		DDrPatch_MakeCall((void*)(OniExe + 0x00003f9f), (void*) DD_LIrPlatform_Mode_Set);
+
+		// LIrMode_Set_Internal: replace LIrPlatform_Mode_Set call with our hook.
+		DDrPatch_MakeCall((void*)(OniExe + 0x00003fff), (void*) DD_LIrPlatform_Mode_Set);
+		
+		// LIrTermiante: replace LIrPlatform_Terminate call with our hook.
+		DDrPatch_MakeCall((void*)(OniExe + 0x000004cb8), (void*) DD_LIrPlatform_Terminate);
+	}
+
 	
 	if (patch_daodaninit)
@@ -714,5 +784,5 @@
 	DDrPatch_MakeJump((void*)(OniExe + 0x000245A0), (void*)DDrPrintWarning);
 	
- 	ONiMain(argc, argv);
+	ONiMain(argc, argv);
 }
 /*
Index: Daodan/src/Daodan.h
===================================================================
--- Daodan/src/Daodan.h	(revision 694)
+++ Daodan/src/Daodan.h	(revision 705)
@@ -3,7 +3,18 @@
 
 #include <windows.h>
+#include <assert.h>
 #include "stdint.h"
 
 #define ONICALL __fastcall
+#define UUmType(t) typedef struct t t;
+
+#define DDmAssert(expr) assert(expr);
+
+typedef unsigned char UUtBool;
+#define UUcTrue  ((UUtBool) 1)
+#define UUcFalse ((UUtBool) 0)
+
+typedef unsigned short UUtError;
+#define UUcError_None ((UUtError) 0)
 
 extern HMODULE DDrDLLModule;
@@ -12,4 +23,5 @@
 extern bool opt_border;
 extern bool opt_topmost;
+extern bool opt_gamma;
 
 #endif
Index: Daodan/src/Daodan_BSL.c
===================================================================
--- Daodan/src/Daodan_BSL.c	(revision 694)
+++ Daodan/src/Daodan_BSL.c	(revision 705)
@@ -764,5 +764,5 @@
 uint16_t ONICALL cinematic_start_patch(sl_callinfo* callinfo, unsigned int numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
 {
-	args[1].val.value_int32 = (double)args[1].val.value_int32 / (double)(gl_eng->DisplayMode.Width) * (4.0 / 3.0 * (double)(gl_eng->DisplayMode.Height));
+	args[1].val.value_int32 = (double)args[1].val.value_int32 / (double)(gl->DisplayMode.Width) * (4.0 / 3.0 * (double)(gl->DisplayMode.Height));
 	return ((sl_func)(OniExe + 0x000f3830))(callinfo, numargs, args, dontuse1, dontuse2, ret);
 }
Index: Daodan/src/Daodan_GL.c
===================================================================
--- Daodan/src/Daodan_GL.c	(revision 694)
+++ Daodan/src/Daodan_GL.c	(revision 705)
@@ -11,20 +11,16 @@
 #include "Oni_GL.h"
 
-#define max_modes (104) // Dirty hack to add more resolutions, it really should only be 16 ^_^
-#define builtin_modes  (sizeof(daodan_reslist) / sizeof(M3tDisplayMode))
-#define builtin_depths (sizeof(daodan_resdepths) / sizeof(short))
-
-bool daodan_testmode(M3tDisplayMode mode);
-
-const M3tDisplayMode daodan_reslist[] = {
-	{ 720 , 480,  0, 0 },
-	{ 720 , 576,  0, 0 },
-	{ 768 , 480,  0, 0 },
-	{ 800 , 480,  0, 0 },
-	{ 800 , 600,  0, 0 },
-	{ 852 , 480,  0, 0 },
-	{ 856 , 480,  0, 0 },
-	{ 960 , 540,  0, 0 },
-	{ 960 , 720,  0, 0 },
+static const M3tDisplayMode daodan_reslist[] =
+{
+	{ 640,  480,  0, 0 },
+	{ 720,  480,  0, 0 },
+	{ 720,  576,  0, 0 },
+	{ 768,  480,  0, 0 },
+	{ 800,  480,  0, 0 },
+	{ 800,  600,  0, 0 },
+	{ 852,  480,  0, 0 },
+	{ 856,  480,  0, 0 },
+	{ 960,  540,  0, 0 },
+	{ 960,  720,  0, 0 },
 	{ 1024, 576,  0, 0 },
 	{ 1024, 600,  0, 0 },
@@ -47,42 +43,20 @@
 	{ 1920, 1440, 0, 0 },
 };
-//Just going to always use 32 bits for now...
-//short daodan_resdepths[] = { 16, 32 };
-short daodan_resdepths[] = { 32 };
-DEVMODE orig_devmode, cur_devmode, new_devmode;
-
-/* Never called
-void init_daodan_gl()
-{
-	DDrStartupMessage("initalizing daodan gl");
-	
-	memset(&orig_devmode, 0, sizeof(orig_devmode));
-	orig_devmode.dmSize = sizeof(orig_devmode);
-	
-	if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &orig_devmode))
-	{
-		orig_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-		orig_devmode.dmBitsPerPel = 32;
-		orig_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
-		orig_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
-	}
-	
-	memcpy(&cur_devmode, &orig_devmode, sizeof(orig_devmode));
-	memcpy(&new_devmode, &orig_devmode, sizeof(orig_devmode));
-}
-*/
-
-void update_cdmode()
-{
-	if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_devmode))
-	{
-		cur_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-		cur_devmode.dmBitsPerPel = 32;
-		cur_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
-		cur_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
-	}
-}
-
-unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[max_modes])
+
+static DWORD window_style, window_exstyle;
+
+// HACK: use additional device entries to store display modes. It would give us
+// 67 mode slots total (far more than enough). I absolutely have no idea where
+// Rossy got his 104 (it would take up to 0x660 bytes while the whole GL state
+// is only 0x63c bytes). Maybe it was just octal (67 + 1).
+// This hack would break (crash!) "m3_display_list" script command.
+#define DD_MAX_MODES ((offsetof(M3tDrawEngineCaps,__unknown) - \
+						offsetof(M3tDrawEngineCaps,DisplayDevices) - \
+						offsetof(M3tDisplayDevice,Modes)) / sizeof(M3tDisplayMode))
+
+// Former daodan_resdepths.
+#define DD_MIN_DEPTH 16
+
+unsigned short ONICALL DD_GLrEnumerateDisplayModes(M3tDisplayMode* modes)
 {
 	unsigned int vmodes = 0;
@@ -90,174 +64,360 @@
 	unsigned int screen_y = GetSystemMetrics(SM_CYSCREEN);
 	
-	uint16_t i, j;
+	unsigned int i;
+	signed int j;
 	
 	DDrStartupMessage("listing display modes");
-	/*
-	if (!M3gResolutionSwitch)
-		daodan_resdepths[0] = orig_devmode.dmBitsPerPel;
-	*/
-	for (i = 0; i < builtin_depths; i ++)
-	{
-		bool scrInsert = false;
+
+	memset(modes, 0, sizeof(M3tDisplayMode) * DD_MAX_MODES);
+
+	if (M3gResolutionSwitch)
+	{
+		// Enumerate in -switch mode. "67 slots ought to be enough for anybody".
+
+		DEVMODE dm;
+
+		dm.dmSize        = sizeof(dm);
+		dm.dmDriverExtra = 0;
+
+		for (i = 0; EnumDisplaySettings(NULL, i, &dm); ++i)
+		{
+			if (dm.dmBitsPerPel < DD_MIN_DEPTH || dm.dmPelsWidth < 640 || dm.dmPelsHeight < 480)
+				continue;
+
+			// Already exists? Search backwards as modes are sorted most of the times
+			for (j = vmodes - 1; j >= 0; --j)
+				if (modes[j].Width == dm.dmPelsWidth && modes[j].Height == dm.dmPelsHeight &&
+					modes[j].Depth == dm.dmBitsPerPel)
+					break;
+
+			if (j >= 0)
+				continue; // We've found a match.
+
+			modes[vmodes].Width  = dm.dmPelsWidth;
+			modes[vmodes].Height = dm.dmPelsHeight;
+			modes[vmodes].Depth  = dm.dmBitsPerPel;
+
+			if (++vmodes >= DD_MAX_MODES)
+				break;
+		}
+	}
+	else
+	{
+		// In -noswtich we put predefined window sizes which don't overlap
+		// deskbar(s) plus one "native" fullscreen mode.
+
+		unsigned int workarea_width, workarea_height, frame_width, frame_height;
+		DWORD style, exstyle;
+		RECT rc;
+
+		if (SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0))
+		{
+			workarea_width  = rc.right - rc.left;
+			workarea_height = rc.bottom - rc.top;
+		}
+		else
+		{
+			workarea_width  = screen_x;
+			workarea_height = screen_y;
+		}
+
+		style   = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE);
+		exstyle = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE);
+
+		// Calculate additional width and height for window borders. Don't
+		// bother with system metrics. Let Windows calculate this.
+		rc.left  = rc.top = 0;
+		rc.right = rc.bottom = 300;
+
+		if (AdjustWindowRectEx(&rc, style, FALSE, exstyle))
+		{
+			frame_width  = rc.right - rc.left - 300;
+			frame_height = rc.bottom - rc.top - 300;
+		}
+		else
+		{
+			frame_width  = 0;
+			frame_height = 0;
+		}
+
+		for (i = 0; i < sizeof(daodan_reslist) / sizeof(daodan_reslist[0]); ++i)
+		{
+			// Don't check the mode which has the same rect as screen. We would
+			// add it later as a special case.
+			if (daodan_reslist[i].Width == screen_x && daodan_reslist[i].Height == screen_y)
+				continue;
+			
+			if (daodan_reslist[i].Width + frame_width <= workarea_width &&
+				daodan_reslist[i].Height + frame_height <= workarea_height)
+			{
+				modes[vmodes] = daodan_reslist[i];
+				modes[vmodes].Depth = GLgInitialMode.dmBitsPerPel;
+
+				if (++vmodes >= DD_MAX_MODES)
+				{
+					--vmodes; // Remove the last mode to make room for "fullscreen" mode.
+					break;
+				}
+			}
+		}
+
+		modes[vmodes].Width  = GLgInitialMode.dmPelsWidth;
+		modes[vmodes].Height = GLgInitialMode.dmPelsHeight;
+		modes[vmodes].Depth  = GLgInitialMode.dmBitsPerPel;
+		++vmodes;
+	}
+
+	DDrStartupMessage("%u modes available:", vmodes);
+	for (i = 0; i < vmodes; ++i)
+		DDrStartupMessage("  %ux%ux%u", modes[i].Width, modes[i].Height, modes[i].Depth);
+
+	return vmodes;
+}
+
+// Sets a new display mode (if it is somehow different from a current mode).
+// NOTE: signature for this function was changed to simplify code.
+UUtBool DD_GLrPlatform_SetDisplayMode(M3tDisplayMode* mode)
+{
+	if (mode->Height < 480)
+		return UUcFalse;
+
+	if (M3gResolutionSwitch)
+	{
+		DEVMODE new_mode, cur_mode;
+
+		cur_mode.dmSize        = sizeof(cur_mode);
+		cur_mode.dmDriverExtra = 0;
+
+		// We don't need this check. Windows does this too (see CDS_RESET).
+		if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_mode) ||
+			cur_mode.dmPelsWidth != mode->Width || cur_mode.dmPelsHeight !=  mode->Height ||
+			cur_mode.dmBitsPerPel != mode->Depth)
+		{
+			new_mode.dmSize       = sizeof(new_mode);
+			new_mode.dmFields     = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;
+			new_mode.dmPelsWidth  = mode->Width;
+			new_mode.dmPelsHeight = mode->Height;
+			new_mode.dmBitsPerPel = mode->Depth;
+
+			if (ChangeDisplaySettings(&new_mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+				return UUcFalse;
+		}
 		
-		modes[vmodes].Width  = 640;
-		modes[vmodes].Height = 480;
-		modes[vmodes].Depth  = daodan_resdepths[i];
+		// We didn't change window size in DD_GLrPlatform_Initialize so we need
+		// to change it here.
+		SetWindowPos(ONgPlatformData.Window, NULL, 0, 0, mode->Width, mode->Height,
+			SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER);
+
+		return UUcTrue;
+	}
+	else
+	{
+		unsigned screen_x, screen_y;
+		DWORD style, exstyle, new_style, new_exstyle;
+		DWORD flags;
+		RECT rc, workarea_rc;
+		POINT pt;
+
+		screen_x = GetSystemMetrics(SM_CXSCREEN);
+		screen_y = GetSystemMetrics(SM_CYSCREEN);
+
+		GetClientRect(ONgPlatformData.Window, &rc);
 		
-		if (++vmodes == max_modes - builtin_modes + i)
-			goto modesfull;
+		// Don't do anything if the mode was not changed.
+		if (rc.right == mode->Width && rc.bottom == mode->Height)
+			return UUcTrue;
+
+		style   = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE);
+		exstyle = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE);
+		flags   = SWP_NOACTIVATE | SWP_NOZORDER;
+
+		// Remember initial window style to correctly restore from fullscreen.
+		if (window_style == 0)
+		{
+			window_style = style;
+			window_exstyle = exstyle;
+		}
+
+		if (mode->Width == screen_x && mode->Height == screen_y)
+		{
+			// "Fullscreen" mode.
+			new_exstyle = exstyle & ~(WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE);
+			new_style   = style & ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME | WS_DLGFRAME);
+			new_style   = new_style | WS_POPUP;
+			rc.left     = 0;
+			rc.top      = 0;
+			rc.right    = mode->Width;
+			rc.bottom   = mode->Height;
+		}
+		else
+		{
+			if (opt_border)
+			{
+				pt.x = rc.left;
+				pt.y = rc.top;
+				ClientToScreen(ONgPlatformData.Window, &pt);
+			}
+			else
+			{
+				pt.x = screen_x / 2 - mode->Width / 2;
+				pt.y = screen_y / 2 - mode->Height / 2;
+			}
+
+			new_exstyle = window_exstyle;
+			new_style   = window_style;
+			rc.left     = pt.x;
+			rc.top      = pt.y;
+			rc.right    = rc.left + mode->Width;
+			rc.bottom   = rc.top + mode->Height;
+
+			AdjustWindowRectEx(&rc, new_style, FALSE, new_exstyle);
+
+			// Convert to width and height.
+			rc.right  -= rc.left;
+			rc.bottom -= rc.top;
+
+			if (SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rc, 0))
+			{
+				// We try to keep window position, but we should prevent window
+				// from going off screen.
+
+				if (rc.left + rc.right > workarea_rc.right)
+					rc.left = workarea_rc.right - rc.right;
+				if (rc.top + rc.bottom > workarea_rc.bottom)
+					rc.top = workarea_rc.bottom - rc.bottom;
+
+				//  Titlebar should always be visible.
+
+				if (rc.left < workarea_rc.left)
+					rc.left = workarea_rc.left;
+				if (rc.top < workarea_rc.top)
+					rc.top = workarea_rc.top;
+			}
+		}
+
+		if (new_style != style)
+		{
+			SetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE, (LONG_PTR) new_style);
+			flags |= SWP_FRAMECHANGED | SWP_DRAWFRAME;
+		}
+
+		if (new_exstyle != exstyle)
+		{
+			SetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE, (LONG_PTR) new_exstyle);
+			flags |= SWP_FRAMECHANGED | SWP_DRAWFRAME;
+		}
+
+		SetWindowPos(ONgPlatformData.Window, NULL, rc.left, rc.top, rc.right, rc.bottom, flags);
+		return UUcTrue;
+	}
+}
+
+static void ONICALL DD_GLiGamma_Restore(void)
+{
+	if (opt_gamma)
+	{
+		if (gl_api->wglSetDeviceGammaRamp3DFX)
+			gl_api->wglSetDeviceGammaRamp3DFX(gl->hDC, GLgInitialGammaRamp);
+		else
+			SetDeviceGammaRamp(gl->hDC, GLgInitialGammaRamp);
+	}
+}
+
+static void ONICALL DD_GLiGamma_Initialize(void)
+{
+	if (opt_gamma)
+	{
+		if (gl_api->wglSetDeviceGammaRamp3DFX)
+		{
+			UUrStartupMessage("Using 3dfx gamma adjustment");
+			GLgGammaRampValid = gl_api->wglGetDeviceGammaRamp3DFX(gl->hDC, GLgInitialGammaRamp);
+		}
+		else
+		{
+			UUrStartupMessage("Using Windows gamma adjustment");
+			GLgGammaRampValid = GetDeviceGammaRamp(gl->hDC, GLgInitialGammaRamp);
+		}
+
+		M3rSetGamma(ONrPersist_GetGamma());
+	}
+	else
+	{
+		GLgGammaRampValid = FALSE;
+	}
+}
+ 
+// Disposes OpenGL engine. Called once.
+void ONICALL DD_GLrPlatform_Dispose(void)
+{
+	DEVMODE dm;
+	
+	DD_GLiGamma_Restore();
+
+	gl_api->wglMakeCurrent(NULL, NULL);
+	gl_api->wglDeleteContext(gl->hGLRC);
+	ReleaseDC(ONgPlatformData.Window, gl->hDC);
+
+	// Restore initial display mode if it does not match current mode.
+	
+	dm.dmSize        = sizeof(dm);
+	dm.dmDriverExtra = 0;
+	
+	if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) ||
+		dm.dmPelsWidth != GLgInitialMode.dmPelsWidth ||
+		dm.dmPelsHeight != GLgInitialMode.dmPelsHeight ||
+		dm.dmBitsPerPel != GLgInitialMode.dmBitsPerPel)
+	{
+		ChangeDisplaySettings(&GLgInitialMode, 0);
+	}
+	
+	// (skipping SetWindowPos as it only adds flickering)
+	gl_unload_library();
+}
+
+// Initializes (and re-initializes) OpenGL.
+UUtBool ONICALL DD_GLrPlatform_Initialize(void)
+{
+	static const M3tDisplayMode FallbackMode = { 640, 480, 16, 0 };
+
+	if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
+	{
+		gl->DisplayMode = FallbackMode;
 		
-		for (j = 0; j < builtin_modes; j ++)
-			if (!(daodan_reslist[j].Width == 640 && daodan_reslist[j].Height == 480) && !(daodan_reslist[j].Width == screen_x && daodan_reslist[j].Height == screen_y) &&
-				((daodan_reslist[j].Width < screen_x && daodan_reslist[j].Height < screen_y) || (M3gResolutionSwitch && daodan_testmode(daodan_reslist[j]))))
-			{
-				if (!scrInsert && (daodan_reslist[j].Width > screen_x || (daodan_reslist[j].Width == screen_x &&  daodan_reslist[j].Height > screen_y)))
-				{
-					modes[vmodes].Width  = screen_x;
-					modes[vmodes].Height = screen_y;
-					modes[vmodes].Depth  = daodan_resdepths[i];
-					
-					if (++vmodes == max_modes - builtin_modes + i)
-						goto modesfull;
-					
-					scrInsert = true;
-				}
-				
-				modes[vmodes].Width  = daodan_reslist[j].Width;
-				modes[vmodes].Height = daodan_reslist[j].Height;
-				modes[vmodes].Depth  = daodan_resdepths[i];
-				
-				if (++vmodes == max_modes - builtin_modes + i)
-					goto modesfull;
-			}
-		
-		if (!scrInsert)
-		{
-			modes[vmodes].Width  = screen_x;
-			modes[vmodes].Height = screen_y;
-			modes[vmodes].Depth  = daodan_resdepths[i];
-			
-			if (++vmodes == max_modes - builtin_modes + i)
-				goto modesfull;
-		}
-		
-		if (!M3gResolutionSwitch)
-			goto modesfull;
-	}
-	
-	modesfull:
-	DDrStartupMessage("%d modes available", vmodes);
-	return vmodes;
-}
-
-bool daodan_testmode(M3tDisplayMode mode)
-{
-	DEVMODE devmode;
-	memset(&devmode, 0, sizeof(devmode));
-	
-	devmode.dmSize = sizeof(devmode);
-	devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-	devmode.dmBitsPerPel = mode.Depth;
-	devmode.dmPelsWidth  = mode.Width;
-	devmode.dmPelsHeight = mode.Height;
-	
-	return (ChangeDisplaySettings(&devmode, CDS_TEST | CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
-}
-
-int daodan_set_display_mode(short width, short height, short depth)
-{
-	if (M3gResolutionSwitch)
-	{
-		DEVMODE new_devmode;
-		new_devmode.dmSize = sizeof(new_devmode);
-		new_devmode.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;
-		new_devmode.dmPelsWidth = width;
-		new_devmode.dmPelsHeight = height;
-		new_devmode.dmBitsPerPel = depth;
-		
-		if (ChangeDisplaySettings(&new_devmode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
-			return 0;
-		
-		if (ChangeDisplaySettings(&new_devmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
-			return 0;
-		
-		update_cdmode();
-		gl_eng->DisplayMode.Width = cur_devmode.dmPelsWidth;
-		gl_eng->DisplayMode.Height = cur_devmode.dmPelsHeight;
-		if (cur_devmode.dmBitsPerPel > (unsigned short)depth)
-			gl_eng->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
-	}
-	else
-	{
-		update_cdmode();
-		if (cur_devmode.dmBitsPerPel > (unsigned short)depth)
-			gl_eng->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
-	}
-	return 1;
-}
-int ONICALL daodangl_platform_initialize()
-{
-	static M3tDisplayMode lastmode = {0, 0, 0, 0};
-	
-	if (lastmode.Width != gl_eng->DisplayMode.Width || lastmode.Height != gl_eng->DisplayMode.Height || lastmode.Depth != gl_eng->DisplayMode.Depth)
-		if (!daodan_set_display_mode(gl_eng->DisplayMode.Width, gl_eng->DisplayMode.Height, gl_eng->DisplayMode.Depth))
-			if (gl_eng->DisplayMode.Width != 640 || gl_eng->DisplayMode.Height != 480 || gl_eng->DisplayMode.Depth != 16)
-			{
-				gl_eng->DisplayMode.Width = 640;
-				gl_eng->DisplayMode.Height = 480;
-				if (!daodan_set_display_mode(640, 480, 16))
-					goto exit_err;
-			}
-
-	if (lastmode.Width != gl_eng->DisplayMode.Width || lastmode.Height != gl_eng->DisplayMode.Height)
-	{
-		RECT Rect;
-		Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (gl_eng->DisplayMode.Width / 2);
-		Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (gl_eng->DisplayMode.Height / 2);
-		Rect.right = Rect.left + gl_eng->DisplayMode.Width;
-		Rect.bottom = Rect.top + gl_eng->DisplayMode.Height;
-		AdjustWindowRect(&Rect, WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CAPTION |WS_TILEDWINDOW , FALSE);
-		
-		SetWindowPos(ONgPlatformData.Window, NULL, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, SWP_NOACTIVATE | SWP_NOZORDER);
-	}
-
-	if (gl_eng->HDC == NULL)
-		if ((gl_eng->HDC = GetDC(ONgPlatformData.Window)) == NULL)
+		if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
+		{
 			goto exit_err;
-	
-	if (gl_api->wglGetDeviceGammaRamp3DFX != NULL)
-	{
-		DDrStartupMessage("Using 3DFX gamma adjustment");
-
-		if (gl_api->wglGetDeviceGammaRamp3DFX(gl_eng->HDC, gl_gamma_ramp))
-			gl_gamma_ramp_valid = 1;
-	}
-	else
-	{
-		DDrStartupMessage("Using standard Windows gamma adjustment");
-
-		if (GetDeviceGammaRamp(gl_eng->HDC, gl_gamma_ramp))
-			gl_gamma_ramp_valid = 1;
-	}
-	
-	/*if (gl_gamma_ramp_valid)
-		daodan_set_gamma(ONrPersist_GetGamma());  
-	else*/
-		DDrStartupMessage("gamma adjustment not supported");
-	
-	if (!gl_platform_set_pixel_format(gl_eng->HDC))
-		if (gl_eng->DisplayMode.Depth != 16)
-		{
-			if (!daodan_set_display_mode(gl_eng->DisplayMode.Width, gl_eng->DisplayMode.Height, 16))
+		}
+	}
+
+	// (DD_GLrPlatform_SetDisplayMode updates a window rectangle for us)
+	
+	if (!gl->hDC && !(gl->hDC = GetDC(ONgPlatformData.Window)))
+	{
+		goto exit_err;
+	}
+
+	if (!M3gResolutionSwitch && opt_gamma)
+	{
+		UUrStartupMessage("Ignoring gamma setting for a windowed mode");
+		opt_gamma = false;
+	}
+
+	DD_GLiGamma_Initialize();
+
+	// This creates a rendering context too.
+	if (!gl_platform_set_pixel_format(gl->hDC))
+	{
+		if (gl->DisplayMode.Depth != 16)
+		{
+			gl->DisplayMode.Depth = 16;
+			if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
 				goto exit_err;
 			
-			if (!gl_platform_set_pixel_format(gl_eng->HDC))
+			if (!gl_platform_set_pixel_format(gl->hDC))
 				goto exit_err;
 		}
-
-	lastmode.Width = gl_eng->DisplayMode.Width;
-	lastmode.Height = gl_eng->DisplayMode.Height;
-	lastmode.Depth = gl_eng->DisplayMode.Depth;
-	return 1;
+	}
+
+	return UUcTrue;
 
 exit_err:
Index: Daodan/src/Daodan_GL.h
===================================================================
--- Daodan/src/Daodan_GL.h	(revision 694)
+++ Daodan/src/Daodan_GL.h	(revision 705)
@@ -5,6 +5,7 @@
 #include "BFW_Motoko_Draw.h"
 
-unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[16]);
-int ONICALL daodangl_platform_initialize();
+unsigned short ONICALL DD_GLrEnumerateDisplayModes(M3tDisplayMode* modes);
+UUtBool ONICALL DD_GLrPlatform_Initialize(void);
+void ONICALL DD_GLrPlatform_Dispose(void);
 
 #endif
Index: Daodan/src/Daodan_Win32.c
===================================================================
--- Daodan/src/Daodan_Win32.c	(revision 694)
+++ Daodan/src/Daodan_Win32.c	(revision 705)
@@ -4,49 +4,171 @@
 #include "Daodan_Win32.h"
 
+#include "BFW_Utility.h"
 #include "Oni.h"
 
-extern HWND onihwnd;
 
-short ONICALL DDrPlatform_Initialize(ONtPlatformData *PlatformData)
+// LIrPlatform_Terminate wrapper. Removes any cursor clipping we've done. Doing
+// this is required for Windows 98 :-D
+void ONICALL DD_LIrPlatform_Terminate(void)
 {
-	WNDCLASSEX WndClass;
-	RECT Rect;
-	const int Width = 640, Height = 480;
-	HINSTANCE temp_Instance = PlatformData->Instance;
+	ClipCursor(NULL);
+	LIrPlatform_Terminate();
+}
 
-	PlatformData->Instance = g_Instance;
+// LIrPlatform_Mode_Set wrapper. Clips cursor to window bounds to
+// prevent loosing focus (mostly on Linux).
+void ONICALL DD_LIrPlatform_Mode_Set(unsigned int active_mode)
+{
+	DDmAssert(ONgPlatformData.Window);
 
-	WndClass.cbSize = sizeof(WndClass);
-	WndClass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
-	WndClass.cbClsExtra = 0;
-	WndClass.cbWndExtra = 0;
-	WndClass.hInstance = PlatformData->Instance;
-	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
-	WndClass.hIcon = LoadIcon(g_Instance, MAKEINTRESOURCE(103) );
-	WndClass.hIconSm = LoadIcon(g_Instance, MAKEINTRESOURCE(103));
+	if (active_mode)
+	{
+		RECT rc;
+		POINT pt;
+
+		pt.x = 0;
+		pt.y = 0;
+
+		if (GetClientRect(ONgPlatformData.Window, &rc) &&
+			ClientToScreen(ONgPlatformData.Window, &pt))
+		{
+			rc.left   += pt.x;
+			rc.top    += pt.y;
+			rc.right  += pt.x;
+			rc.bottom += pt.y;
+
+			ClipCursor(&rc);
+		}
+	}
+	else
+	{
+		ClipCursor(NULL);
+	}
+
+	LIrPlatform_Mode_Set(active_mode);
+}
+
+BOOL WINAPI DD_GetCursorPos(LPPOINT lpPoint)
+{
+	DDmAssert(ONgPlatformData.Window);
+	
+	return GetCursorPos(lpPoint) && ScreenToClient(ONgPlatformData.Window, lpPoint);
+}
+
+BOOL WINAPI DD_SetCursorPos(int X, int Y)
+{
+	POINT pt;
+	pt.x = X;
+	pt.y = Y;
+	
+	DDmAssert(ONgPlatformData.Window);
+	
+	return ClientToScreen(ONgPlatformData.Window, &pt) && SetCursorPos(pt.x, pt.y);
+}
+
+static LRESULT CALLBACK DD_ONrPlatform_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	switch (uMsg)
+	{
+		case WM_SYSCOMMAND:
+			if (wParam == SC_SCREENSAVE)
+			{
+				// Prevent screen saver from starting when Oni has focus.
+				return 0;
+			}
+			break;
+		
+		case WM_PAINT:
+		{
+			PAINTSTRUCT ps;
+			BeginPaint(hWnd, &ps);
+			// Oni does a useless PatBlt here.
+			EndPaint(hWnd, &ps);
+			return 0;
+		}
+		
+		case WM_CLOSE:
+			// There's no way to reliably terminate a modal dialog.
+			// The following condition is (almost) always true.
+			if (WMgActive)
+				exit(0);
+
+			ONgTerminateGame = UUcTrue;
+			return 0;
+			
+		case WM_SETCURSOR:
+			// If a mouse is inside our client area, we hide cursor (always),
+			// otherwise we ask DefWindowProc to set an appropriate arrow for us.
+			if (LOWORD(lParam) == HTCLIENT)
+			{
+				SetCursor(NULL);
+				return TRUE;
+			}
+			
+			break;
+	}
+	
+	return ONrPlatform_WindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
+UUtError ONICALL DD_ONrPlatform_Initialize(ONtPlatformData *PlatformData)
+{
+ 	WNDCLASSEX WndClass;
+ 	RECT Rect;
+ 	const int Width = 640, Height = 480;
+	DWORD window_style, window_style_ex;
+ 
+	PlatformData->Instance = ONgInstance;
+	PlatformData->Window   = NULL;
+	
+	if (FindWindow("ONI ", "ONI "))
+	{
+		AUrMessageBox(1, "There is already an instance of the game running.");
+		exit(0);
+	}
+	
+	WndClass.cbSize        = sizeof(WndClass);
+	WndClass.style         = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
+	WndClass.cbClsExtra    = 0;
+	WndClass.cbWndExtra    = 0;
+	WndClass.hInstance     = PlatformData->Instance;
+	WndClass.hCursor       = NULL; // To debug: LoadCursor(NULL, IDC_ARROW);
+	WndClass.hIcon         = LoadIcon(ONgInstance, MAKEINTRESOURCE(103));
+	WndClass.hIconSm       = LoadIcon(ONgInstance, MAKEINTRESOURCE(103));
 	WndClass.hbrBackground = GetStockObject(BLACK_BRUSH);
 	WndClass.lpszMenuName = NULL;
-	WndClass.lpszClassName = "ONI ";
-	WndClass.lpfnWndProc = ONrPlatform_WindowProc;
+	WndClass.lpszMenuName  = NULL;
+ 	WndClass.lpszClassName = "ONI ";
+	WndClass.lpfnWndProc   = DD_ONrPlatform_WindowProc;
+ 
+ 	RegisterClassEx(&WndClass);
+ 	
+	if (M3gResolutionSwitch)
+	{
+		// Do not allow border and topmost flag for a fullscreen window.
+		window_style    = WS_POPUP;
+		window_style_ex = 0;
+	}
+	else
+	{
+		window_style    = (opt_border) ? WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME | WS_MINIMIZEBOX : WS_POPUP;
+		window_style_ex = (opt_topmost) ? WS_EX_TOPMOST : 0;
+	}
+	
+ 	Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2);
+ 	Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2);
+ 	Rect.right = Rect.left + Width;
+ 	Rect.bottom = Rect.top + Height;
+	AdjustWindowRectEx(&Rect, window_style, FALSE, window_style_ex);
+	
+	PlatformData->Window = CreateWindowEx(window_style_ex, WndClass.lpszClassName, "ONI ", window_style,
+		Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top,
+		NULL, NULL, PlatformData->Instance, NULL);
+	
+ 	ShowWindow(PlatformData->Window, SW_SHOWNORMAL);
+ 	UpdateWindow(PlatformData->Window);
+ 
+	return UUcError_None;
+ }
 
-	RegisterClassEx(&WndClass);
-	
-	Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2);
-	Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2);
-	Rect.right = Rect.left + Width;
-	Rect.bottom = Rect.top + Height;
-	AdjustWindowRect(&Rect, WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_POPUP | WS_TILEDWINDOW , FALSE);
-	PlatformData->Window = CreateWindowEx(0, "ONI ", "ONI ",  WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_POPUP | WS_TILEDWINDOW, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, NULL, NULL, PlatformData->Instance, NULL);
-	onihwnd = PlatformData->Window;
-	ShowWindow(PlatformData->Window, SW_SHOWNORMAL);
-	UpdateWindow(PlatformData->Window);
-
-	ShowCursor(FALSE);
-	
-	// I dont know why this is needed but Oni doesn't init without it.
-	ONgPlatformData.Window = PlatformData->Window;
-	ONgPlatformData.Instance = PlatformData->Instance;
-	
-	return 0;
-}
-
Index: Daodan/src/Daodan_Win32.h
===================================================================
--- Daodan/src/Daodan_Win32.h	(revision 694)
+++ Daodan/src/Daodan_Win32.h	(revision 705)
@@ -5,5 +5,9 @@
 #include "Oni.h"
 
-short ONICALL DDrPlatform_Initialize(ONtPlatformData *PlatformData);
+UUtError ONICALL DD_ONrPlatform_Initialize(ONtPlatformData *PlatformData);
+BOOL WINAPI DD_GetCursorPos(LPPOINT lpPoint);
+BOOL WINAPI DD_SetCursorPos(int X, int Y);
+void ONICALL DD_LIrPlatform_Mode_Set(unsigned int active_mode);
+void ONICALL DD_LIrPlatform_Terminate(void);
 
 #endif
Index: Daodan/src/Daodan_WindowHack.c
===================================================================
--- Daodan/src/Daodan_WindowHack.c	(revision 694)
+++ 	(revision )
@@ -1,175 +1,0 @@
-#include <windows.h>
-#include "Daodan_WindowHack.h"
-#include "Daodan_Patch.h"
-
-#include "Oni.h"
-#include "Oni_GL.h"
-
-volatile HWND onihwnd, boxhwnd = NULL;
-int inclient = 0;
-int dragging = 0;
-
-LRESULT CALLBACK DDrHack_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-	switch (msg)
-	{
-		case WM_KEYDOWN:
-		case WM_ACTIVATE:
-		case WM_CHAR:
-		case WM_KEYUP:
-			ONrPlatform_WindowProc(onihwnd, msg, wParam, lParam);
-			return DefWindowProc(hwnd, msg, wParam, lParam);
-		case WM_SETCURSOR:
-			if (LOWORD(lParam) == HTCLIENT)
-			{
-				if (!inclient)
-				{
-					inclient = 1;
-					ShowCursor(FALSE);
-				}
-			}
-			else if (inclient)
-			{
-				inclient = 0;
-				ShowCursor(TRUE);
-			}
-			break;
-//		case WM_CLOSE:
-//			CHARTest();
-//			break;
-		case WM_DESTROY:
-			PostQuitMessage(0);
-			ExitProcess(0);
-			break;
-		case WM_ENTERSIZEMOVE:
-			dragging = 1;
-			break;
-		case WM_EXITSIZEMOVE:
-			dragging = 0;
-			break;
-		default:
-			return DefWindowProc(hwnd, msg, wParam, lParam);
-	}
-	return 0;
-}
-
-DWORD WINAPI DDrHack_WndMain(LPVOID param)
-{
-	MSG Msg;
-	RECT re;
-	WNDCLASSEX wc;
-	
-	wc.cbSize = sizeof(WNDCLASSEX);
-	wc.style = 0;
-	wc.lpfnWndProc = DDrHack_WndProc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 0;
-	wc.hInstance = DDrDLLModule;
-	wc.hIcon = LoadIcon(DDrONiModule, MAKEINTRESOURCE(103));
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
-	wc.lpszMenuName = NULL;
-	wc.lpszClassName = "OniGanbatte";
-	wc.hIconSm = NULL;
-	RegisterClassEx(&wc);
-	
-	
-	re.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (640 / 2);
-	re.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (480 / 2);
-	re.right = re.left + 640;
-	re.bottom = re.top + 480;
-	AdjustWindowRect(&re, WS_POPUP | (opt_border ? WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU : 0), FALSE);
-	
-	boxhwnd = CreateWindowEx(0, "OniGanbatte", "Oni", WS_POPUP | (opt_border ? WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU : 0), re.left, re.top, re.right - re.left, re.bottom - re.top, NULL, NULL, DDrDLLModule, NULL);
-	
-	while (GetMessage(&Msg, NULL, 0, 0) > 0)
-	{
-		TranslateMessage(&Msg);
-		DispatchMessage(&Msg);
-	}
-	return 0;
-}
-
-HWND WINAPI ONrPI_CreateWindowExHook(DWORD dwExStyle, const char* lpClassName, const char* lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
-{
-	CloseHandle(CreateThread(NULL, 0, DDrHack_WndMain, NULL, 0, NULL));
-	
-	while (!boxhwnd)
-		Sleep(50);
-	
-	onihwnd = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, boxhwnd, hMenu, hInstance, lpParam);
-	SetParent(onihwnd, boxhwnd);
-	return onihwnd;
-}
-
-BOOL WINAPI glpi_SetWindowPosHook(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
-{
-	RECT re;
-	SetWindowLong(onihwnd, GWL_STYLE, WS_CHILD | WS_VISIBLE);
-	SetCursor(LoadCursor(NULL, IDC_ARROW));
-	
-	
-	re.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (cx / 2);
-	re.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (cy / 2);
-	re.right = re.left + cx;
-	re.bottom = re.top + cy;
-	AdjustWindowRect(&re, WS_POPUP | (opt_border ? WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU : 0), FALSE);
-	
-	SetWindowPos(boxhwnd, opt_topmost ? HWND_TOPMOST : NULL, re.left, re.top, re.right - re.left, re.bottom - re.top, (opt_topmost ? uFlags & ~SWP_NOZORDER : uFlags | SWP_NOOWNERZORDER));
-	ShowWindow(boxhwnd, SW_SHOW);
-	UpdateWindow(boxhwnd);
-	return SetWindowPos(hWnd, NULL, 0, 0, cx, cy, uFlags | SWP_NOOWNERZORDER);
-}
-
-BOOL WINAPI LIiP_GetCursorPosHook(LPPOINT lpPoint)
-{
-	if (GetAsyncKeyState(VK_F4) || dragging)
-	{
-		lpPoint->x = gl_eng->DisplayMode.Width / 2;
-		lpPoint->y = gl_eng->DisplayMode.Height / 2;
-	}
-	else
-	{
-		if (!GetCursorPos(lpPoint))
-			return 0;
-		if (onihwnd != NULL)
-			ScreenToClient(onihwnd, lpPoint);
-	}
-	return 1;
-}
-
-BOOL WINAPI LIiP_SetCursorPosHook(int X, int Y)
-{
-	if (GetAsyncKeyState(VK_F4) || dragging)
-		return TRUE;
-	else
-	{
-		POINT pt;
-		pt.x = X;
-		pt.y = Y;
-		if (onihwnd != NULL)
-			ClientToScreen(onihwnd, &pt);
-		return SetCursorPos(pt.x, pt.y);
-	}
-}
-
-void DDrWindowHack_Install()
-{
-	DDrPatch_NOOP((char*)0x0050F764, 6);
-	DDrPatch_MakeCall((char*)0x0050F764, (void*)ONrPI_CreateWindowExHook);
-	
-	DDrPatch_NOOP((char*)0x00407E9F, 6);
-	DDrPatch_MakeCall((char*)0x00407E9F, (void*)glpi_SetWindowPosHook);
-	
-	DDrPatch_NOOP((char*)0x004032CC, 6);
-	DDrPatch_MakeCall((char*)0x004032CC, (void*)LIiP_GetCursorPosHook);
-	
-	DDrPatch_NOOP((char*)0x00402CC2, 6);
-	DDrPatch_MakeCall((char*)0x00402CC2, (void*)LIiP_GetCursorPosHook);
-	
-	DDrPatch_NOOP((char*)0x004032B7, 6);
-	DDrPatch_MakeCall((char*)0x004032B7, (void*)LIiP_SetCursorPosHook);
-	
-	DDrPatch_NOOP((char*)0x00403349, 6);
-	DDrPatch_MakeCall((char*)0x00403349, (void*)LIiP_SetCursorPosHook);
-}
Index: Daodan/src/Daodan_WindowHack.h
===================================================================
--- Daodan/src/Daodan_WindowHack.h	(revision 694)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#ifndef DAODAN_WINDOWHACK_H
-#define DAODAN_WINDOWHACK_H
-
-#include <windows.h>
-
-void DDrWindowHack_Install();
-BOOL WINAPI LIiP_GetCursorPosHook(LPPOINT lpPoint);
-BOOL WINAPI LIiP_SetCursorPosHook(int X, int Y);
-
-#endif
Index: Daodan/src/Oni.h
===================================================================
--- Daodan/src/Oni.h	(revision 694)
+++ Daodan/src/Oni.h	(revision 705)
@@ -8,4 +8,6 @@
 
 typedef unsigned char onibool;
+
+#define WMcMessage_Quit 0x39 // WM_QUIT equivalent.
 
 typedef struct {
@@ -20,5 +22,7 @@
 	void** PointerList, //Where the found pointers go
 	int* FoundCount		//Where the number of pointers found go.
-); 
+);
+
+UUmType(WMtWindow);
 
 #include "Oni_Symbols.h"
Index: Daodan/src/Oni_GL.h
===================================================================
--- Daodan/src/Oni_GL.h	(revision 694)
+++ Daodan/src/Oni_GL.h	(revision 705)
@@ -58,6 +58,6 @@
 	int f_0624;
 	char *TextureBuffer;
-	HDC HDC;
-	HGLRC HGLRC;
+	HDC hDC;
+	HGLRC hGLRC;
 	char vsync;
 	char f_0635[3];
Index: Daodan/src/Oni_Symbols.h
===================================================================
--- Daodan/src/Oni_Symbols.h	(revision 694)
+++ Daodan/src/Oni_Symbols.h	(revision 705)
@@ -32,12 +32,19 @@
 #define COgFadeTimeValue	(*((uint32_t*)0x00533f68))
 
-// Some kind of graphics context?
-#define g_Instance			(*((HINSTANCE*)0x0061F9E4))
-
-// OpenGL Gamma related
-#define gl_gamma_ramp		(((M3tWin32GammaRamp*)0x0055fdfc))
-
-// OpenGL Gamma related
-#define gl_gamma_ramp_valid	(*((int*)0x005603fc))
+// Game termination flag (ONiRunGame loops on it).
+#define ONgTerminateGame	(*((UUtBool*)0x00630ffd))
+ 
+// Window manager is running (drawing and updating windows).
+#define WMgActive			(*((UUtBool*)0x005e99a0))
+ 
+// Set by WinMain, used by UUrPlatform_Initialize and ONrPlatform_Initialize,
+// which copies it into ONgPlatformData.
+#define ONgInstance			(*((HINSTANCE*)0x0061f9e4))
+ 
+// Keeps initial gamma ramp value (before any change).
+#define GLgInitialGammaRamp	(((M3tWin32GammaRamp*)0x0055fdfc))
+
+// Nonzero when gamma ramp was successfully read into GLgInitialGammaRamp.
+#define GLgGammaRampValid	(*((int*)0x005603fc))
 
 // OpenGL: list of pointers to opengl32.dll functions (and a few functions from GL extensions)
@@ -45,7 +52,11 @@
 
 // OpenGL render engine descriptor (resolutions, flags, context methods)
-#define gl_eng				(*((gl_engine_t**)0x00560600))
-
-// Value of -switch/-noswitch?
+#define gl				(*((gl_engine_t**)0x00560600))
+
+// Initial display mode (saved by gl_library_is_loaded).
+#define GLgInitialMode		(*((DEVMODE*)0x0055fd60))
+
+// False to prevent Oni from changing display settings (however Bink
+// player does not respect this setting).
 #define M3gResolutionSwitch	(*((char*)0x00531634))
 
@@ -57,5 +68,5 @@
 
 // Current ONtPlatformData
-#define ONgPlatformData		(*((ONtPlatformData*)0x0053100c))
+#define ONgPlatformData		(*((ONtPlatformData*)0x00631008))
 
 // Load non levelX_final-files yes/no
@@ -104,6 +115,8 @@
 DefFunc(int, gl_platform_set_pixel_format, ONICALL, (HDC hdc), 0x00407b50);
 
-// Original graphics initialization method patched to use "daodangl_platform_initialize" instead if daodangl is used
-DefFunc(int, gl_platform_initialize, ONICALL, (), 0x00407da0);
+// Original graphics initialization/cleanup functions patched to use
+// DD_GLrPlatform_Initialize/DD_GLrPlatform_Dispoose instead if daodangl is used.
+DefFunc(UUtBool, gl_platform_initialize, ONICALL, (void), 0x00407da0);
+DefFunc(void, gl_platform_dispose, ONICALL, (void), 0x408210);
 
 // Retrieve gamma value from settings
@@ -199,6 +212,28 @@
 
 // Make a dialog element (in)visible and change its position
-DefFunc(void, WMrWindow_SetVisible, ONICALL, (int window, int visibility), 0x00475a10);
-DefFunc(void, WMrWindow_SetLocation, ONICALL, (int window, int x, int y), 0x004756d0);
+DefFunc(void, WMrWindow_SetVisible, ONICALL, (WMtWindow* window, int visibility), 0x00475a10);
+DefFunc(void, WMrWindow_SetLocation, ONICALL, (WMtWindow* window, int x, int y), 0x004756d0);
+
+// Plays movie using Bink blitting method (ie., non-OpenGL blitting).
+DefFunc(void, ONrMovie_Play, ONICALL, (const char* movie, int unknown), 0x004d5580);
+
+// Sets minimum and maximum values for a slider control.
+DefFunc(void, WMrSlider_SetRange, ONICALL, (WMtWindow* window, int min_value, int max_value), 0x00472650);
+
+// Enables or disables window.
+DefFunc(void, WMrWindow_SetEnabled, ONICALL, (WMtWindow* window, UUtBool enabled), 0x00475580);
+
+// Sets gamma to specified factor (0.0 .. 1.0).
+DefFunc(void, M3rSetGamma, ONICALL, (float factor), 0x00407a60);
+
+// Resets gl_api pointers, unloads OPENGL32.DLL.
+DefFunc(void, gl_unload_library, ONICALL, (void), 0x0040ac40);
+
+// Notifies platform-specific local input implementation about internal (ie.,
+// real) input mode change.
+DefFunc(void, LIrPlatform_Mode_Set, ONICALL, (unsigned int active_mode), 0x00402cf0);
+
+// Terminates platform-specific local-input.
+DefFunc(void, LIrPlatform_Terminate, ONICALL, (void), 0x00403620);
 
 #undef DefFunc
