diff --git a/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-1.png b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-1.png new file mode 100644 index 0000000000..2974654872 --- /dev/null +++ b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf3510069b105e277d5d07f827e258acac2b78ada9195443b1a63984dc1a84d2 +size 1886535 diff --git a/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-2.png b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-2.png new file mode 100644 index 0000000000..720284c8e7 --- /dev/null +++ b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cd9c398dd47d18c88fcbda20787ecc59910606d48e17b4a1c4e9ac7b3add363 +size 853248 diff --git a/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-3.png b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-3.png new file mode 100644 index 0000000000..2d6af188f2 --- /dev/null +++ b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/hellenes1-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23f1cd531dcd14224664f8d94938a9ebc57cc339adbb7d3bd5a315399688627c +size 1129747 diff --git a/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/textures.xml b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/textures.xml new file mode 100644 index 0000000000..6eb234e577 --- /dev/null +++ b/binaries/data/mods/public/art/textures/ui/pregame/backgrounds/textures.xml @@ -0,0 +1,4 @@ + + + + diff --git a/binaries/data/mods/public/gui/pregame/mainmenu.js b/binaries/data/mods/public/gui/pregame/mainmenu.js index a17019648b..996a550ac1 100644 --- a/binaries/data/mods/public/gui/pregame/mainmenu.js +++ b/binaries/data/mods/public/gui/pregame/mainmenu.js @@ -9,6 +9,31 @@ function init() userReportEnabledText = getGUIObjectByName("userReportEnabledText").caption; } +var t0 = new Date; +function scrollBackgrounds() +{ + var layer1 = getGUIObjectByName("backgroundLayer1"); + var layer2 = getGUIObjectByName("backgroundLayer2"); + var layer3 = getGUIObjectByName("backgroundLayer3"); + + var screen = layer1.parent.getComputedSize(); + var h = screen.bottom - screen.top; // height of screen + var w = h*16/9; // width of background image + + // Offset the layers by oscillating amounts + var t = (t0 - new Date) / 1000; + var speed = 1/10; + var off1 = 0.10 * w * (1+Math.cos(t*speed)); + var off2 = 0.18 * w * (1+Math.cos(t*speed)) - h*6/9; + var off3 = 0.20 * w * (1+Math.cos(t*speed)); + + var left = screen.right - w * (1 + Math.ceil(screen.right / w)); + layer1.size = new GUISize(left + off1, screen.top, screen.right + off1, screen.bottom); + + layer2.size = new GUISize(screen.right - h + off2, screen.top, screen.right + off2, screen.bottom); + layer3.size = new GUISize(screen.right - h + off3, screen.top, screen.right + off3, screen.bottom); +} + function submitUserReportMessage() { var input = getGUIObjectByName("userReportMessageInput"); @@ -55,6 +80,8 @@ function formatUserReportStatus(status) function onTick() { + scrollBackgrounds(); + if (Engine.IsUserReportEnabled()) { getGUIObjectByName("userReportDisabled").hidden = true; diff --git a/binaries/data/mods/public/gui/pregame/mainmenu.xml b/binaries/data/mods/public/gui/pregame/mainmenu.xml index 3eb2bfd955..f91e631495 100644 --- a/binaries/data/mods/public/gui/pregame/mainmenu.xml +++ b/binaries/data/mods/public/gui/pregame/mainmenu.xml @@ -13,11 +13,20 @@ - + + + + + onTick(); @@ -445,7 +454,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 @@ -468,7 +477,7 @@ You can automatically send us anonymous feedback that will help us fix bugs, and diff --git a/binaries/data/mods/public/gui/pregame/sprites.xml b/binaries/data/mods/public/gui/pregame/sprites.xml index 9288b21f12..be6022bf7e 100644 --- a/binaries/data/mods/public/gui/pregame/sprites.xml +++ b/binaries/data/mods/public/gui/pregame/sprites.xml @@ -2,16 +2,27 @@ - + + + - - + + + + + diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index e4f9f10421..18fdf8fb6d 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -1590,6 +1590,36 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite else image.m_CellSize = size; } else + if (attr_name == "fixed_h_aspect_ratio") + { + float val; + if (!GUI::ParseString(attr_value, val)) + LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); + else image.m_FixedHAspectRatio = val; + } + else + if (attr_name == "round_coordinates") + { + bool b; + if (!GUI::ParseString(attr_value, b)) + LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); + else image.m_RoundCoordinates = b; + } + else + if (attr_name == "wrap_mode") + { + if (attr_value == L"repeat") + image.m_WrapMode = GL_REPEAT; + else if (attr_value == L"mirrored_repeat") + image.m_WrapMode = GL_MIRRORED_REPEAT; + else if (attr_value == L"clamp_to_edge") + image.m_WrapMode = GL_CLAMP_TO_EDGE; + else if (attr_value == L"clamp_to_border") + image.m_WrapMode = GL_CLAMP_TO_BORDER; + else + LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); + } + else if (attr_name == "z_level") { float z_level; diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index ea8ed0aa9c..fa7ed9aca3 100644 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -77,7 +77,11 @@ struct SGUIImageEffects */ struct SGUIImage { - SGUIImage() : m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) {} + SGUIImage() : + m_FixedHAspectRatio(0.f), m_RoundCoordinates(true), m_WrapMode(GL_REPEAT), + m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) + { + } // Filename of the texture VfsPath m_TextureName; @@ -99,6 +103,23 @@ struct SGUIImage // Equal to CSize(0,0) for non-celled textures. CSize m_CellSize; + /** + * If non-zero, then the image's width will be adjusted when rendering so that + * the width:height ratio equals this value. + */ + float m_FixedHAspectRatio; + + /** + * If true, the image's coordinates will be rounded to integer pixels when + * rendering, to avoid blurry filtering. + */ + bool m_RoundCoordinates; + + /** + * Texture wrapping mode (GL_REPEAT, GL_CLAMP_TO_BORDER, etc) + */ + GLint m_WrapMode; + // Visual effects (e.g. colour modulation) SGUIImageEffects* m_Effects; diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 251f5c128a..e266056c68 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -452,15 +452,19 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, } Call.m_Vertices = ObjectSize; - // Round the vertex coordinates to integers, to avoid ugly filtering artifacts - Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f); - Call.m_Vertices.right = (int)(Call.m_Vertices.right + 0.5f); - Call.m_Vertices.top = (int)(Call.m_Vertices.top + 0.5f); - Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f); + if (cit->m_RoundCoordinates) + { + // Round the vertex coordinates to integers, to avoid ugly filtering artifacts + Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f); + Call.m_Vertices.right = (int)(Call.m_Vertices.right + 0.5f); + Call.m_Vertices.top = (int)(Call.m_Vertices.top + 0.5f); + Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f); + } if (! cit->m_TextureName.empty()) { CTextureProperties textureProps(cit->m_TextureName); + textureProps.SetWrap(cit->m_WrapMode); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); Call.m_HasTexture = true; @@ -535,6 +539,9 @@ CRect SDrawCall::ComputeTexCoords() const // Get the screen's position/size for the block CRect BlockScreen = m_Image->m_TextureSize.GetClientArea(m_ObjectSize); + if (m_Image->m_FixedHAspectRatio) + BlockScreen.right = BlockScreen.left + BlockScreen.GetHeight() * m_Image->m_FixedHAspectRatio; + // Get the texture's position/size for the block: CRect BlockTex; @@ -593,6 +600,9 @@ void GUIRenderer::Draw(DrawCalls &Calls) glDisable(GL_BLEND); + // Set LOD bias so mipmapped textures are prettier + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.f); + // Iterate through each DrawCall, and execute whatever drawing code is being called for (DrawCalls::const_iterator cit = Calls.begin(); cit != Calls.end(); ++cit) { @@ -670,4 +680,6 @@ void GUIRenderer::Draw(DrawCalls &Calls) glDisable(GL_BLEND); } + + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.f); } diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index 324add9985..de5e60dc91 100644 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -147,6 +147,7 @@ class IGUIObject // Allow getProperty to access things like GetParent() friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp); + friend JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp); public: IGUIObject(); diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index aeb7cf2cfd..65ad181b41 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -49,6 +49,7 @@ JSFunctionSpec JSI_IGUIObject::JSI_methods[] = { "toString", JSI_IGUIObject::toString, 0, 0 }, { "focus", JSI_IGUIObject::focus, 0, 0 }, { "blur", JSI_IGUIObject::blur, 0, 0 }, + { "getComputedSize", JSI_IGUIObject::getComputedSize, 0, 0 }, { 0 } }; @@ -75,7 +76,8 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* propName == "prototype" || propName == "toString" || propName == "focus" || - propName == "blur" + propName == "blur" || + propName == "getComputedSize" ) return JS_TRUE; @@ -647,3 +649,32 @@ JSBool JSI_IGUIObject::blur(JSContext* cx, uintN argc, jsval* vp) JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } + +JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp) +{ + UNUSED2(argc); + + IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); + if (!e) + return JS_FALSE; + + e->UpdateCachedSize(); + CRect size = e->m_CachedActualSize; + + JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL); + try + { + g_ScriptingHost.SetObjectProperty_Double(obj, "left", size.left); + g_ScriptingHost.SetObjectProperty_Double(obj, "right", size.right); + g_ScriptingHost.SetObjectProperty_Double(obj, "top", size.top); + g_ScriptingHost.SetObjectProperty_Double(obj, "bottom", size.bottom); + } + catch (PSERROR_Scripting_ConversionFailed) + { + debug_warn(L"Error creating size object!"); + return JS_FALSE; + } + + JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); + return JS_TRUE; +} diff --git a/source/gui/scripting/JSInterface_IGUIObject.h b/source/gui/scripting/JSInterface_IGUIObject.h index 3f2bab844f..8a2bc1e344 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.h +++ b/source/gui/scripting/JSInterface_IGUIObject.h @@ -31,6 +31,7 @@ namespace JSI_IGUIObject JSBool toString(JSContext* cx, uintN argc, jsval* vp); JSBool focus(JSContext* cx, uintN argc, jsval* vp); JSBool blur(JSContext* cx, uintN argc, jsval* vp); + JSBool getComputedSize(JSContext* cx, uintN argc, jsval* vp); void init(); } diff --git a/source/ps/Overlay.cpp b/source/ps/Overlay.cpp index 99c7f6c716..28d79aca25 100644 --- a/source/ps/Overlay.cpp +++ b/source/ps/Overlay.cpp @@ -249,9 +249,19 @@ CPos CRect::TopLeft() const return CPos(left, top); } +CPos CRect::TopRight() const +{ + return CPos(right, top); +} + +CPos CRect::BottomLeft() const +{ + return CPos(left, bottom); +} + CPos CRect::BottomRight() const { - return CPos(right, right); + return CPos(right, bottom); } CPos CRect::CenterPoint() const diff --git a/source/ps/Overlay.h b/source/ps/Overlay.h index 84f564752d..d4ed860ea2 100644 --- a/source/ps/Overlay.h +++ b/source/ps/Overlay.h @@ -119,6 +119,16 @@ public: */ CPos TopLeft() const; + /** + * Get Position equivalent to top/right corner + */ + CPos TopRight() const; + + /** + * Get Position equivalent to bottom/left corner + */ + CPos BottomLeft() const; + /** * Get Position equivalent to bottom/right corner */