Report S3TC non-support with an in-game GUI message box.

Fixes #313.

This was SVN commit r7390.
This commit is contained in:
Ykkrosh 2010-03-23 22:45:07 +00:00
parent 600ab80a79
commit 00e18e4ea8
8 changed files with 86 additions and 19 deletions

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<objects>
<script>
<script><![CDATA[
function init(data)
{
var mbMainObj = getGUIObjectByName ("mbMain");
var mbTitleObj = getGUIObjectByName ("mbTitleBar");
var mbTextObj = getGUIObjectByName ("mbText");
var mbMainObj = getGUIObjectByName("mbMain");
var mbTitleObj = getGUIObjectByName("mbTitleBar");
var mbTextObj = getGUIObjectByName("mbText");
var mbButton1Obj = getGUIObjectByName ("mbButton1");
var mbButton2Obj = getGUIObjectByName ("mbButton2");
var mbButton3Obj = getGUIObjectByName ("mbButton3");
var mbButton1Obj = getGUIObjectByName("mbButton1");
var mbButton2Obj = getGUIObjectByName("mbButton2");
var mbButton3Obj = getGUIObjectByName("mbButton3");
// Calculate size
var mbLRDiff = data.width / 2; // Message box left/right difference from 50% of screen
@ -24,6 +24,9 @@
mbTitleObj.caption = data.title;
mbTextObj.caption = data.message;
if (data.font)
mbTextObj.font = data.font;
// Message box modes
// There is a number of standard modes, and if none of these is used (mbMode == 0), the button captions will be
// taken from the array mbButtonCaptions; there currently is a maximum of three buttons.
@ -49,19 +52,19 @@
if (data.buttonCaptions.length >= 1)
{
mbButton1Obj.caption = data.buttonCaptions[0];
mbButton1Obj.onPress = function () { Engine.PopGuiPage(); if (codes[0]) codes[0](); }
mbButton1Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[0]) codes[0](); }
mbButton1Obj.hidden = false;
}
if (data.buttonCaptions.length >= 2)
{
mbButton2Obj.caption = data.buttonCaptions[1];
mbButton2Obj.onPress = function () { Engine.PopGuiPage(); if (codes[1]) codes[1](); }
mbButton2Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[1]) codes[1](); }
mbButton2Obj.hidden = false;
}
if (data.buttonCaptions.length >= 3)
{
mbButton3Obj.caption = data.buttonCaptions[2];
mbButton3Obj.onPress = function () { Engine.PopGuiPage(); if (codes[2]) codes[2](); }
mbButton3Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[2]) codes[2](); }
mbButton3Obj.hidden = false;
}
@ -81,18 +84,16 @@
break;
}
}
</script>
]]></script>
<object>
<object name="mbMain"
style="wheatWindow"
type="image"
size="50%-400 50%-200 50%+400 50%+200"
z="198"
>
<object name="mbTitleBar"
style="wheatWindowTitleBar"
type="button"
type="text"
/>
<object name="mbText"
@ -120,7 +121,6 @@
size="66%+30 100%-50 100%-40 100%-20"
/>
</object>
</object>
</objects>

View File

@ -100,6 +100,21 @@ void CGUIManager::PopPage()
m_PageStack.pop_back();
}
void CGUIManager::DisplayMessageBox(int width, int height, const CStrW& title, const CStrW& message)
{
// Set up scripted init data for the standard message box window
CScriptValRooted data;
m_ScriptInterface.Eval("({})", data);
m_ScriptInterface.SetProperty(data.get(), "width", width, false);
m_ScriptInterface.SetProperty(data.get(), "height", height, false);
m_ScriptInterface.SetProperty(data.get(), "mode", 2, false);
m_ScriptInterface.SetProperty(data.get(), "font", std::string("verdana16"), false);
m_ScriptInterface.SetProperty(data.get(), "title", std::wstring(title), false);
m_ScriptInterface.SetProperty(data.get(), "message", std::wstring(message), false);
// Display the message box
PushPage(L"page_msgbox.xml", data.get());
}
void CGUIManager::LoadPage(SGUIPage& page)
{

View File

@ -61,6 +61,11 @@ public:
// (There must be at least two pages when you call this.)
void PopPage();
/**
* Display a modal message box with an "OK" button.
*/
void DisplayMessageBox(int width, int height, const CStrW& title, const CStrW& message);
// Hotload pages when their .xml files have changed
LibError ReloadChangedFiles(const VfsPath& path);

View File

@ -704,8 +704,10 @@ static void detect_gl_upload_caps()
}
// warn if more-or-less essential features are missing
// (but don't use DEBUG_DISPLAY_ERROR; the app should check ogl_tex_has_s3tc
// and give friendlier error messages, since this is a common problem)
if(!have_s3tc)
DEBUG_DISPLAY_ERROR(L"Performance warning: your graphics card does not support compressed textures. The game will try to continue anyway, but may be slower than expected. Please try updating your graphics drivers; if that doesn't help, please try upgrading your hardware.");
debug_printf(L"Performance warning: your graphics card does not support compressed textures. The game will try to continue anyway, but may be slower than expected. Please try updating your graphics drivers; if that doesn't help, please try upgrading your hardware.\n");
}
@ -1007,3 +1009,13 @@ LibError ogl_tex_transform_to(Handle ht, size_t new_flags)
LibError ret = tex_transform_to(&ot->t, new_flags);
return ret;
}
// return whether native S3TC support is available
bool ogl_tex_has_s3tc()
{
// ogl_tex_upload must be called before this
debug_assert(have_s3tc != -1);
return have_s3tc;
}

