Index: ps/trunk/source/graphics/ColladaManager.h =================================================================== --- ps/trunk/source/graphics/ColladaManager.h (revision 13418) +++ ps/trunk/source/graphics/ColladaManager.h (revision 13419) @@ -1,76 +1,78 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_COLLADAMANAGER #define INCLUDED_COLLADAMANAGER #include "lib/file/vfs/vfs.h" class CStr8; class CColladaManagerImpl; class MD5; class CColladaManager { + NONCOPYABLE(CColladaManager); + public: enum FileType { PMD, PSA }; CColladaManager(const PIVFS& vfs); ~CColladaManager(); /** * Returns the VFS path to a PMD/PSA file for the given source file. * Performs a (cached) conversion from COLLADA if necessary. * * @param pathnameNoExtension path and name, minus extension, of file to load. * One of either "sourceName.pmd" or "sourceName.dae" should exist. * @param type FileType, .pmd or .psa * * @return full VFS path (including extension) of file to load; or empty * string if there was a problem and it could not be loaded. Doesn't knowingly * return an invalid path. */ VfsPath GetLoadablePath(const VfsPath& pathnameNoExtension, FileType type); /** * Converts DAE to archive cached .pmd/psa and outputs the resulting path * (used by archive builder) * * @param[in] sourcePath path of the .dae to load * @param[in] type FileType, .pmd or .psa * @param[out] archiveCachePath output path of the cached file * * @return true if COLLADA converter completed successfully; or false if it failed */ bool GenerateCachedFile(const VfsPath& sourcePath, FileType type, VfsPath& archiveCachePath); private: /** * Creates MD5 hash key from skeletons.xml info and COLLADA converter version, * used to invalidate cached .pmd/psas * * @param[out] hash resulting MD5 hash * @param[out] version version passed to CCacheLoader, used if code change should force * cache invalidation */ void PrepareCacheKey(MD5& hash, u32& version); CColladaManagerImpl* m; PIVFS m_VFS; }; #endif // INCLUDED_COLLADAMANAGER Index: ps/trunk/source/graphics/MapGenerator.h =================================================================== --- ps/trunk/source/graphics/MapGenerator.h (revision 13418) +++ ps/trunk/source/graphics/MapGenerator.h (revision 13419) @@ -1,145 +1,146 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_MAPGENERATOR #define INCLUDED_MAPGENERATOR #include "ps/FileIo.h" #include "ps/ThreadUtil.h" #include "scriptinterface/ScriptInterface.h" #include #include class CMapGeneratorWorker; /** * Random map generator interface. Initialized by CMapReader and then checked * periodically during loading, until it's finished (progress value is 0). * * The actual work is performed by CMapGeneratorWorker in a separate thread. */ class CMapGenerator { + NONCOPYABLE(CMapGenerator); public: CMapGenerator(); ~CMapGenerator(); /** * Start the map generator thread * * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js" * @param settings JSON string containing settings for the map generator */ void GenerateMap(const VfsPath& scriptFile, const std::string& settings); /** * Get status of the map generator thread * * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error */ int GetProgress(); /** * Get random map data, according to this format: * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat * * @return StructuredClone containing map data */ shared_ptr GetResults(); private: CMapGeneratorWorker* m_Worker; }; /** * Random map generator worker thread. * (This is run in a thread so that the GUI remains responsive while loading) * * Thread-safety: * - Initialize and constructor/destructor must be called from the main thread. * - ScriptInterface created and destroyed by thread * - StructuredClone used to return JS map data - jsvals can't be used across threads/runtimes */ class CMapGeneratorWorker { public: CMapGeneratorWorker(); ~CMapGeneratorWorker(); /** * Start the map generator thread * * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js" * @param settings JSON string containing settings for the map generator */ void Initialize(const VfsPath& scriptFile, const std::string& settings); /** * Get status of the map generator thread * * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error */ int GetProgress(); /** * Get random map data, according to this format: * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat * * @return StructuredClone containing map data */ shared_ptr GetResults(); private: // Mapgen /** * Load all scripts of the given library * * @param libraryName String specifying name of the library (subfolder of ../maps/random/) * @return true if all scripts ran successfully, false if there's an error */ bool LoadScripts(const std::wstring& libraryName); // callbacks for script functions static bool LoadLibrary(void* cbdata, std::wstring name); static void ExportMap(void* cbdata, CScriptValRooted data); static void SetProgress(void* cbdata, int progress); static void MaybeGC(void* cbdata); static std::vector GetCivData(void* cbdata); std::set m_LoadedLibraries; shared_ptr m_MapData; boost::rand48 m_MapGenRNG; int m_Progress; ScriptInterface* m_ScriptInterface; VfsPath m_ScriptPath; std::string m_Settings; // Thread static void* RunThread(void* data); bool Run(); pthread_t m_WorkerThread; CMutex m_WorkerMutex; }; #endif //INCLUDED_MAPGENERATOR Index: ps/trunk/source/graphics/TextureManager.h =================================================================== --- ps/trunk/source/graphics/TextureManager.h (revision 13418) +++ ps/trunk/source/graphics/TextureManager.h (revision 13419) @@ -1,289 +1,291 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_TEXTUREMANAGER #define INCLUDED_TEXTUREMANAGER #include "Texture.h" #include "lib/ogl.h" #include "lib/file/vfs/vfs.h" #include "lib/res/handle.h" #include class CTextureProperties; class CTextureManagerImpl; /** * Texture manager with asynchronous loading and automatic DDS conversion/compression. * * Input textures can be any format. They will be converted to DDS using settings defined * in files named "texture.xml", in the same directory as the texture and in its parent * directories. See CTextureConverter for the XML syntax. The DDS file will be cached * for faster loading in the future. * * Typically the graphics code will initialise many textures at the start of the game, * mostly for off-screen objects, by calling CreateTexture(). * Loading texture data may be very slow (especially if it needs to be converted * to DDS), and we don't want the game to become unresponsive. * CreateTexture therefore returns an object immediately, without loading the * texture. If the object is never used then the data will never be loaded. * * Typically, the renderer will call CTexture::Bind() when it wants to use the * texture. This will trigger the loading of the texture data. If it can be loaded * quickly (i.e. there is already a cached DDS version), then it will be loaded before * the function returns, and the texture can be rendered as normal. * * If loading will take a long time, then Bind() binds a default placeholder texture * and starts loading the texture in the background. It will use the correct texture * when the renderer next calls Bind() after the load has finished. * * It is also possible to prefetch textures which are not being rendered yet, but * are expected to be rendered soon (e.g. for off-screen terrain tiles). * These will be loaded in the background, when there are no higher-priority textures * to load. * * The same texture file can be safely loaded multiple times with different GL parameters * (but this should be avoided whenever possible, as it wastes VRAM). * * For release packages, DDS files can be precached by appending ".dds" to their name, * which will be used instead of doing runtime conversion. This means most players should * never experience the slow asynchronous conversion behaviour. * These cache files will typically be packed into an archive for faster loading; * if no archive cache is available then the source file will be converted and stored * as a loose cache file on the user's disk. */ class CTextureManager { + NONCOPYABLE(CTextureManager); + public: /** * Construct texture manager. vfs must be the VFS instance used for all textures * loaded from this object. * highQuality is slower and intended for batch-conversion modes. * disableGL is intended for tests, and will disable all GL uploads. */ CTextureManager(PIVFS vfs, bool highQuality, bool disableGL); ~CTextureManager(); /** * Create a texture with the given GL properties. * The texture data will not be loaded immediately. */ CTexturePtr CreateTexture(const CTextureProperties& props); /** * Returns a magenta texture. Use this for highlighting errors * (e.g. missing terrain textures). */ CTexturePtr GetErrorTexture(); /** * Work on asynchronous texture loading operations, if any. * Returns true if it did any work. * The caller should typically loop this per frame until it returns * false or exceeds the allocated time for this frame. */ bool MakeProgress(); /** * Synchronously converts and compresses and saves the texture, * and returns the output path (minus a "cache/" prefix). This * is intended for pre-caching textures in release archives. * @return true on success */ bool GenerateCachedTexture(const VfsPath& path, VfsPath& outputPath); private: CTextureManagerImpl* m; }; /** * Represents the filename and GL parameters of a texture, * for passing to CTextureManager::CreateTexture. */ class CTextureProperties { friend class CTextureManagerImpl; friend struct TextureCacheCmp; friend struct TPequal_to; friend struct TPhash; public: /** * Use the given texture name, and default GL parameters. */ explicit CTextureProperties(const VfsPath& path) : m_Path(path), m_Filter(GL_LINEAR_MIPMAP_LINEAR), m_WrapS(GL_REPEAT), m_WrapT(GL_REPEAT), m_Aniso(1.0f) { } /** * Set min/mag filter mode (typically GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST, etc). */ void SetFilter(GLint filter) { m_Filter = filter; } /** * Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc). */ void SetWrap(GLint wrap) { m_WrapS = wrap; m_WrapT = wrap; } /** * Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc), * separately for S and T. */ void SetWrap(GLint wrap_s, GLint wrap_t) { m_WrapS = wrap_s; m_WrapT = wrap_t; } /** * Set maximum anisotropy value. Must be >= 1.0. Should be a power of 2. */ void SetMaxAnisotropy(float aniso) { m_Aniso = aniso; } // TODO: rather than this static definition of texture properties // (especially anisotropy), maybe we want something that can be more // easily tweaked in an Options menu? e.g. the caller just specifies // "terrain texture mode" and we combine it with the user's options. // That'd let us dynamically change texture properties easily. // // enum EQualityMode // { // NONE, // TERRAIN, // MODEL, // GUI // } // void SetQuality(EQualityMode mode, float anisotropy, float lodbias, int reducemipmaps, ...); // // or something a bit like that. private: VfsPath m_Path; GLint m_Filter; GLint m_WrapS; GLint m_WrapT; float m_Aniso; }; /** * Represents a texture object. * The texture data may or may not have been loaded yet. * Before it has been loaded, all operations will act on a default * 1x1-pixel grey texture instead. */ class CTexture { friend class CTextureManagerImpl; friend struct TextureCacheCmp; friend struct TPequal_to; friend struct TPhash; // Only the texture manager can create these explicit CTexture(Handle handle, const CTextureProperties& props, CTextureManagerImpl* textureManager); NONCOPYABLE(CTexture); public: ~CTexture(); /** * Returns the width (in pixels) of the current texture. */ size_t GetWidth() const; /** * Returns the height (in pixels) of the current texture. */ size_t GetHeight() const; /** * Returns whether the current texture has an alpha channel. */ bool HasAlpha() const; /** * Returns the ARGB value of the lowest mipmap level (i.e. the * average of the whole texture). * Returns 0 if the texture has no mipmaps. */ u32 GetBaseColour() const; /** * Bind the texture to the given GL texture unit. * If the texture data hasn't been loaded yet, this may wait a short while to * load it. If loading takes too long then it will return sooner and the data will * be loaded in a background thread, so this does not guarantee the texture really * will be loaded. */ void Bind(size_t unit = 0); /** * Returns a ogl_tex handle, for later binding. See comments from Bind(). */ Handle GetHandle(); /** * Attempt to load the texture data quickly, as with Bind(). * Returns whether the texture data is currently loaded. */ bool TryLoad(); /** * Returns whether the texture data is currently loaded. */ bool IsLoaded(); /** * Activate the prefetching optimisation for this texture. * Use this if it is likely the texture will be needed in the near future. * It will be loaded in the background so that it is likely to be ready when * it is used by Bind(). */ void Prefetch(); private: /** * Replace the Handle stored by this object. * If takeOwnership is true, it will not increment the Handle's reference count. */ void SetHandle(Handle handle, bool takeOwnership = false); const CTextureProperties m_Properties; Handle m_Handle; u32 m_BaseColour; enum { UNLOADED, // loading has not started PREFETCH_NEEDS_LOADING, // was prefetched; currently waiting to try loading from cache PREFETCH_NEEDS_CONVERTING, // was prefetched; currently waiting to be sent to the texture converter PREFETCH_IS_CONVERTING, // was prefetched; currently being processed by the texture converter HIGH_NEEDS_CONVERTING, // high-priority; currently waiting to be sent to the texture converter HIGH_IS_CONVERTING, // high-priority; currently being processed by the texture converter LOADED // loading has completed (successfully or not) } m_State; CTextureManagerImpl* m_TextureManager; // Self-reference to let us recover the CTexturePtr for this object. // (weak pointer to avoid cycles) boost::weak_ptr m_Self; }; #endif // INCLUDED_TEXTUREMANAGER Index: ps/trunk/source/gui/CGUI.h =================================================================== --- ps/trunk/source/gui/CGUI.h (revision 13418) +++ ps/trunk/source/gui/CGUI.h (revision 13419) @@ -1,683 +1,685 @@ /* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ /* CGUI --Overview-- This is the top class of the whole GUI, all objects and settings are stored within this class. --More info-- Check GUI.h */ #ifndef INCLUDED_CGUI #define INCLUDED_CGUI //-------------------------------------------------------- // Includes / Compiler directives //-------------------------------------------------------- // NOTE: GUI.h included at the bottom of this file (has to be after CGUI class // definition) #include "GUITooltip.h" #include "GUIbase.h" #include "ps/Overlay.h" // CPos and CRect #include "lib/input.h" #include "ps/XML/Xeromyces.h" #include //-------------------------------------------------------- // Macros //-------------------------------------------------------- //-------------------------------------------------------- // Types //-------------------------------------------------------- //-------------------------------------------------------- // Error declarations //-------------------------------------------------------- ERROR_TYPE(GUI, JSOpenFailed); //-------------------------------------------------------- // Declarations //-------------------------------------------------------- /** * Contains a list of values for new defaults to objects. */ struct SGUIStyle { // A list of defaults for std::map m_SettingsDefaults; }; struct JSObject; // The GUI stores a JSObject*, so needs to know that JSObject exists class IGUIObject; class CGUISpriteInstance; struct SGUIText; struct CColor; struct SGUIText; struct SGUIIcon; class CGUIString; class CGUISprite; struct SGUIImageEffects; struct SGUIScrollBarStyle; class GUITooltip; /** * The main object that represents a whole GUI page. * * No interfacial functions throws. */ class CGUI { + NONCOPYABLE(CGUI); + friend class IGUIObject; friend class IGUIScrollBarOwner; friend class CInternalCGUIAccessorBase; private: // Private typedefs typedef IGUIObject *(*ConstructObjectFunction)(); public: CGUI(); ~CGUI(); /** * Initializes GUI script classes */ static void ScriptingInit(); /** * Initializes the GUI, needs to be called before the GUI is used */ void Initialize(); /** * Performs processing that should happen every frame * (including sending the "Tick" event to scripts) */ void TickObjects(); /** * Sends a specified script event to every object * * @param EventName String representation of event name */ void SendEventToAll(const CStr& EventName); /** * Displays the whole GUI */ void Draw(); /** * Draw GUI Sprite * * @param Sprite Object referring to the sprite (which also caches * calculations for faster rendering) * @param CellID Number of the icon cell to use. (Ignored if this sprite doesn't * have any images with "cell-size") * @param Z Drawing order, depth value * @param Rect Position and Size * @param Clipping The sprite shouldn't be drawn outside this rectangle */ void DrawSprite(const CGUISpriteInstance& Sprite, int CellID, const float &Z, const CRect &Rect, const CRect &Clipping=CRect()); /** * Draw a SGUIText object * * @param Text Text object. * @param DefaultColor Color used if no tag applied. * @param pos position * @param z z value. * @param clipping */ void DrawText(SGUIText &Text, const CColor &DefaultColor, const CPos &pos, const float &z, const CRect &clipping); /** * Clean up, call this to clean up all memory allocated * within the GUI. */ void Destroy(); /** * The replacement of Process(), handles an SDL_Event_ * * @param ev SDL Event, like mouse/keyboard input */ InReaction HandleEvent(const SDL_Event_* ev); /** * Load a GUI XML file into the GUI. * * VERY IMPORTANT! All \-files must be read before * everything else! * * @param Filename Name of file * @param Paths Set of paths; all XML and JS files loaded will be added to this */ void LoadXmlFile(const VfsPath& Filename, boost::unordered_set& Paths); /** * Checks if object exists and return true or false accordingly * * @param Name String name of object * @return true if object exists */ bool ObjectExists(const CStr& Name) const; /** * Returns the GUI object with the desired name, or NULL * if no match is found, * * @param Name String name of object * @return Matching object, or NULL */ IGUIObject* FindObjectByName(const CStr& Name) const; /** * Returns the GUI object under the mouse, or NULL if none. */ IGUIObject* FindObjectUnderMouse() const; /** * The GUI needs to have all object types inputted and * their constructors. Also it needs to associate a type * by a string name of the type. * * To add a type: * @code * AddObjectType("button", &CButton::ConstructObject); * @endcode * * @param str Reference name of object type * @param pFunc Pointer of function ConstuctObject() in the object * * @see CGUI#ConstructObject() */ void AddObjectType(const CStr& str, ConstructObjectFunction pFunc) { m_ObjectTypes[str] = pFunc; } /** * Update Resolution, should be called every time the resolution * of the OpenGL screen has been changed, this is because it needs * to re-cache all its actual sizes * * Needs no input since screen resolution is global. * * @see IGUIObject#UpdateCachedSize() */ void UpdateResolution(); /** * Generate a SGUIText object from the inputted string. * The function will break down the string and its * tags to calculate exactly which rendering queries * will be sent to the Renderer. Also, horizontal alignment * is taken into acount in this method but NOT vertical alignment. * * Done through the CGUI since it can communicate with * * @param Text Text to generate SGUIText object from * @param Font Default font, notice both Default color and default font * can be changed by tags. * @param Width Width, 0 if no word-wrapping. * @param BufferZone space between text and edge, and space between text and images. * @param pObject Optional parameter for error output. Used *only* if error parsing fails, * and we need to be able to output which object the error occured in to aid the user. */ SGUIText GenerateText(const CGUIString &Text, const CStrW& Font, const float &Width, const float &BufferZone, const IGUIObject *pObject=NULL); /** * Returns the JSObject* associated with the GUI * * @return The relevant JS object */ JSObject* GetScriptObject() { return m_ScriptObject; } /** * Check if an icon exists */ bool IconExists(const CStr& str) const { return (m_Icons.count(str) != 0); } /** * Get Icon (a copy, can never be changed) */ SGUIIcon GetIcon(const CStr& str) const { return m_Icons.find(str)->second; } /** * Get pre-defined color (if it exists) * Returns false if it fails. */ bool GetPreDefinedColor(const CStr& name, CColor &Output); private: /** * Updates the object pointers, needs to be called each * time an object has been added or removed. * * This function is atomic, meaning if it throws anything, it will * have seen it through that nothing was ultimately changed. * * @throws PSERROR_GUI that is thrown from IGUIObject::AddToPointersMap(). */ void UpdateObjects(); /** * Adds an object to the GUI's object database * Private, since you can only add objects through * XML files. Why? Because it enables the GUI to * be much more encapsulated and safe. * * @throws Rethrows PSERROR_GUI from IGUIObject::AddChild(). */ void AddObject(IGUIObject* pObject); /** * You input the name of the object type, and let's * say you input "button", then it will construct a * CGUIObjet* as a CButton. * * @param str Name of object type * @return Newly constructed IGUIObject (but constructed as a subclass) */ IGUIObject *ConstructObject(const CStr& str); /** * Get Focused Object. */ IGUIObject *GetFocusedObject() { return m_FocusedObject; } public: /** * Change focus to new object. * Will send LOST_FOCUS/GOT_FOCUS messages as appropriate. * pObject can be NULL to remove all focus. */ void SetFocusedObject(IGUIObject* pObject); private: //-------------------------------------------------------- /** @name XML Reading Xeromyces specific subroutines * * These does not throw! * Because when reading in XML files, it won't be fatal * if an error occurs, perhaps one particular object * fails, but it'll still continue reading in the next. * All Error are reported with ReportParseError */ //-------------------------------------------------------- /* Xeromyces_* functions tree (ReadRootObjects) | +-