diff --git a/src/console/Device.cpp b/src/console/Device.cpp index 9bb65a2..9605750 100644 --- a/src/console/Device.cpp +++ b/src/console/Device.cpp @@ -11,11 +11,39 @@ CVar* s_cvGxMaximize; CVar* s_cvGxResolution; CVar* s_cvGxWidescreen; CVar* s_cvGxWindow; +CVar* s_cvGxApi; DefaultSettings s_defaults; bool s_hwDetect; bool s_hwChanged; CGxFormat s_requestedFormat; +const char* g_gxApiNames[GxApis_Last] = { + "OpenGL", // GxApi_OpenGl + "D3D9", // GxApi_D3d9 + "D3D9Ex", // GxApi_D3d9Ex + "D3D10", // GxApi_D3d10 + "D3D11", // GxApi_D3d11 + "GLL", // GxApi_GLL + "GLSDL" // GxApi_GLSDL +}; + +EGxApi g_gxApiSupported[] = { +#if defined(WHOA_SYSTEM_WIN) + GxApi_D3d9, + GxApi_GLSDL +#endif + +#if defined(WHOA_SYSTEM_MAC) + GxApi_GLL +#endif + +#if defined(WHOA_SYSTEM_LINUX) + GxApi_GLSDL +#endif +}; + +size_t g_numGxApiSupported = sizeof(g_gxApiSupported) / sizeof(EGxApi); + bool CVGxMaximizeCallback(CVar*, const char*, const char*, void*) { // TODO return true; @@ -35,6 +63,49 @@ bool CVGxWindowCallback(CVar*, const char*, const char*, void*) { return true; } +bool CVGxApiCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + for (size_t api = 0; api < g_numGxApiSupported; api++) { + auto apiString = g_gxApiNames[g_gxApiSupported[api]]; + if (SStrCmpI(newValue, apiString, STORM_MAX_STR) == 0) { + // New gxApi is supported, pass + ConsoleWrite("GxApi set pending gxRestart", DEFAULT_COLOR); + return true; + } + } + + // Supported gxApi not supplied, show available apis + constexpr size_t msgsize = 1024; + char msg[msgsize] = {0}; + SStrPack(msg, "unsupported api, must be one of ", msgsize); + + for (size_t api = 0; api < g_numGxApiSupported; api++) { + if (api > 0) { + SStrPack(msg, ", ", msgsize); + } + auto apiString = g_gxApiNames[g_gxApiSupported[api]]; + SStrPack(msg, "'", msgsize); + SStrPack(msg, apiString, msgsize); + SStrPack(msg, "'", msgsize); + } + + ConsoleWrite(msg, DEFAULT_COLOR); + return false; +} + +EGxApi GxApiDefault() { +#if defined(WHOA_SYSTEM_WIN) + return GxApi_D3d9; +#endif + +#if defined(WHOA_SYSTEM_MAC) + return GxApi_GLL; +#endif + +#if defined(WHOA_SYSTEM_LINUX) + return GxApi_GLSDL; +#endif +} + void RegisterGxCVars() { auto& format = s_defaults.format; @@ -97,6 +168,19 @@ void RegisterGxCVars() { // TODO s_cvGxRefresh // TODO s_cvGxTripleBuffer // TODO s_cvGxApi + + s_cvGxApi = CVar::Register( + "gxApi", + "graphics api", + 0x1 | 0x2, + g_gxApiNames[GxApiDefault()], + CVGxApiCallback, + 1, + false, + nullptr, + false + ); + // TODO s_cvGxVSync // TODO s_cvGxAspect // TODO s_cvGxCursor @@ -194,17 +278,24 @@ void ConsoleDeviceInitialize(const char* title) { CGxFormat format; memcpy(&format, &s_requestedFormat, sizeof(s_requestedFormat)); - // TODO proper api selection - EGxApi api = GxApi_OpenGl; -#if defined(WHOA_SYSTEM_WIN) - api = GxApi_D3d9; + // Select gxApi based on user CVars and command-line parameters + EGxApi api = GxApiDefault(); - if (CmdLineGetBool(CMD_OPENGL)) { - api = GxApi_OpenGl; + auto gxApiName = s_cvGxApi->GetString(); + + auto gxOverride = CmdLineGetString(WOWCMD_GX_OVERRIDE); + if (*gxOverride != '\0') { + gxApiName = gxOverride; + } + + // Sanitize chosen gxApi against list of supported gxApis + for (size_t i = 0; i < g_numGxApiSupported; i++) { + EGxApi supportedApi = g_gxApiSupported[i]; + if (SStrCmp(gxApiName, g_gxApiNames[supported], STORM_MAX_STR) == 0) { + api = supportedApi; + break; + } } -#elif defined(WHOA_SYSTEM_MAC) - api = GxApi_GLL; -#endif CGxDevice* device = GxDevCreate(api, OsWindowProc, format);