View File

@ -426,4 +426,14 @@ extern LibError ogl_tex_transform(Handle ht, size_t flags);
*/
extern LibError ogl_tex_transform_to(Handle ht, size_t new_flags);
/**
* Return whether native S3TC texture compression support is available.
* If not, textures will be decompressed automatically, hurting performance.
*
* @return true if native S3TC supported
*
* ogl_tex_upload must be called at least once before this.
*/
extern bool ogl_tex_has_s3tc();
#endif // #ifndef INCLUDED_OGL_TEX

View File

@ -583,6 +583,22 @@ static void InitPs(bool setup_gui)
g_GUI->SwitchPage(L"page_pregame.xml", JSVAL_VOID);
else
g_GUI->SwitchPage(L"page_session_new.xml", JSVAL_VOID);
// Warn nicely about missing S3TC support
if (!ogl_tex_has_s3tc())
{
g_GUI->DisplayMessageBox(600, 350, L"Warning",
L"Performance warning:\n\n"
L"Your graphics drivers do not support S3TC compressed textures. This will significantly reduce performance and increase memory usage.\n\n"
#if OS_LINUX
L"See http://dri.freedesktop.org/wiki/S3TC for details. "
L"Installing the libtxc_dxtn library will fix these problems. "
L"Alternatively, running 'driconf' and setting force_s3tc_enable will fix the performance but may cause rendering bugs."
#else
L"Please try updating your graphics drivers to ensure you have full hardware acceleration."
#endif
);
}
}
else
{

View File

@ -447,6 +447,14 @@ bool ScriptInterface::Eval_(const char* code, jsval& rval)
return ok ? true : false;
}
bool ScriptInterface::Eval_(const wchar_t* code, jsval& rval)
{
utf16string codeUtf16(code, code+wcslen(code));
JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uintN)codeUtf16.length(), "(eval)", 1, &rval);
return ok ? true : false;
}
void ScriptInterface::ReportError(const char* msg)
{
// JS_ReportError by itself doesn't seem to set a JS-style exception, and so

View File

@ -136,7 +136,7 @@ public:
bool Eval(const char* code);
template<typename T> bool Eval(const char* code, T& out);
template<typename T, typename CHAR> bool Eval(const CHAR* code, T& out);
/**
* Report the given error message through the JS error reporting mechanism,
@ -188,6 +188,7 @@ public:
private:
bool CallFunction_(jsval val, const char* name, std::vector<jsval>& args, jsval& ret);
bool Eval_(const char* code, jsval& ret);
bool Eval_(const wchar_t* code, jsval& ret);
bool SetGlobal_(const char* name, jsval value, bool replace);
bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly);
bool GetProperty_(jsval obj, const char* name, jsval& value);
@ -317,8 +318,8 @@ bool ScriptInterface::GetProperty(jsval obj, const char* name, T& out)
return FromJSVal(GetContext(), val, out);
}
template<typename T>
bool ScriptInterface::Eval(const char* code, T& ret)
template<typename T, typename CHAR>
bool ScriptInterface::Eval(const CHAR* code, T& ret)
{
jsval rval;
if (! Eval_(code, rval))