├── .gitignore ├── .gitmodules ├── README ├── bounds.h ├── conffile.cpp ├── conffile.h ├── display.cpp ├── display.h ├── frustum.cpp ├── frustum.h ├── ftgl └── FTUnicode.h ├── fxfont.cpp ├── fxfont.h ├── gl.h ├── logger.cpp ├── logger.h ├── mousecursor.cpp ├── mousecursor.h ├── pi.h ├── plane.cpp ├── plane.h ├── png_writer.cpp ├── png_writer.h ├── ppm.cpp ├── ppm.h ├── quadtree.cpp ├── quadtree.h ├── regex.cpp ├── regex.h ├── resource.cpp ├── resource.h ├── sdlapp.cpp ├── sdlapp.h ├── seeklog.cpp ├── seeklog.h ├── settings.cpp ├── settings.h ├── shader.cpp ├── shader.h ├── shader_common.cpp ├── shader_common.h ├── stringhash.cpp ├── stringhash.h ├── texture.cpp ├── texture.h ├── tga.cpp ├── tga.h ├── timer.cpp ├── timer.h ├── timezone.cpp ├── timezone.h ├── ui ├── action.h ├── button.cpp ├── button.h ├── checkbox.cpp ├── checkbox.h ├── colour.cpp ├── colour.h ├── console.cpp ├── console.h ├── element.cpp ├── element.h ├── file_selector.cpp ├── file_selector.h ├── group.cpp ├── group.h ├── image.cpp ├── image.h ├── label.cpp ├── label.h ├── layout.cpp ├── layout.h ├── scroll_bar.cpp ├── scroll_bar.h ├── scroll_layout.cpp ├── scroll_layout.h ├── select.cpp ├── select.h ├── slider.cpp ├── slider.h ├── solid_layout.cpp ├── solid_layout.h ├── subgroup.cpp ├── subgroup.h ├── ui.cpp └── ui.h ├── utf8 ├── checked.h ├── core.h ├── cpp11.h ├── unchecked.h └── utf8.h ├── vbo.cpp ├── vbo.h ├── vectors.cpp └── vectors.h /.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | .dirstamp 3 | .makepp 4 | Makefile 5 | *.o 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acaudwell/Core/df513a31f531e869a0eb7a2a6174a0e93b8d2ffb/.gitmodules -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Core library used by Gource and Logstalgia. 2 | -------------------------------------------------------------------------------- /bounds.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef BOUNDS_H 29 | #define BOUNDS_H 30 | 31 | #include "display.h" 32 | #include "vectors.h" 33 | 34 | class Bounds2D { 35 | public: 36 | vec2 min; 37 | vec2 max; 38 | bool first; 39 | 40 | vec2 centre() const { 41 | return min + (max - min) * 0.5f; 42 | } 43 | 44 | float width() const { 45 | return max.x - min.x; 46 | } 47 | 48 | float height() const { 49 | return max.y - min.y; 50 | } 51 | 52 | float area() const { 53 | return width() * height(); 54 | } 55 | 56 | void reset() { 57 | min = vec2(0.0, 0.0); 58 | max = vec2(0.0, 0.0); 59 | first = true; 60 | } 61 | 62 | Bounds2D() { 63 | reset(); 64 | } 65 | 66 | Bounds2D(const vec2& min, const vec2& max) { 67 | reset(); 68 | update(min); 69 | update(max); 70 | } 71 | 72 | void update(const Bounds2D& bounds) { 73 | update(bounds.min); 74 | update(bounds.max); 75 | } 76 | 77 | 78 | void set(const Bounds2D& bounds) { 79 | reset(); 80 | update(bounds); 81 | } 82 | 83 | void set(vec2 point) { 84 | reset(); 85 | update(point); 86 | } 87 | 88 | void set(const vec2& a, const vec2& b) { 89 | reset(); 90 | update(a); 91 | update(b); 92 | } 93 | 94 | void update(const vec2& point) { 95 | if(first) { 96 | min = point; 97 | max = point; 98 | first=false; 99 | return; 100 | } 101 | 102 | if(min.x > point.x) min.x = point.x; 103 | if(min.y > point.y) min.y = point.y; 104 | if(max.x < point.x) max.x = point.x; 105 | if(max.y < point.y) max.y = point.y; 106 | } 107 | 108 | bool contains(const vec2& point) const { 109 | if(first) return false; 110 | 111 | if(min.x<=point.x && min.y<=point.y && max.x >= point.x && max.y >= point.y) 112 | return true; 113 | 114 | return false; 115 | } 116 | 117 | bool overlaps(const Bounds2D & b) const { 118 | 119 | if(max.y < b.min.y) return false; 120 | if(min.y > b.max.y) return false; 121 | if(max.x < b.min.x) return false; 122 | if(min.x > b.max.x) return false; 123 | 124 | return true; 125 | } 126 | 127 | void draw() const{ 128 | glBegin(GL_LINE_STRIP); 129 | glVertex2fv(glm::value_ptr(min)); 130 | glVertex2f(max.x, min.y); 131 | glVertex2fv(glm::value_ptr(max)); 132 | glVertex2f(min.x, max.y); 133 | glVertex2fv(glm::value_ptr(min)); 134 | glEnd(); 135 | } 136 | }; 137 | 138 | class Bounds3D { 139 | public: 140 | vec3 min; 141 | vec3 max; 142 | bool first; 143 | 144 | void reset() { 145 | min = vec3(0.0, 0.0, 0.0); 146 | max = vec3(0.0, 0.0, 0.0); 147 | first = true; 148 | } 149 | 150 | Bounds3D() { 151 | reset(); 152 | } 153 | 154 | Bounds3D(vec3 min, vec3 max) { 155 | reset(); 156 | update(min); 157 | update(max); 158 | } 159 | 160 | float width() { 161 | return max.x - min.x; 162 | } 163 | 164 | float height() { 165 | return max.y - min.y; 166 | } 167 | 168 | float depth() { 169 | return max.z - min.z; 170 | } 171 | 172 | float area() { 173 | return width() * height() * depth(); 174 | } 175 | 176 | vec3 centre() { 177 | return min + ((max-min) * 0.5f); 178 | } 179 | 180 | void update(vec3 point) { 181 | if(first) { 182 | min = point; 183 | max = point; 184 | first = false; 185 | return; 186 | } 187 | 188 | if(min.x > point.x) min.x = point.x; 189 | if(min.y > point.y) min.y = point.y; 190 | if(min.z > point.z) min.z = point.z; 191 | if(max.x < point.x) max.x = point.x; 192 | if(max.y < point.y) max.y = point.y; 193 | if(max.z < point.z) max.z = point.z; 194 | } 195 | 196 | bool contains(vec3& point) { 197 | if(first) return false; 198 | 199 | if(min.x<=point.x && min.y<=point.y && min.z<=point.z && max.x >= point.x && max.y >= point.y && max.z >= point.z) 200 | return true; 201 | 202 | return false; 203 | } 204 | 205 | void draw() { 206 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 207 | glBegin(GL_LINES); 208 | glVertex3fv(glm::value_ptr(min)); 209 | glVertex3fv(glm::value_ptr(max)); 210 | glEnd(); 211 | } 212 | 213 | }; 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /conffile.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 7 | 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #ifndef CONF_FILE_H 19 | #define CONF_FILE_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "vectors.h" 29 | 30 | class ConfFileException : public std::exception { 31 | protected: 32 | std::string errmsg; 33 | public: 34 | ConfFileException(const std::string& errmsg, const std::string& conffile, int lineno = 0) : errmsg(errmsg), conffile(conffile), lineno(lineno) {} 35 | 36 | std::string conffile; 37 | int lineno; 38 | 39 | virtual ~ConfFileException() throw () {}; 40 | 41 | virtual const char* what() const throw() { return errmsg.c_str(); } 42 | }; 43 | 44 | class ConfEntry { 45 | std::string name; 46 | std::string value; 47 | int lineno; 48 | 49 | public: 50 | ConfEntry(); 51 | ConfEntry(const std::string& name); 52 | ConfEntry(const std::string& name, const std::string& value, int lineno = 0); 53 | ConfEntry(const std::string& name, int value); 54 | ConfEntry(const std::string& name, float value); 55 | ConfEntry(const std::string& name, bool value); 56 | ConfEntry(const std::string& name, vec2 value); 57 | ConfEntry(const std::string& name, vec3 value); 58 | ConfEntry(const std::string& name, vec4 value); 59 | 60 | void setName(const std::string& name); 61 | 62 | void setString(const std::string& value); 63 | void setFloat(float value); 64 | void setInt(int value); 65 | void setBool(bool value); 66 | void setVec2(vec2 value); 67 | void setVec3(vec3 value); 68 | void setVec4(vec4 value); 69 | 70 | bool hasValue(); 71 | 72 | int getLineNumber(); 73 | std::string getName(); 74 | 75 | std::string getString(); 76 | int getInt(); 77 | float getFloat(); 78 | bool getBool(); 79 | vec2 getVec2(); 80 | vec3 getVec3(); 81 | vec4 getVec4(); 82 | 83 | bool isFloat(); 84 | bool isInt(); 85 | bool isBool(); 86 | bool isVec2(); 87 | bool isVec3(); 88 | bool isVec4(); 89 | }; 90 | 91 | typedef std::list ConfEntryList; 92 | 93 | class ConfFile; 94 | 95 | class ConfSection { 96 | std::map entrymap; 97 | std::string name; 98 | int lineno; 99 | ConfFile* conf; 100 | public: 101 | ConfSection(); 102 | ConfSection(const std::string& name, int lineno = 0); 103 | ~ConfSection(); 104 | 105 | void clear(); 106 | 107 | ConfFile* getConfFile(); 108 | ConfEntry* getEntry(const std::string& key); 109 | ConfEntryList* getEntries(const std::string& key); 110 | 111 | void setConfFile(ConfFile* conf); 112 | 113 | void sectionException(ConfEntry* entry, std::string reason); 114 | 115 | std::string getName(); 116 | 117 | int getLineNumber(); 118 | 119 | bool hasValue(const std::string& key); 120 | 121 | std::string getString(const std::string& key); 122 | int getInt(const std::string& key); 123 | float getFloat(const std::string& key); 124 | bool getBool(const std::string& key); 125 | vec3 getVec3(const std::string& key); 126 | vec4 getVec4(const std::string& key); 127 | 128 | void print(std::ostream& out); 129 | 130 | void setEntry(ConfEntry* entry); 131 | void addEntry(ConfEntry* entry); 132 | 133 | void setEntry(const std::string& name, const std::string& value, int lineno=0); 134 | void addEntry(const std::string& name, const std::string& value, int lineno=0); 135 | }; 136 | 137 | typedef std::list ConfSectionList; 138 | 139 | class ConfFile { 140 | 141 | std::string conffile; 142 | 143 | std::map sectionmap; 144 | public: 145 | ConfFile(); 146 | ~ConfFile(); 147 | void clear(); 148 | 149 | void setFilename(const std::string& filename); 150 | std::string getFilename(); 151 | 152 | void load(const std::string& conffile); 153 | void load(); 154 | 155 | void save(const std::string& conffile); 156 | void save(); 157 | 158 | bool hasSection(const std::string& section); 159 | ConfSection* getSection(const std::string& section); 160 | ConfSectionList* getSections(const std::string& section); 161 | 162 | ConfEntry* getEntry(const std::string& section, const std::string& key); 163 | ConfEntryList* getEntries(const std::string& section, const std::string& key); 164 | 165 | void addSection(ConfSection* section); 166 | ConfSection* addSection(const std::string& section); 167 | 168 | void setSection(ConfSection* section); 169 | 170 | int countSection(const std::string& section); 171 | 172 | void setEntry(const std::string& section, const std::string& key, const std::string& value); 173 | 174 | bool hasEntry(const std::string& section, const std::string& key); 175 | bool hasValue(const std::string& section, const std::string& key); 176 | std::string getString(const std::string& section, const std::string& key); 177 | int getInt(const std::string& section, const std::string& key); 178 | float getFloat(const std::string& section, const std::string& key); 179 | bool getBool(const std::string& section, const std::string& key); 180 | vec3 getVec3(const std::string& section, const std::string& key); 181 | vec4 getVec4(const std::string& section, const std::string& key); 182 | 183 | static void trim(std::string& value); 184 | 185 | void unknownOptionException(ConfEntry* entry); 186 | void missingValueException(ConfEntry* entry); 187 | void invalidValueException(ConfEntry* entry); 188 | void missingEntryException(ConfSection* section, std::string entryname); 189 | void sectionException(ConfSection* section, std::string reason); 190 | void entryException(ConfEntry* entry, std::string reason); 191 | }; 192 | 193 | #endif 194 | -------------------------------------------------------------------------------- /display.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (c) 2008 Andrew Caudwell (acaudwell@gmail.com) 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. The name of the author may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef SDLAPP_DISPLAY_H 30 | #define SDLAPP_DISPLAY_H 31 | 32 | #include "gl.h" 33 | 34 | #include "shader.h" 35 | #include "logger.h" 36 | #include "vectors.h" 37 | #include "texture.h" 38 | #include "fxfont.h" 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | class SDLInitException : public std::exception { 48 | protected: 49 | std::string error; 50 | public: 51 | SDLInitException(const std::string& error) : error(error) {} 52 | virtual ~SDLInitException() throw () {}; 53 | 54 | virtual const char* what() const throw() { return error.c_str(); } 55 | }; 56 | 57 | class SDLAppDisplay { 58 | 59 | bool enable_alpha; 60 | bool resizable; 61 | bool fullscreen; 62 | bool frameless; 63 | bool experimental; 64 | bool high_dpi_aware; 65 | bool vsync; 66 | 67 | int zbuffer_depth; 68 | int multi_sample; 69 | 70 | Uint32 SDLWindowFlags(bool fullscreen); 71 | 72 | void setupExtensions(); 73 | void updateViewportDPIRatio(); 74 | public: 75 | int width, height; 76 | int desktop_width, desktop_height; 77 | int windowed_width, windowed_height; 78 | vec2 viewport_dpi_ratio; 79 | 80 | #if SDL_VERSION_ATLEAST(2,0,0) 81 | SDL_Window* sdl_window; 82 | SDL_GLContext gl_context; 83 | 84 | int framed_width, framed_height; 85 | int framed_x, framed_y; 86 | #else 87 | SDL_Surface *surface; 88 | #endif 89 | vec4 clear_colour; 90 | 91 | SDLAppDisplay(); 92 | ~SDLAppDisplay(); 93 | 94 | void getFullscreenResolution(int& width, int& height); 95 | void toggleFullscreen(); 96 | void toggleFrameless(); 97 | 98 | bool isFullscreen() const; 99 | bool isFrameless() const; 100 | 101 | void resize(int width, int height); 102 | 103 | void init(std::string window_title, int width, int height, bool fullscreen, int screen = -1); 104 | void setVideoMode(int width, int height, bool fullscreen, int screen = -1); 105 | 106 | bool multiSamplingEnabled(); 107 | 108 | void quit(); 109 | 110 | void update(); 111 | void clear(); 112 | 113 | void setClearColour(vec3 colour); 114 | void setClearColour(vec4 colour); 115 | 116 | void setZBufferDepth(int zbuffer_depth); 117 | 118 | void enableVsync(bool vsync); 119 | void enableAlpha(bool enable); 120 | void enableResize(bool resizable); 121 | void enableFrameless(bool frameless); 122 | void enableHighDPIAwareness(bool enable); 123 | void enableExperimental(bool enable); 124 | 125 | void multiSample(int sample); 126 | 127 | void mode3D(float fov, float znear, float zfar); 128 | void mode2D(); 129 | 130 | void push2D(); 131 | void pop2D(); 132 | 133 | vec4 currentColour(); 134 | 135 | vec3 project(vec3 pos); 136 | vec3 unproject(vec2 pos); 137 | }; 138 | 139 | extern SDLAppDisplay display; 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /frustum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "frustum.h" 29 | 30 | // Lighthouse 3D Frustum tutorial: 31 | // http://www.lighthouse3d.com/opengl/viewfrustum/index.php?gasource 32 | 33 | Frustum::Frustum() { 34 | } 35 | 36 | Frustum::Frustum(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance) { 37 | update(source, target, up, fov, near_distance, far_distance); 38 | } 39 | 40 | void Frustum::update(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance) { 41 | updatePerspective(fov, near_distance, far_distance); 42 | updateView(source, target, up); 43 | } 44 | 45 | void Frustum::updatePerspective(float fov, float near_distance, float far_distance) { 46 | 47 | this->near_distance = near_distance; 48 | this->far_distance = far_distance; 49 | 50 | view_ratio = (float) display.width / (float) display.height; 51 | 52 | float toa = (float) tan(fov * 0.5 * DEGREES_TO_RADIANS); 53 | 54 | near_half_height = near_distance * toa; 55 | near_half_width = near_half_height * view_ratio; 56 | far_half_height = far_distance * toa; 57 | far_half_width = far_half_height * view_ratio; 58 | } 59 | 60 | void Frustum::updateView(const vec3& source, const vec3& target, const vec3& up) { 61 | 62 | vec3 view_ray = normalise(target - source); 63 | 64 | vec3 horiz_normal = normalise(glm::cross(view_ray,up)); 65 | 66 | vec3 vert_normal = glm::cross(horiz_normal, view_ray); 67 | 68 | //calculate the positions of the 8 points that make up 69 | //the viewing frustum and then use them to create the 6 planes 70 | 71 | vec3 near_centre = source + view_ray * near_distance; 72 | vec3 far_centre = source + view_ray * far_distance; 73 | 74 | vec3 near_horiz_offset = horiz_normal * near_half_width; 75 | vec3 near_vert_offset = vert_normal * near_half_height; 76 | 77 | near_top_left = near_centre + near_vert_offset - near_horiz_offset; 78 | near_top_right = near_centre + near_vert_offset + near_horiz_offset; 79 | near_bottom_left = near_centre - near_vert_offset - near_horiz_offset; 80 | near_bottom_right = near_centre - near_vert_offset + near_horiz_offset; 81 | 82 | vec3 far_horiz_offset = horiz_normal * far_half_width; 83 | vec3 far_vert_offset = vert_normal * far_half_height; 84 | 85 | far_top_left = far_centre + far_vert_offset - far_horiz_offset; 86 | far_top_right = far_centre + far_vert_offset + far_horiz_offset; 87 | far_bottom_left = far_centre - far_vert_offset - far_horiz_offset; 88 | far_bottom_right = far_centre - far_vert_offset + far_horiz_offset; 89 | 90 | //top 91 | planes[0] = Plane(near_top_right, near_top_left, far_top_left); 92 | 93 | //bottom 94 | planes[1] = Plane(near_bottom_left, near_bottom_right, far_bottom_right); 95 | 96 | //left 97 | planes[2] = Plane(near_top_left, near_bottom_left, far_bottom_left); 98 | 99 | //right 100 | planes[3] = Plane(near_bottom_right, near_top_right, far_bottom_right); 101 | 102 | //near 103 | planes[4] = Plane(near_top_left, near_top_right, near_bottom_right); 104 | 105 | //far 106 | planes[5] = Plane(far_top_right, far_top_left, far_bottom_left); 107 | } 108 | 109 | bool Frustum::contains(const vec3& p) const { 110 | 111 | for(int i=0; i < 6; i++) { 112 | float dist = planes[i].distance(p); 113 | 114 | if(dist < 0) return false; 115 | } 116 | 117 | return true; 118 | } 119 | 120 | bool Frustum::intersects(const Bounds3D& bounds) const { 121 | 122 | vec3 corner; 123 | 124 | for(int i=0; i<6; i++) { 125 | 126 | corner.x = planes[i].normal.x > 0.0 ? bounds.max.x : bounds.min.x; 127 | corner.y = planes[i].normal.y > 0.0 ? bounds.max.y : bounds.min.y; 128 | corner.z = planes[i].normal.z > 0.0 ? bounds.max.z : bounds.min.z; 129 | 130 | if (planes[i].distance(corner) < 0.0) return false; 131 | } 132 | 133 | return true; 134 | 135 | } 136 | 137 | bool Frustum::intersects(const Bounds2D& bounds, float z) const { 138 | 139 | vec3 corner; 140 | 141 | for(int i=0; i<6; i++) { 142 | 143 | corner.x = planes[i].normal.x > 0.0 ? bounds.max.x : bounds.min.x; 144 | corner.y = planes[i].normal.y > 0.0 ? bounds.max.y : bounds.min.y; 145 | corner.z = z; 146 | 147 | if (planes[i].distance(corner) < 0.0) return false; 148 | } 149 | 150 | return true; 151 | } 152 | 153 | 154 | -------------------------------------------------------------------------------- /frustum.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef FRUSTUM_H 29 | #define FRUSTUM_H 30 | 31 | #include "gl.h" 32 | #include "plane.h" 33 | #include "pi.h" 34 | #include "bounds.h" 35 | 36 | class Frustum { 37 | 38 | float near_distance, far_distance; 39 | float view_ratio; 40 | float fov; 41 | 42 | float near_half_width; 43 | float near_half_height; 44 | float far_half_width; 45 | float far_half_height; 46 | 47 | vec3 near_top_left, near_top_right; 48 | vec3 near_bottom_left, near_bottom_right; 49 | vec3 far_top_left, far_top_right; 50 | vec3 far_bottom_left, far_bottom_right; 51 | 52 | Plane planes[6]; 53 | public: 54 | Frustum(); 55 | Frustum(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance); 56 | 57 | void update(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance); 58 | 59 | void updatePerspective(float fov, float near_distance, float far_distance); 60 | void updateView(const vec3& source, const vec3& target, const vec3& up); 61 | 62 | bool contains(const vec3& p) const; 63 | 64 | bool intersects(const Bounds3D& bounds) const; 65 | bool intersects(const Bounds2D& bounds, float z = 0.0) const; 66 | }; 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /gl.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_GL_H 2 | #define CORE_GL_H 3 | 4 | #include 5 | 6 | #define PRINT_GL_ERRORS 7 | 8 | #ifdef PRINT_GL_ERRORS 9 | #define glCheckError() { \ 10 | int gl_error = glGetError(); \ 11 | if(gl_error != GL_NO_ERROR) warnLog("GL error %s at %s:%d", gluErrorString(gl_error), __FILE__, __LINE__); \ 12 | } 13 | #else 14 | #define glCheckError() 15 | #endif 16 | 17 | #endif 18 | 19 | 20 | -------------------------------------------------------------------------------- /logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "logger.h" 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | std::map log_levels = boost::assign::map_list_of 36 | (LOG_LEVEL_ERROR, " ERROR" ) 37 | (LOG_LEVEL_CONSOLE, "CONSOLE" ) 38 | (LOG_LEVEL_INFO, " INFO" ) 39 | (LOG_LEVEL_SCRIPT, " SCRIPT" ) 40 | (LOG_LEVEL_DEBUG, " DEBUG" ) 41 | (LOG_LEVEL_WARN, " WARN" ) 42 | (LOG_LEVEL_PEDANTIC, " PEDANT" ); 43 | 44 | #define PARSE_AND_LOG(LOG_LEVEL) \ 45 | Logger* logger = Logger::getDefault(); \ 46 | \ 47 | if(!logger || logger->getLevel() < LOG_LEVEL) return; \ 48 | \ 49 | char msgbuff[65536]; \ 50 | char* buffer = msgbuff; \ 51 | \ 52 | va_list vl; \ 53 | \ 54 | va_start(vl, str); \ 55 | int string_size = vsnprintf(buffer, sizeof(msgbuff), str, vl) + 1; \ 56 | \ 57 | if(string_size > sizeof(msgbuff)) { \ 58 | buffer = new char[string_size]; \ 59 | string_size = vsnprintf(buffer, string_size, str, vl); \ 60 | } \ 61 | \ 62 | va_end(vl); \ 63 | \ 64 | \ 65 | logger->message( LOG_LEVEL, buffer ); \ 66 | \ 67 | if(buffer != msgbuff) delete[] buffer; 68 | 69 | // LoggerMessage 70 | 71 | LoggerMessage::LoggerMessage(int level, const std::string& message) 72 | : level(level), message(message) { 73 | } 74 | 75 | // Logger 76 | 77 | Logger* Logger::getDefault() { 78 | return default_logger; 79 | } 80 | 81 | Logger::Logger(int level, FILE* stream, int hist_capacity) { 82 | init(level, stream, hist_capacity); 83 | } 84 | 85 | void Logger::init(int level, FILE* stream, int hist_capacity) { 86 | this->level = level; 87 | this->stream = stream; 88 | this->hist_capacity = hist_capacity; 89 | this->message_count = 0; 90 | this->auto_flush = false; 91 | } 92 | 93 | int Logger::getMessageCount() { 94 | return message_count; 95 | } 96 | 97 | void Logger::message(int level, const std::string& message) { 98 | 99 | if(!level || this->level < level) return; 100 | 101 | if(stream != 0) { 102 | fprintf(stream, "%s: %s\n", log_levels[level].c_str(), message.c_str()); 103 | if(auto_flush) fflush(stream); 104 | } 105 | 106 | if(!hist_capacity) return; 107 | 108 | while(history.size() >= hist_capacity) { 109 | history.pop_front(); 110 | } 111 | 112 | history.push_back(LoggerMessage(level, message)); 113 | message_count++; 114 | } 115 | 116 | const std::deque& Logger::getHistory() const { 117 | return history; 118 | } 119 | 120 | void Logger::setHistoryCapacity(int hist_capacity) { 121 | this->hist_capacity = hist_capacity; 122 | } 123 | 124 | void Logger::setAutoFlush(bool auto_flush) { 125 | this->auto_flush = auto_flush; 126 | } 127 | 128 | void warnLog(const char *str, ...) { 129 | PARSE_AND_LOG(LOG_LEVEL_WARN); 130 | } 131 | 132 | void debugLog(const char *str, ...) { 133 | PARSE_AND_LOG(LOG_LEVEL_DEBUG); 134 | } 135 | 136 | void infoLog(const char *str, ...) { 137 | PARSE_AND_LOG(LOG_LEVEL_INFO); 138 | } 139 | 140 | void errorLog(const char *str, ...) { 141 | PARSE_AND_LOG(LOG_LEVEL_ERROR) 142 | } 143 | 144 | void consoleLog(const char *str, ...) { 145 | PARSE_AND_LOG(LOG_LEVEL_CONSOLE); 146 | } 147 | 148 | void scriptLog(const char *str, ...) { 149 | PARSE_AND_LOG(LOG_LEVEL_SCRIPT); 150 | } 151 | 152 | void pedanticLog(const char *str, ...) { 153 | PARSE_AND_LOG(LOG_LEVEL_PEDANTIC); 154 | } 155 | 156 | Logger* Logger::default_logger = new Logger(LOG_LEVEL_ERROR, stderr, 0); 157 | 158 | LoggerStringStream WarnLog() { 159 | return LoggerStringStream(LOG_LEVEL_WARN); 160 | } 161 | 162 | LoggerStringStream DebugLog() { 163 | return LoggerStringStream(LOG_LEVEL_DEBUG); 164 | } 165 | 166 | LoggerStringStream InfoLog() { 167 | return LoggerStringStream(LOG_LEVEL_INFO); 168 | } 169 | 170 | LoggerStringStream ErrorLog() { 171 | return LoggerStringStream(LOG_LEVEL_ERROR); 172 | } 173 | 174 | LoggerStringStream ConsoleLog() { 175 | return LoggerStringStream(LOG_LEVEL_CONSOLE); 176 | } 177 | 178 | LoggerStringStream ScriptLog() { 179 | return LoggerStringStream(LOG_LEVEL_SCRIPT); 180 | } 181 | -------------------------------------------------------------------------------- /logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef LOGGER_H 29 | #define LOGGER_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | enum logger_level { LOG_LEVEL_OFF, LOG_LEVEL_ERROR, LOG_LEVEL_CONSOLE, LOG_LEVEL_INFO, LOG_LEVEL_SCRIPT, LOG_LEVEL_DEBUG, LOG_LEVEL_WARN, LOG_LEVEL_PEDANTIC }; 37 | 38 | class LoggerMessage { 39 | 40 | public: 41 | LoggerMessage(int level, const std::string& message); 42 | 43 | int level; 44 | std::string message; 45 | }; 46 | 47 | class Logger { 48 | protected: 49 | std::deque history; 50 | int hist_capacity; 51 | FILE* stream; 52 | int level; 53 | static Logger* default_logger; 54 | int message_count; 55 | bool auto_flush; 56 | public: 57 | static Logger* getDefault(); 58 | 59 | const std::deque& getHistory() const; 60 | 61 | void setLevel(int level) { this->level = level; }; 62 | int getLevel() const { return level; } 63 | 64 | int getMessageCount(); 65 | 66 | void setHistoryCapacity(int hist_capacity); 67 | void setAutoFlush(bool auto_flush); 68 | 69 | Logger(int level, FILE* stream, int history_capacity = 0); 70 | 71 | void init(int level, FILE* stream, int history_capacity); 72 | 73 | void message(int level, const std::string& message); 74 | }; 75 | 76 | void warnLog(const char *args, ...); 77 | void debugLog(const char *args, ...); 78 | void infoLog(const char *args, ...); 79 | void errorLog(const char *args, ...); 80 | void consoleLog(const char *args, ...); 81 | void scriptLog(const char *args, ...); 82 | void pedanticLog(const char *args, ...); 83 | 84 | class LoggerStringStream { 85 | protected: 86 | Logger* logger; 87 | std::ostringstream* ss; 88 | logger_level log_level; 89 | int count; 90 | public: 91 | LoggerStringStream(logger_level level) : ss(nullptr), log_level(level), count(0) { 92 | logger = Logger::getDefault(); 93 | } 94 | ~LoggerStringStream() { 95 | if(logger && ss != nullptr && count > 0) { 96 | logger->message(log_level, ss->str()); 97 | } 98 | delete ss; 99 | } 100 | 101 | template 102 | LoggerStringStream& operator<<(const T& value) { 103 | if(logger != nullptr && logger->getLevel() >= log_level) { 104 | if(!ss) ss = new std::ostringstream(); 105 | if(count > 0) { 106 | *ss << " "; 107 | } 108 | *ss << value; 109 | count++; 110 | } 111 | return *this; 112 | } 113 | }; 114 | 115 | LoggerStringStream WarnLog(); 116 | LoggerStringStream DebugLog(); 117 | LoggerStringStream InfoLog(); 118 | LoggerStringStream ErrorLog(); 119 | LoggerStringStream ConsoleLog(); 120 | LoggerStringStream ScriptLog(); 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /mousecursor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "mousecursor.h" 29 | 30 | MouseCursor::MouseCursor() { 31 | system_cursor = true; 32 | cursortex = 0; 33 | hidden = false; 34 | timeout = 3.0f; 35 | idle = timeout; 36 | scrollwheel = 0; 37 | 38 | left_click = false; 39 | right_click = false; 40 | middle_click = false; 41 | 42 | sdl_default_cursor = SDL_GetCursor(); 43 | 44 | 45 | Uint8 data[4*32]; 46 | Uint8 mask[4*32]; 47 | 48 | memset(data, 0, sizeof(data)); 49 | memset(mask, 0, sizeof(mask)); 50 | 51 | sdl_hidden_cursor = SDL_CreateCursor(data, mask, 32, 32, 0, 0); 52 | } 53 | 54 | MouseCursor::~MouseCursor() { 55 | SDL_SetCursor(sdl_default_cursor); 56 | SDL_FreeCursor(sdl_hidden_cursor); 57 | } 58 | 59 | void MouseCursor::useSystemCursor(bool system_cursor) { 60 | this->system_cursor = system_cursor; 61 | 62 | if(!hidden) { 63 | if(system_cursor) SDL_SetCursor(sdl_default_cursor); 64 | else SDL_SetCursor(sdl_hidden_cursor); 65 | } else { 66 | SDL_SetCursor(sdl_hidden_cursor); 67 | } 68 | } 69 | 70 | void MouseCursor::showCursor(bool show) { 71 | if(this->hidden == !show) return; 72 | 73 | this->hidden = !show; 74 | if(show) idle = 0.0; 75 | 76 | if(system_cursor) { 77 | if(show) SDL_SetCursor(sdl_default_cursor); 78 | else SDL_SetCursor(sdl_hidden_cursor); 79 | } 80 | } 81 | const vec2& MouseCursor::getPos() const { 82 | return mousepos; 83 | } 84 | 85 | const vec2& MouseCursor::getRelativePos() const { 86 | return rel; 87 | } 88 | 89 | void MouseCursor::updateRelativePos(const vec2& rel) { 90 | this->rel = rel; 91 | } 92 | 93 | void MouseCursor::leftClick(bool click) { 94 | left_click = click; 95 | } 96 | 97 | void MouseCursor::rightClick(bool click) { 98 | right_click = click; 99 | } 100 | 101 | void MouseCursor::middleClick(bool click) { 102 | middle_click = click; 103 | } 104 | 105 | bool MouseCursor::leftClick() const { 106 | return left_click; 107 | } 108 | 109 | bool MouseCursor::rightClick() const { 110 | return right_click; 111 | } 112 | 113 | bool MouseCursor::middleClick() const { 114 | return middle_click; 115 | } 116 | 117 | bool MouseCursor::leftButtonPressed() const { 118 | Uint8 ms = SDL_GetMouseState(0,0); 119 | return ms & SDL_BUTTON(SDL_BUTTON_LEFT); 120 | } 121 | 122 | bool MouseCursor::rightButtonPressed() const { 123 | Uint8 ms = SDL_GetMouseState(0,0); 124 | return ms & SDL_BUTTON(SDL_BUTTON_RIGHT); 125 | } 126 | 127 | bool MouseCursor::bothPressed() const { 128 | Uint8 ms = SDL_GetMouseState(0,0); 129 | return (ms & SDL_BUTTON(SDL_BUTTON_RIGHT) && ms & SDL_BUTTON(SDL_BUTTON_LEFT)); 130 | } 131 | 132 | bool MouseCursor::buttonPressed() const { 133 | Uint8 ms = SDL_GetMouseState(0,0); 134 | return (ms & SDL_BUTTON(SDL_BUTTON_RIGHT) || ms & SDL_BUTTON(SDL_BUTTON_LEFT)); 135 | } 136 | 137 | int MouseCursor::scrollWheel() const { 138 | return scrollwheel; 139 | } 140 | 141 | bool MouseCursor::isSystemCursor() const { 142 | return system_cursor; 143 | } 144 | 145 | bool MouseCursor::isHidden() const { 146 | return hidden; 147 | } 148 | 149 | bool MouseCursor::isVisible() const { 150 | return (!hidden && idle < timeout && hasFocus()); 151 | } 152 | 153 | bool MouseCursor::hasFocus() const { 154 | #if SDL_VERSION_ATLEAST(2,0,0) 155 | return (SDL_GetMouseFocus() == display.sdl_window); 156 | #else 157 | return (SDL_GetAppState() & SDL_APPMOUSEFOCUS); 158 | #endif 159 | } 160 | 161 | void MouseCursor::setCursorTexture(TextureResource* texture) { 162 | cursortex = texture; 163 | } 164 | 165 | void MouseCursor::updatePos(const vec2& pos) { 166 | mousepos = pos; 167 | idle = 0.0f; 168 | } 169 | 170 | void MouseCursor::scroll(bool dir) { 171 | scrollwheel += dir ? 1 : -1; 172 | } 173 | 174 | void MouseCursor::resetButtonState() { 175 | scrollwheel = 0; 176 | right_click = false; 177 | left_click = false; 178 | middle_click = false; 179 | } 180 | 181 | void MouseCursor::logic(float dt) { 182 | idle += dt; 183 | } 184 | 185 | void MouseCursor::draw() const { 186 | if(system_cursor || cursortex == 0) return; 187 | if(!isVisible()) return; 188 | 189 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 190 | 191 | glEnable(GL_TEXTURE_2D); 192 | glEnable(GL_BLEND); 193 | 194 | cursortex->bind(); 195 | 196 | glTranslatef(mousepos.x, mousepos.y, 0.0f); 197 | 198 | glPushMatrix(); 199 | glBegin(GL_QUADS); 200 | glTexCoord2f(0.0f,0.0f); 201 | glVertex2i(0, 0); 202 | 203 | glTexCoord2f(1.0f,0.0f); 204 | glVertex2i(cursortex->w, 0); 205 | 206 | glTexCoord2f(1.0f,1.0f); 207 | glVertex2i(cursortex->w, cursortex->h); 208 | 209 | glTexCoord2f(0.0f,1.0f); 210 | glVertex2i(0, cursortex->h); 211 | glEnd(); 212 | 213 | glPopMatrix(); 214 | } 215 | -------------------------------------------------------------------------------- /mousecursor.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef SDLAPP_MOUSECURSOR_H 29 | #define SDLAPP_MOUSECURSOR_H 30 | 31 | #include "display.h" 32 | 33 | class MouseCursor { 34 | 35 | vec2 mousepos; 36 | vec2 rel; 37 | 38 | bool hidden; 39 | bool system_cursor; 40 | 41 | float idle; 42 | float timeout; 43 | 44 | int scrollwheel; 45 | 46 | SDL_Cursor* sdl_default_cursor; 47 | SDL_Cursor* sdl_hidden_cursor; 48 | 49 | bool left_click; 50 | bool right_click; 51 | bool middle_click; 52 | 53 | TextureResource* cursortex; 54 | public: 55 | MouseCursor(); 56 | ~MouseCursor(); 57 | 58 | const vec2& getPos() const; 59 | const vec2& getRelativePos() const; 60 | 61 | void leftClick(bool click); 62 | void rightClick(bool click); 63 | void middleClick(bool click); 64 | 65 | bool leftClick() const; 66 | bool rightClick() const; 67 | bool middleClick() const; 68 | 69 | bool leftButtonPressed() const; 70 | bool rightButtonPressed() const; 71 | bool bothPressed() const; 72 | bool buttonPressed() const; 73 | 74 | int scrollWheel() const; 75 | 76 | bool isHidden() const; 77 | bool isSystemCursor()const; 78 | bool isVisible() const; 79 | bool hasFocus() const; 80 | 81 | void scroll(bool dir); 82 | 83 | void resetButtonState(); 84 | 85 | void updateRelativePos(const vec2& rel); 86 | void updatePos(const vec2& pos); 87 | 88 | void showCursor(bool show); 89 | void useSystemCursor(bool system_cursor); 90 | 91 | void setCursorTexture(TextureResource* texture); 92 | 93 | void logic(float dt); 94 | void draw() const; 95 | }; 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /pi.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef PI_H 29 | #define PI_H 30 | 31 | #define PI 3.14159265 32 | #define RADIANS_TO_DEGREES 57.29577951 33 | #define DEGREES_TO_RADIANS 0.017453292 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /plane.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "plane.h" 29 | 30 | Plane::Plane() { 31 | d = 0.0f; 32 | } 33 | 34 | Plane::Plane(const vec3 & v1, const vec3 & v2, const vec3 & v3) { 35 | vec3 edge1 = v1 - v2; 36 | vec3 edge2 = v3 - v2; 37 | 38 | normal = glm::normalize(glm::cross(edge2, edge1)); 39 | point = v2; 40 | 41 | d = -(glm::dot(normal, point)); 42 | } 43 | 44 | float Plane::distance(const vec3 & p) const { 45 | return d + glm::dot(normal, p); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /plane.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef PLANE_H 29 | #define PLANE_H 30 | 31 | #include "vectors.h" 32 | 33 | class Plane { 34 | public: 35 | vec3 normal; 36 | vec3 point; 37 | float d; 38 | 39 | Plane(); 40 | Plane(const vec3 & v1, const vec3 & v2, const vec3 & v3); 41 | 42 | float distance(const vec3 & p) const; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /png_writer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "png_writer.h" 29 | #include "display.h" 30 | 31 | #include 32 | 33 | #define PNG_SKIP_SETJMP_CHECK 34 | #include 35 | 36 | PNGWriter::PNGWriter(int components) 37 | : components(components) { 38 | out = 0; 39 | } 40 | 41 | bool PNGWriter::open(const std::string& filename) { 42 | 43 | out = new std::ofstream(filename.c_str(), std::ios::out | std::ios::binary); 44 | 45 | if(out->fail()) { 46 | delete out; 47 | out = 0; 48 | return false; 49 | } 50 | 51 | return true; 52 | } 53 | 54 | void PNGWriter::close() { 55 | ((std::fstream*)out)->close(); 56 | } 57 | 58 | void PNGWriter::setOutputStream(std::ostream* out) { 59 | this->out = out; 60 | } 61 | 62 | void PNGWriter::screenshot(const std::string& filename) { 63 | 64 | if(!open(filename)) return; 65 | 66 | std::vector buffer; 67 | buffer.resize(display.width * display.height * components); 68 | 69 | capture(buffer); 70 | writePNG(buffer); 71 | 72 | close(); 73 | } 74 | 75 | void PNGWriter::capture(std::vector& buffer) { 76 | GLenum pixel_format = components == 4 ? GL_RGBA : GL_RGB; 77 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 78 | glReadPixels(0, 0, display.width, display.height, pixel_format, GL_UNSIGNED_BYTE, &(buffer[0])); 79 | } 80 | 81 | void png_writer_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { 82 | std::ostream* out = (std::ostream*) png_get_io_ptr(png_ptr); 83 | if (!out->write((char*)data, length)) png_error(png_ptr, "png_writer_write_data error"); 84 | } 85 | 86 | void png_writer_flush_data(png_structp png_ptr) { 87 | std::ostream *out = (std::ostream*) png_get_io_ptr(png_ptr); 88 | if (!out->flush()) png_error(png_ptr, "png_writer_flush_data error"); 89 | } 90 | 91 | void PNGWriter::writePNG(std::vector& buffer) { 92 | 93 | png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); 94 | 95 | if(!png_ptr) throw PNGExporterException("png_create_write_struct failed"); 96 | 97 | png_set_write_fn(png_ptr, out, png_writer_write_data, png_writer_flush_data); 98 | 99 | png_infop info_ptr = png_create_info_struct(png_ptr); 100 | 101 | if(!info_ptr) throw PNGExporterException("png_create_info_struct failed"); 102 | 103 | if(setjmp(png_jmpbuf(png_ptr))) { 104 | throw PNGExporterException("setjmp failed"); 105 | } 106 | 107 | int colour_type = (components == 4) ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB; 108 | 109 | png_set_IHDR(png_ptr, info_ptr, display.width, display.height, 8, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 110 | 111 | std::vector rows(display.height); 112 | for (int i = 0; i < display.height; i++) { 113 | rows[i] = (png_bytep) &(buffer[(display.height-i-1) * components * display.width]); 114 | } 115 | 116 | png_write_info(png_ptr, info_ptr); 117 | png_write_image(png_ptr, &(rows[0])); 118 | png_write_end(png_ptr, 0); 119 | 120 | png_destroy_write_struct(&png_ptr, &info_ptr); 121 | } 122 | 123 | // PNGExporter 124 | 125 | PNGExporter::PNGExporter(const std::string& filename) { 126 | 127 | buffer1.resize(display.width * display.height * 3); 128 | buffer2.resize(display.width * display.height * 3); 129 | 130 | buffer_shared_ptr = 0; 131 | 132 | thread_state = PNG_EXPORTER_WAIT; 133 | 134 | cond = SDL_CreateCond(); 135 | mutex = SDL_CreateMutex(); 136 | 137 | if(filename == "-") { 138 | writer.setOutputStream(&std::cout); 139 | } else { 140 | this->filename = filename; 141 | 142 | if(!writer.open(filename)) { 143 | throw PNGExporterException(filename); 144 | } 145 | } 146 | 147 | #if SDL_VERSION_ATLEAST(2,0,0) 148 | thread = SDL_CreateThread( PNGExporter::startThread, "png_exporter", this ); 149 | #else 150 | thread = SDL_CreateThread( PNGExporter::startThread, this ); 151 | #endif 152 | } 153 | 154 | PNGExporter::~PNGExporter() { 155 | 156 | stop(); 157 | 158 | SDL_DestroyCond(cond); 159 | SDL_DestroyMutex(mutex); 160 | 161 | buffer_shared_ptr = 0; 162 | 163 | if(!filename.empty()) { 164 | writer.close(); 165 | } 166 | } 167 | 168 | int PNGExporter::startThread(void *exporter) { 169 | (static_cast(exporter))->run(); 170 | return 0; 171 | } 172 | 173 | void PNGExporter::run() { 174 | 175 | SDL_mutexP(mutex); 176 | 177 | while(thread_state != PNG_EXPORTER_EXIT) { 178 | 179 | thread_state = PNG_EXPORTER_WAIT; 180 | 181 | while (thread_state == PNG_EXPORTER_WAIT) { 182 | SDL_CondWait(cond, mutex); 183 | } 184 | 185 | if (thread_state != PNG_EXPORTER_WRITE) break; 186 | 187 | if (buffer_shared_ptr != 0) { 188 | writer.writePNG(*buffer_shared_ptr); 189 | } 190 | } 191 | 192 | thread_state = PNG_EXPORTER_STOPPED; 193 | 194 | SDL_mutexV(mutex); 195 | } 196 | 197 | void PNGExporter::stop() { 198 | if(!thread) return; 199 | 200 | if(thread_state == PNG_EXPORTER_STOPPED || thread_state == PNG_EXPORTER_EXIT) return; 201 | 202 | SDL_mutexP(mutex); 203 | 204 | thread_state = PNG_EXPORTER_EXIT; 205 | 206 | SDL_CondSignal(cond); 207 | 208 | SDL_mutexV(mutex); 209 | 210 | SDL_WaitThread(thread, 0); 211 | 212 | thread = 0; 213 | } 214 | 215 | void PNGExporter::capture() { 216 | 217 | std::vector* next_pixel_ptr = (buffer_shared_ptr == &buffer1) ? 218 | &buffer2 : &buffer1; 219 | 220 | writer.capture(*next_pixel_ptr); 221 | 222 | SDL_mutexP(mutex); 223 | 224 | buffer_shared_ptr = next_pixel_ptr; 225 | thread_state = PNG_EXPORTER_WRITE; 226 | 227 | SDL_CondSignal(cond); 228 | SDL_mutexV(mutex); 229 | } 230 | -------------------------------------------------------------------------------- /png_writer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef PNG_WRITER_H 29 | #define PNG_WRITER_H 30 | 31 | #include "SDL_thread.h" 32 | 33 | #include 34 | #include 35 | 36 | class PNGWriter { 37 | protected: 38 | std::ostream* out; 39 | size_t components; 40 | 41 | void init(); 42 | public: 43 | PNGWriter(int components = 3); 44 | 45 | bool open(const std::string& filename); 46 | void close(); 47 | 48 | void setOutputStream(std::ostream* out); 49 | 50 | void screenshot(const std::string& filename); 51 | void capture(std::vector& buffer); 52 | void writePNG(std::vector& buffer); 53 | }; 54 | 55 | enum png_exporter_state { PNG_EXPORTER_WAIT, PNG_EXPORTER_WRITE, PNG_EXPORTER_EXIT, PNG_EXPORTER_STOPPED }; 56 | 57 | class PNGExporter { 58 | protected: 59 | PNGWriter writer; 60 | 61 | std::vector* buffer_shared_ptr; 62 | 63 | std::vector buffer1; 64 | std::vector buffer2; 65 | 66 | SDL_cond* cond; 67 | SDL_mutex* mutex; 68 | SDL_Thread* thread; 69 | 70 | int thread_state; 71 | 72 | std::string filename; 73 | 74 | static int startThread(void *exporter); 75 | public: 76 | PNGExporter(const std::string& filename); 77 | ~PNGExporter(); 78 | 79 | void run(); 80 | void stop(); 81 | 82 | void capture(); 83 | }; 84 | 85 | class PNGExporterException : public std::exception { 86 | protected: 87 | std::string filename; 88 | public: 89 | PNGExporterException(const std::string& filename) : filename(filename) {}; 90 | 91 | virtual ~PNGExporterException() throw () {}; 92 | virtual const char* what() const throw() { return filename.c_str(); }; 93 | }; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /ppm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Johannes Schindelin (johannes.schindelin@gmx.de) 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 7 | 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #include "ppm.h" 19 | #include "display.h" 20 | #include "sdlapp.h" 21 | 22 | #ifdef _WIN32 23 | #include 24 | #include 25 | #endif 26 | 27 | extern "C" { 28 | static int dumper_thread(void *arg) { 29 | FrameExporter *e = static_cast(arg); 30 | 31 | e->dumpThr(); 32 | 33 | return 0; 34 | } 35 | }; 36 | 37 | // FrameExporter 38 | 39 | FrameExporter::FrameExporter() { 40 | 41 | //this now assumes the display is setup 42 | //before the frame exporter is created 43 | //(which seems reasonable) 44 | 45 | rowstride = display.width * 3; 46 | 47 | pixels1 = new char[display.height * rowstride]; 48 | pixels2 = new char[display.height * rowstride]; 49 | pixels_out = new char[display.height * rowstride]; 50 | 51 | pixels_shared_ptr = 0; 52 | 53 | dumper_thread_state = FRAME_EXPORTER_WAIT; 54 | 55 | cond = SDL_CreateCond(); 56 | mutex = SDL_CreateMutex(); 57 | 58 | #if SDL_VERSION_ATLEAST(2,0,0) 59 | thread = SDL_CreateThread( dumper_thread, "frame_exporter", this ); 60 | #else 61 | thread = SDL_CreateThread( dumper_thread, this ); 62 | #endif 63 | } 64 | 65 | FrameExporter::~FrameExporter() { 66 | stop(); 67 | 68 | SDL_DestroyCond(cond); 69 | SDL_DestroyMutex(mutex); 70 | 71 | pixels_shared_ptr = 0; 72 | 73 | delete[] pixels1; 74 | delete[] pixels2; 75 | delete[] pixels_out; 76 | } 77 | 78 | void FrameExporter::stop() { 79 | if(!thread) return; 80 | 81 | if(dumper_thread_state == FRAME_EXPORTER_STOPPED || dumper_thread_state == FRAME_EXPORTER_EXIT) return; 82 | 83 | SDL_mutexP(mutex); 84 | 85 | dumper_thread_state = FRAME_EXPORTER_EXIT; 86 | 87 | SDL_CondSignal(cond); 88 | 89 | SDL_mutexV(mutex); 90 | 91 | SDL_WaitThread(thread, 0); 92 | 93 | thread = 0; 94 | } 95 | 96 | void FrameExporter::dump() { 97 | 98 | display.mode2D(); 99 | 100 | glEnable(GL_TEXTURE_2D); 101 | glDisable(GL_BLEND); 102 | 103 | char* next_pixel_ptr = (pixels_shared_ptr == pixels1) ? pixels2 : pixels1; 104 | 105 | // copy pixels - now the right way up 106 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 107 | glReadPixels(0, 0, display.width, display.height, 108 | GL_RGB, GL_UNSIGNED_BYTE, next_pixel_ptr); 109 | 110 | // wait for lock before changing the pointer to point to our new buffer 111 | SDL_mutexP(mutex); 112 | 113 | //flip buffer we are pointing at 114 | pixels_shared_ptr = next_pixel_ptr; 115 | dumper_thread_state = FRAME_EXPORTER_DUMP; 116 | 117 | SDL_CondSignal(cond); 118 | SDL_mutexV(mutex); 119 | } 120 | 121 | void FrameExporter::dumpThr() { 122 | 123 | SDL_mutexP(mutex); 124 | 125 | while(dumper_thread_state != FRAME_EXPORTER_EXIT) { 126 | 127 | dumper_thread_state = FRAME_EXPORTER_WAIT; 128 | 129 | while (dumper_thread_state == FRAME_EXPORTER_WAIT) { 130 | SDL_CondWait(cond, mutex); 131 | } 132 | 133 | if (dumper_thread_state == FRAME_EXPORTER_EXIT) break; 134 | 135 | if (pixels_shared_ptr != 0) { 136 | 137 | //invert image 138 | for(int y=0;yfail()) { 169 | delete output; 170 | throw PPMExporterException(outputfile); 171 | } 172 | } 173 | 174 | //write header 175 | sprintf(ppmheader, "P6\n%d %d 255\n", display.width, display.height); 176 | } 177 | 178 | PPMExporter::~PPMExporter() { 179 | stop(); 180 | 181 | if(filename.size()>0) 182 | ((std::fstream*)output)->close(); 183 | } 184 | 185 | void PPMExporter::dumpImpl() { 186 | *output << ppmheader; 187 | output->write(pixels_out, rowstride * display.height); 188 | } 189 | -------------------------------------------------------------------------------- /ppm.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Johannes Schindelin (johannes.schindelin@gmx.de) 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 7 | 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #ifndef PPM_FRAME_EXPORTER_H 19 | #define PPM_FRAME_EXPORTER_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "SDL.h" 28 | #include "gl.h" 29 | 30 | enum { FRAME_EXPORTER_WAIT, 31 | FRAME_EXPORTER_DUMP, 32 | FRAME_EXPORTER_EXIT, 33 | FRAME_EXPORTER_STOPPED }; 34 | 35 | class FrameExporter { 36 | protected: 37 | 38 | char* pixels1; 39 | char* pixels2; 40 | char* pixels_out; 41 | 42 | char* pixels_shared_ptr; 43 | 44 | size_t rowstride; 45 | 46 | GLuint screentex; 47 | 48 | SDL_Thread* thread; 49 | SDL_mutex* mutex; 50 | SDL_cond* cond; 51 | int dumper_thread_state; 52 | 53 | public: 54 | FrameExporter(); 55 | virtual ~FrameExporter(); 56 | void stop(); 57 | void dump(); 58 | void dumpThr(); 59 | virtual void dumpImpl() {}; 60 | }; 61 | 62 | class PPMExporterException : public std::exception { 63 | protected: 64 | std::string filename; 65 | public: 66 | PPMExporterException(std::string& filename) : filename(filename) {} 67 | virtual ~PPMExporterException() throw () {}; 68 | 69 | virtual const char* what() const throw() { return filename.c_str(); } 70 | }; 71 | 72 | class PPMExporter : public FrameExporter { 73 | protected: 74 | std::ostream* output; 75 | std::string filename; 76 | char ppmheader[1024]; 77 | 78 | public: 79 | PPMExporter(std::string outputfile); 80 | virtual ~PPMExporter(); 81 | virtual void dumpImpl(); 82 | }; 83 | 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /quadtree.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef QUADTREE_H 29 | #define QUADTREE_H 30 | 31 | #include 32 | #include 33 | 34 | #include "gl.h" 35 | #include "bounds.h" 36 | #include "frustum.h" 37 | 38 | class QuadItem { 39 | public: 40 | Bounds2D quadItemBounds; 41 | int node_count; 42 | virtual ~QuadItem() {}; 43 | virtual void updateQuadItemBounds() {}; 44 | virtual void drawQuadItem() {}; 45 | }; 46 | 47 | template 48 | class VisitFunctor{ 49 | public: 50 | virtual void operator()(Data *)=0; 51 | }; 52 | 53 | class QuadTree; 54 | 55 | class QuadNode { 56 | GLuint listid; 57 | 58 | Bounds2D bounds; 59 | 60 | std::vector children; 61 | std::list items; 62 | 63 | QuadTree* tree; 64 | 65 | int getChildIndex(const vec2 & pos) const; 66 | void addToChild(QuadItem* item); 67 | 68 | int depth; 69 | 70 | QuadNode* parent; 71 | public: 72 | bool allowMoreItems(); 73 | int usedChildren(); 74 | 75 | QuadNode(QuadTree* tree, QuadNode* parent, Bounds2D itembounds, int parent_depth); 76 | ~QuadNode(); 77 | 78 | void addItem(QuadItem* item); //if not subdivided, subdivide, add to correct subdivided node. 79 | 80 | int getItemsAt(std::set& itemset, vec2 pos); 81 | void getLeavesInFrustum(std::set& nodeset, Frustum& frustum); 82 | int getItemsInFrustum(std::set& itemset, Frustum& frustum); 83 | int getItemsInBounds(std::set& itemset, Bounds2D& bounds) const; 84 | 85 | void visitItemsInFrustum(const Frustum & frustum, VisitFunctor & visit); 86 | void visitItemsInBounds(const Bounds2D & bounds, VisitFunctor & visit); 87 | void visitItemsAt(const vec2 & pos, VisitFunctor & visit); 88 | void visitLeavesInFrustum(const Frustum & frustum, VisitFunctor & visit); 89 | 90 | bool empty(); 91 | void generateLists(); 92 | int draw(Frustum& frustum); 93 | void outline(); 94 | void outlineItems(); 95 | }; 96 | 97 | 98 | class QuadTree { 99 | Bounds2D bounds; 100 | QuadNode* root; 101 | public: 102 | int unique_item_count; 103 | int item_count; 104 | int node_count; 105 | int max_node_depth; 106 | int max_node_items; 107 | 108 | int getItemsAt(std::set& itemset, vec2 pos); 109 | void getLeavesInFrustum(std::set& nodeset, Frustum& frustum); 110 | int getItemsInFrustum(std::set& itemset, Frustum& frustum); 111 | int getItemsInBounds(std::set& itemset, Bounds2D& bounds) const; 112 | 113 | void visitItemsAt(const vec2 & pos, VisitFunctor & visit); 114 | void visitLeavesInFrustum(const Frustum & frustum, VisitFunctor & visit); 115 | void visitItemsInFrustum(const Frustum & frustum, VisitFunctor & visit); 116 | void visitItemsInBounds(const Bounds2D & bounds, VisitFunctor & visit); 117 | void addItem(QuadItem* item); 118 | void generateLists(); 119 | int drawNodesInFrustum(Frustum& frustum); 120 | QuadTree(Bounds2D bounds, int max_node_depth, int max_node_items); 121 | ~QuadTree(); 122 | void outline(); 123 | void outlineItems(); 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /regex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "regex.h" 29 | 30 | Regex::Regex(std::string regex, bool test) { 31 | 32 | int errornumber; 33 | PCRE2_SIZE erroroffset; 34 | 35 | re = pcre2_compile( 36 | (PCRE2_SPTR) regex.c_str(), 37 | regex.size(), 38 | 0, 39 | &errornumber, 40 | &erroroffset, 41 | NULL 42 | ); 43 | 44 | if(!re) { 45 | valid = false; 46 | 47 | if(!test) { 48 | throw RegexCompilationException(regex); 49 | } 50 | 51 | } else { 52 | valid = true; 53 | } 54 | 55 | } 56 | 57 | Regex::Regex(const Regex& regex) { 58 | if(regex.isValid()) { 59 | re = pcre2_code_copy(regex.re); 60 | valid = true; 61 | } else { 62 | re = 0; 63 | valid = false; 64 | } 65 | } 66 | 67 | Regex::~Regex() { 68 | if(re != 0) pcre2_code_free(re); 69 | } 70 | 71 | bool Regex::isValid() const { 72 | return valid; 73 | } 74 | 75 | bool Regex::replace(std::string& str, const std::string& replacement_str) { 76 | 77 | int offset = replaceOffset(str, replacement_str, 0); 78 | 79 | return (offset != -1); 80 | } 81 | 82 | bool Regex::replaceAll(std::string& str, const std::string& replacement_str) { 83 | 84 | 85 | int offset = -1; 86 | 87 | while((offset = replaceOffset(str, replacement_str, offset+1)) != -1 && offset < str.size()); 88 | 89 | return (offset != -1); 90 | } 91 | 92 | int Regex::replaceOffset(std::string& str, const std::string& replacement_str, int offset) { 93 | 94 | pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(re, NULL); 95 | 96 | int rc = pcre2_match( 97 | re, 98 | (PCRE2_SPTR) str.c_str(), 99 | str.size(), 100 | offset, 101 | 0, 102 | match_data, 103 | NULL 104 | ); 105 | 106 | //failed match 107 | if(rc<1) { 108 | pcre2_match_data_free(match_data); 109 | return -1; 110 | } 111 | 112 | PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data); 113 | 114 | // replace matched section of string 115 | std::string new_str = str; 116 | new_str.replace(ovector[0], ovector[1]-ovector[0], replacement_str); 117 | 118 | size_t end_offset = ovector[0] + replacement_str.size(); 119 | 120 | for (int i = 1; i < rc; i++) { 121 | int match_start = ovector[2*i]; 122 | int match_end = ovector[2*i+1]; 123 | 124 | std::string matched_str; 125 | 126 | if(match_start != -1) { 127 | matched_str = std::string(str, match_start, match_end-match_start); 128 | } 129 | 130 | // check if 'str' contains $i, if it does, replace with match string 131 | size_t string_size = new_str.size(); 132 | 133 | for(size_t j=0; j* results) { 150 | 151 | if(results != 0) results->clear(); 152 | int offset = matchOffset(str, results, 0); 153 | return offset != -1; 154 | } 155 | 156 | bool Regex::matchAll(const std::string& str, std::vector* results) { 157 | 158 | int offset = 0; 159 | int match_count = 0; 160 | if(results != 0) results->clear(); 161 | 162 | int str_size = str.size(); 163 | 164 | while((offset = matchOffset(str, results, offset)) != -1) { 165 | match_count++; 166 | if(offset >= str_size) break; 167 | } 168 | 169 | return match_count > 0; 170 | } 171 | 172 | int Regex::matchOffset(const std::string& str, std::vector* results, int offset) { 173 | 174 | if(offset >= str.size()) return -1; 175 | 176 | pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(re, NULL); 177 | 178 | int rc = pcre2_match( 179 | re, 180 | // To allow ^ to match the start of the remaining string 181 | // offset the string before passing it 182 | (PCRE2_SPTR)(str.c_str() + offset), 183 | str.size() - offset, 184 | 0, 185 | 0, 186 | match_data, 187 | NULL 188 | ); 189 | 190 | //failed match 191 | if(rc < 1) { 192 | pcre2_match_data_free(match_data); 193 | return -1; 194 | } 195 | 196 | PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data); 197 | 198 | if(results != 0) { 199 | for (int i = 1; i < rc; i++) { 200 | int match_start = ovector[2*i]; 201 | int match_end = ovector[2*i+1]; 202 | 203 | // insert a empty string for non-matching optional regex 204 | if(match_start == -1) { 205 | results->push_back(std::string("")); 206 | } else { 207 | std::string match(str, match_start+offset, match_end-match_start); 208 | results->push_back(match); 209 | } 210 | } 211 | } 212 | 213 | int result_offset = ovector[1] + offset; 214 | 215 | pcre2_match_data_free(match_data); 216 | 217 | return result_offset; 218 | } 219 | -------------------------------------------------------------------------------- /regex.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef REGEX_H 29 | #define REGEX_H 30 | 31 | #define PCRE2_CODE_UNIT_WIDTH 8 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | class RegexCompilationException : public std::exception { 39 | protected: 40 | std::string regex; 41 | public: 42 | RegexCompilationException(std::string& regex) : regex(regex) {} 43 | virtual ~RegexCompilationException() throw () {}; 44 | 45 | virtual const char* what() const throw() { return regex.c_str(); } 46 | }; 47 | 48 | class Regex { 49 | protected: 50 | pcre2_code *re; 51 | bool valid; 52 | 53 | int replaceOffset(std::string& str, const std::string& replacement_str, int offset=0); 54 | int matchOffset(const std::string& str, std::vector* results = 0, int offset=0); 55 | public: 56 | Regex(std::string regex, bool test = false); 57 | Regex(const Regex& regex); 58 | ~Regex(); 59 | 60 | bool match(const std::string& str, std::vector* results = 0); 61 | bool matchAll(const std::string& str, std::vector* results = 0); 62 | 63 | bool replace(std::string& str, const std::string& replacement_str); 64 | bool replaceAll(std::string& str, const std::string& replacement_str); 65 | 66 | bool isValid() const; 67 | 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /resource.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "resource.h" 29 | #include 30 | 31 | ResourceManager::ResourceManager() { 32 | } 33 | 34 | std::string ResourceManager::getDir() { 35 | return resource_dir; 36 | } 37 | 38 | void ResourceManager::setDir(const std::string& resource_dir) { 39 | this->resource_dir = resource_dir; 40 | } 41 | 42 | void ResourceManager::purge() { 43 | //free all resources - should be called BEFORE SDL_QUIT ... 44 | for(std::map::iterator it= resources.begin(); it!=resources.end();it++) { 45 | delete it->second; 46 | } 47 | 48 | resources.clear(); 49 | } 50 | 51 | ResourceManager::~ResourceManager() { 52 | } 53 | 54 | bool ResourceManager::fileExists(const std::string& filename) { 55 | return boost::filesystem::is_regular_file(filename); 56 | } 57 | 58 | bool ResourceManager::dirExists(const std::string& dirname) { 59 | return boost::filesystem::is_directory(dirname); 60 | } 61 | 62 | void ResourceManager::release(Resource* resource) { 63 | Resource* r = resources[resource->resource_name]; 64 | 65 | if(r==0) return; 66 | 67 | //debugLog("decrementing ref count for %s\n", name.c_str()); 68 | r->deref(); 69 | 70 | if(r->refcount()<=0) { 71 | //debugLog("no refs to %s, deleting\n", name.c_str()); 72 | resources.erase(r->resource_name); //sufficient? 73 | delete r; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef RESOURCEMANAGER_H 29 | #define RESOURCEMANAGER_H 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | class ResourceException : public std::exception { 36 | protected: 37 | std::string resource; 38 | public: 39 | ResourceException(const std::string& resource) : resource(resource) {} 40 | virtual ~ResourceException() throw () {}; 41 | 42 | virtual const char* what() const throw() { return resource.c_str(); } 43 | }; 44 | 45 | class Resource { 46 | int refs; 47 | public: 48 | std::string resource_name; 49 | Resource() { refs =0; }; 50 | Resource(const std::string& resource_name) : resource_name(resource_name), refs(0) {}; 51 | virtual ~Resource() {}; 52 | 53 | void setResourceName(const std::string& resource_name) { 54 | if(this->resource_name.empty()) this->resource_name = resource_name; 55 | }; 56 | 57 | int refcount() { return refs; }; 58 | void addref() { refs++; }; 59 | void deref() { refs--; }; 60 | }; 61 | 62 | class ResourceManager { 63 | protected: 64 | std::map resources; 65 | std::string resource_dir; 66 | public: 67 | 68 | void setDir(const std::string& resource_dir); 69 | std::string getDir(); 70 | 71 | ResourceManager(); 72 | virtual ~ResourceManager(); 73 | 74 | static bool fileExists(const std::string& filename); 75 | static bool dirExists(const std::string& dirname); 76 | 77 | void purge(); 78 | void release(Resource* resource); 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /sdlapp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef SDLAPP_H 29 | #define SDLAPP_H 30 | 31 | #include "SDL.h" 32 | 33 | #ifdef _WIN32 34 | 35 | #ifdef _WIN32_WINNT 36 | #undef _WIN32_WINNT 37 | #endif 38 | 39 | #define _WIN32_WINNT 0x0501 40 | #include "windows.h" 41 | #endif 42 | 43 | #include "gl.h" 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | extern std::string gSDLAppConfDir; 50 | extern std::string gSDLAppResourceDir; 51 | extern std::string gSDLAppPathSeparator; 52 | 53 | extern std::string gSDLAppTitle; 54 | extern std::string gSDLAppExec; 55 | 56 | void SDLAppInfo(std::string msg); 57 | void SDLAppQuit(std::string error); 58 | 59 | void SDLAppInit(std::string apptitle, std::string execname, std::string exepath = ""); 60 | std::string SDLAppAddSlash(std::string path); 61 | 62 | void SDLAppParseArgs(int argc, char *argv[], int* xres, int* yres, bool* fullscreen, std::vector* otherargs = 0); 63 | 64 | class SDLAppException : public std::exception { 65 | protected: 66 | std::string message; 67 | bool showhelp; 68 | 69 | public: 70 | SDLAppException(const char* str, ...) : showhelp(false) { 71 | 72 | va_list vl; 73 | char msg[65536]; 74 | 75 | va_start(vl, str); 76 | vsnprintf(msg, 65536, str, vl); 77 | va_end(vl); 78 | 79 | message = std::string(msg); 80 | } 81 | 82 | SDLAppException(std::string message) : showhelp(false), message(message) {} 83 | 84 | ~SDLAppException() throw () {}; 85 | 86 | bool showHelp() const { return showhelp; } 87 | void setShowHelp(bool showhelp) { this->showhelp = showhelp; }; 88 | 89 | virtual const char* what() const throw() { return message.c_str(); } 90 | }; 91 | 92 | class SDLApp { 93 | int frame_count; 94 | int fps_updater; 95 | int return_code; 96 | 97 | void updateFramerate(); 98 | protected: 99 | int min_delta_msec; 100 | bool appFinished; 101 | 102 | void stop(int return_code); 103 | 104 | virtual bool handleEvent(SDL_Event& event); 105 | public: 106 | float fps; 107 | 108 | SDLApp(); 109 | virtual ~SDLApp() {}; 110 | 111 | #ifdef USE_X11 112 | static void initX11ClipboardEventFilter(); 113 | static int X11ClipboardEventFilter(const SDL_Event *event); 114 | #endif 115 | 116 | #ifdef _WIN32 117 | static HWND console_window; 118 | static bool existing_console; 119 | 120 | static void initConsole(); 121 | static void showConsole(bool show); 122 | static void resizeConsole(int height); 123 | #endif 124 | 125 | int run(); 126 | 127 | static bool getClipboardText(std::string& text); 128 | static void setClipboardText(const std::string& text); 129 | 130 | virtual void resize(int width, int height) {}; 131 | 132 | virtual void update(float t, float dt) {}; 133 | virtual void init() {}; 134 | 135 | virtual void logic(float t, float dt) {}; 136 | virtual void draw(float t, float dt) {}; 137 | 138 | virtual void quit() { appFinished = true; }; 139 | 140 | virtual void mouseMove(SDL_MouseMotionEvent *e) {}; 141 | virtual void mouseClick(SDL_MouseButtonEvent *e) {}; 142 | virtual void keyPress(SDL_KeyboardEvent *e) {}; 143 | 144 | #if SDL_VERSION_ATLEAST(2,0,0) 145 | virtual void textInput(SDL_TextInputEvent* e) {}; 146 | virtual void textEdit(SDL_TextEditingEvent* e) {}; 147 | 148 | virtual void mouseWheel(SDL_MouseWheelEvent *e) {}; 149 | #endif 150 | 151 | int returnCode(); 152 | bool isFinished(); 153 | }; 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /seeklog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "seeklog.h" 29 | #include "sdlapp.h" 30 | 31 | #ifndef _MSC_VER 32 | #include 33 | #endif 34 | 35 | long long gSeekLogMaxBufferSize = 104857600; 36 | 37 | //StreamLog 38 | 39 | StreamLog::StreamLog() { 40 | this->stream = &std::cin; 41 | 42 | fcntl_fail = false; 43 | 44 | #ifdef _WIN32 45 | stdin_handle = GetStdHandle(STD_INPUT_HANDLE); 46 | #else 47 | int ret = fcntl(STDIN_FILENO, F_GETFL, 0); 48 | 49 | if (fcntl (STDIN_FILENO, F_SETFL, ret | O_NONBLOCK) < 0) { 50 | debugLog("fcntl(stdin) failed"); 51 | fcntl_fail = true; 52 | } 53 | #endif 54 | } 55 | 56 | StreamLog::~StreamLog() { 57 | } 58 | 59 | bool StreamLog::getNextLine(std::string& line) { 60 | 61 | //try and fix the stream 62 | if(isFinished()) stream->clear(); 63 | 64 | #ifdef _WIN32 65 | 66 | DWORD available_bytes; 67 | 68 | if (!PeekNamedPipe(stdin_handle, 0, 0, 0, 69 | &available_bytes, 0)) return false; 70 | 71 | if(available_bytes==0) return false; 72 | 73 | #endif 74 | 75 | std::getline(*stream, line); 76 | 77 | //remove carriage returns 78 | if (line.size() > 0 && line[line.size()-1] == '\r') { 79 | line.resize(line.size() - 1); 80 | } 81 | 82 | if(isFinished()) { 83 | return false; 84 | } 85 | 86 | return true; 87 | } 88 | 89 | bool StreamLog::isFinished() { 90 | 91 | if(fcntl_fail || stream->fail() || stream->eof()) { 92 | return true; 93 | } 94 | 95 | return false; 96 | } 97 | 98 | // SeekLog 99 | 100 | SeekLog::SeekLog(std::string logfile) { 101 | this->logfile = logfile; 102 | 103 | this->stream = 0; 104 | 105 | if(!readFully()) { 106 | throw SeekLogException(logfile); 107 | } 108 | } 109 | 110 | bool SeekLog::readFully() { 111 | 112 | if(stream!=0) delete stream; 113 | 114 | std::ifstream* file = new std::ifstream(logfile.c_str(), std::ios::in | std::ios::binary | std::ios::ate); 115 | 116 | file_size = file->tellg(); 117 | 118 | if(!file->is_open()) { 119 | delete file; 120 | return false; 121 | } 122 | 123 | file->seekg (0, std::ios::beg); 124 | 125 | //dont load into memory if larger than 126 | if(file_size > gSeekLogMaxBufferSize) { 127 | stream = file; 128 | return true; 129 | } 130 | 131 | 132 | //buffer entire file into memory 133 | char* filebuffer = new char[file_size+1]; 134 | 135 | if(!file->read(filebuffer, file_size)) { 136 | file->close(); 137 | delete file; 138 | delete [] filebuffer; 139 | return false; 140 | } 141 | filebuffer[file_size] = '\0'; 142 | 143 | file->close(); 144 | delete file; 145 | 146 | stream = new std::istringstream(std::string(filebuffer)); 147 | 148 | delete[] filebuffer; 149 | 150 | return true; 151 | } 152 | 153 | SeekLog::~SeekLog() { 154 | if(stream!=0) delete stream; 155 | } 156 | 157 | float SeekLog::getPercent() { 158 | return current_percent; 159 | } 160 | 161 | void SeekLog::setPointer(std::streampos pointer) { 162 | stream->clear(); 163 | stream->seekg(pointer); 164 | } 165 | 166 | std::streampos SeekLog::getPointer() { 167 | return stream->tellg(); 168 | } 169 | 170 | void SeekLog::seekTo(float percent) { 171 | 172 | std::streampos mem_offset = (std::streampos) (percent * file_size); 173 | 174 | setPointer(mem_offset); 175 | 176 | //throw away end of line 177 | if(mem_offset != (std::streampos)0) { 178 | std::string eol; 179 | getNextLine(eol); 180 | } 181 | } 182 | 183 | bool SeekLog::getNextLine(std::string& line) { 184 | 185 | //try and fix the stream 186 | if(isFinished()) stream->clear(); 187 | 188 | std::getline(*stream, line); 189 | 190 | //remove carriage returns 191 | if (line.size() > 0 && line[line.size()-1] == '\r') { 192 | line.resize(line.size() - 1); 193 | } 194 | 195 | if(stream->fail()) { 196 | return false; 197 | } 198 | 199 | current_percent = (float) stream->tellg() / file_size; 200 | //debugLog("current_percent = %.2f\n", current_percent); 201 | 202 | return true; 203 | } 204 | 205 | // temporarily move the file pointer to get a line somewhere else in the file 206 | bool SeekLog::getNextLineAt(std::string& line, float percent) { 207 | std::streampos currpointer = getPointer(); 208 | 209 | seekTo(percent); 210 | 211 | bool success = getNextLine(line); 212 | 213 | //set the pointer back 214 | setPointer(currpointer); 215 | 216 | return success; 217 | } 218 | 219 | bool SeekLog::isFinished() { 220 | bool finished = false; 221 | 222 | if(stream->fail() || stream->eof()) { 223 | //debugLog("stream is finished"); 224 | finished=true; 225 | } 226 | 227 | return finished; 228 | } 229 | -------------------------------------------------------------------------------- /seeklog.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef SEEK_LOG_H 29 | #define SEEK_LOG_H 30 | 31 | #include "display.h" 32 | #include "logger.h" 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | class BaseLog { 40 | 41 | protected: 42 | std::istream* stream; 43 | public: 44 | virtual ~BaseLog() {}; 45 | virtual bool getNextLine(std::string& line) { return false; }; 46 | virtual bool isFinished() { return false; }; 47 | }; 48 | 49 | class StreamLog : public BaseLog { 50 | 51 | bool fcntl_fail; 52 | #ifdef _WIN32 53 | void* stdin_handle; 54 | #endif 55 | public: 56 | StreamLog(); 57 | ~StreamLog(); 58 | 59 | bool getNextLine(std::string& line); 60 | bool isFinished(); 61 | }; 62 | 63 | class SeekLogException : public std::exception { 64 | protected: 65 | std::string filename; 66 | public: 67 | SeekLogException(std::string& filename) : filename(filename) {} 68 | virtual ~SeekLogException() throw () {}; 69 | 70 | virtual const char* what() const throw() { return filename.c_str(); } 71 | }; 72 | 73 | class SeekLog : public BaseLog { 74 | 75 | std::string logfile; 76 | 77 | long long file_size; 78 | float current_percent; 79 | 80 | bool readFully(); 81 | public: 82 | SeekLog(std::string logfile); 83 | ~SeekLog(); 84 | 85 | void setPointer(std::streampos pointer); 86 | std::streampos getPointer(); 87 | 88 | void seekTo(float percent); 89 | bool getNextLine(std::string& line); 90 | bool getNextLineAt(std::string& line, float percent); 91 | float getPercent(); 92 | 93 | bool isFinished(); 94 | }; 95 | 96 | extern long long gSeekLogMaxBufferSize; 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 7 | 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SDLAPP_SETTINGS_H 19 | #define SDLAPP_SETTINGS_H 20 | 21 | #include "conffile.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | class SDLAppSettings { 28 | protected: 29 | std::string default_section_name; 30 | 31 | std::map arg_types; 32 | std::map arg_aliases; 33 | std::map conf_sections; 34 | 35 | virtual void commandLineOption(const std::string& name, const std::string& value) {} 36 | 37 | bool parseRectangle(const std::string& value, int& x, int& y); 38 | bool parseViewport(const std::string& value, int& x, int& y, bool& no_resize); 39 | public: 40 | int display_width; 41 | int display_height; 42 | int window_x; 43 | int window_y; 44 | int screen; 45 | bool viewport_specified; 46 | bool multisample; 47 | bool fullscreen; 48 | bool frameless; 49 | bool transparent; 50 | bool resizable; 51 | bool vsync; 52 | bool high_dpi; 53 | 54 | std::string output_ppm_filename; 55 | int output_framerate; 56 | 57 | SDLAppSettings(); 58 | 59 | static bool parseDateTime(const std::string& datetime, time_t& timestamp); 60 | 61 | void parseArgs(int argc, char *argv[], ConfFile& conffile, std::vector* files = 0); 62 | void parseArgs(const std::vector& args, ConfFile& conffile, std::vector* files = 0); 63 | 64 | void exportDisplaySettings(ConfFile& conf); 65 | void importDisplaySettings(ConfFile& conf); 66 | 67 | void setDisplayDefaults(); 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /shader.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | #ifndef GLSL_SHADER_H 28 | #define GLSL_SHADER_H 29 | 30 | #include "vectors.h" 31 | #include "resource.h" 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "shader_common.h" 41 | 42 | class Shader; 43 | 44 | class ShaderPass : public AbstractShaderPass { 45 | public: 46 | ShaderPass(Shader* parent, int shader_object_type, const std::string& shader_object_desc); 47 | ~ShaderPass(); 48 | 49 | void attachTo(unsigned int program); 50 | void unload(); 51 | void compile(); 52 | void checkError(); 53 | }; 54 | 55 | class Shader : public AbstractShader { 56 | protected: 57 | void checkProgramError(); 58 | public: 59 | Shader(); 60 | Shader(const std::string& prefix); 61 | ~Shader(); 62 | 63 | void applyUniform(ShaderUniform* u); 64 | 65 | int getUniformLocation(const std::string& uniform_name); 66 | 67 | void loadPrefix(); 68 | 69 | void compile(); 70 | void link(); 71 | 72 | void load(); 73 | void unload(); 74 | 75 | void bind(); 76 | void unbind(); 77 | 78 | AbstractShaderPass* grabShaderPass(unsigned int shader_object_type); 79 | }; 80 | 81 | class ShaderManager : public ResourceManager { 82 | public: 83 | ShaderManager(); 84 | Shader* grab(const std::string& shader_prefix); 85 | 86 | void manage(Shader* shader); 87 | 88 | void unload(); 89 | void reload(bool force = false); 90 | }; 91 | 92 | extern ShaderManager shadermanager; 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /stringhash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "stringhash.h" 29 | 30 | int gStringHashSeed = 31; 31 | 32 | int stringHash(const std::string& str) { 33 | 34 | int val = 0; 35 | int n = str.size(); 36 | 37 | for (int i = 0; i < n; i++) { 38 | val = val + str[i] * (gStringHashSeed^(n-i)); 39 | } 40 | 41 | if(val<0) { 42 | val = -val; 43 | } 44 | 45 | return val; 46 | } 47 | 48 | vec2 vec2Hash(const std::string& str) { 49 | int hash = stringHash(str); 50 | 51 | int x = ((hash/7) % 255) - 127; 52 | int y = ((hash/3) % 255) - 127; 53 | 54 | vec2 v = normalise(vec2(x, y)); 55 | 56 | return v; 57 | } 58 | 59 | vec3 vec3Hash(const std::string& str) { 60 | int hash = stringHash(str); 61 | 62 | int x = ((hash/7) % 255) - 127; 63 | int y = ((hash/3) % 255) - 127; 64 | int z = hash % 255; 65 | 66 | vec3 v = normalise(vec3(x, y, z)); 67 | 68 | return v; 69 | } 70 | 71 | vec3 colourHash(const std::string& str) { 72 | int hash = stringHash(str); 73 | 74 | if(hash == 0) hash++; 75 | 76 | int r = (hash/7) % 255; 77 | int g = (hash/3) % 255; 78 | int b = hash % 255; 79 | 80 | vec3 colour = normalise(vec3(r, g, b)); 81 | 82 | return colour; 83 | } 84 | -------------------------------------------------------------------------------- /stringhash.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef STRINGHASH_H 29 | #define STRINGHASH_H 30 | 31 | #include 32 | 33 | #include "vectors.h" 34 | 35 | //basic string hash algorithm 36 | int stringHash(const std::string& str); 37 | vec2 vec2Hash(const std::string& str); 38 | vec3 vec3Hash(const std::string& str); 39 | vec3 colourHash(const std::string& str); 40 | 41 | extern int gStringHashSeed; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /texture.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef TEXTURE_H 29 | #define TEXTURE_H 30 | 31 | #include "SDL_image.h" 32 | 33 | #include "resource.h" 34 | #include "gl.h" 35 | 36 | #include 37 | 38 | class TextureException : public ResourceException { 39 | public: 40 | TextureException(std::string& texture_file) : ResourceException(texture_file) {} 41 | }; 42 | 43 | class TextureResource : public Resource { 44 | bool mipmaps; 45 | GLint wrap; 46 | GLint min_filter; 47 | GLint mag_filter; 48 | std::string filename; 49 | 50 | GLenum colourFormat(SDL_Surface* surface); 51 | public: 52 | int w, h; 53 | GLenum target; 54 | GLenum format; 55 | GLuint textureid; 56 | GLubyte* data; 57 | 58 | TextureResource(); 59 | TextureResource(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data = 0); 60 | TextureResource(const std::string& filename, bool mipmaps, GLint wrap, bool external); 61 | 62 | void setWrapStyle(GLint wrap); 63 | 64 | void setFiltering(GLint min_filter, GLint mag_filter); 65 | void setDefaultFiltering(); 66 | 67 | void bind(); 68 | 69 | void createTexture(); 70 | 71 | void reload(); 72 | 73 | void load(bool reload = false); 74 | 75 | void unload(); 76 | 77 | ~TextureResource(); 78 | }; 79 | 80 | class TextureManager : public ResourceManager { 81 | int resource_seq; 82 | 83 | void addResource(TextureResource* r); 84 | public: 85 | bool trilinear; 86 | 87 | TextureManager(); 88 | 89 | TextureResource* grabFile(const std::string& filename, bool mipmaps = true, GLint wrap = GL_CLAMP_TO_EDGE); 90 | TextureResource* grab(const std::string& filename, bool mipmaps = true, GLint wrap = GL_CLAMP_TO_EDGE, bool external_file = false); 91 | 92 | TextureResource* create(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data = 0); 93 | TextureResource* create(GLenum target = GL_TEXTURE_2D); 94 | 95 | void unload(); 96 | void reload(); 97 | }; 98 | 99 | extern TextureManager texturemanager; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /tga.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef TGA_WRITER_H 29 | #define TGA_WRITER_H 30 | 31 | #include "SDL_thread.h" 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | class TGAWriter { 39 | protected: 40 | bool rle; 41 | 42 | size_t components; 43 | size_t rle_count; 44 | size_t raw_count; 45 | 46 | std::ostream* out; 47 | 48 | void writeHeader(); 49 | 50 | inline void writeRLE(int pixel_count, const char* pixel); 51 | inline void writeRaw(std::vector& buffer, int start, int pixel_count); 52 | 53 | void writeScanlines(std::vector& buffer, int width, int height); 54 | 55 | void init(); 56 | 57 | public: 58 | TGAWriter(int components = 3); 59 | 60 | bool open(const std::string& filename); 61 | void close(); 62 | 63 | void setOutputStream(std::ostream* out); 64 | 65 | void screenshot(const std::string& filename); 66 | void capture(std::vector& buffer); 67 | void writeTGA(std::vector& buffer); 68 | }; 69 | 70 | enum tga_exporter_state { TGA_EXPORTER_WAIT, TGA_EXPORTER_WRITE, TGA_EXPORTER_EXIT, TGA_EXPORTER_STOPPED }; 71 | 72 | class TGAExporter { 73 | protected: 74 | TGAWriter writer; 75 | 76 | std::vector* buffer_shared_ptr; 77 | 78 | std::vector buffer1; 79 | std::vector buffer2; 80 | 81 | SDL_cond* cond; 82 | SDL_mutex* mutex; 83 | SDL_Thread* thread; 84 | 85 | int thread_state; 86 | 87 | std::string filename; 88 | 89 | static int startThread(void *exporter); 90 | public: 91 | TGAExporter(const std::string& filename); 92 | ~TGAExporter(); 93 | 94 | void run(); 95 | void stop(); 96 | 97 | void capture(); 98 | }; 99 | 100 | class TGAExporterException : public std::exception { 101 | protected: 102 | std::string filename; 103 | public: 104 | TGAExporterException(const std::string& filename) : filename(filename) {}; 105 | 106 | virtual ~TGAExporterException() throw () {}; 107 | virtual const char* what() const throw() { return filename.c_str(); }; 108 | }; 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /timer.cpp: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | 3 | // GLTimer 4 | 5 | GLTimer::GLTimer() { 6 | query_id = 0; 7 | query_value = 0; 8 | query_start = 0; 9 | query_stop = 0; 10 | cpu_time = 0; 11 | } 12 | 13 | GLTimer::GLTimer(const std::string& name) : name(name) { 14 | query_id = 0; 15 | query_value = 0; 16 | query_start = 0; 17 | query_stop = 0; 18 | cpu_time = 0; 19 | } 20 | 21 | GLTimer::~GLTimer() { 22 | unload(); 23 | } 24 | 25 | void GLTimer::unload() { 26 | query_value = 0; 27 | if(query_id) { 28 | glDeleteQueries(1, &query_id); 29 | query_id = 0; 30 | } 31 | query_start = query_stop = 0; 32 | } 33 | 34 | void GLTimer::start() { 35 | if(query_start > 0) return; 36 | 37 | query_start = SDL_GetTicks(); 38 | 39 | if(!query_id) glGenQueries( 1, &query_id ); 40 | 41 | glBeginQuery(GL_TIME_ELAPSED, query_id); 42 | 43 | query_stop = 0; 44 | } 45 | 46 | void GLTimer::stop() { 47 | if(!query_start || query_stop > 0) return; 48 | glEndQuery(GL_TIME_ELAPSED); 49 | query_stop = SDL_GetTicks(); 50 | } 51 | 52 | const std::string& GLTimer::getName() const { 53 | return name; 54 | } 55 | 56 | GLuint64 GLTimer::getValue() const { 57 | return query_value; 58 | } 59 | 60 | Uint32 GLTimer::getGLMillis() const { 61 | return query_value / 1000000; 62 | } 63 | 64 | Uint32 GLTimer::getCPUMillis() const { 65 | return cpu_time; 66 | } 67 | 68 | bool GLTimer::check() { 69 | if(!query_start) return false; 70 | 71 | GLuint64 elapsed; 72 | GLint available = 0; 73 | 74 | glGetQueryObjectiv(query_id, GL_QUERY_RESULT_AVAILABLE, &available); 75 | 76 | if(!available) return false; 77 | 78 | glGetQueryObjectui64v(query_id, GL_QUERY_RESULT, &elapsed); 79 | 80 | query_value = elapsed; 81 | cpu_time = query_stop-query_start; 82 | query_start = query_stop = 0; 83 | 84 | return true; 85 | } 86 | -------------------------------------------------------------------------------- /timer.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_TIMER_H 2 | #define CORE_TIMER_H 3 | 4 | #include 5 | 6 | #include "gl.h" 7 | 8 | class GLTimer { 9 | Uint32 query_start; 10 | Uint32 query_stop; 11 | Uint32 cpu_time; 12 | GLuint64 query_value; 13 | GLuint query_id; 14 | std::string name; 15 | public: 16 | GLTimer(); 17 | GLTimer(const std::string& name); 18 | ~GLTimer(); 19 | 20 | void start(); 21 | void stop(); 22 | bool check(); 23 | 24 | const std::string& getName() const; 25 | GLuint64 getValue() const; 26 | Uint32 getGLMillis() const; 27 | Uint32 getCPUMillis() const; 28 | 29 | void unload(); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /timezone.cpp: -------------------------------------------------------------------------------- 1 | #include "timezone.h" 2 | 3 | #include 4 | #include 5 | 6 | std::string local_tz; 7 | bool tz_initialized = false; 8 | 9 | void init_tz() { 10 | if(tz_initialized) return; 11 | 12 | //check if TZ is set, store current value 13 | char* current_tz_env = getenv("TZ"); 14 | if(current_tz_env != 0) { 15 | local_tz = std::string("TZ="); 16 | local_tz += std::string(current_tz_env); 17 | } 18 | 19 | tz_initialized = true; 20 | } 21 | 22 | void set_utc_tz() { 23 | //change TZ to UTC 24 | putenv((char*)"TZ=UTC"); 25 | tzset(); 26 | } 27 | 28 | void unset_utc_tz() { 29 | if(!local_tz.empty()) { 30 | putenv((char*)local_tz.c_str()); 31 | } else { 32 | #ifndef _WIN32 33 | unsetenv("TZ"); 34 | #else 35 | putenv((char*)"TZ="); 36 | #endif 37 | } 38 | tzset(); 39 | } 40 | 41 | time_t mktime_utc(struct tm* timeinfo) { 42 | init_tz(); 43 | 44 | set_utc_tz(); 45 | 46 | time_t time_utc = mktime(timeinfo); 47 | 48 | unset_utc_tz(); 49 | 50 | return time_utc; 51 | } 52 | -------------------------------------------------------------------------------- /timezone.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_TIMEZONE_H 2 | #define CORE_TIMEZONE_H 3 | 4 | #include 5 | 6 | extern "C" { 7 | void init_tz(); 8 | void set_utc_tz(); 9 | void unset_utc_tz(); 10 | 11 | time_t mktime_utc(struct tm* timeinfo); 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ui/action.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_ACTION_H 2 | #define UI_ACTION_H 3 | 4 | class UIElement; 5 | 6 | class UIAction { 7 | public: 8 | UIAction() {}; 9 | virtual ~UIAction() {}; 10 | 11 | virtual void perform() {}; 12 | virtual void idle() {}; 13 | }; 14 | 15 | class UIElementAction : public UIAction { 16 | protected: 17 | UIElement* element; 18 | public: 19 | UIElementAction(UIElement* element) : element(element) {}; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ui/button.cpp: -------------------------------------------------------------------------------- 1 | #include "button.h" 2 | 3 | UIButton::UIButton(const std::string& name, UIAction* action) 4 | : action(action), UISolidLayout(false) { 5 | 6 | label = new UILabel(name, false); 7 | 8 | addElement(label); 9 | 10 | button_anim = 0.0f; 11 | label->setMargin(3.0f); 12 | 13 | selectable = true; 14 | centre = true; 15 | min_rect = vec2(50.0f, 1.0f); 16 | } 17 | 18 | void UIButton::click(const vec2& pos) { 19 | action->perform(); 20 | 21 | inverted=true; 22 | button_anim = 0.25f; 23 | } 24 | 25 | void UIButton::update(float dt) { 26 | 27 | UILayout::update(dt); 28 | 29 | if(button_anim > 0.0f) { 30 | button_anim -=dt; 31 | if(button_anim <= 0.0f) inverted=false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ui/button.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_BUTTON_H 2 | #define UI_BUTTON_H 3 | 4 | #include "solid_layout.h" 5 | #include "label.h" 6 | #include "action.h" 7 | 8 | class UIButton : public UISolidLayout { 9 | float button_anim; 10 | UILabel* label; 11 | UIAction* action; 12 | public: 13 | UIButton(const std::string& name, UIAction* action); 14 | 15 | int getType() const { return UI_BUTTON; } 16 | 17 | void click(const vec2& pos); 18 | 19 | void update(float dt); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ui/checkbox.cpp: -------------------------------------------------------------------------------- 1 | #include "checkbox.h" 2 | 3 | //UICheckbox 4 | 5 | UICheckbox::UICheckbox(UIAction* action) 6 | : action(action), UIElement() { 7 | checktex = texturemanager.grab("ui/checkbox.png"); 8 | rect = vec2(16, 16.0f); 9 | } 10 | 11 | void UICheckbox::drawContent() { 12 | checktex->bind(); 13 | 14 | glColor4fv(glm::value_ptr(ui->getTintColour())); 15 | 16 | //background 17 | if(isChecked()) { 18 | drawQuad(vec2(16.0f,16.0f), vec4(0.0f, 0.5f, 0.5f, 1.0f)); 19 | } else { 20 | drawQuad(vec2(16.0f,16.0f), vec4(0.0f, 0.0f, 0.5f, 0.5f)); 21 | } 22 | } 23 | 24 | void UICheckbox::idle() { 25 | if(action != 0) action->idle(); 26 | } 27 | 28 | //UIBoolCheckbox 29 | 30 | UIBoolCheckbox::UIBoolCheckbox(bool *value, UIAction* action) 31 | : value(value), UICheckbox(action) { 32 | } 33 | 34 | void UIBoolCheckbox::click(const vec2& pos) { 35 | *value = !(*value); 36 | if(action != 0) action->perform(); 37 | } 38 | 39 | bool UIBoolCheckbox::isChecked() { 40 | return *value; 41 | } 42 | 43 | //UIFloatCheckbox 44 | 45 | UIFloatCheckbox::UIFloatCheckbox(float *value, UIAction* action) 46 | : value(value), UICheckbox(action) { 47 | } 48 | 49 | void UIFloatCheckbox::click(const vec2& pos) { 50 | *value = isChecked() ? 0.0f : 1.0f; 51 | if(action != 0) action->perform(); 52 | } 53 | 54 | bool UIFloatCheckbox::isChecked() { 55 | return *value == 1.0f; 56 | } 57 | 58 | //UILabelBoolCheckbox 59 | 60 | UILabelBoolCheckbox::UILabelBoolCheckbox(const std::string& label, bool* value, UIAction* action) : UILabelledElement(label) { 61 | 62 | layout->setMinRect(vec2(216.0f, 0.0f)); 63 | layout->addElement(new UIBoolCheckbox(value, action)); 64 | layout->setPadding(2.0f); 65 | } 66 | 67 | //UILabelBoolCheckboxSet 68 | 69 | UILabelBoolCheckboxSet::UILabelBoolCheckboxSet(const std::string& label, bool* value1, bool* value2, bool* value3, UIAction* action) : UILabelledElement(label) { 70 | 71 | layout->setMinRect(vec2(216.0f, 0.0f)); 72 | layout->addElement(new UIBoolCheckbox(value1, action)); 73 | layout->addElement(new UIBoolCheckbox(value2, action)); 74 | layout->addElement(new UIBoolCheckbox(value3, action)); 75 | layout->setPadding(2.0f); 76 | } 77 | 78 | //UILabelFloatCheckboxSet 79 | 80 | UILabelFloatCheckboxSet::UILabelFloatCheckboxSet(const std::string& label, float* value1, float* value2, float* value3, UIAction* action) : UILabelledElement(label) { 81 | 82 | layout->setMinRect(vec2(216.0f, 0.0f)); 83 | layout->addElement(new UIFloatCheckbox(value1, action)); 84 | layout->addElement(new UIFloatCheckbox(value2, action)); 85 | layout->addElement(new UIFloatCheckbox(value3, action)); 86 | layout->setPadding(2.0f); 87 | } 88 | -------------------------------------------------------------------------------- /ui/checkbox.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_CHECKBOX_H 2 | #define UI_CHECKBOX_H 3 | 4 | #include "element.h" 5 | #include "layout.h" 6 | #include "label.h" 7 | 8 | class UICheckbox : public UIElement { 9 | protected: 10 | TextureResource* checktex; 11 | UIAction* action; 12 | public: 13 | UICheckbox(UIAction* action = 0); 14 | 15 | int getType() const { return UI_CHECKBOX; }; 16 | 17 | virtual void click(const vec2& pos) {}; 18 | virtual bool isChecked() { return false; }; 19 | void drawContent(); 20 | void idle(); 21 | }; 22 | 23 | class UIBoolCheckbox : public UICheckbox { 24 | protected: 25 | bool* value; 26 | public: 27 | UIBoolCheckbox(bool* value, UIAction* action = 0); 28 | 29 | void click(const vec2& pos); 30 | bool isChecked(); 31 | }; 32 | 33 | class UIFloatCheckbox : public UICheckbox { 34 | protected: 35 | float* value; 36 | public: 37 | UIFloatCheckbox(float* value, UIAction* action = 0); 38 | 39 | void click(const vec2& pos); 40 | 41 | bool isChecked(); 42 | }; 43 | 44 | class UILabelBoolCheckbox : public UILabelledElement { 45 | 46 | public: 47 | UILabelBoolCheckbox(const std::string& label, bool* value,UIAction* action = 0); 48 | }; 49 | 50 | class UILabelBoolCheckboxSet : public UILabelledElement { 51 | 52 | public: 53 | UILabelBoolCheckboxSet(const std::string& label, bool* value1, bool* value2, bool* value3, UIAction* action = 0); 54 | }; 55 | 56 | class UILabelFloatCheckboxSet : public UILabelledElement { 57 | 58 | public: 59 | UILabelFloatCheckboxSet(const std::string& label, float* value1, float* value2, float* value3, UIAction* action = 0); 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /ui/colour.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_COLOUR_H 2 | #define UI_COLOUR_H 3 | 4 | #include "element.h" 5 | #include "slider.h" 6 | #include "label.h" 7 | #include "group.h" 8 | 9 | class UIColour : public UIElement { 10 | public: 11 | bool active; 12 | 13 | vec3* colour; 14 | 15 | float hue; 16 | float saturation; 17 | float lightness; 18 | 19 | UIColour(vec3* colour); 20 | 21 | void toHSL(); 22 | void toColour(); 23 | 24 | static void toHSL(const vec3& colour, float& hue, float& saturation, float& lightness); 25 | static vec3 toColour(float hue, float saturation, float lightness); 26 | 27 | void setColour(vec3* colour); 28 | 29 | int getType() const { return UI_COLOUR; }; 30 | 31 | void updateRect(); 32 | void drawContent(); 33 | }; 34 | 35 | class UILabelColour : public UILabelledElement { 36 | 37 | public: 38 | UIColour* ui_colour; 39 | 40 | UILabelColour(const std::string& label); 41 | UILabelColour(const std::string& label, vec3* value); 42 | UILabelColour(const std::string& label, vec3* a, vec3* b, vec3* c); 43 | UILabelColour(const std::string& label, vec3* a, vec3* b, vec3* c, vec3* d, vec3* e, vec3* f); 44 | 45 | void setColour(vec3* value); 46 | 47 | }; 48 | 49 | class UIColourSlider : public UISlider { 50 | protected: 51 | void drawGradient(const vec2& rect, const vec4& colour1, const vec4& colour2); 52 | public: 53 | UIColourSlider(); 54 | 55 | UIColour* colour; 56 | float* attribute; 57 | 58 | void drag(const vec2& pos); 59 | void setValue(float value); 60 | void scroll(bool up); 61 | 62 | virtual void setColour(UIColour* colour); 63 | 64 | void updateRect(); 65 | }; 66 | 67 | class UIHueSlider : public UIColourSlider { 68 | public: 69 | UIHueSlider(); 70 | 71 | void drawContent(); 72 | 73 | void setColour(UIColour* colour); 74 | }; 75 | 76 | class UILightnessSlider : public UIColourSlider { 77 | public: 78 | UILightnessSlider(); 79 | 80 | void drawContent(); 81 | 82 | void setColour(UIColour* colour); 83 | 84 | }; 85 | 86 | class UISatSlider : public UIColourSlider { 87 | public: 88 | UISatSlider(); 89 | 90 | void drawContent(); 91 | 92 | void setColour(UIColour* colour); 93 | }; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /ui/console.cpp: -------------------------------------------------------------------------------- 1 | #include "console.h" 2 | 3 | // UIConsole 4 | 5 | UIConsole::UIConsole(const vec2& console_rect) 6 | : UIGroup("Console", false, true) { 7 | 8 | layout->setMinRect(console_rect); 9 | 10 | history = new UIScrollLayout(vec2(0.0f, 0.0f)); 11 | history->setDrawBackground(false); 12 | history->setFill(true); 13 | 14 | message_count = 0; 15 | 16 | prompt = new UIConsolePrompt(this); 17 | 18 | layout->addElement(history); 19 | layout->addElement(prompt); 20 | } 21 | 22 | UIConsole::~UIConsole() { 23 | 24 | for(auto it = commands.begin(); it != commands.end(); it++) { 25 | delete it->second; 26 | } 27 | 28 | commands.clear(); 29 | } 30 | 31 | void UIConsole::showHide() { 32 | if(hidden) open(); 33 | else close(); 34 | } 35 | 36 | void UIConsole::open() { 37 | hidden=false; 38 | if(ui!=0) ui->selectElement(prompt); 39 | } 40 | 41 | void UIConsole::close() { 42 | hidden=true; 43 | if(ui!=0) ui->deselect(); 44 | } 45 | 46 | void UIConsole::updateHistory() { 47 | if(hidden) return; 48 | 49 | int message_count = Logger::getDefault()->getMessageCount(); 50 | 51 | if(this->message_count == message_count) return; 52 | 53 | this->message_count = message_count; 54 | 55 | // TODO: test if history has changed since last call 56 | 57 | bool stick_to_end = history->vertical_scrollbar->atEnd(); 58 | 59 | const std::deque& history_log = Logger::getDefault()->getHistory(); 60 | 61 | while(history->getElementCount() < history_log.size()) { 62 | history->addElement(new UIConsoleEntry(this)); 63 | } 64 | 65 | int history_size = history->getElementCount(); 66 | 67 | int i=0; 68 | for(auto it = history_log.rbegin(); it != history_log.rend(); it++) { 69 | const LoggerMessage& l = (*it); 70 | 71 | UIConsoleEntry* entry = (UIConsoleEntry*) history->getElement(history_size-i-1); 72 | 73 | switch(l.level) { 74 | case LOG_LEVEL_INFO: 75 | entry->setTextColour(vec4(1.0f)); 76 | break; 77 | case LOG_LEVEL_DEBUG: 78 | entry->setTextColour(vec4(0.0f, 1.0f, 0.0f, 1.0f)); 79 | break; 80 | case LOG_LEVEL_CONSOLE: 81 | entry->setTextColour(vec4(1.0f, 1.0f, 0.0f, 1.0f)); 82 | break; 83 | case LOG_LEVEL_SCRIPT: 84 | entry->setTextColour(vec4(1.0f, 0.5f, 0.25f, 1.0f)); 85 | break; 86 | case LOG_LEVEL_ERROR: 87 | entry->setTextColour(vec4(1.0f, 0.0f, 0.0f, 1.0f)); 88 | break; 89 | case LOG_LEVEL_WARN: 90 | entry->setTextColour(vec4(1.0f, 0.5f, 0.2f, 1.0f)); 91 | break; 92 | default: 93 | entry->setTextColour(vec4(1.0f)); 94 | break; 95 | } 96 | 97 | entry->setText(l.message); 98 | i++; 99 | } 100 | 101 | if(stick_to_end) { 102 | history->vertical_scrollbar->stickToEnd(); 103 | } 104 | } 105 | 106 | void UIConsole::registerCommand(UIConsoleCommand* command) { 107 | assert(getCommand(command->getName()) == 0); 108 | 109 | commands[command->getName()] = command; 110 | } 111 | 112 | UIConsoleCommand* UIConsole::getCommand(const std::string& name) { 113 | 114 | auto it = commands.find(name); 115 | 116 | if(it != commands.end()) { 117 | return it->second; 118 | } 119 | 120 | return 0; 121 | } 122 | 123 | bool UIConsole::executeCommand(const std::string& command_string) { 124 | 125 | consoleLog(command_string.c_str()); 126 | 127 | size_t s = command_string.find(" "); 128 | 129 | std::string command_name; 130 | std::string command_args; 131 | 132 | if(s != std::string::npos) { 133 | command_name = command_string.substr(0, s); 134 | if(s != command_string.size()-1) { 135 | command_args = command_string.substr(s+1); 136 | } 137 | } else { 138 | command_name = command_string; 139 | } 140 | 141 | UIConsoleCommand* command = getCommand(command_name); 142 | 143 | if(!command) { 144 | errorLog("no such console command '%s'", command_name.c_str()); 145 | return false; 146 | } 147 | 148 | return command->execute(command_args); 149 | } 150 | 151 | void UIConsole::update(float dt) { 152 | updateHistory(); 153 | 154 | UIGroup::update(dt); 155 | } 156 | 157 | // UIConsoleEntry 158 | 159 | UIConsoleEntry::UIConsoleEntry(UIConsole* console) 160 | : console(console), UILabel("", false) { 161 | setFillHorizontal(true); 162 | } 163 | 164 | 165 | //UIConsoleCommand 166 | 167 | UIConsoleCommand::UIConsoleCommand(const std::string& name) 168 | : name(name) { 169 | } 170 | 171 | const std::string& UIConsoleCommand::getName() const { 172 | return name; 173 | } 174 | 175 | bool UIConsoleCommand::execute(const std::string& args) { 176 | 177 | if(!args.empty()) return false; 178 | 179 | return execute(); 180 | } 181 | 182 | // UIConsolePrompt 183 | 184 | UIConsolePrompt::UIConsolePrompt(UIConsole* console) 185 | : console(console), UILabel("", true), history_index(-1) { 186 | setFillHorizontal(true); 187 | } 188 | 189 | bool UIConsolePrompt::submit() { 190 | 191 | if(text.empty()) return false; 192 | 193 | std::string command = text; 194 | 195 | setText(""); 196 | 197 | command_history.push_back(command); 198 | history_index = -1; 199 | 200 | return console->executeCommand(command); 201 | } 202 | 203 | void UIConsolePrompt::tab() { 204 | //auto complete? 205 | } 206 | 207 | void UIConsolePrompt::updateRect() { 208 | UILabel::updateRect(); 209 | } 210 | 211 | void UIConsolePrompt::updateContent() { 212 | bgcolour = selected ? vec4(1.0f, 1.0f, 1.0f, 0.15f) : vec4(0.0f); 213 | } 214 | 215 | void UIConsolePrompt::drawContent() { 216 | UILabel::drawContent(); 217 | } 218 | 219 | bool UIConsolePrompt::keyPress(SDL_KeyboardEvent *e) { 220 | 221 | if(e->keysym.sym == SDLK_BACKQUOTE) { 222 | console->showHide(); 223 | return true; 224 | } 225 | 226 | if(e->keysym.sym == SDLK_UP) { 227 | if(history_index == -1 && !command_history.empty()) { 228 | history_index = command_history.size() - 1; 229 | setText(command_history[history_index]); 230 | } else if(history_index > 0) { 231 | history_index--; 232 | setText(command_history[history_index]); 233 | } 234 | return true; 235 | } 236 | 237 | if(e->keysym.sym == SDLK_DOWN) { 238 | if(history_index < command_history.size()-1) { 239 | history_index++; 240 | setText(command_history[history_index]); 241 | } else { 242 | history_index = -1; 243 | setText(""); 244 | } 245 | 246 | return true; 247 | } 248 | 249 | return UILabel::keyPress(e); 250 | } 251 | 252 | -------------------------------------------------------------------------------- /ui/console.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_CONSOLE_H 2 | #define UI_CONSOLE_H 3 | 4 | #include "scroll_layout.h" 5 | #include "group.h" 6 | 7 | class UIConsoleCommand { 8 | protected: 9 | std::string name; 10 | public: 11 | UIConsoleCommand(const std::string& name); 12 | virtual ~UIConsoleCommand() {}; 13 | 14 | const std::string& getName() const; 15 | 16 | virtual bool execute(const std::string& args); 17 | virtual bool execute() { return false; }; 18 | }; 19 | 20 | class UIConsole : public UIGroup { 21 | UIScrollLayout* history; 22 | UILabel* prompt; 23 | 24 | int message_count; 25 | 26 | void updateHistory(); 27 | 28 | std::map commands; 29 | public: 30 | UIConsole(const vec2& console_rect); 31 | ~UIConsole(); 32 | 33 | void registerCommand(UIConsoleCommand* command); 34 | 35 | UIConsoleCommand* getCommand(const std::string& name); 36 | bool executeCommand(const std::string& command_string); 37 | 38 | void showHide(); 39 | void open(); 40 | void close(); 41 | 42 | void update(float dt); 43 | }; 44 | 45 | class UIConsoleEntry : public UILabel { 46 | protected: 47 | UIConsole* console; 48 | public: 49 | UIConsoleEntry(UIConsole* console); 50 | }; 51 | 52 | class UIConsolePrompt : public UILabel { 53 | protected: 54 | UIConsole* console; 55 | std::vector command_history; 56 | int history_index; 57 | public: 58 | UIConsolePrompt(UIConsole* console); 59 | 60 | void updateRect(); 61 | void updateContent(); 62 | void drawContent(); 63 | 64 | bool keyPress(SDL_KeyboardEvent *e); 65 | 66 | bool submit(); 67 | void tab(); 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /ui/element.cpp: -------------------------------------------------------------------------------- 1 | #include "element.h" 2 | 3 | #include 4 | 5 | std::map element_names = boost::assign::map_list_of 6 | (UI_INVALID, "Invalid" ) 7 | (UI_ELEMENT, "Element" ) 8 | (UI_LABEL, "Label" ) 9 | (UI_BUTTON, "Button" ) 10 | (UI_IMAGE, "Image" ) 11 | (UI_LAYOUT, "Layout" ) 12 | (UI_GROUP, "Group" ) 13 | (UI_COLOUR, "Colour" ) 14 | (UI_SELECT, "Select" ) 15 | (UI_SLIDER, "Slider" ) 16 | (UI_SCROLL_BAR, "ScrollBar" ) 17 | (UI_CHECKBOX, "Checkbox" ); 18 | 19 | UIElement::~UIElement() { 20 | { if(ui && selected) ui->deselect(); }; 21 | } 22 | 23 | const std::string& UIElement::getElementName() const { 24 | return getElementName(this->getType()); 25 | } 26 | 27 | const std::string& UIElement::getElementName(int type) { 28 | 29 | auto it = element_names.find(type); 30 | 31 | if(it != element_names.end()) return it->second; 32 | 33 | return element_names[UI_INVALID]; 34 | } 35 | 36 | void UIElement::drawOutline() { 37 | //fprintf(stderr, "rect %.2f, %.2f\n", rect.x, rect.y); 38 | ui->setTextured(false); 39 | 40 | glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 41 | 42 | glPushMatrix(); 43 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 44 | 45 | glLineWidth(1.0f); 46 | glTranslatef(0.5f, 0.5f, 0.0f); 47 | glBegin(GL_QUADS); 48 | glVertex2f(0.0f, 0.0f); 49 | glVertex2f(rect.x, 0.0f); 50 | glVertex2f(rect.x, rect.y); 51 | glVertex2f(0.0f, rect.y); 52 | glEnd(); 53 | 54 | glPopMatrix(); 55 | 56 | glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 57 | 58 | ui->setTextured(true); 59 | } 60 | 61 | void UIElement::getModifiers(bool& left_ctrl, bool& left_shift) { 62 | 63 | left_ctrl = left_shift = false; 64 | 65 | const Uint8* keystate = SDL_GetKeyboardState(NULL); 66 | 67 | if(keystate[SDL_SCANCODE_LCTRL]) left_ctrl = true; 68 | if(keystate[SDL_SCANCODE_LSHIFT]) left_shift = true; 69 | } 70 | 71 | double UIElement::granulaity(double initial, double scale) { 72 | 73 | bool left_ctrl, left_shift; 74 | getModifiers(left_ctrl, left_shift); 75 | 76 | double granul = initial; 77 | 78 | if(left_ctrl) granul *= scale; 79 | if(left_shift) granul *= scale; 80 | 81 | return granul; 82 | } 83 | 84 | void UIElement::drawOutline(const vec2& rect) { 85 | glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 86 | 87 | glPushMatrix(); 88 | glLineWidth(1.0f); 89 | glTranslatef(0.5f, 0.5f, 0.0f); 90 | 91 | glBegin(GL_QUADS); 92 | glVertex2f(0.0f, 0.0f); 93 | glVertex2f(rect.x, 0.0f); 94 | glVertex2f(rect.x, rect.y); 95 | glVertex2f(0.0f, rect.y); 96 | glEnd(); 97 | 98 | glPopMatrix(); 99 | 100 | glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 101 | } 102 | 103 | void UIElement::drawQuad(const vec2& pos, const vec2& rect, const vec4& texcoord) { 104 | 105 | glPushMatrix(); 106 | glTranslatef(pos.x, pos.y, 0.0f); 107 | drawQuad(rect, texcoord); 108 | glPopMatrix(); 109 | } 110 | 111 | void UIElement::drawQuad(const vec2& rect, const vec4& texcoord) { 112 | 113 | glBegin(GL_QUADS); 114 | glTexCoord2f(texcoord.x,texcoord.y); 115 | glVertex2f(0.0f, 0.0f); 116 | 117 | glTexCoord2f(texcoord.z,texcoord.y); 118 | glVertex2f(rect.x, 0.0f); 119 | 120 | glTexCoord2f(texcoord.z,texcoord.w); 121 | glVertex2f(rect.x, rect.y); 122 | 123 | glTexCoord2f(texcoord.x,texcoord.w); 124 | glVertex2f(0.0f, rect.y); 125 | glEnd(); 126 | } 127 | 128 | void UIElement::draw() { 129 | glPushMatrix(); 130 | glTranslatef(pos.x, pos.y, 0.0f); 131 | drawContent(); 132 | //if(selected) drawOutline(); 133 | glPopMatrix(); 134 | } 135 | 136 | void UIElement::update(float dt) { 137 | updateContent(); 138 | updateRect(); 139 | updateZIndex(); 140 | } 141 | 142 | void UIElement::updateZIndex() { 143 | if(parent != 0) zindex = parent->zindex + 1; 144 | } 145 | 146 | void UIElement::scroll(bool up) { 147 | if(parent != 0) parent->scroll(up); 148 | } 149 | 150 | bool UIElement::elementsByType(std::list& found, int type) { 151 | 152 | if(getType() == type) { 153 | found.push_back(this); 154 | return true; 155 | } 156 | 157 | return false; 158 | } 159 | 160 | void UIElement::elementsAt(const vec2& pos, std::list& elements_found) { 161 | 162 | if(hidden) return; 163 | 164 | vec2 rect = getRect(); 165 | 166 | if( pos.x >= this->pos.x && pos.x <= (this->pos.x + rect.x) 167 | && pos.y >= this->pos.y && pos.y <= (this->pos.y + rect.y)) { 168 | elements_found.push_back(this); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /ui/element.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_ELEMENT_H 2 | #define UI_ELEMENT_H 3 | 4 | #include "../display.h" 5 | #include "../vectors.h" 6 | 7 | #include "ui.h" 8 | 9 | #include 10 | 11 | enum { UI_INVALID, UI_ELEMENT, UI_LABEL, UI_BUTTON, UI_IMAGE, UI_LAYOUT, UI_GROUP, UI_COLOUR, UI_SELECT, UI_SLIDER, UI_SCROLL_BAR, UI_CHECKBOX }; 12 | 13 | class UIElement { 14 | protected: 15 | UI* ui; 16 | bool fill_horizontal; 17 | bool fill_vertical; 18 | public: 19 | vec2 pos; 20 | vec2 rect; 21 | bool editable; 22 | bool selected; 23 | bool disabled; 24 | bool hidden; 25 | bool scrollable; 26 | bool selectable; 27 | 28 | int zindex; 29 | 30 | UIElement* parent; 31 | 32 | // border around element between this element and other elements 33 | // doesnt affect the selectable area of the element 34 | vec4 margin; 35 | 36 | // padding around elements inside this element 37 | // affects the selectable area of the element 38 | vec2 padding; 39 | 40 | UIElement() : padding(0.0f, 0.0f), margin(0.0f, 0.0f, 0.0f, 0.0f), ui(0), disabled(false), selected(false), editable(false), hidden(false), fill_horizontal(false), fill_vertical(false), scrollable(false), selectable(true), zindex(0), parent(0) {}; 41 | 42 | virtual void setUI(UI* ui) { this->ui = ui; }; 43 | virtual ~UIElement(); 44 | 45 | virtual void drawOutline(); 46 | 47 | void drawOutline(const vec2& rect); 48 | 49 | static void getModifiers(bool& left_ctrl, bool& left_shift); 50 | static double granulaity(double initial, double scale); 51 | 52 | void drawQuad(const vec2& rect, const vec4& texcoord); 53 | void drawQuad(const vec2& pos, const vec2& rect, const vec4& texcoord); 54 | 55 | void setPadding(const vec2& padding) { this->padding = padding; }; 56 | void setPadding(float padding) { this->padding = vec2(padding, padding); }; 57 | 58 | void setMargin(const vec4& margin) { this->margin = margin; }; 59 | void setMargin(const vec2& margin) { this->margin = vec4(margin.x, margin.y, margin.x, margin.y); }; 60 | void setMargin(float margin) { this->margin = vec4(margin); }; 61 | 62 | virtual vec4 getMargin() const { return margin; }; 63 | 64 | void setFillHorizontal(bool fill) { this->fill_horizontal = fill; }; 65 | void setFillVertical (bool fill) { this->fill_vertical = fill; }; 66 | void setFill(bool fill) { this->fill_horizontal = fill; this->fill_vertical = fill; }; 67 | 68 | bool fillVertical() const { return fill_vertical; } 69 | bool fillHorizontal() const { return fill_horizontal; } 70 | 71 | virtual bool isVisible() const { return !hidden; } 72 | 73 | void setPos(const vec2& pos) { this->pos = pos; }; 74 | 75 | void hide() { hidden=true; }; 76 | void show() { hidden=false; }; 77 | 78 | virtual void idle() {}; 79 | 80 | virtual void setText(const std::string& text) {}; 81 | 82 | virtual void setSelected(bool selected) { this->selected = selected; }; 83 | 84 | virtual bool elementsByType(std::list& found, int type); 85 | 86 | virtual void elementsAt(const vec2& pos, std::list& elements_found); 87 | 88 | virtual vec2 getRect() { return rect; }; 89 | 90 | virtual int getType() const { return UI_ELEMENT; }; 91 | 92 | const std::string& getElementName() const; 93 | static const std::string& getElementName(int type); 94 | 95 | virtual void updatePos(const vec2& pos) { this->pos = pos; }; 96 | virtual void expandRect(const vec2& expand) {}; 97 | virtual void resetRect() {}; 98 | 99 | virtual void updateContent() {}; 100 | virtual void updateRect() {}; 101 | virtual void updateZIndex(); 102 | 103 | virtual bool keyPress(SDL_KeyboardEvent *e) { return false; }; 104 | virtual bool submit() { return false; }; 105 | 106 | virtual void update(float dt); 107 | 108 | virtual void scroll(bool up); 109 | 110 | virtual void drag(const vec2& pos) {}; 111 | virtual void click(const vec2& pos) { if(parent!=0) parent->click(pos); }; 112 | virtual void doubleClick(const vec2& pos) { click(pos); }; 113 | 114 | virtual bool isEditable() { return editable; }; 115 | virtual bool isScrollable() { return scrollable; }; 116 | virtual bool isSelectable() { return selectable; }; 117 | 118 | virtual void drawContent() {}; 119 | 120 | virtual void draw(); 121 | 122 | static bool reverse_zindex_sort (UIElement* e1, UIElement* e2) { 123 | if(e1->zindex != e2->zindex) return e1->zindex < e2->zindex; 124 | return e1 < e2; 125 | } 126 | 127 | static bool zindex_sort (UIElement* e1, UIElement* e2) { 128 | if(e2->zindex != e1->zindex) return e2->zindex < e1->zindex; 129 | return e1 < e2; 130 | } 131 | }; 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /ui/file_selector.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_FILE_SELECTOR_H 2 | #define UI_FILE_SELECTOR_H 3 | 4 | #include "group.h" 5 | #include "select.h" 6 | #include "scroll_layout.h" 7 | 8 | class UIFileSelectorAction { 9 | public: 10 | UIFileSelectorAction() {}; 11 | virtual void perform(const std::string& path) {}; 12 | }; 13 | 14 | class UIFileSelector : public UIGroup { 15 | 16 | UILabel* dir_path; 17 | UILabel* file_path; 18 | 19 | UIScrollLayout* listing; 20 | UISelect* filter_select; 21 | 22 | std::string previous_dir; 23 | 24 | std::string selected_path; 25 | std::string current_dir; 26 | 27 | std::string next_dir; 28 | UIOptionLabel* current_filter; 29 | 30 | UIFileSelectorAction* action; 31 | 32 | public: 33 | UIFileSelector(const std::string& title, const std::string& dir, UIFileSelectorAction* action); 34 | 35 | void prettyDirectory(std::string& dir_string); 36 | 37 | void addFilter(const std::string& name, const std::string& extension, bool select = false); 38 | 39 | bool changeDir(const std::string& dir); 40 | void updateListing(); 41 | 42 | void selectFile(const std::string& filename); 43 | void selectPath(const std::string& path); 44 | void confirm(); 45 | 46 | const std::string& getCurrentDir() const; 47 | 48 | std::string autocomplete(const std::string& input, bool dirs_only = false); 49 | 50 | void toggle(); 51 | void open(); 52 | void close(); 53 | 54 | void update(float dt); 55 | }; 56 | 57 | class UIFileSelectorLabel : public UILabel { 58 | protected: 59 | std::string path; 60 | bool directory; 61 | UIFileSelector* selector; 62 | public: 63 | UIFileSelectorLabel(UIFileSelector* selector, const std::string& path); 64 | UIFileSelectorLabel(UIFileSelector* selector, const std::string& label, const std::string& path); 65 | 66 | bool isDir() const { return directory; }; 67 | const std::string& getPath() const { return path; }; 68 | 69 | void doubleClick(const vec2& pos); 70 | void click(const vec2& pos); 71 | 72 | bool submit(); 73 | 74 | void updateContent(); 75 | }; 76 | 77 | class UIFileInputLabel : public UILabel { 78 | UIFileSelector* selector; 79 | public: 80 | UIFileInputLabel(UIFileSelector* selector, const std::string& filename); 81 | 82 | void tab(); 83 | 84 | bool submit(); 85 | }; 86 | 87 | class UIDirInputLabel : public UILabel { 88 | UIFileSelector* selector; 89 | public: 90 | UIDirInputLabel(UIFileSelector* selector, const std::string& dirname); 91 | 92 | void tab(); 93 | 94 | bool submit(); 95 | }; 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /ui/group.cpp: -------------------------------------------------------------------------------- 1 | #include "group.h" 2 | 3 | //UIGroup 4 | 5 | UIGroup::UIGroup(const std::string& groupname, bool minimized, bool resizable) 6 | : UILayout(false) { 7 | 8 | selectable = false; 9 | minimizable = true; 10 | 11 | layout = resizable ? new UIResizableLayout(): new UILayout(); 12 | layout->hidden = minimized; 13 | 14 | bar = new UIGroupBar(groupname); 15 | bar->setMargin(3.0f); 16 | 17 | layout->setMargin(vec2(3.0f, 3.0f)); 18 | layout->setPadding(3.0f); 19 | layout->setDrawBackground(true); 20 | layout->setFillHorizontal(true); 21 | layout->parent = this; 22 | 23 | setMinRect(vec2(350.0f, 0.0f)); 24 | 25 | addElement(bar); 26 | addElement(layout); 27 | 28 | open_action = 0; 29 | } 30 | 31 | void UIGroup::setTitle(const std::string& text) { 32 | bar->setText(text); 33 | } 34 | 35 | void UIGroup::minimize() { 36 | if(layout->hidden) return; 37 | layout->hidden = true; 38 | } 39 | 40 | void UIGroup::maximize() { 41 | layout->hidden=false; 42 | } 43 | 44 | void UIGroup::toggle() { 45 | if(!minimizable) return; 46 | 47 | layout->hidden = !layout->hidden; 48 | 49 | if(!layout->hidden && open_action != 0) { 50 | open_action->perform(); 51 | } 52 | } 53 | 54 | void UIGroup::setOpenAction(UIAction* action) { 55 | open_action = action; 56 | } 57 | 58 | //UIGroupBar 59 | 60 | UIGroupBar::UIGroupBar(const std::string& text) : UISolidLayout(true) { 61 | selectable = true; 62 | 63 | label = new UILabel(text, false); 64 | addElement(label); 65 | 66 | setFillHorizontal(true); 67 | } 68 | 69 | void UIGroupBar::setText(const std::string& text) { 70 | label->setText(text); 71 | } 72 | 73 | void UIGroupBar::click(const vec2& pos) { 74 | ((UIGroup*)parent)->toggle(); 75 | } 76 | -------------------------------------------------------------------------------- /ui/group.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_GROUP_h 2 | #define UI_GROUP_h 3 | 4 | #include "label.h" 5 | #include "solid_layout.h" 6 | 7 | class UIGroupBar : public UISolidLayout { 8 | public: 9 | UILabel* label; 10 | UIGroupBar(const std::string& text); 11 | void setText(const std::string& text); 12 | void click(const vec2& pos); 13 | }; 14 | 15 | class UIGroup : public UILayout { 16 | 17 | protected: 18 | UILayout* layout; 19 | UIAction* open_action; 20 | UIGroupBar* bar; 21 | 22 | bool minimizable; 23 | public: 24 | UIGroup(const std::string& groupname, bool minimized = false, bool resizable = false); 25 | virtual ~UIGroup() {}; 26 | 27 | void setOpenAction(UIAction* action); 28 | 29 | int getType() const { return UI_GROUP; }; 30 | 31 | UILayout* getLayout() { return layout; }; 32 | 33 | void setTitle(const std::string& text); 34 | 35 | virtual void toggle(); 36 | virtual void minimize(); 37 | virtual void maximize(); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ui/image.cpp: -------------------------------------------------------------------------------- 1 | #include "image.h" 2 | 3 | UIImage::UIImage(const std::string& image_path) 4 | : image_path(image_path), coords(0.0f, 0.0f, 1.0f, 1.0f) { 5 | 6 | rect = vec2(0.0f, 0.0f); 7 | init(); 8 | } 9 | 10 | UIImage::UIImage(const std::string& image_path, const vec2& rect, const vec4& coords) 11 | : image_path(image_path), coords(coords) { 12 | 13 | this->rect = rect; 14 | 15 | init(); 16 | } 17 | 18 | UIImage::~UIImage() { 19 | if(imagetex != 0) texturemanager.release(imagetex); 20 | } 21 | 22 | void UIImage::init() { 23 | imagetex = texturemanager.grab(image_path); 24 | 25 | colour = vec4(1.0f); 26 | shadow_offset = vec2(1.0f, 1.0f); 27 | shadow = 0.0f; 28 | 29 | if(glm::length(rect) < 1.0f) { 30 | rect = vec2(imagetex->w, imagetex->h); 31 | } 32 | } 33 | 34 | void UIImage::setTextureCoords(const vec4& coords) { 35 | this->coords = coords; 36 | } 37 | 38 | void UIImage::drawContent() { 39 | imagetex->bind(); 40 | 41 | if(shadow > 0.0f) { 42 | glColor4f(0.0f, 0.0f, 0.0f, shadow); 43 | drawQuad(rect + shadow_offset, coords); 44 | } 45 | 46 | glColor4fv(glm::value_ptr(colour)); 47 | drawQuad(rect, coords); 48 | } 49 | -------------------------------------------------------------------------------- /ui/image.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_IMAGE_H 2 | #define UI_IMAGE_H 3 | 4 | #include "element.h" 5 | 6 | class UIImage : public UIElement { 7 | TextureResource* imagetex; 8 | public: 9 | std::string image_path; 10 | vec4 coords; 11 | float shadow; 12 | vec2 shadow_offset; 13 | vec4 colour; 14 | 15 | UIImage(const std::string& image_path); 16 | UIImage(const std::string& image_path, const vec2& rect, const vec4& coords); 17 | 18 | void setTextureCoords(const vec4& coords); 19 | 20 | void init(); 21 | 22 | ~UIImage(); 23 | 24 | int getType() const { return UI_IMAGE; }; 25 | 26 | void drawContent(); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ui/label.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_LABEL_H 2 | #define UI_LABEL_H 3 | 4 | #include "element.h" 5 | #include "layout.h" 6 | #include "action.h" 7 | 8 | class UISlider; 9 | class UIFloatSlider; 10 | class UIColourSlider; 11 | class UILayout; 12 | 13 | class UILabel : public UIElement { 14 | protected: 15 | float cursor_anim; 16 | float expanded; 17 | 18 | bool text_changed; 19 | 20 | UIAction* action; 21 | 22 | std::string* value; 23 | 24 | void drawBackground(); 25 | public: 26 | vec4 bgcolour; 27 | vec4 selected_edit_bgcolour; 28 | vec4 edit_bgcolour; 29 | vec4 text_colour; 30 | 31 | UISlider* slider; 32 | std::string text; 33 | std::string display_text; 34 | 35 | UILabel(const std::string& text, bool editable = false, float width = -1.0f, UIAction* action = 0, std::string* value = 0); 36 | 37 | float width; 38 | 39 | bool keyPress(SDL_KeyboardEvent *e); 40 | 41 | int getType() const { return UI_LABEL; } 42 | 43 | virtual void tab(); 44 | 45 | virtual void backspace(); 46 | 47 | bool submit(); 48 | 49 | void setWidth(float width); 50 | void setText(const std::string& text); 51 | void setTextColour(const vec4& colour); 52 | 53 | void update(float dt); 54 | 55 | void elementsAt(const vec2& pos, std::list& elements_found); 56 | 57 | vec2 getRect(); 58 | void expandRect(const vec2& expand); 59 | void resetRect(); 60 | 61 | void updateRect(); 62 | 63 | void drawContent(); 64 | 65 | void idle(); 66 | }; 67 | 68 | class UIIntLabel : public UILabel { 69 | int* value; 70 | public: 71 | UIIntLabel(int* value, bool editable, UIAction* action = 0); 72 | 73 | bool keyPress(SDL_KeyboardEvent *e); 74 | bool submit(); 75 | 76 | void updateContent(); 77 | }; 78 | 79 | class UIFloatLabel : public UILabel { 80 | protected: 81 | float* value; 82 | public: 83 | UIFloatLabel(float* value, bool editable, UIAction* action = 0); 84 | UIFloatLabel(UIFloatSlider* slider, bool editable, UIAction* action = 0); 85 | 86 | void setValue(float* value); 87 | void setValue(float value); 88 | 89 | void scroll(bool up); 90 | void scale(bool up, float value_scale); 91 | 92 | bool keyPress(SDL_KeyboardEvent *e); 93 | bool submit(); 94 | 95 | void setSelected(bool selected); 96 | 97 | void updateContent(); 98 | }; 99 | 100 | class UIColourLabel : public UIFloatLabel { 101 | public: 102 | UIColourLabel(UIColourSlider* slider, bool editable); 103 | 104 | bool submit(); 105 | 106 | void updateContent(); 107 | }; 108 | 109 | class UILabelString : public UILabelledElement { 110 | public: 111 | UILabelString(const std::string& label, std::string* value, bool editable = false, UIAction* action = 0); 112 | }; 113 | 114 | class UILabelVec3 : public UILabelledElement { 115 | protected: 116 | vec3* value; 117 | public: 118 | UILabelVec3(const std::string& label, vec3* value, bool editable = false, UIAction* action = 0); 119 | }; 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /ui/layout.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_LAYOUT_H 2 | #define UI_LAYOUT_H 3 | 4 | #include "element.h" 5 | 6 | enum { 7 | UI_LAYOUT_ALIGN_NONE, 8 | UI_LAYOUT_ALIGN_TOP_LEFT, 9 | UI_LAYOUT_ALIGN_BOTTOM_LEFT, 10 | UI_LAYOUT_ALIGN_TOP_RIGHT, 11 | UI_LAYOUT_ALIGN_BOTTOM_RIGHT 12 | }; 13 | 14 | class UILabel; 15 | 16 | class UILayout : public UIElement { 17 | protected: 18 | int alignment; 19 | bool horizontal; 20 | std::vector elements; 21 | 22 | vec2 min_rect; 23 | vec2 expanded_rect; 24 | bool centre; 25 | bool drawbg; 26 | 27 | virtual void drawBackground(); 28 | public: 29 | vec4 bgcolour; 30 | 31 | UILayout(bool horizontal = false); 32 | ~UILayout(); 33 | 34 | void clear(); 35 | 36 | int getType() const { return UI_LAYOUT; }; 37 | 38 | vec2 getInnerRect(); 39 | vec2 getRect(); 40 | 41 | void expandRect(const vec2& expand); 42 | void resetRect(); 43 | 44 | void setUI(UI* ui); 45 | 46 | void addElement(UIElement* e); 47 | 48 | void setDrawBackground(bool drawbg); 49 | 50 | void setHorizontal(bool horizontal); 51 | void setAlignment(int alignment) { this->alignment = alignment; }; 52 | 53 | void setMinRect(const vec2& min_rect); 54 | 55 | int getElementCount() { return elements.size(); }; 56 | 57 | UIElement* getElement(int index) { return elements[index]; }; 58 | 59 | bool elementsByType(std::list& found, int type); 60 | 61 | void elementsAt(const vec2& pos, std::list& elements_found); 62 | 63 | virtual void resize(const vec2& pos); 64 | 65 | void updatePos(const vec2& pos); 66 | 67 | void update(float dt); 68 | 69 | void draw(); 70 | void drawOutline(); 71 | }; 72 | 73 | 74 | class UILabelledElement : public UILayout { 75 | protected: 76 | UILayout* layout; 77 | UILabel* label; 78 | public: 79 | UILabelledElement(const std::string text, UIElement* e = 0, float width = -1.0f); 80 | 81 | UILabel* getLabel(); 82 | UILayout* getLayout(); 83 | }; 84 | 85 | 86 | class UIResizeButton : public UIElement { 87 | protected: 88 | TextureResource* resizetex; 89 | public: 90 | UIResizeButton(); 91 | ~UIResizeButton(); 92 | 93 | void drag(const vec2& pos); 94 | void drawContent(); 95 | }; 96 | 97 | class UIResizableLayout : public UILayout { 98 | UIResizeButton* resize_button; 99 | public: 100 | UIResizableLayout(bool horizontal = false); 101 | ~UIResizableLayout(); 102 | 103 | void elementsAt(const vec2& pos, std::list& elements_found); 104 | 105 | void setUI(UI* ui); 106 | void updatePos(const vec2& pos); 107 | void update(float dt); 108 | void draw(); 109 | }; 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /ui/scroll_bar.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SCROLL_BAR_H 2 | #define UI_SCROLL_BAR_H 3 | 4 | #include "element.h" 5 | 6 | class UIScrollLayout; 7 | 8 | class UIScrollBar: public UIElement { 9 | protected: 10 | std::vector bartex; 11 | public: 12 | bool inverted; 13 | bool horizontal; 14 | float bar_width; 15 | float bar_min; 16 | float bar_step; 17 | float bar_percent; 18 | float bar_offset; 19 | float bar_visual_offset; 20 | bool flip_sides; 21 | 22 | bool dragging; 23 | vec2 drag_start; 24 | 25 | bool stick_to_end; 26 | 27 | vec2 bar_rect; 28 | 29 | UIScrollBar(UIScrollLayout* parent, bool horizontal = false); 30 | ~UIScrollBar(); 31 | 32 | int getType() const { return UI_SCROLL_BAR; }; 33 | 34 | void idle(); 35 | void setSelected(bool selected); 36 | void drag(const vec2& pos); 37 | void scroll(bool up); 38 | 39 | bool isScrollable(); 40 | 41 | void scrollToStart(); 42 | void scrollToEnd(); 43 | 44 | void stickToEnd(); 45 | 46 | bool atStart(); 47 | bool atEnd(); 48 | 49 | void flipSides(bool flip_sides); 50 | 51 | void elementsAt(const vec2& pos, std::list& elements_found); 52 | 53 | void reset(); 54 | 55 | void updateRect(); 56 | void updatePos(); 57 | void drawContent(); 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /ui/scroll_layout.cpp: -------------------------------------------------------------------------------- 1 | #include "scroll_layout.h" 2 | 3 | UIScrollLayout::UIScrollLayout(const vec2& scroll_rect, bool horizontal) : scroll_rect(scroll_rect), UILayout(horizontal) { 4 | 5 | vertical_scrollbar = new UIScrollBar(this, false); 6 | horizontal_scrollbar = new UIScrollBar(this, true); 7 | setFill(true); 8 | } 9 | 10 | UIScrollLayout::~UIScrollLayout() { 11 | delete vertical_scrollbar; 12 | delete horizontal_scrollbar; 13 | } 14 | 15 | vec2 UIScrollLayout::getRect() { 16 | return glm::min(scroll_rect,rect)+expanded_rect; 17 | } 18 | 19 | vec2 UIScrollLayout::getScrollRect() { 20 | return glm::min(scroll_rect,rect)+expanded_rect; 21 | } 22 | 23 | vec4 UIScrollLayout::getMargin() const { 24 | vec4 scroll_margin = margin; 25 | 26 | if(vertical_scrollbar->isScrollable()) { 27 | if(vertical_scrollbar->flip_sides) { 28 | scroll_margin.x += vertical_scrollbar->bar_width; 29 | } else { 30 | scroll_margin.z += vertical_scrollbar->bar_width; 31 | } 32 | } 33 | 34 | if(horizontal_scrollbar->isScrollable()) { 35 | scroll_margin.y += horizontal_scrollbar->bar_width; 36 | } 37 | 38 | return scroll_margin; 39 | 40 | } 41 | 42 | vec2 UIScrollLayout::getInnerRect() { 43 | return rect; 44 | } 45 | 46 | void UIScrollLayout::setUI(UI* ui) { 47 | UILayout::setUI(ui); 48 | 49 | vertical_scrollbar->setUI(ui); 50 | horizontal_scrollbar->setUI(ui); 51 | } 52 | 53 | void UIScrollLayout::updateZIndex() { 54 | UILayout::updateZIndex(); 55 | 56 | vertical_scrollbar->updateZIndex(); 57 | horizontal_scrollbar->updateZIndex(); 58 | } 59 | 60 | void UIScrollLayout::drawBackground() { 61 | if(!drawbg) return; 62 | 63 | if(bgcolour.w > 0.0f) { 64 | glColor4fv(glm::value_ptr(bgcolour)); 65 | } else { 66 | glColor4fv(glm::value_ptr(ui->getBackgroundColour())); 67 | } 68 | 69 | vec2 rect = glm::max(getRect(),getInnerRect()); 70 | 71 | glDisable(GL_TEXTURE_2D); 72 | drawQuad(pos, rect, vec4(0.0f, 0.0f, 1.0f, 1.0f)); 73 | glEnable(GL_TEXTURE_2D); 74 | } 75 | 76 | void UIScrollLayout::update(float dt) { 77 | 78 | if(fill_vertical && !parent) scroll_rect.y = display.height; 79 | 80 | UILayout::update(dt); 81 | 82 | //rect = scroll_rect;//glm::min( scroll_rect, rect ); 83 | 84 | vertical_scrollbar->update(dt); 85 | horizontal_scrollbar->update(dt); 86 | } 87 | 88 | void UIScrollLayout::updatePos(const vec2& pos) { 89 | 90 | UILayout::updatePos(pos); 91 | 92 | vertical_scrollbar->updatePos(); 93 | horizontal_scrollbar->updatePos(); 94 | } 95 | 96 | bool UIScrollLayout::isScrollable() { 97 | return vertical_scrollbar->isScrollable(); 98 | } 99 | 100 | void UIScrollLayout::scroll(bool up) { 101 | vertical_scrollbar->scroll(up); 102 | } 103 | 104 | void UIScrollLayout::elementsAt(const vec2& pos, std::list& elements_found) { 105 | 106 | vertical_scrollbar->elementsAt(pos, elements_found); 107 | horizontal_scrollbar->elementsAt(pos, elements_found); 108 | 109 | //apply scroll offset to position 110 | 111 | vec2 scrolled_pos = vec2(horizontal_scrollbar->bar_offset * rect.x, vertical_scrollbar->bar_offset * rect.y) + pos; 112 | 113 | UIElement* found = 0; 114 | 115 | for(UIElement* e: elements) { 116 | e->elementsAt(scrolled_pos, elements_found); 117 | } 118 | 119 | UIElement::elementsAt(pos, elements_found); 120 | } 121 | 122 | void UIScrollLayout::draw() { 123 | 124 | glEnable(GL_SCISSOR_TEST); 125 | 126 | vec2 scroll_offset = vec2(horizontal_scrollbar->bar_offset * -rect.x, vertical_scrollbar->bar_offset * -rect.y); 127 | 128 | glPushMatrix(); 129 | glTranslatef(scroll_offset.x, scroll_offset.y, 0.0f); 130 | 131 | glScissor(pos.x, display.height-(pos.y+scroll_rect.y+expanded_rect.y), scroll_rect.x+expanded_rect.x, scroll_rect.y+expanded_rect.y); 132 | 133 | UILayout::draw(); 134 | 135 | glDisable(GL_SCISSOR_TEST); 136 | glPopMatrix(); 137 | 138 | vertical_scrollbar->draw(); 139 | horizontal_scrollbar->draw(); 140 | } 141 | -------------------------------------------------------------------------------- /ui/scroll_layout.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SCROLL_LAYOUT_H 2 | #define UI_SCROLL_LAYOUT_H 3 | 4 | #include "layout.h" 5 | #include "scroll_bar.h" 6 | 7 | class UIScrollLayout : public UILayout { 8 | protected: 9 | vec2 scroll_rect; 10 | vec2 inner_rect; 11 | 12 | void drawBackground(); 13 | public: 14 | 15 | UIScrollBar* vertical_scrollbar; 16 | UIScrollBar* horizontal_scrollbar; 17 | 18 | UIScrollLayout(const vec2& scroll_rect, bool horizontal = false); 19 | ~UIScrollLayout(); 20 | 21 | void scroll(bool up); 22 | 23 | bool isScrollable(); 24 | 25 | void updateZIndex(); 26 | 27 | void elementsAt(const vec2& pos, std::list& elements_found); 28 | 29 | void updatePos(const vec2& pos); 30 | 31 | vec2 getRect(); 32 | vec2 getScrollRect(); 33 | vec2 getInnerRect(); 34 | 35 | vec4 getMargin() const; 36 | 37 | void setUI(UI* ui); 38 | 39 | void update(float dt); 40 | void draw(); 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ui/select.cpp: -------------------------------------------------------------------------------- 1 | #include "select.h" 2 | 3 | UISelect::UISelect() : UISolidLayout(true) { 4 | 5 | label = new UILabel("Select", false, 150.0f); 6 | addElement(label); 7 | 8 | options_layout = new UISolidLayout(false); 9 | options_layout->setMargin(3.0f); 10 | options_layout->parent = this; 11 | 12 | setMargin(vec4(3.0f)); 13 | selected_option = 0; 14 | 15 | open = false; 16 | selectable = true; 17 | 18 | selectex = texturemanager.grab("ui/select.png", false); 19 | selectex->bind(); 20 | selectex->setFiltering(GL_NEAREST, GL_NEAREST); 21 | selectex->setWrapStyle(GL_CLAMP); 22 | } 23 | 24 | void UISelect::setUI(UI* ui) { 25 | UISolidLayout::setUI(ui); 26 | options_layout->setUI(ui); 27 | } 28 | 29 | UISelect::~UISelect() { 30 | delete options_layout; 31 | if(selectex!=0) texturemanager.release(selectex); 32 | } 33 | 34 | void UISelect::click(const vec2& pos) { 35 | open = !open; 36 | } 37 | 38 | UIOptionLabel* UISelect::getSelectedOption() { 39 | return selected_option; 40 | } 41 | 42 | void UISelect::selectOption(UIOptionLabel* option, bool submit) { 43 | label->setText(option->text); 44 | selected_option = option; 45 | if(submit) selected_option->submit(); 46 | open = false; 47 | } 48 | 49 | UIOptionLabel* UISelect::addOption(const std::string& name, const std::string& value, bool select_option) { 50 | UIOptionLabel* option = new UIOptionLabel(this, name, value); 51 | 52 | options_layout->addElement(option); 53 | 54 | if(select_option) selectOption(option); 55 | 56 | // if we have no selected option select option but dont submit 57 | if(!selected_option) selectOption(option, false); 58 | 59 | return option; 60 | } 61 | 62 | UIOptionLabel* UISelect::addOption(const std::string& name, UIAction* action, bool select_option) { 63 | UIOptionLabel* option = new UIOptionLabel(this, name, action); 64 | 65 | options_layout->addElement(option); 66 | 67 | if(select_option) selectOption(option); 68 | 69 | // if we have no selected option select option but dont submit 70 | if(!selected_option) selectOption(option, false); 71 | 72 | return option; 73 | } 74 | 75 | void UISelect::elementsAt(const vec2& pos, std::list& elements_found) { 76 | 77 | UIElement* found = 0; 78 | 79 | if(open) { 80 | options_layout->elementsAt(pos, elements_found); 81 | } 82 | 83 | UISolidLayout::elementsAt(pos, elements_found); 84 | } 85 | 86 | void UISelect::updatePos(const vec2& pos) { 87 | 88 | vec2 adjusted_pos = pos; 89 | 90 | if(open && parent && adjusted_pos.y + options_layout->getRect().y > parent->getRect().y) { 91 | adjusted_pos.y -= options_layout->getRect().y - this->getRect().y; 92 | } 93 | 94 | UISolidLayout::updatePos(adjusted_pos); 95 | options_layout->updatePos(adjusted_pos); 96 | } 97 | 98 | void UISelect::update(float dt) { 99 | 100 | updateZIndex(); 101 | 102 | if(open) options_layout->zindex = this->zindex + 1; 103 | else options_layout->zindex = this->zindex; 104 | 105 | UISolidLayout::update(dt); 106 | options_layout->update(dt); 107 | } 108 | 109 | void UISelect::draw() { 110 | if(!open) { 111 | UISolidLayout::draw(); 112 | 113 | selectex->bind(); 114 | glColor4fv(glm::value_ptr(ui->getSolidColour())); 115 | drawQuad(pos + vec2(rect.x-16.0f,1.0f), vec2(16.0f, 16.0f), vec4(0.0f, 0.0f, 1.0f, 1.0f)); 116 | } 117 | else { 118 | options_layout->draw(); 119 | } 120 | } 121 | 122 | UIIntSelectAction::UIIntSelectAction(int* field, int value, UIAction* action) : field(field), value(value), action(action) { 123 | } 124 | 125 | void UIIntSelectAction::perform() { 126 | *field = value; 127 | if(action != 0) { 128 | action->perform(); 129 | } 130 | } 131 | 132 | // UIOptionLabel 133 | 134 | UIOptionLabel::UIOptionLabel(UISelect* select, const std::string& text, const std::string& value, UIAction* action) 135 | : select(select), value(value), action(action), UILabel(text, false, 150.0f) { 136 | selectable = true; 137 | } 138 | 139 | UIOptionLabel::UIOptionLabel(UISelect* select, const std::string& text, UIAction* action) 140 | : select(select), value(text), action(action), UILabel(text, false, 150.0f) { 141 | selectable = true; 142 | } 143 | 144 | bool UIOptionLabel::submit() { 145 | 146 | if(action!=0) { 147 | action->perform(); 148 | return true; 149 | } 150 | 151 | return false; 152 | } 153 | 154 | void UIOptionLabel::click(const vec2& pos) { 155 | select->selectOption(this); 156 | } 157 | -------------------------------------------------------------------------------- /ui/select.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SELECT_H 2 | #define UI_SELECT_H 3 | 4 | #include "action.h" 5 | #include "label.h" 6 | #include "solid_layout.h" 7 | 8 | class UISelect; 9 | 10 | class UIIntSelectAction : public UIAction { 11 | int* field; 12 | int value; 13 | UIAction* action; 14 | public: 15 | UIIntSelectAction(int* field, int value, UIAction* action = 0); 16 | 17 | void perform(); 18 | }; 19 | 20 | class UIOptionLabel : public UILabel { 21 | UISelect* select; 22 | UIAction* action; 23 | public: 24 | std::string value; 25 | 26 | UIOptionLabel(UISelect* select, const std::string& text, const std::string& value, UIAction* action = 0); 27 | UIOptionLabel(UISelect* select, const std::string& text, UIAction* action = 0); 28 | 29 | void click(const vec2& pos); 30 | 31 | bool submit(); 32 | }; 33 | 34 | class UISelect : public UISolidLayout { 35 | UILabel* label; 36 | UILayout* options_layout; 37 | 38 | UIOptionLabel* selected_option; 39 | 40 | TextureResource* selectex; 41 | public: 42 | bool open; 43 | 44 | UISelect(); 45 | ~UISelect(); 46 | 47 | int getType() const { return UI_SELECT; }; 48 | 49 | void setUI(UI* ui); 50 | 51 | void selectOption(UIOptionLabel* option, bool submit = true); 52 | 53 | UIOptionLabel* getSelectedOption(); 54 | 55 | UIOptionLabel* addOption(const std::string& name, const std::string& value, bool select_option = false); 56 | UIOptionLabel* addOption(const std::string& name, UIAction* action, bool select_option = false); 57 | 58 | void click(const vec2& pos); 59 | 60 | void elementsAt(const vec2& pos, std::list& elements_found); 61 | 62 | void updatePos(const vec2& pos); 63 | void update(float dt); 64 | 65 | void draw(); 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /ui/slider.cpp: -------------------------------------------------------------------------------- 1 | #include "slider.h" 2 | 3 | //UISlider 4 | 5 | UISlider::UISlider(const std::string& slider_texture, float width, UIAction* action) : slider_width(width), action(action), UIElement() { 6 | slidertex = texturemanager.grab(slider_texture); 7 | rect = vec2(slider_width, 16.0f); 8 | background = true; 9 | selectable = true; 10 | scrollable = true; 11 | dragging = false; 12 | } 13 | 14 | void UISlider::drawSlider(float position) { 15 | 16 | float slider_position = position * (slider_width-4.0f) + 4.0f; 17 | 18 | //background 19 | //drawQuad(vec2(slider_width,16.0f), vec4(0.0f, 0.0f, 1.0f, 0.5f)); 20 | 21 | vec4 tint = ui->getTintColour(); 22 | vec4 alpha = ui->getAlpha(); 23 | 24 | if(selected) tint = glm::clamp(tint + 0.75f, 0.0f, 1.0f); 25 | 26 | if(background) { 27 | 28 | ui->setTextured(false); 29 | 30 | glLineWidth(1.0f); 31 | 32 | glColor4f(0.0f, 0.0f, 0.0f, alpha.w); 33 | glBegin(GL_QUADS); 34 | glVertex2f(0.0f, 3.0f); 35 | glVertex2f(slider_width, 3.0f); 36 | glVertex2f(slider_width, 11.0f); 37 | glVertex2f(0.0f, 11.0f); 38 | glEnd(); 39 | 40 | glPushMatrix(); 41 | glTranslatef(0.5f, 0.5f, 0.0f); 42 | 43 | glColor4fv(glm::value_ptr(tint)); 44 | 45 | glBegin(GL_LINE_STRIP); 46 | glVertex2f(0.0f, 3.0f); 47 | glVertex2f(slider_width, 3.0f); 48 | glVertex2f(slider_width, 11.0f); 49 | glVertex2f(0.0f, 11.0f); 50 | glVertex2f(0.0f, 3.0f); 51 | glEnd(); 52 | 53 | glPopMatrix(); 54 | 55 | ui->setTextured(true); 56 | } 57 | 58 | slidertex->bind(); 59 | 60 | glColor4fv(glm::value_ptr(ui->getSolidColour())); 61 | 62 | //slider 63 | drawQuad(vec2(slider_position-4.0, 0.0f), vec2(16.0,16.0), vec4(0.0f, 0.0f, 1.0f, 1.0f)); 64 | } 65 | 66 | bool UISlider::keyPress(SDL_KeyboardEvent *e) { 67 | 68 | switch(e->keysym.sym) { 69 | case SDLK_MINUS: 70 | scroll(false); 71 | return true; 72 | break; 73 | case SDLK_EQUALS: 74 | scroll(true); 75 | return true; 76 | break; 77 | default: 78 | break; 79 | } 80 | 81 | return false; 82 | } 83 | 84 | void UISlider::idle() { 85 | if(action != 0) action->idle(); 86 | dragging = false; 87 | } 88 | 89 | 90 | //UIFloatSlider 91 | 92 | UIFloatSlider::UIFloatSlider(float* value, float min, float max, UIAction* action) : 93 | min(min), max(max), value(value), UISlider("ui/slider.png", 128.0f, action) { 94 | } 95 | 96 | void UIFloatSlider::scroll(bool up) { 97 | scale(up, 0.1f); 98 | } 99 | 100 | void UIFloatSlider::scale(bool up, float value_scale) { 101 | 102 | if(!value) return; 103 | 104 | float value_inc = (min!=max) ? ((max-min) / 100.0f) : glm::max( 0.00001f, glm::abs(glm::max(1.0f, *value)) * 0.1f ); 105 | 106 | if(!up) value_inc = -value_inc; 107 | 108 | setValue(*value + UIElement::granulaity(value_inc, value_scale)); 109 | } 110 | 111 | void UIFloatSlider::click(const vec2& pos) { 112 | float percent = (pos.x - this->pos.x) / slider_width; 113 | 114 | float new_value; 115 | 116 | if(min!=max) { 117 | new_value = percent * (max-min) + min; 118 | } else { 119 | float v = *value; 120 | if(v == 0.0f) v = 1.0f; 121 | 122 | new_value = percent * 2.0 * v; 123 | } 124 | 125 | //debugLog("new value = %f", new_value); 126 | 127 | setValue(new_value); 128 | } 129 | 130 | void UIFloatSlider::drag(const vec2& pos) { 131 | if(!dragging) { 132 | old_value = *value; 133 | dragging = true; 134 | } 135 | 136 | float percent = (pos.x - this->pos.x) / slider_width; 137 | 138 | float new_value = (min!=max) 139 | ? percent * (max-min) + min 140 | : percent * 2.0 * old_value; 141 | 142 | //debugLog("drag: percent %f new_value %f", percent, new_value); 143 | 144 | setValue(new_value); 145 | } 146 | 147 | void UIFloatSlider::setFloat(float* f) { 148 | value = f; 149 | } 150 | 151 | void UIFloatSlider::setValue(float v) { 152 | if(!value) return; 153 | 154 | if(min!=max) { 155 | *value = std::max(std::min(max,v), min); 156 | } else { 157 | *value = v; 158 | } 159 | 160 | if(action != 0) action->perform(); 161 | } 162 | 163 | void UIFloatSlider::drawContent() { 164 | if(!value) return; 165 | 166 | float position; 167 | 168 | if (min!=max) { 169 | position = std::min(1.0f, ((*value) - min) / ((float)max-min)); 170 | 171 | } else { 172 | if(dragging) { 173 | position = std::max(0.0f, std::min(1.0f, *value / (old_value * 2.0f))); 174 | } else { 175 | position = 0.5f; 176 | } 177 | } 178 | 179 | drawSlider(position); 180 | } 181 | 182 | //UIIntSlider 183 | 184 | UIIntSlider::UIIntSlider(int* value, int min, int max, UIAction* action) : 185 | min(min), max(max), value(value), UISlider("ui/slider.png", 128.0f, action) { 186 | } 187 | 188 | void UIIntSlider::scroll(bool up) { 189 | int value_inc = 1; 190 | 191 | if(!up) value_inc = -value_inc; 192 | 193 | setValue(*value+value_inc); 194 | } 195 | 196 | void UIIntSlider::click(const vec2& pos) { 197 | int new_value = ((pos.x - this->pos.x) / slider_width) * (max-min) + min; 198 | 199 | setValue(new_value); 200 | } 201 | 202 | void UIIntSlider::drag(const vec2& pos) { 203 | int new_value = ((pos.x - this->pos.x) / slider_width) * (max-min) + min; 204 | 205 | setValue(new_value); 206 | } 207 | 208 | void UIIntSlider::setValue(int v) { 209 | if(min!=max) { 210 | *value = std::max(std::min(max,v), min); 211 | } else { 212 | *value = v; 213 | } 214 | 215 | if(action != 0) action->perform(); 216 | } 217 | 218 | void UIIntSlider::drawContent() { 219 | 220 | float position = std::min(1.0f, ((*value) - min) / ((float)max-min)); 221 | 222 | drawSlider(position); 223 | } 224 | 225 | // UILabelFloatSlider 226 | 227 | UILabelFloatSlider::UILabelFloatSlider(const std::string& label, float* value, float min, float max, UIAction* action) : UILabelledElement(label) { 228 | 229 | slider = new UIFloatSlider(value, min, max, action); 230 | 231 | flabel = new UIFloatLabel(value, true, action); 232 | flabel->slider = slider; 233 | 234 | layout->addElement(slider); 235 | layout->addElement(flabel); 236 | 237 | padding = vec2(5.0f, 0.0f); 238 | scrollable = true; 239 | 240 | setFillHorizontal(true); 241 | } 242 | 243 | void UILabelFloatSlider::setFloat(float* f) { 244 | slider->setFloat(f); 245 | flabel->setValue(f); 246 | // flabel->updateContent(); 247 | } 248 | 249 | void UILabelFloatSlider::scroll(bool up) { 250 | slider->scroll(up); 251 | flabel->updateContent(); 252 | } 253 | 254 | void UILabelFloatSlider::scale(bool up) { 255 | slider->scale(up); 256 | flabel->updateContent(); 257 | } 258 | 259 | void UILabelFloatSlider::scale(bool up, float value_scale) { 260 | slider->scale(up, value_scale); 261 | } 262 | 263 | // UILabelIntSlider 264 | 265 | UILabelIntSlider::UILabelIntSlider(const std::string& label, int* value, int min, int max, UIAction* action) : UILabelledElement(label) { 266 | 267 | slider = new UIIntSlider(value, min, max, action); 268 | 269 | ilabel = new UIIntLabel(value, true, action); 270 | ilabel->slider = slider; 271 | 272 | layout->addElement(slider); 273 | layout->addElement(ilabel); 274 | 275 | padding = vec2(5.0f, 0.0f); 276 | scrollable = true; 277 | 278 | setFillHorizontal(true); 279 | 280 | } 281 | 282 | void UILabelIntSlider::scroll(bool up) { 283 | slider->scroll(up); 284 | ilabel->updateContent(); 285 | } 286 | 287 | void UILabelIntSlider::scale(bool up) { 288 | slider->scale(up); 289 | ilabel->updateContent(); 290 | } 291 | -------------------------------------------------------------------------------- /ui/slider.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SLIDER_H 2 | #define UI_SLIDER_H 3 | 4 | #include "element.h" 5 | #include "label.h" 6 | #include "layout.h" 7 | 8 | class UISlider : public UIElement { 9 | protected: 10 | TextureResource* slidertex; 11 | float slider_width; 12 | bool background; 13 | UIAction* action; 14 | 15 | bool dragging; 16 | 17 | void drawSlider(float position); 18 | public: 19 | UISlider(const std::string& slider_texure, float width, UIAction* action = 0); 20 | 21 | bool keyPress(SDL_KeyboardEvent *e); 22 | 23 | virtual void scroll(bool up) {}; 24 | virtual void scale(bool up) {}; 25 | 26 | void idle(); 27 | 28 | int getType() const { return UI_SLIDER; }; 29 | }; 30 | 31 | class UIFloatSlider : public UISlider { 32 | public: 33 | float* value; 34 | float min; 35 | float max; 36 | 37 | 38 | float old_value; 39 | 40 | UIFloatSlider(float* value, float min = 0.0f, float max = 0.0f, UIAction* action = 0); 41 | 42 | void scale(bool up, float value_scale = 0.25f); 43 | void scroll(bool up); 44 | void click(const vec2& pos); 45 | void drag(const vec2& pos); 46 | 47 | void setFloat(float* f); 48 | 49 | void setValue(float v); 50 | 51 | void drawContent(); 52 | }; 53 | 54 | class UIIntSlider : public UISlider { 55 | public: 56 | int* value; 57 | int min; 58 | int max; 59 | 60 | UIIntSlider(int* value, int min = 0, int max = 0, UIAction* action = 0); 61 | 62 | void scroll(bool up); 63 | void click(const vec2& pos); 64 | void drag(const vec2& pos); 65 | void setValue(int v); 66 | 67 | void drawContent(); 68 | }; 69 | 70 | class UILabelFloatSlider : public UILabelledElement { 71 | 72 | UIFloatSlider* slider; 73 | UIFloatLabel* flabel; 74 | public: 75 | UILabelFloatSlider(const std::string& label, float* value, float min = 0.0f, float max = 0.0f, UIAction* action = 0); 76 | 77 | void setFloat(float* f); 78 | 79 | void scale(bool up); 80 | void scale(bool up, float value_scale); 81 | void scroll(bool up); 82 | }; 83 | 84 | class UILabelIntSlider : public UILabelledElement { 85 | 86 | UIIntSlider* slider; 87 | UIIntLabel* ilabel; 88 | public: 89 | UILabelIntSlider(const std::string& label, int* value, int min = 0.0f, int max = 0.0f, UIAction* action = 0); 90 | 91 | void scale(bool up); 92 | void scroll(bool up); 93 | }; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /ui/solid_layout.cpp: -------------------------------------------------------------------------------- 1 | #include "solid_layout.h" 2 | 3 | UISolidLayout::UISolidLayout(bool horizontal) : UILayout(horizontal) { 4 | 5 | inverted = false; 6 | 7 | bgtex.resize(4); 8 | 9 | bgtex[0] = texturemanager.grab("ui/layout_tl.png", false); 10 | bgtex[1] = texturemanager.grab("ui/layout_tr.png", false); 11 | bgtex[2] = texturemanager.grab("ui/layout_br.png", false); 12 | bgtex[3] = texturemanager.grab("ui/layout_bl.png", false); 13 | 14 | for(TextureResource* t: bgtex) { 15 | t->bind(); 16 | t->setFiltering(GL_NEAREST, GL_NEAREST); 17 | t->setWrapStyle(GL_CLAMP); 18 | } 19 | } 20 | 21 | UISolidLayout::~UISolidLayout() { 22 | for(TextureResource* t: bgtex) { 23 | texturemanager.release(t); 24 | } 25 | bgtex.clear(); 26 | } 27 | 28 | void UISolidLayout::drawBackground() { 29 | 30 | glPushMatrix(); 31 | 32 | glTranslatef(pos.x, pos.y, 0.0f); 33 | 34 | glColor4fv(glm::value_ptr(ui->getSolidColour())); 35 | 36 | ui->setTextured(true); 37 | 38 | vec4 texcoord; 39 | 40 | vec2 rect = getRect(); 41 | 42 | for(int i=0; i < 4; i++) { 43 | 44 | glPushMatrix(); 45 | 46 | if(inverted) { 47 | bgtex[(i+2)%4]->bind(); 48 | 49 | switch(i) { 50 | case 0: 51 | texcoord = vec4(1.0f, 1.0f, 1.0-(rect.x/32.0f), 1.0-(rect.y/32.0f)); 52 | break; 53 | case 1: 54 | texcoord = vec4((rect.x/32.0f), 1.0f, 0.0, 1.0-(rect.y/32.0f)); 55 | glTranslatef(rect.x*0.5, 0.0f, 0.0f); 56 | break; 57 | case 2: 58 | texcoord = vec4(rect.x/32.0f, rect.y/32.0f, 0.0f, 0.0f); 59 | glTranslatef(rect.x*0.5, rect.y*0.5, 0.0f); 60 | break; 61 | case 3: 62 | texcoord = vec4(1.0f, (rect.y/32.0f), 1.0f-(rect.x/32.0f), 0.0f); 63 | glTranslatef(0.0f, rect.y*0.5, 0.0f); 64 | break; 65 | } 66 | } else { 67 | bgtex[i]->bind(); 68 | 69 | switch(i) { 70 | case 0: 71 | texcoord = vec4(0.0f, 0.0f, rect.x/32.0f, rect.y/32.0f); 72 | break; 73 | case 1: 74 | texcoord = vec4(1.0f-(rect.x/32.0f), 0.0f, 1.0f, (rect.y/32.0f)); 75 | glTranslatef(rect.x*0.5, 0.0f, 0.0f); 76 | break; 77 | case 2: 78 | texcoord = vec4(1.0-rect.x/32.0f, 1.0-rect.y/32.0f, 1.0f, 1.0f); 79 | glTranslatef(rect.x*0.5, rect.y*0.5, 0.0f); 80 | break; 81 | case 3: 82 | texcoord = vec4(0.0, 1.0-(rect.y/32.0f), (rect.x/32.0f), 1.0f);; 83 | glTranslatef(0.0f, rect.y*0.5, 0.0f); 84 | break; 85 | } 86 | } 87 | 88 | glBegin(GL_QUADS); 89 | glTexCoord2f(texcoord.x,texcoord.y); 90 | glVertex2f(0.0f, 0.0f); 91 | 92 | glTexCoord2f(texcoord.z,texcoord.y); 93 | glVertex2f(rect.x*0.5, 0.0f); 94 | 95 | glTexCoord2f(texcoord.z,texcoord.w); 96 | glVertex2f(rect.x*0.5, rect.y*0.5); 97 | 98 | glTexCoord2f(texcoord.x,texcoord.w); 99 | glVertex2f(0.0f, rect.y*0.5); 100 | glEnd(); 101 | 102 | glPopMatrix(); 103 | } 104 | 105 | glPopMatrix(); 106 | } 107 | -------------------------------------------------------------------------------- /ui/solid_layout.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SOLID_LAYOUT_H 2 | #define UI_SOLID_LAYOUT_H 3 | 4 | #include "layout.h" 5 | 6 | class UISolidLayout : public UILayout { 7 | protected: 8 | std::vector bgtex; 9 | bool inverted; 10 | 11 | void drawBackground(); 12 | public: 13 | UISolidLayout(bool horizontal = false); 14 | ~UISolidLayout(); 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ui/subgroup.cpp: -------------------------------------------------------------------------------- 1 | #include "subgroup.h" 2 | #include "image.h" 3 | 4 | //UISubGroup 5 | 6 | UISubGroup::UISubGroup(const std::string& groupname, bool minimized) 7 | : open_action(0), UILayout(false) { 8 | 9 | UISubGroupBar* bar = new UISubGroupBar(groupname); 10 | bar->parent = this; 11 | 12 | layout = new UILayout(false); 13 | layout->hidden = minimized; 14 | layout->setMargin(vec4(10.0f, 0.0f, 0.0f, 0.0f)); 15 | layout->setFillHorizontal(true); 16 | 17 | addElement(bar); 18 | addElement(layout); 19 | 20 | setFillHorizontal(true); 21 | } 22 | 23 | 24 | void UISubGroup::setOpenAction(UIAction* action) { 25 | this->open_action = action; 26 | } 27 | 28 | void UISubGroup::minimize() { 29 | layout->hidden = true; 30 | } 31 | 32 | void UISubGroup::maximize() { 33 | layout->hidden = false; 34 | } 35 | 36 | bool UISubGroup::toggle() { 37 | layout->hidden = !layout->hidden; 38 | 39 | if(!layout->hidden && open_action != 0) { 40 | open_action->perform(); 41 | } 42 | 43 | return layout->hidden; 44 | } 45 | 46 | //UISubGroupBar 47 | 48 | UISubGroupBar::UISubGroupBar(const std::string& text) : UILayout(true) { 49 | selectable = true; 50 | 51 | expander = new UIImage("ui/expand.png", vec2(16.0f,16.0f), vec4(0.0f, 0.0f, 0.5f, 0.5f)); 52 | 53 | addElement(new UILabel(text, false)); 54 | addElement(expander); 55 | } 56 | 57 | void UISubGroupBar::click(const vec2& pos) { 58 | if(((UISubGroup*)parent)->toggle()) { 59 | expander->setTextureCoords(vec4(0.0f, 0.5f, 0.5f, 1.0f)); 60 | } else { 61 | expander->setTextureCoords(vec4(0.0f, 0.0f, 0.5f, 0.5f)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ui/subgroup.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_SUBGROUP_h 2 | #define UI_SUBGROUP_h 3 | 4 | #include "label.h" 5 | #include "image.h" 6 | #include "solid_layout.h" 7 | 8 | class UISubGroupBar : public UILayout { 9 | UIImage* expander; 10 | public: 11 | UISubGroupBar(const std::string& text); 12 | 13 | void click(const vec2& pos); 14 | }; 15 | 16 | class UISubGroup : public UILayout { 17 | protected: 18 | UISubGroupBar* bar; 19 | UILayout* layout; 20 | UIAction* open_action; 21 | public: 22 | UISubGroup(const std::string& groupname, bool minimized = true); 23 | 24 | void setOpenAction(UIAction* action) ; 25 | 26 | void setTitle(const std::string& text); 27 | 28 | UILayout* getLayout() const { return layout; }; 29 | 30 | bool toggle(); 31 | void minimize(); 32 | void maximize(); 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /ui/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_H 2 | #define UI_H 3 | 4 | #include "../display.h" 5 | #include "../mousecursor.h" 6 | 7 | #include 8 | #include 9 | 10 | class UIElement; 11 | class UIColour; 12 | 13 | class UI { 14 | Shader* shader; 15 | 16 | UIElement* selectedElement; 17 | std::vector elements; 18 | 19 | float double_click_interval; 20 | float double_click_timer; 21 | 22 | bool interaction; 23 | char toChar(SDL_KeyboardEvent *e); 24 | protected: 25 | vec4 background_colour; 26 | vec4 solid_colour; 27 | vec4 text_colour; 28 | vec4 tint_colour; 29 | vec4 ui_alpha; 30 | 31 | bool left_pressed; 32 | bool left_drag; 33 | bool scrolling; 34 | 35 | vec2 cursor_pos; 36 | 37 | virtual UIElement* click(const MouseCursor& cursor); 38 | virtual UIElement* drag(const MouseCursor& cursor); 39 | virtual UIElement* scroll(MouseCursor& cursor); 40 | public: 41 | FXFont font; 42 | 43 | UI(); 44 | ~UI(); 45 | 46 | void clear(); 47 | 48 | void drawText(float x, float y, const char *str, ...); 49 | void drawText(float x, float y, const std::string& text); 50 | 51 | void addElement(UIElement* e); 52 | void removeElement(UIElement* e); 53 | 54 | UIElement* getSelected(); 55 | 56 | bool acceptingTextInput(); 57 | 58 | bool elementsByType(std::list& found, int type); 59 | 60 | void elementsAt(const vec2& pos, std::list& found_elements); 61 | 62 | UIElement* scrollableElementAt(const vec2& pos); 63 | UIElement* selectElementAt(const vec2& pos); 64 | 65 | void selectElement(UIElement* element); 66 | 67 | void deselect(); 68 | 69 | bool keyPress(SDL_KeyboardEvent *e); 70 | 71 | virtual UIElement* processMouse(MouseCursor& cursor); 72 | 73 | virtual vec4 getSolidColour(); 74 | virtual vec4 getBackgroundColour(); 75 | virtual vec4 getTextColour(); 76 | virtual vec4 getTintColour(); 77 | virtual vec4 getAlpha(); 78 | 79 | void textEdit(SDL_TextEditingEvent* e); 80 | void textInput(SDL_TextInputEvent* e); 81 | 82 | UIColour* getActiveColour(); 83 | 84 | void update(float dt); 85 | 86 | void setTextured(bool textured); 87 | void setIntensity(float intensity); 88 | 89 | void draw(); 90 | void drawOutline(); 91 | }; 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /utf8/cpp11.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 29 | #define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 30 | 31 | #include "checked.h" 32 | #include 33 | 34 | namespace utf8 35 | { 36 | 37 | inline void append(char32_t cp, std::string& s) 38 | { 39 | append(uint32_t(cp), std::back_inserter(s)); 40 | } 41 | 42 | inline std::string utf16to8(const std::u16string& s) 43 | { 44 | std::string result; 45 | utf16to8(s.begin(), s.end(), std::back_inserter(result)); 46 | return result; 47 | } 48 | 49 | inline std::u16string utf8to16(const std::string& s) 50 | { 51 | std::u16string result; 52 | utf8to16(s.begin(), s.end(), std::back_inserter(result)); 53 | return result; 54 | } 55 | 56 | inline std::string utf32to8(const std::u32string& s) 57 | { 58 | std::string result; 59 | utf32to8(s.begin(), s.end(), std::back_inserter(result)); 60 | return result; 61 | } 62 | 63 | inline std::u32string utf8to32(const std::string& s) 64 | { 65 | std::u32string result; 66 | utf8to32(s.begin(), s.end(), std::back_inserter(result)); 67 | return result; 68 | } 69 | 70 | inline std::size_t find_invalid(const std::string& s) 71 | { 72 | std::string::const_iterator invalid = find_invalid(s.begin(), s.end()); 73 | return (invalid == s.end()) ? std::string::npos : (invalid - s.begin()); 74 | } 75 | 76 | inline bool is_valid(const std::string& s) 77 | { 78 | return is_valid(s.begin(), s.end()); 79 | } 80 | 81 | inline std::string replace_invalid(const std::string& s, char32_t replacement) 82 | { 83 | std::string result; 84 | replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); 85 | return result; 86 | } 87 | 88 | inline std::string replace_invalid(const std::string& s) 89 | { 90 | std::string result; 91 | replace_invalid(s.begin(), s.end(), std::back_inserter(result)); 92 | return result; 93 | } 94 | 95 | inline bool starts_with_bom(const std::string& s) 96 | { 97 | return starts_with_bom(s.begin(), s.end()); 98 | } 99 | 100 | } // namespace utf8 101 | 102 | #endif // header guard 103 | 104 | -------------------------------------------------------------------------------- /utf8/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 30 | 31 | #include "checked.h" 32 | #include "unchecked.h" 33 | 34 | #endif // header guard 35 | -------------------------------------------------------------------------------- /vbo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "vbo.h" 29 | 30 | //quadbuf 31 | 32 | quadbuf::quadbuf(int vertex_capacity) : vertex_capacity(vertex_capacity) { 33 | vertex_count = 0; 34 | 35 | data = vertex_capacity > 0 ? new quadbuf_vertex[vertex_capacity] : 0; 36 | 37 | //fprintf(stderr, "size of quadbuf_vertex = %d\n", sizeof(quadbuf_vertex)); 38 | } 39 | 40 | quadbuf::~quadbuf() { 41 | if(data!=0) delete[] data; 42 | } 43 | 44 | void quadbuf::unload() { 45 | buf.unload(); 46 | } 47 | 48 | void quadbuf::resize(int new_size) { 49 | 50 | quadbuf_vertex* _data = data; 51 | 52 | data = new quadbuf_vertex[new_size]; 53 | 54 | for(int i=0;i vertex_capacity) { 99 | resize(vertex_count*2); 100 | } 101 | 102 | data[i] = v1; 103 | data[i+1] = v2; 104 | data[i+2] = v3; 105 | data[i+3] = v4; 106 | 107 | if(textureid>0 && (textures.empty() || textures.back().textureid != textureid)) { 108 | textures.push_back(quadbuf_tex(i, textureid)); 109 | } 110 | } 111 | 112 | void quadbuf::add(GLuint textureid, const quadbuf_vertex& v1, const quadbuf_vertex& v2, const quadbuf_vertex& v3, const quadbuf_vertex& v4) { 113 | 114 | int i = vertex_count; 115 | 116 | vertex_count += 4; 117 | 118 | if(vertex_count > vertex_capacity) { 119 | resize(vertex_count*2); 120 | } 121 | 122 | data[i] = v1; 123 | data[i+1] = v2; 124 | data[i+2] = v3; 125 | data[i+3] = v4; 126 | 127 | if(textureid>0 && (textures.empty() || textures.back().textureid != textureid)) { 128 | textures.push_back(quadbuf_tex(i, textureid)); 129 | } 130 | } 131 | 132 | void quadbuf::update() { 133 | if(vertex_count==0) return; 134 | 135 | //recreate buffer if less than the vertex_count 136 | buf.buffer( vertex_count, sizeof(quadbuf_vertex), vertex_capacity, &(data[0].pos.x), GL_DYNAMIC_DRAW ); 137 | } 138 | 139 | void quadbuf::draw() { 140 | if(vertex_count==0) return; 141 | 142 | buf.bind(); 143 | 144 | glEnableClientState(GL_VERTEX_ARRAY); 145 | glEnableClientState(GL_COLOR_ARRAY); 146 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 147 | 148 | glVertexPointer(2, GL_FLOAT, sizeof(quadbuf_vertex), 0); 149 | glColorPointer(4, GL_FLOAT, sizeof(quadbuf_vertex), (GLvoid*)8); // offset pos (2x4 bytes) 150 | glTexCoordPointer(2, GL_FLOAT, sizeof(quadbuf_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) 151 | 152 | int last_index = vertex_count-1; 153 | 154 | if(textures.empty()) { 155 | 156 | glDrawArrays(GL_QUADS, 0, vertex_count); 157 | 158 | } else { 159 | for(std::vector::iterator it = textures.begin(); it != textures.end();) { 160 | quadbuf_tex* tex = &(*it); 161 | 162 | int end_index; 163 | 164 | it++; 165 | 166 | if(it == textures.end()) { 167 | end_index = last_index; 168 | } else { 169 | end_index = (*it).start_index; 170 | } 171 | 172 | glBindTexture(GL_TEXTURE_2D, tex->textureid); 173 | glDrawArrays(GL_QUADS, tex->start_index, end_index - tex->start_index + 1); 174 | 175 | if(end_index==last_index) break; 176 | } 177 | } 178 | 179 | glDisableClientState(GL_VERTEX_ARRAY); 180 | glDisableClientState(GL_COLOR_ARRAY); 181 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 182 | 183 | buf.unbind(); 184 | } 185 | -------------------------------------------------------------------------------- /vbo.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef CORE_VBO_H 29 | #define CORE_VBO_H 30 | 31 | 32 | #include 33 | #include 34 | 35 | #include "gl.h" 36 | #include "vectors.h" 37 | #include "logger.h" 38 | 39 | class VBO { 40 | public: 41 | GLuint id; 42 | GLenum buffer_type; 43 | 44 | int capacity; 45 | 46 | VBO(GLenum buffer_type = GL_ARRAY_BUFFER) : buffer_type(buffer_type) { 47 | capacity = 0; 48 | id = 0; 49 | } 50 | 51 | ~VBO() { 52 | unload(); 53 | } 54 | 55 | void init() { 56 | if(!id) glGenBuffers(1, &id); 57 | } 58 | 59 | void unload() { 60 | capacity = 0; 61 | if(id != 0) { 62 | glDeleteBuffers(1, &id); 63 | id = 0; 64 | } 65 | } 66 | 67 | void bind() { 68 | if(!id) init(); 69 | glBindBuffer(buffer_type, id); 70 | } 71 | 72 | void buffer(int item_count, int item_size, int item_capacity, GLvoid* data, GLenum usage) { 73 | 74 | bind(); 75 | 76 | if(capacity < item_count) { 77 | capacity = item_capacity; 78 | glBufferData(buffer_type, capacity * item_size, data, usage); 79 | } else { 80 | glBufferSubData(buffer_type, 0, item_count * item_size, data); 81 | } 82 | 83 | unbind(); 84 | } 85 | 86 | void unbind() { 87 | glBindBuffer(buffer_type, 0); 88 | } 89 | }; 90 | 91 | //note this should be 32 bytes (8x4 bytes) 92 | class quadbuf_vertex { 93 | public: 94 | quadbuf_vertex() {}; 95 | quadbuf_vertex(const vec2& pos, const vec4& colour, const vec2& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; 96 | 97 | vec2 pos; 98 | vec4 colour; 99 | vec2 texcoord; 100 | }; 101 | 102 | //maintain ranges corresponding to each texture 103 | class quadbuf_tex { 104 | public: 105 | quadbuf_tex() {}; 106 | quadbuf_tex(int start_index, GLuint textureid) : start_index(start_index), textureid(textureid) {}; 107 | int start_index; 108 | GLuint textureid; 109 | }; 110 | 111 | class quadbuf { 112 | 113 | quadbuf_vertex* data; 114 | int vertex_capacity; 115 | 116 | std::vector textures; 117 | 118 | VBO buf; 119 | 120 | int vertex_count; 121 | 122 | void resize(int new_size); 123 | public: 124 | quadbuf(int data_size = 0); 125 | ~quadbuf(); 126 | 127 | void unload(); 128 | void reset(); 129 | 130 | size_t vertices(); 131 | size_t capacity(); 132 | size_t texture_changes(); 133 | 134 | void add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour); 135 | void add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord); 136 | void add(GLuint textureid, const quadbuf_vertex& v1, const quadbuf_vertex& v2, const quadbuf_vertex& v3, const quadbuf_vertex& v4); 137 | 138 | void update(); 139 | void draw(); 140 | }; 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /vectors.cpp: -------------------------------------------------------------------------------- 1 | #include "vectors.h" 2 | 3 | vec2 rotate_vec2(const vec2& v, float s, float c) { 4 | return vec2( v.x * c - v.y * s, v.x * s + v.y * c ); 5 | } 6 | 7 | vec2 normalise(const vec2& v) { 8 | float l = glm::length(v); 9 | if(l > 0.0) return v / l; 10 | return v; 11 | } 12 | 13 | vec3 normalise(const vec3& v) { 14 | float l = glm::length(v); 15 | if(l > 0.0) return v / l; 16 | return v; 17 | } 18 | 19 | vec4 normalise(const vec4& v) { 20 | float l = glm::length(v); 21 | if(l > 0.0) return v / l; 22 | return v; 23 | } 24 | -------------------------------------------------------------------------------- /vectors.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com) 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef VECTORS_H 29 | #define VECTORS_H 30 | 31 | #define GLM_FORCE_RADIANS 32 | 33 | // the following are required for compatibility with GLM 0.9.9 34 | #define GLM_FORCE_CTOR_INIT 35 | #define GLM_ENABLE_EXPERIMENTAL 36 | 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | using glm::vec2; 45 | using glm::vec3; 46 | using glm::vec4; 47 | using glm::mat3; 48 | using glm::mat4; 49 | 50 | vec2 rotate_vec2(const vec2& v, float s, float c); 51 | 52 | vec2 normalise(const vec2& v); 53 | vec3 normalise(const vec3& v); 54 | vec4 normalise(const vec4& v); 55 | 56 | class lerp2 : public glm::vec2 { 57 | public: 58 | vec2 p; 59 | vec2 l; 60 | 61 | lerp2() : vec2(), p(), l() { 62 | } 63 | 64 | const lerp2& snap() { 65 | p = *this; 66 | return *this; 67 | } 68 | 69 | static vec2 lerp(const vec2& a, const vec2& b, float n) { 70 | return a + (b - a) * n; 71 | } 72 | 73 | const vec2& lerp(float n) { 74 | l = p + (*this - p) * n; 75 | return l; 76 | } 77 | 78 | const lerp2& operator= (const vec2& vec) { 79 | this->x = vec.x; 80 | this->y = vec.y; 81 | return *this; 82 | } 83 | }; 84 | 85 | class lerp3 : public vec3 { 86 | public: 87 | vec3 p; 88 | vec3 l; 89 | 90 | lerp3() : vec3(), p(), l() { 91 | } 92 | 93 | const lerp3& snap() { 94 | p = *this; 95 | return *this; 96 | } 97 | 98 | static vec3 lerp(const vec3& a, const vec3& b, float n) { 99 | return a + (b - a) * n; 100 | } 101 | 102 | const vec3& lerp(float n) { 103 | l = p + (*this - p) * n; 104 | return l; 105 | } 106 | 107 | const lerp3& operator= (const vec3& vec) { 108 | this->x = vec.x; 109 | this->y = vec.y; 110 | this->z = vec.z; 111 | return *this; 112 | } 113 | }; 114 | 115 | #endif 116 | --------------------------------------------------------------------------------