mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
Report S3TC non-support with an in-game GUI message box.
Fixes #313. This was SVN commit r7390.
This commit is contained in:
parent
600ab80a79
commit
00e18e4ea8
8 changed files with 86 additions and 19 deletions
|
|
@ -1,16 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<objects>
|
<objects>
|
||||||
<script>
|
<script><![CDATA[
|
||||||
function init(data)
|
function init(data)
|
||||||
{
|
{
|
||||||
var mbMainObj = getGUIObjectByName ("mbMain");
|
var mbMainObj = getGUIObjectByName("mbMain");
|
||||||
var mbTitleObj = getGUIObjectByName ("mbTitleBar");
|
var mbTitleObj = getGUIObjectByName("mbTitleBar");
|
||||||
var mbTextObj = getGUIObjectByName ("mbText");
|
var mbTextObj = getGUIObjectByName("mbText");
|
||||||
|
|
||||||
var mbButton1Obj = getGUIObjectByName ("mbButton1");
|
var mbButton1Obj = getGUIObjectByName("mbButton1");
|
||||||
var mbButton2Obj = getGUIObjectByName ("mbButton2");
|
var mbButton2Obj = getGUIObjectByName("mbButton2");
|
||||||
var mbButton3Obj = getGUIObjectByName ("mbButton3");
|
var mbButton3Obj = getGUIObjectByName("mbButton3");
|
||||||
|
|
||||||
// Calculate size
|
// Calculate size
|
||||||
var mbLRDiff = data.width / 2; // Message box left/right difference from 50% of screen
|
var mbLRDiff = data.width / 2; // Message box left/right difference from 50% of screen
|
||||||
|
|
@ -24,6 +24,9 @@
|
||||||
mbTitleObj.caption = data.title;
|
mbTitleObj.caption = data.title;
|
||||||
mbTextObj.caption = data.message;
|
mbTextObj.caption = data.message;
|
||||||
|
|
||||||
|
if (data.font)
|
||||||
|
mbTextObj.font = data.font;
|
||||||
|
|
||||||
// Message box modes
|
// Message box modes
|
||||||
// There is a number of standard modes, and if none of these is used (mbMode == 0), the button captions will be
|
// 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.
|
// taken from the array mbButtonCaptions; there currently is a maximum of three buttons.
|
||||||
|
|
@ -49,19 +52,19 @@
|
||||||
if (data.buttonCaptions.length >= 1)
|
if (data.buttonCaptions.length >= 1)
|
||||||
{
|
{
|
||||||
mbButton1Obj.caption = data.buttonCaptions[0];
|
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;
|
mbButton1Obj.hidden = false;
|
||||||
}
|
}
|
||||||
if (data.buttonCaptions.length >= 2)
|
if (data.buttonCaptions.length >= 2)
|
||||||
{
|
{
|
||||||
mbButton2Obj.caption = data.buttonCaptions[1];
|
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;
|
mbButton2Obj.hidden = false;
|
||||||
}
|
}
|
||||||
if (data.buttonCaptions.length >= 3)
|
if (data.buttonCaptions.length >= 3)
|
||||||
{
|
{
|
||||||
mbButton3Obj.caption = data.buttonCaptions[2];
|
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;
|
mbButton3Obj.hidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,18 +84,16 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
]]></script>
|
||||||
<object>
|
<object>
|
||||||
<object name="mbMain"
|
<object name="mbMain"
|
||||||
style="wheatWindow"
|
style="wheatWindow"
|
||||||
type="image"
|
type="image"
|
||||||
size="50%-400 50%-200 50%+400 50%+200"
|
|
||||||
z="198"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<object name="mbTitleBar"
|
<object name="mbTitleBar"
|
||||||
style="wheatWindowTitleBar"
|
style="wheatWindowTitleBar"
|
||||||
type="button"
|
type="text"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<object name="mbText"
|
<object name="mbText"
|
||||||
|
|
@ -120,7 +121,6 @@
|
||||||
size="66%+30 100%-50 100%-40 100%-20"
|
size="66%+30 100%-50 100%-40 100%-20"
|
||||||
/>
|
/>
|
||||||
</object>
|
</object>
|
||||||
|
|
||||||
</object>
|
</object>
|
||||||
|
|
||||||
</objects>
|
</objects>
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,21 @@ void CGUIManager::PopPage()
|
||||||
m_PageStack.pop_back();
|
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)
|
void CGUIManager::LoadPage(SGUIPage& page)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,11 @@ public:
|
||||||
// (There must be at least two pages when you call this.)
|
// (There must be at least two pages when you call this.)
|
||||||
void PopPage();
|
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
|
// Hotload pages when their .xml files have changed
|
||||||
LibError ReloadChangedFiles(const VfsPath& path);
|
LibError ReloadChangedFiles(const VfsPath& path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -704,8 +704,10 @@ static void detect_gl_upload_caps()
|
||||||
}
|
}
|
||||||
|
|
||||||
// warn if more-or-less essential features are missing
|
// 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)
|
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);
|
LibError ret = tex_transform_to(&ot->t, new_flags);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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
|
#endif // #ifndef INCLUDED_OGL_TEX
|
||||||
|
|
|
||||||
|
|
@ -583,6 +583,22 @@ static void InitPs(bool setup_gui)
|
||||||
g_GUI->SwitchPage(L"page_pregame.xml", JSVAL_VOID);
|
g_GUI->SwitchPage(L"page_pregame.xml", JSVAL_VOID);
|
||||||
else
|
else
|
||||||
g_GUI->SwitchPage(L"page_session_new.xml", JSVAL_VOID);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -447,6 +447,14 @@ bool ScriptInterface::Eval_(const char* code, jsval& rval)
|
||||||
return ok ? true : false;
|
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)
|
void ScriptInterface::ReportError(const char* msg)
|
||||||
{
|
{
|
||||||
// JS_ReportError by itself doesn't seem to set a JS-style exception, and so
|
// JS_ReportError by itself doesn't seem to set a JS-style exception, and so
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ public:
|
||||||
|
|
||||||
bool Eval(const char* code);
|
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,
|
* Report the given error message through the JS error reporting mechanism,
|
||||||
|
|
@ -188,6 +188,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool CallFunction_(jsval val, const char* name, std::vector<jsval>& args, jsval& ret);
|
bool CallFunction_(jsval val, const char* name, std::vector<jsval>& args, jsval& ret);
|
||||||
bool Eval_(const char* code, 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 SetGlobal_(const char* name, jsval value, bool replace);
|
||||||
bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly);
|
bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly);
|
||||||
bool GetProperty_(jsval obj, const char* name, jsval& value);
|
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);
|
return FromJSVal(GetContext(), val, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename CHAR>
|
||||||
bool ScriptInterface::Eval(const char* code, T& ret)
|
bool ScriptInterface::Eval(const CHAR* code, T& ret)
|
||||||
{
|
{
|
||||||
jsval rval;
|
jsval rval;
|
||||||
if (! Eval_(code, rval))
|
if (! Eval_(code, rval))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue