#include #include #include "Oni.h" #include "Oni_Persistence.h" #include "Daodan_Utility.h" #include #include #include "gl/wglext.h" //WGL extensions #include "gl/glext.h" //GL extensions #include "Daodan_Win32.h" #include "BFW_Utility.h" #include "daodan_gl.h" #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)) 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 }, { 1024, 576, 0, 0 }, { 1024, 600, 0, 0 }, { 1024, 640, 0, 0 }, { 1024, 768, 0, 0 }, { 1152, 768, 0, 0 }, { 1152, 864, 0, 0 }, { 1280, 720, 0, 0 }, { 1280, 768, 0, 0 }, { 1280, 800, 0, 0 }, { 1280, 960, 0, 0 }, { 1280, 1024, 0, 0 }, { 1366, 768, 0, 0 }, { 1400, 1050, 0, 0 }, { 1440, 900, 0, 0 }, { 1600, 900, 0, 0 }, { 1600, 1200, 0, 0 }, { 1920, 1080, 0, 0 }, { 1920, 1200, 0, 0 }, { 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; 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]) { unsigned int vmodes = 0; unsigned int screen_x = GetSystemMetrics(SM_CXSCREEN); unsigned int screen_y = GetSystemMetrics(SM_CYSCREEN); uint16_t i, j; DDrStartupMessage("listing display modes"); /* if (!M3gResolutionSwitch) daodan_resdepths[0] = orig_devmode.dmBitsPerPel; */ for (i = 0; i < builtin_depths; i ++) { bool scrInsert = false; modes[vmodes].Width = 640; modes[vmodes].Height = 480; modes[vmodes].Depth = daodan_resdepths[i]; if (++vmodes == max_modes - builtin_modes + i) goto modesfull; 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 > depth) gl_eng->DisplayMode.Depth = cur_devmode.dmBitsPerPel; } else { update_cdmode(); if (cur_devmode.dmBitsPerPel > 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) 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)) goto exit_err; if (!gl_platform_set_pixel_format(gl_eng->HDC)) goto exit_err; } lastmode.Width = gl_eng->DisplayMode.Width; lastmode.Height = gl_eng->DisplayMode.Height; lastmode.Depth = gl_eng->DisplayMode.Depth; return 1; exit_err: AUrMessageBox(1, "Failed to initialize OpenGL contexts; Oni will now exit."); exit(0); return 0; }