Codebase list gource / 28ed18b
Merge tag 'upstream/0.38' Upstream version 0.38 Andrew Caudwell 12 years ago
132 changed file(s) with 8118 addition(s) and 4508 deletion(s). Raw diff Collapse all Expand all
0 0.38:
1 * New high quality sprites.
2 * Fullscreen toggle with alt + enter.
3 * Window is now resizable. -WIDTHxHEIGHT! creates a non-resizable window.
4 * Lowered minimum zoom distance.
5 * Use AM_CPPFLAGS in Makefile.am to allow passing custom CPPFLAGS.
6 * Don't add files that match the path of a known directory.
7 * Fixed divide by zero in text shader causing artifacts on some video cards.
8 * Recursively search for repository directory when log-format not specified
9 (thanks to Jörg Bachmann for original concept / prototype).
10 * New dependency on Boost Filesystem.
11 * Doubled the maximum zoom out distance.
12 * Allow negative timestamps before 1970 in custom log (artzub).
13 * Fix for UTF8-CPP checked.h compilation issue (vszakats).
14 * Fixed bug causing missing characters in text.
15 * Fixed --highlight-users option not using highlight-colour.
16 * highlight-colour default changed to white.
17 * Added --selection-colour option (applied to selected users and files).
18 * Added --dir-colour option (applied to directories).
19
020 0.37:
121 * Made SVN log GMT timestamp conversion fix portable.
222
99 1. Dependencies
1010 ===============
1111
12 Gource requires the following libraries to compile:
12 Gource requires the following libraries to compile (package names may vary):
1313
1414 SDL 1.2 (libsdl1.2-dev)
1515 SDL Image 1.2 (libsdl-image1.2-dev)
1616 PCRE3 (libpcre3-dev)
1717 Freetype 2 (libfreetype6-dev)
1818 GLEW (libglew-dev)
19 GLM (libglm-dev) >= 0.9.3
20 Boost Filesystem >= 1.46 (libboost-filesystem-dev)
1921
2022 Optional:
2123
2224 TinyXML (libtinyxml-dev)
2325
24 Note: SDL Image needs to have been built with support PNG and JPEG images.
26 SDL Image needs to have been built with support PNG and JPEG images.
27
28 GLM is a header only library that you can get from http://glm.g-truc.net/ if your distribution does not include it.
2529
2630 2. Building
2731 ===========
3640 git submodule init
3741 git submodule update
3842
39 Building on Linux/Mac OS:
43 Generic build instructions for Linux/Mac OS:
4044
4145 ./configure
4246 make
4852 for the Code Blocks IDE (www.codeblocks.org).
4953
5054 A pre-built version for Windows is normally available from the homepage.
55
56 Gource expects SDL to have been built with the NO_STDIO_REDIRECT flag.
5157
5258 3. Configure Options
5359 ====================
33
44 gource_SOURCES = \
55 src/action.cpp src/action.h \
6 src/apache.cpp src/apache.h \
7 src/bloom.cpp src/bloom.h \
8 src/bzr.cpp src/bzr.h \
9 src/commitlog.cpp src/commitlog.h \
6 src/bloom.cpp src/bloom.h \
107 src/core/bounds.h \
11 src/core/camera.cpp src/core/camera.h \
128 src/core/conffile.cpp src/core/conffile.h \
139 src/core/display.cpp src/core/display.h \
1410 src/core/frustum.cpp src/core/frustum.h \
3329 src/core/utf8/unchecked.h \
3430 src/core/utf8/utf8.h \
3531 src/core/vbo.cpp src/core/vbo.h \
36 src/core/vectors.h \
37 src/custom.cpp src/custom.h \
38 src/cvs-exp.cpp src/cvs-exp.h \
39 src/cvs2cl.cpp src/cvs2cl.h \
32 src/core/vectors.cpp src/core/vectors.h \
4033 src/dirnode.cpp src/dirnode.h \
4134 src/file.cpp src/file.h \
42 src/git.cpp src/git.h \
43 src/gitraw.cpp src/gitraw.h \
35 src/formats/apache.cpp src/formats/apache.h \
36 src/formats/bzr.cpp src/formats/bzr.h \
37 src/formats/commitlog.cpp src/formats/commitlog.h \
38 src/formats/custom.cpp src/formats/custom.h \
39 src/formats/cvs-exp.cpp src/formats/cvs-exp.h \
40 src/formats/cvs2cl.cpp src/formats/cvs2cl.h \
41 src/formats/git.cpp src/formats/git.h \
42 src/formats/gitraw.cpp src/formats/gitraw.h \
43 src/formats/hg.cpp src/formats/hg.h \
44 src/formats/svn.cpp src/formats/svn.h \
4445 src/gource.cpp src/gource.h \
4546 src/gource_shell.cpp src/gource_shell.h \
4647 src/gource_settings.cpp src/gource_settings.h \
47 src/hg.cpp src/hg.h \
4848 src/key.cpp src/key.h \
49 src/logmill.cpp src/logmill.h \
4950 src/main.cpp src/main.h \
5051 src/pawn.cpp src/pawn.h \
5152 src/slider.cpp src/slider.h \
5253 src/spline.cpp src/spline.h \
53 src/svn.cpp src/svn.h \
5454 src/textbox.cpp src/textbox.h \
5555 src/user.cpp src/user.h \
5656 src/zoomcamera.cpp src/zoomcamera.h
5757
58 CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\"
58 AM_CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\"
5959
60 dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/cursor.png data/file.png data/no_photo.png data/gource.style
60 dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/file.png data/user.png data/gource.style
6161
6262 shadersdir = $(pkgdatadir)/shaders
6363 dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag data/shaders/bloom.vert data/shaders/bloom.frag data/shaders/text.vert data/shaders/text.frag
7979 endif
8080
8181 if FONTDIR
82 CPPFLAGS += -DSDLAPP_FONT_DIR=\"$(gourcefontdir)\"
82 AM_CPPFLAGS += -DSDLAPP_FONT_DIR=\"$(gourcefontdir)\"
8383 else
8484 fontsdir = $(pkgdatadir)/fonts
8585 dist_fonts_DATA = data/fonts/README data/fonts/FreeSans.ttf
5353 $(top_srcdir)/m4/ax_check_glu.m4 \
5454 $(top_srcdir)/m4/ax_lang_compiler_ms.m4 \
5555 $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/freetype2.m4 \
56 $(top_srcdir)/m4/sdl.m4 $(top_srcdir)/configure.ac
56 $(top_srcdir)/m4/m4_ax_boost_base.m4 \
57 $(top_srcdir)/m4/m4_ax_boost_filesystem.m4 \
58 $(top_srcdir)/m4/m4_ax_boost_system.m4 $(top_srcdir)/m4/sdl.m4 \
59 $(top_srcdir)/configure.ac
5760 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
5861 $(ACLOCAL_M4)
5962 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
6467 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(fontsdir)" \
6568 "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(shadersdir)"
6669 PROGRAMS = $(bin_PROGRAMS)
67 am__gource_SOURCES_DIST = src/action.cpp src/action.h src/apache.cpp \
68 src/apache.h src/bloom.cpp src/bloom.h src/bzr.cpp src/bzr.h \
69 src/commitlog.cpp src/commitlog.h src/core/bounds.h \
70 src/core/camera.cpp src/core/camera.h src/core/conffile.cpp \
70 am__gource_SOURCES_DIST = src/action.cpp src/action.h src/bloom.cpp \
71 src/bloom.h src/core/bounds.h src/core/conffile.cpp \
7172 src/core/conffile.h src/core/display.cpp src/core/display.h \
7273 src/core/frustum.cpp src/core/frustum.h src/core/fxfont.cpp \
7374 src/core/fxfont.h src/core/gl.h src/core/logger.cpp \
8283 src/core/stringhash.h src/core/texture.cpp src/core/texture.h \
8384 src/core/utf8/checked.h src/core/utf8/core.h \
8485 src/core/utf8/unchecked.h src/core/utf8/utf8.h \
85 src/core/vbo.cpp src/core/vbo.h src/core/vectors.h \
86 src/custom.cpp src/custom.h src/cvs-exp.cpp src/cvs-exp.h \
87 src/cvs2cl.cpp src/cvs2cl.h src/dirnode.cpp src/dirnode.h \
88 src/file.cpp src/file.h src/git.cpp src/git.h src/gitraw.cpp \
89 src/gitraw.h src/gource.cpp src/gource.h src/gource_shell.cpp \
90 src/gource_shell.h src/gource_settings.cpp \
91 src/gource_settings.h src/hg.cpp src/hg.h src/key.cpp \
92 src/key.h src/main.cpp src/main.h src/pawn.cpp src/pawn.h \
93 src/slider.cpp src/slider.h src/spline.cpp src/spline.h \
94 src/svn.cpp src/svn.h src/textbox.cpp src/textbox.h \
86 src/core/vbo.cpp src/core/vbo.h src/core/vectors.cpp \
87 src/core/vectors.h src/dirnode.cpp src/dirnode.h src/file.cpp \
88 src/file.h src/formats/apache.cpp src/formats/apache.h \
89 src/formats/bzr.cpp src/formats/bzr.h \
90 src/formats/commitlog.cpp src/formats/commitlog.h \
91 src/formats/custom.cpp src/formats/custom.h \
92 src/formats/cvs-exp.cpp src/formats/cvs-exp.h \
93 src/formats/cvs2cl.cpp src/formats/cvs2cl.h \
94 src/formats/git.cpp src/formats/git.h src/formats/gitraw.cpp \
95 src/formats/gitraw.h src/formats/hg.cpp src/formats/hg.h \
96 src/formats/svn.cpp src/formats/svn.h src/gource.cpp \
97 src/gource.h src/gource_shell.cpp src/gource_shell.h \
98 src/gource_settings.cpp src/gource_settings.h src/key.cpp \
99 src/key.h src/logmill.cpp src/logmill.h src/main.cpp \
100 src/main.h src/pawn.cpp src/pawn.h src/slider.cpp src/slider.h \
101 src/spline.cpp src/spline.h src/textbox.cpp src/textbox.h \
95102 src/user.cpp src/user.h src/zoomcamera.cpp src/zoomcamera.h \
96103 src/tinyxml/tinyxmlerror.cpp src/tinyxml/tinystr.cpp \
97104 src/tinyxml/tinystr.h src/tinyxml/tinyxml.cpp \
103110 @USE_BUNDLED_TINYXML_TRUE@ src/tinyxml/tinystr.$(OBJEXT) \
104111 @USE_BUNDLED_TINYXML_TRUE@ src/tinyxml/tinyxml.$(OBJEXT) \
105112 @USE_BUNDLED_TINYXML_TRUE@ src/tinyxml/tinyxmlparser.$(OBJEXT)
106 am_gource_OBJECTS = src/action.$(OBJEXT) src/apache.$(OBJEXT) \
107 src/bloom.$(OBJEXT) src/bzr.$(OBJEXT) src/commitlog.$(OBJEXT) \
108 src/core/camera.$(OBJEXT) src/core/conffile.$(OBJEXT) \
109 src/core/display.$(OBJEXT) src/core/frustum.$(OBJEXT) \
110 src/core/fxfont.$(OBJEXT) src/core/logger.$(OBJEXT) \
111 src/core/mousecursor.$(OBJEXT) src/core/plane.$(OBJEXT) \
112 src/core/ppm.$(OBJEXT) src/core/quadtree.$(OBJEXT) \
113 src/core/regex.$(OBJEXT) src/core/resource.$(OBJEXT) \
114 src/core/sdlapp.$(OBJEXT) src/core/seeklog.$(OBJEXT) \
115 src/core/settings.$(OBJEXT) src/core/shader.$(OBJEXT) \
116 src/core/stringhash.$(OBJEXT) src/core/texture.$(OBJEXT) \
117 src/core/vbo.$(OBJEXT) src/custom.$(OBJEXT) \
118 src/cvs-exp.$(OBJEXT) src/cvs2cl.$(OBJEXT) \
119 src/dirnode.$(OBJEXT) src/file.$(OBJEXT) src/git.$(OBJEXT) \
120 src/gitraw.$(OBJEXT) src/gource.$(OBJEXT) \
113 am_gource_OBJECTS = src/action.$(OBJEXT) src/bloom.$(OBJEXT) \
114 src/core/conffile.$(OBJEXT) src/core/display.$(OBJEXT) \
115 src/core/frustum.$(OBJEXT) src/core/fxfont.$(OBJEXT) \
116 src/core/logger.$(OBJEXT) src/core/mousecursor.$(OBJEXT) \
117 src/core/plane.$(OBJEXT) src/core/ppm.$(OBJEXT) \
118 src/core/quadtree.$(OBJEXT) src/core/regex.$(OBJEXT) \
119 src/core/resource.$(OBJEXT) src/core/sdlapp.$(OBJEXT) \
120 src/core/seeklog.$(OBJEXT) src/core/settings.$(OBJEXT) \
121 src/core/shader.$(OBJEXT) src/core/stringhash.$(OBJEXT) \
122 src/core/texture.$(OBJEXT) src/core/vbo.$(OBJEXT) \
123 src/core/vectors.$(OBJEXT) src/dirnode.$(OBJEXT) \
124 src/file.$(OBJEXT) src/formats/apache.$(OBJEXT) \
125 src/formats/bzr.$(OBJEXT) src/formats/commitlog.$(OBJEXT) \
126 src/formats/custom.$(OBJEXT) src/formats/cvs-exp.$(OBJEXT) \
127 src/formats/cvs2cl.$(OBJEXT) src/formats/git.$(OBJEXT) \
128 src/formats/gitraw.$(OBJEXT) src/formats/hg.$(OBJEXT) \
129 src/formats/svn.$(OBJEXT) src/gource.$(OBJEXT) \
121130 src/gource_shell.$(OBJEXT) src/gource_settings.$(OBJEXT) \
122 src/hg.$(OBJEXT) src/key.$(OBJEXT) src/main.$(OBJEXT) \
131 src/key.$(OBJEXT) src/logmill.$(OBJEXT) src/main.$(OBJEXT) \
123132 src/pawn.$(OBJEXT) src/slider.$(OBJEXT) src/spline.$(OBJEXT) \
124 src/svn.$(OBJEXT) src/textbox.$(OBJEXT) src/user.$(OBJEXT) \
133 src/textbox.$(OBJEXT) src/user.$(OBJEXT) \
125134 src/zoomcamera.$(OBJEXT) $(am__objects_1)
126135 gource_OBJECTS = $(am_gource_OBJECTS)
127136 gource_LDADD = $(LDADD)
182191 AUTOHEADER = @AUTOHEADER@
183192 AUTOMAKE = @AUTOMAKE@
184193 AWK = @AWK@
194 BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
195 BOOST_FILESYSTEM_LIB = @BOOST_FILESYSTEM_LIB@
196 BOOST_LDFLAGS = @BOOST_LDFLAGS@
197 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
185198 CC = @CC@
186199 CCDEPMODE = @CCDEPMODE@
187200 CFLAGS = @CFLAGS@
188201 CPP = @CPP@
189 CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" $(am__append_2)
202 CPPFLAGS = @CPPFLAGS@
190203 CXX = @CXX@
191204 CXXCPP = @CXXCPP@
192205 CXXDEPMODE = @CXXDEPMODE@
295308 top_builddir = @top_builddir@
296309 top_srcdir = @top_srcdir@
297310 ACLOCAL_AMFLAGS = -I m4
298 gource_SOURCES = src/action.cpp src/action.h src/apache.cpp \
299 src/apache.h src/bloom.cpp src/bloom.h src/bzr.cpp src/bzr.h \
300 src/commitlog.cpp src/commitlog.h src/core/bounds.h \
301 src/core/camera.cpp src/core/camera.h src/core/conffile.cpp \
302 src/core/conffile.h src/core/display.cpp src/core/display.h \
303 src/core/frustum.cpp src/core/frustum.h src/core/fxfont.cpp \
304 src/core/fxfont.h src/core/gl.h src/core/logger.cpp \
305 src/core/logger.h src/core/mousecursor.cpp \
306 src/core/mousecursor.h src/core/pi.h src/core/plane.cpp \
307 src/core/plane.h src/core/ppm.cpp src/core/ppm.h \
308 src/core/quadtree.cpp src/core/quadtree.h src/core/regex.cpp \
309 src/core/regex.h src/core/resource.cpp src/core/resource.h \
310 src/core/sdlapp.cpp src/core/sdlapp.h src/core/seeklog.cpp \
311 src/core/seeklog.h src/core/settings.cpp src/core/settings.h \
312 src/core/shader.cpp src/core/shader.h src/core/stringhash.cpp \
313 src/core/stringhash.h src/core/texture.cpp src/core/texture.h \
311 gource_SOURCES = src/action.cpp src/action.h src/bloom.cpp src/bloom.h \
312 src/core/bounds.h src/core/conffile.cpp src/core/conffile.h \
313 src/core/display.cpp src/core/display.h src/core/frustum.cpp \
314 src/core/frustum.h src/core/fxfont.cpp src/core/fxfont.h \
315 src/core/gl.h src/core/logger.cpp src/core/logger.h \
316 src/core/mousecursor.cpp src/core/mousecursor.h src/core/pi.h \
317 src/core/plane.cpp src/core/plane.h src/core/ppm.cpp \
318 src/core/ppm.h src/core/quadtree.cpp src/core/quadtree.h \
319 src/core/regex.cpp src/core/regex.h src/core/resource.cpp \
320 src/core/resource.h src/core/sdlapp.cpp src/core/sdlapp.h \
321 src/core/seeklog.cpp src/core/seeklog.h src/core/settings.cpp \
322 src/core/settings.h src/core/shader.cpp src/core/shader.h \
323 src/core/stringhash.cpp src/core/stringhash.h \
324 src/core/texture.cpp src/core/texture.h \
314325 src/core/utf8/checked.h src/core/utf8/core.h \
315326 src/core/utf8/unchecked.h src/core/utf8/utf8.h \
316 src/core/vbo.cpp src/core/vbo.h src/core/vectors.h \
317 src/custom.cpp src/custom.h src/cvs-exp.cpp src/cvs-exp.h \
318 src/cvs2cl.cpp src/cvs2cl.h src/dirnode.cpp src/dirnode.h \
319 src/file.cpp src/file.h src/git.cpp src/git.h src/gitraw.cpp \
320 src/gitraw.h src/gource.cpp src/gource.h src/gource_shell.cpp \
321 src/gource_shell.h src/gource_settings.cpp \
322 src/gource_settings.h src/hg.cpp src/hg.h src/key.cpp \
323 src/key.h src/main.cpp src/main.h src/pawn.cpp src/pawn.h \
324 src/slider.cpp src/slider.h src/spline.cpp src/spline.h \
325 src/svn.cpp src/svn.h src/textbox.cpp src/textbox.h \
327 src/core/vbo.cpp src/core/vbo.h src/core/vectors.cpp \
328 src/core/vectors.h src/dirnode.cpp src/dirnode.h src/file.cpp \
329 src/file.h src/formats/apache.cpp src/formats/apache.h \
330 src/formats/bzr.cpp src/formats/bzr.h \
331 src/formats/commitlog.cpp src/formats/commitlog.h \
332 src/formats/custom.cpp src/formats/custom.h \
333 src/formats/cvs-exp.cpp src/formats/cvs-exp.h \
334 src/formats/cvs2cl.cpp src/formats/cvs2cl.h \
335 src/formats/git.cpp src/formats/git.h src/formats/gitraw.cpp \
336 src/formats/gitraw.h src/formats/hg.cpp src/formats/hg.h \
337 src/formats/svn.cpp src/formats/svn.h src/gource.cpp \
338 src/gource.h src/gource_shell.cpp src/gource_shell.h \
339 src/gource_settings.cpp src/gource_settings.h src/key.cpp \
340 src/key.h src/logmill.cpp src/logmill.h src/main.cpp \
341 src/main.h src/pawn.cpp src/pawn.h src/slider.cpp src/slider.h \
342 src/spline.cpp src/spline.h src/textbox.cpp src/textbox.h \
326343 src/user.cpp src/user.h src/zoomcamera.cpp src/zoomcamera.h \
327344 $(am__append_1)
328 dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/cursor.png data/file.png data/no_photo.png data/gource.style
345 AM_CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" $(am__append_2)
346 dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/file.png data/user.png data/gource.style
329347 shadersdir = $(pkgdatadir)/shaders
330348 dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag data/shaders/bloom.vert data/shaders/bloom.frag data/shaders/text.vert data/shaders/text.frag
331349 @FONTDIR_FALSE@fontsdir = $(pkgdatadir)/fonts
413431 @: > src/$(DEPDIR)/$(am__dirstamp)
414432 src/action.$(OBJEXT): src/$(am__dirstamp) \
415433 src/$(DEPDIR)/$(am__dirstamp)
416 src/apache.$(OBJEXT): src/$(am__dirstamp) \
417 src/$(DEPDIR)/$(am__dirstamp)
418434 src/bloom.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
419 src/bzr.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
420 src/commitlog.$(OBJEXT): src/$(am__dirstamp) \
421 src/$(DEPDIR)/$(am__dirstamp)
422435 src/core/$(am__dirstamp):
423436 @$(MKDIR_P) src/core
424437 @: > src/core/$(am__dirstamp)
425438 src/core/$(DEPDIR)/$(am__dirstamp):
426439 @$(MKDIR_P) src/core/$(DEPDIR)
427440 @: > src/core/$(DEPDIR)/$(am__dirstamp)
428 src/core/camera.$(OBJEXT): src/core/$(am__dirstamp) \
429 src/core/$(DEPDIR)/$(am__dirstamp)
430441 src/core/conffile.$(OBJEXT): src/core/$(am__dirstamp) \
431442 src/core/$(DEPDIR)/$(am__dirstamp)
432443 src/core/display.$(OBJEXT): src/core/$(am__dirstamp) \
463474 src/core/$(DEPDIR)/$(am__dirstamp)
464475 src/core/vbo.$(OBJEXT): src/core/$(am__dirstamp) \
465476 src/core/$(DEPDIR)/$(am__dirstamp)
466 src/custom.$(OBJEXT): src/$(am__dirstamp) \
467 src/$(DEPDIR)/$(am__dirstamp)
468 src/cvs-exp.$(OBJEXT): src/$(am__dirstamp) \
469 src/$(DEPDIR)/$(am__dirstamp)
470 src/cvs2cl.$(OBJEXT): src/$(am__dirstamp) \
471 src/$(DEPDIR)/$(am__dirstamp)
477 src/core/vectors.$(OBJEXT): src/core/$(am__dirstamp) \
478 src/core/$(DEPDIR)/$(am__dirstamp)
472479 src/dirnode.$(OBJEXT): src/$(am__dirstamp) \
473480 src/$(DEPDIR)/$(am__dirstamp)
474481 src/file.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
475 src/git.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
476 src/gitraw.$(OBJEXT): src/$(am__dirstamp) \
477 src/$(DEPDIR)/$(am__dirstamp)
482 src/formats/$(am__dirstamp):
483 @$(MKDIR_P) src/formats
484 @: > src/formats/$(am__dirstamp)
485 src/formats/$(DEPDIR)/$(am__dirstamp):
486 @$(MKDIR_P) src/formats/$(DEPDIR)
487 @: > src/formats/$(DEPDIR)/$(am__dirstamp)
488 src/formats/apache.$(OBJEXT): src/formats/$(am__dirstamp) \
489 src/formats/$(DEPDIR)/$(am__dirstamp)
490 src/formats/bzr.$(OBJEXT): src/formats/$(am__dirstamp) \
491 src/formats/$(DEPDIR)/$(am__dirstamp)
492 src/formats/commitlog.$(OBJEXT): src/formats/$(am__dirstamp) \
493 src/formats/$(DEPDIR)/$(am__dirstamp)
494 src/formats/custom.$(OBJEXT): src/formats/$(am__dirstamp) \
495 src/formats/$(DEPDIR)/$(am__dirstamp)
496 src/formats/cvs-exp.$(OBJEXT): src/formats/$(am__dirstamp) \
497 src/formats/$(DEPDIR)/$(am__dirstamp)
498 src/formats/cvs2cl.$(OBJEXT): src/formats/$(am__dirstamp) \
499 src/formats/$(DEPDIR)/$(am__dirstamp)
500 src/formats/git.$(OBJEXT): src/formats/$(am__dirstamp) \
501 src/formats/$(DEPDIR)/$(am__dirstamp)
502 src/formats/gitraw.$(OBJEXT): src/formats/$(am__dirstamp) \
503 src/formats/$(DEPDIR)/$(am__dirstamp)
504 src/formats/hg.$(OBJEXT): src/formats/$(am__dirstamp) \
505 src/formats/$(DEPDIR)/$(am__dirstamp)
506 src/formats/svn.$(OBJEXT): src/formats/$(am__dirstamp) \
507 src/formats/$(DEPDIR)/$(am__dirstamp)
478508 src/gource.$(OBJEXT): src/$(am__dirstamp) \
479509 src/$(DEPDIR)/$(am__dirstamp)
480510 src/gource_shell.$(OBJEXT): src/$(am__dirstamp) \
481511 src/$(DEPDIR)/$(am__dirstamp)
482512 src/gource_settings.$(OBJEXT): src/$(am__dirstamp) \
483513 src/$(DEPDIR)/$(am__dirstamp)
484 src/hg.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
485514 src/key.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
515 src/logmill.$(OBJEXT): src/$(am__dirstamp) \
516 src/$(DEPDIR)/$(am__dirstamp)
486517 src/main.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
487518 src/pawn.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
488519 src/slider.$(OBJEXT): src/$(am__dirstamp) \
489520 src/$(DEPDIR)/$(am__dirstamp)
490521 src/spline.$(OBJEXT): src/$(am__dirstamp) \
491522 src/$(DEPDIR)/$(am__dirstamp)
492 src/svn.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
493523 src/textbox.$(OBJEXT): src/$(am__dirstamp) \
494524 src/$(DEPDIR)/$(am__dirstamp)
495525 src/user.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
516546 mostlyclean-compile:
517547 -rm -f *.$(OBJEXT)
518548 -rm -f src/action.$(OBJEXT)
519 -rm -f src/apache.$(OBJEXT)
520549 -rm -f src/bloom.$(OBJEXT)
521 -rm -f src/bzr.$(OBJEXT)
522 -rm -f src/commitlog.$(OBJEXT)
523 -rm -f src/core/camera.$(OBJEXT)
524550 -rm -f src/core/conffile.$(OBJEXT)
525551 -rm -f src/core/display.$(OBJEXT)
526552 -rm -f src/core/frustum.$(OBJEXT)
539565 -rm -f src/core/stringhash.$(OBJEXT)
540566 -rm -f src/core/texture.$(OBJEXT)
541567 -rm -f src/core/vbo.$(OBJEXT)
542 -rm -f src/custom.$(OBJEXT)
543 -rm -f src/cvs-exp.$(OBJEXT)
544 -rm -f src/cvs2cl.$(OBJEXT)
568 -rm -f src/core/vectors.$(OBJEXT)
545569 -rm -f src/dirnode.$(OBJEXT)
546570 -rm -f src/file.$(OBJEXT)
547 -rm -f src/git.$(OBJEXT)
548 -rm -f src/gitraw.$(OBJEXT)
571 -rm -f src/formats/apache.$(OBJEXT)
572 -rm -f src/formats/bzr.$(OBJEXT)
573 -rm -f src/formats/commitlog.$(OBJEXT)
574 -rm -f src/formats/custom.$(OBJEXT)
575 -rm -f src/formats/cvs-exp.$(OBJEXT)
576 -rm -f src/formats/cvs2cl.$(OBJEXT)
577 -rm -f src/formats/git.$(OBJEXT)
578 -rm -f src/formats/gitraw.$(OBJEXT)
579 -rm -f src/formats/hg.$(OBJEXT)
580 -rm -f src/formats/svn.$(OBJEXT)
549581 -rm -f src/gource.$(OBJEXT)
550582 -rm -f src/gource_settings.$(OBJEXT)
551583 -rm -f src/gource_shell.$(OBJEXT)
552 -rm -f src/hg.$(OBJEXT)
553584 -rm -f src/key.$(OBJEXT)
585 -rm -f src/logmill.$(OBJEXT)
554586 -rm -f src/main.$(OBJEXT)
555587 -rm -f src/pawn.$(OBJEXT)
556588 -rm -f src/slider.$(OBJEXT)
557589 -rm -f src/spline.$(OBJEXT)
558 -rm -f src/svn.$(OBJEXT)
559590 -rm -f src/textbox.$(OBJEXT)
560591 -rm -f src/tinyxml/tinystr.$(OBJEXT)
561592 -rm -f src/tinyxml/tinyxml.$(OBJEXT)
568599 -rm -f *.tab.c
569600
570601 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/action.Po@am__quote@
571 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/apache.Po@am__quote@
572602 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bloom.Po@am__quote@
573 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bzr.Po@am__quote@
574 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/commitlog.Po@am__quote@
575 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/custom.Po@am__quote@
576 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cvs-exp.Po@am__quote@
577 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cvs2cl.Po@am__quote@
578603 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dirnode.Po@am__quote@
579604 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/file.Po@am__quote@
580 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/git.Po@am__quote@
581 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gitraw.Po@am__quote@
582605 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gource.Po@am__quote@
583606 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gource_settings.Po@am__quote@
584607 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gource_shell.Po@am__quote@
585 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/hg.Po@am__quote@
586608 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/key.Po@am__quote@
609 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logmill.Po@am__quote@
587610 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/main.Po@am__quote@
588611 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pawn.Po@am__quote@
589612 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/slider.Po@am__quote@
590613 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/spline.Po@am__quote@
591 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/svn.Po@am__quote@
592614 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/textbox.Po@am__quote@
593615 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/user.Po@am__quote@
594616 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/zoomcamera.Po@am__quote@
595 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/camera.Po@am__quote@
596617 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/conffile.Po@am__quote@
597618 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/display.Po@am__quote@
598619 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/frustum.Po@am__quote@
611632 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/stringhash.Po@am__quote@
612633 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/texture.Po@am__quote@
613634 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/vbo.Po@am__quote@
635 @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/vectors.Po@am__quote@
636 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/apache.Po@am__quote@
637 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/bzr.Po@am__quote@
638 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/commitlog.Po@am__quote@
639 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/custom.Po@am__quote@
640 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/cvs-exp.Po@am__quote@
641 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/cvs2cl.Po@am__quote@
642 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/git.Po@am__quote@
643 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/gitraw.Po@am__quote@
644 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/hg.Po@am__quote@
645 @AMDEP_TRUE@@am__include@ @am__quote@src/formats/$(DEPDIR)/svn.Po@am__quote@
614646 @AMDEP_TRUE@@am__include@ @am__quote@src/tinyxml/$(DEPDIR)/tinystr.Po@am__quote@
615647 @AMDEP_TRUE@@am__include@ @am__quote@src/tinyxml/$(DEPDIR)/tinyxml.Po@am__quote@
616648 @AMDEP_TRUE@@am__include@ @am__quote@src/tinyxml/$(DEPDIR)/tinyxmlerror.Po@am__quote@
923955 -rm -f src/$(am__dirstamp)
924956 -rm -f src/core/$(DEPDIR)/$(am__dirstamp)
925957 -rm -f src/core/$(am__dirstamp)
958 -rm -f src/formats/$(DEPDIR)/$(am__dirstamp)
959 -rm -f src/formats/$(am__dirstamp)
926960 -rm -f src/tinyxml/$(DEPDIR)/$(am__dirstamp)
927961 -rm -f src/tinyxml/$(am__dirstamp)
928962
935969
936970 distclean: distclean-am
937971 -rm -f $(am__CONFIG_DISTCLEAN_FILES)
938 -rm -rf src/$(DEPDIR) src/core/$(DEPDIR) src/tinyxml/$(DEPDIR)
972 -rm -rf src/$(DEPDIR) src/core/$(DEPDIR) src/formats/$(DEPDIR) src/tinyxml/$(DEPDIR)
939973 -rm -f Makefile
940974 distclean-am: clean-am distclean-compile distclean-generic \
941975 distclean-tags
9851019 maintainer-clean: maintainer-clean-am
9861020 -rm -f $(am__CONFIG_DISTCLEAN_FILES)
9871021 -rm -rf $(top_srcdir)/autom4te.cache
988 -rm -rf src/$(DEPDIR) src/core/$(DEPDIR) src/tinyxml/$(DEPDIR)
1022 -rm -rf src/$(DEPDIR) src/core/$(DEPDIR) src/formats/$(DEPDIR) src/tinyxml/$(DEPDIR)
9891023 -rm -f Makefile
9901024 maintainer-clean-am: distclean-am maintainer-clean-generic
9911025
4242
4343 -WIDTHxHEIGHT, --viewport WIDTHxHEIGHT
4444 Set the viewport size. If -f is also supplied, will attempt to set
45 the video mode to this also.
45 the video mode to this also. Add ! to make the window non-resizable.
4646
4747 -f, --fullscreen
4848 Fullscreen.
8888 Elasticity of nodes.
8989
9090 -b, --background-colour FFFFFF
91 Background colour in hex.
91 Background colour in hex.
9292
9393 --background-image IMAGE
94 Set a background image.
94 Set a background image.
9595
9696 --logo IMAGE
97 Logo to display in the foreground.
97 Logo to display in the foreground.
9898
9999 --logo-offset XxY
100 Offset position of the logo.
100 Offset position of the logo.
101101
102102 --title TITLE
103 Set a title.
103 Set a title.
104104
105105 --font-size SIZE
106 Font size.
106 Font size used by the date and title.
107107
108108 --font-colour FFFFFF
109 Font colour in hex.
109 Font colour used by the date and title in hex.
110110
111111 --key
112 Show file extension key.
112 Show file extension key.
113113
114114 --date-format FORMAT
115115 Specify display date string (strftime format).
128128 --follow-user USER
129129 Have the camera automatically follow a particular user.
130130
131 --highlight-dirs
132 Highlight the names of all directories.
133
131134 --highlight-user USER
132135 Highlight the names of a particular user.
133136
134137 --highlight-users
135138 Highlight the names of all users.
136139
137 --highlight-dirs
138 Highlight the names of all directories.
139
140140 --highlight-colour FFFFFF
141 Highlighted text colour in hex.
141 Font colour for highlighted users in hex.
142
143 --selection-colour FFFFFF
144 Font colour for selected users and files.
145
146 --dir-colour FFFFFF
147 Font colour for directories.
142148
143149 --file-filter REGEX
144150 Filter out any files matching a specified regular expression.
171177 --no-vsync
172178 Disable vsync.
173179
174 --bloom-multiplier FLOAT
180 --bloom-multiplier FLOAT
175181 Adjust the amount of bloom.
176182
177183 --bloom-intensity FLOAT
191197 Max speed users can travel per second.
192198
193199 --user-friction SECONDS
194 Time users come to a complete hault.
200 Time users take to come to a halt.
195201
196202 --user-scale SCALE
197203 Change scale of users.
246252 file (see log commands or the custom log format), a Gource conf
247253 file or '-' to read STDIN.
248254
249 If path is ommited, gource will attempt to read a log from the
255 If path is omitted, gource will attempt to read a log from the
250256 current directory.
251257
252258 Git, Bazaar, Mercurial and SVN Examples:
253259
254 View the log of the respository in the current path:
260 View the log of the repository in the current path:
255261
256262 gource
257263
313319 log entry read and is incremented according to the simulation speed
314320 (--seconds-per-day).
315321
316 Pressing SPACE at any time will pause/unpause the simulation. While paused you
322 Pressing SPACE at any time will pause/resume the simulation. While paused you
317323 may use the mouse to inspect the detail of individual files and users.
318324
319325 TAB cycles through selecting the current visible users.
335341 (+-) Adjust simulation speed.
336342 (<>) Adjust time scale.
337343 (TAB) Cycle through visible users
344
345 (Alt+Enter) Toggle Fullscreen
346
338347 (ESC) Quit
339348
340349 4. Copyright
953953 m4_include([m4/ax_lang_compiler_ms.m4])
954954 m4_include([m4/ax_pthread.m4])
955955 m4_include([m4/freetype2.m4])
956 m4_include([m4/m4_ax_boost_base.m4])
957 m4_include([m4/m4_ax_boost_filesystem.m4])
958 m4_include([m4/m4_ax_boost_system.m4])
956959 m4_include([m4/sdl.m4])
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.68 for Gource 0.37.
2 # Generated by GNU Autoconf 2.68 for Gource 0.38.
33 #
44 # Report bugs to <acaudwell@gmail.com>.
55 #
559559 # Identity of this package.
560560 PACKAGE_NAME='Gource'
561561 PACKAGE_TARNAME='gource'
562 PACKAGE_VERSION='0.37'
563 PACKAGE_STRING='Gource 0.37'
562 PACKAGE_VERSION='0.38'
563 PACKAGE_STRING='Gource 0.38'
564564 PACKAGE_BUGREPORT='acaudwell@gmail.com'
565565 PACKAGE_URL=''
566566
610610 gourcefontdir
611611 FONTDIR_FALSE
612612 FONTDIR_TRUE
613 BOOST_FILESYSTEM_LIB
614 BOOST_SYSTEM_LIB
615 BOOST_LDFLAGS
616 BOOST_CPPFLAGS
613617 FT2_LIBS
614618 FT2_CFLAGS
615619 FT2_CONFIG
734738 with_ft_prefix
735739 with_ft_exec_prefix
736740 enable_freetypetest
741 with_boost
742 with_boost_libdir
743 with_boost_system
744 with_boost_filesystem
737745 enable_ttf_font_dir
738746 with_tinyxml
739747 '
12931301 # Omit some internal or obsolete options to make the list less imposing.
12941302 # This message is too long to be a string in the A/UX 3.1 sh.
12951303 cat <<_ACEOF
1296 \`configure' configures Gource 0.37 to adapt to many kinds of systems.
1304 \`configure' configures Gource 0.38 to adapt to many kinds of systems.
12971305
12981306 Usage: $0 [OPTION]... [VAR=VALUE]...
12991307
13671375
13681376 if test -n "$ac_init_help"; then
13691377 case $ac_init_help in
1370 short | recursive ) echo "Configuration of Gource 0.37:";;
1378 short | recursive ) echo "Configuration of Gource 0.38:";;
13711379 esac
13721380 cat <<\_ACEOF
13731381
13921400 --with-ft-prefix=PREFIX Prefix where FreeType is installed (optional)
13931401 --with-ft-exec-prefix=PREFIX
13941402 Exec prefix where FreeType is installed (optional)
1403 --with-boost[=ARG] use Boost library from a standard location
1404 (ARG=yes), from the specified location (ARG=<path>),
1405 or disable it (ARG=no) [ARG=yes]
1406 --with-boost-libdir=LIB_DIR
1407 Force given directory for boost libraries. Note that
1408 this will override library path detection, so use
1409 this parameter only if default library detection
1410 fails and you know exactly where your boost
1411 libraries are located.
1412 --with-boost-system[=special-lib]
1413 use the System library from boost - it is possible
1414 to specify a certain library for the linker e.g.
1415 --with-boost-system=boost_system-gcc-mt
1416 --with-boost-filesystem[=special-lib]
1417 use the Filesystem library from boost - it is
1418 possible to specify a certain library for the linker
1419 e.g. --with-boost-filesystem=boost_filesystem-gcc-mt
13951420 --with-tinyxml Use system installed TinyXML library
13961421
13971422 Some influential environment variables:
14741499 test -n "$ac_init_help" && exit $ac_status
14751500 if $ac_init_version; then
14761501 cat <<\_ACEOF
1477 Gource configure 0.37
1502 Gource configure 0.38
14781503 generated by GNU Autoconf 2.68
14791504
14801505 Copyright (C) 2010 Free Software Foundation, Inc.
21282153 This file contains any messages produced by compilers while
21292154 running configure, to aid debugging if configure makes a mistake.
21302155
2131 It was created by Gource $as_me 0.37, which was
2156 It was created by Gource $as_me 0.38, which was
21322157 generated by GNU Autoconf 2.68. Invocation command line was
21332158
21342159 $ $0 $@
29452970
29462971 # Define the identity of the package.
29472972 PACKAGE='gource'
2948 VERSION='0.37'
2973 VERSION='0.38'
29492974
29502975
29512976 cat >>confdefs.h <<_ACEOF
67986823 if test "x$ac_cv_lib_GLEW_glewInit" = xyes; then :
67996824 LIBS="$LIBS -lGLEW"
68006825 else
6801 as_fn_error $? "GLEW required. Please see INSTALL" "$LINENO" 5
6802 fi
6826 as_fn_error $? "GLEW is required. Please see INSTALL" "$LINENO" 5
6827 fi
6828
6829
6830 #BOOST
6831
6832
6833 # Check whether --with-boost was given.
6834 if test "${with_boost+set}" = set; then :
6835 withval=$with_boost;
6836 if test "$withval" = "no"; then
6837 want_boost="no"
6838 elif test "$withval" = "yes"; then
6839 want_boost="yes"
6840 ac_boost_path=""
6841 else
6842 want_boost="yes"
6843 ac_boost_path="$withval"
6844 fi
6845
6846 else
6847 want_boost="yes"
6848 fi
6849
6850
6851
6852
6853 # Check whether --with-boost-libdir was given.
6854 if test "${with_boost_libdir+set}" = set; then :
6855 withval=$with_boost_libdir;
6856 if test -d "$withval"
6857 then
6858 ac_boost_lib_path="$withval"
6859 else
6860 as_fn_error $? "--with-boost-libdir expected directory name" "$LINENO" 5
6861 fi
6862
6863 else
6864 ac_boost_lib_path=""
6865
6866 fi
6867
6868
6869 if test "x$want_boost" = "xyes"; then
6870 boost_lib_version_req=1.46
6871 boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([0-9]*\.[0-9]*\)'`
6872 boost_lib_version_req_major=`expr $boost_lib_version_req : '\([0-9]*\)'`
6873 boost_lib_version_req_minor=`expr $boost_lib_version_req : '[0-9]*\.\([0-9]*\)'`
6874 boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
6875 if test "x$boost_lib_version_req_sub_minor" = "x" ; then
6876 boost_lib_version_req_sub_minor="0"
6877 fi
6878 WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
6879 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= $boost_lib_version_req" >&5
6880 $as_echo_n "checking for boostlib >= $boost_lib_version_req... " >&6; }
6881 succeeded=no
6882
6883 libsubdirs="lib"
6884 ax_arch=`uname -m`
6885 if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then
6886 libsubdirs="lib64 lib lib64"
6887 fi
6888
6889 if test "$ac_boost_path" != ""; then
6890 BOOST_CPPFLAGS="-I$ac_boost_path/include"
6891 for ac_boost_path_tmp in $libsubdirs; do
6892 if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then
6893 BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp"
6894 break
6895 fi
6896 done
6897 elif test "$cross_compiling" != yes; then
6898 for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
6899 if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
6900 for libsubdir in $libsubdirs ; do
6901 if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
6902 done
6903 BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir"
6904 BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
6905 break;
6906 fi
6907 done
6908 fi
6909
6910 if test "$ac_boost_lib_path" != ""; then
6911 BOOST_LDFLAGS="-L$ac_boost_lib_path"
6912 fi
6913
6914 CPPFLAGS_SAVED="$CPPFLAGS"
6915 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
6916 export CPPFLAGS
6917
6918 LDFLAGS_SAVED="$LDFLAGS"
6919 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
6920 export LDFLAGS
6921
6922
6923 ac_ext=cpp
6924 ac_cpp='$CXXCPP $CPPFLAGS'
6925 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6926 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6927 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
6928
6929 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
6930 /* end confdefs.h. */
6931
6932 #include <boost/version.hpp>
6933
6934 int
6935 main ()
6936 {
6937
6938 #if BOOST_VERSION >= $WANT_BOOST_VERSION
6939 // Everything is okay
6940 #else
6941 # error Boost version is too old
6942 #endif
6943
6944 ;
6945 return 0;
6946 }
6947 _ACEOF
6948 if ac_fn_cxx_try_compile "$LINENO"; then :
6949
6950 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
6951 $as_echo "yes" >&6; }
6952 succeeded=yes
6953 found_system=yes
6954
6955 fi
6956 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6957 ac_ext=cpp
6958 ac_cpp='$CXXCPP $CPPFLAGS'
6959 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6960 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6961 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
6962
6963
6964
6965
6966 if test "x$succeeded" != "xyes"; then
6967 _version=0
6968 if test "$ac_boost_path" != ""; then
6969 if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
6970 for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
6971 _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
6972 V_CHECK=`expr $_version_tmp \> $_version`
6973 if test "$V_CHECK" = "1" ; then
6974 _version=$_version_tmp
6975 fi
6976 VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
6977 BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
6978 done
6979 fi
6980 else
6981 if test "$cross_compiling" != yes; then
6982 for ac_boost_path in /usr /usr/local /opt /opt/local ; do
6983 if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
6984 for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
6985 _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
6986 V_CHECK=`expr $_version_tmp \> $_version`
6987 if test "$V_CHECK" = "1" ; then
6988 _version=$_version_tmp
6989 best_path=$ac_boost_path
6990 fi
6991 done
6992 fi
6993 done
6994
6995 VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
6996 BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
6997 if test "$ac_boost_lib_path" = ""; then
6998 for libsubdir in $libsubdirs ; do
6999 if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
7000 done
7001 BOOST_LDFLAGS="-L$best_path/$libsubdir"
7002 fi
7003 fi
7004
7005 if test "x$BOOST_ROOT" != "x"; then
7006 for libsubdir in $libsubdirs ; do
7007 if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
7008 done
7009 if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then
7010 version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
7011 stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
7012 stage_version_shorten=`expr $stage_version : '\([0-9]*\.[0-9]*\)'`
7013 V_CHECK=`expr $stage_version_shorten \>\= $_version`
7014 if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
7015 { $as_echo "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5
7016 $as_echo "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;}
7017 BOOST_CPPFLAGS="-I$BOOST_ROOT"
7018 BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
7019 fi
7020 fi
7021 fi
7022 fi
7023
7024 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
7025 export CPPFLAGS
7026 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
7027 export LDFLAGS
7028
7029 ac_ext=cpp
7030 ac_cpp='$CXXCPP $CPPFLAGS'
7031 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7032 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7033 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7034
7035 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7036 /* end confdefs.h. */
7037
7038 #include <boost/version.hpp>
7039
7040 int
7041 main ()
7042 {
7043
7044 #if BOOST_VERSION >= $WANT_BOOST_VERSION
7045 // Everything is okay
7046 #else
7047 # error Boost version is too old
7048 #endif
7049
7050 ;
7051 return 0;
7052 }
7053 _ACEOF
7054 if ac_fn_cxx_try_compile "$LINENO"; then :
7055
7056 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
7057 $as_echo "yes" >&6; }
7058 succeeded=yes
7059 found_system=yes
7060
7061 fi
7062 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
7063 ac_ext=cpp
7064 ac_cpp='$CXXCPP $CPPFLAGS'
7065 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7066 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7067 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7068
7069 fi
7070
7071 if test "$succeeded" != "yes" ; then
7072 if test "$_version" = "0" ; then
7073 { $as_echo "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&5
7074 $as_echo "$as_me: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&6;}
7075 else
7076 { $as_echo "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5
7077 $as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
7078 fi
7079 # execute ACTION-IF-NOT-FOUND (if present):
7080 as_fn_error $? "Boost Filesystem >= 1.46 is required. Please see INSTALL" "$LINENO" 5
7081 else
7082
7083
7084
7085 $as_echo "#define HAVE_BOOST /**/" >>confdefs.h
7086
7087 # execute ACTION-IF-FOUND (if present):
7088 :
7089 fi
7090
7091 CPPFLAGS="$CPPFLAGS_SAVED"
7092 LDFLAGS="$LDFLAGS_SAVED"
7093 fi
7094
7095
7096
7097
7098 # Check whether --with-boost-system was given.
7099 if test "${with_boost_system+set}" = set; then :
7100 withval=$with_boost_system;
7101 if test "$withval" = "no"; then
7102 want_boost="no"
7103 elif test "$withval" = "yes"; then
7104 want_boost="yes"
7105 ax_boost_user_system_lib=""
7106 else
7107 want_boost="yes"
7108 ax_boost_user_system_lib="$withval"
7109 fi
7110
7111 else
7112 want_boost="yes"
7113
7114 fi
7115
7116
7117 if test "x$want_boost" = "xyes"; then
7118
7119
7120 CPPFLAGS_SAVED="$CPPFLAGS"
7121 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
7122 export CPPFLAGS
7123
7124 LDFLAGS_SAVED="$LDFLAGS"
7125 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
7126 export LDFLAGS
7127
7128 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::System library is available" >&5
7129 $as_echo_n "checking whether the Boost::System library is available... " >&6; }
7130 if ${ax_cv_boost_system+:} false; then :
7131 $as_echo_n "(cached) " >&6
7132 else
7133 ac_ext=cpp
7134 ac_cpp='$CXXCPP $CPPFLAGS'
7135 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7136 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7137 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7138
7139 CXXFLAGS_SAVE=$CXXFLAGS
7140
7141 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7142 /* end confdefs.h. */
7143 #include <boost/system/error_code.hpp>
7144 int
7145 main ()
7146 {
7147 boost::system::system_category
7148 ;
7149 return 0;
7150 }
7151 _ACEOF
7152 if ac_fn_cxx_try_compile "$LINENO"; then :
7153 ax_cv_boost_system=yes
7154 else
7155 ax_cv_boost_system=no
7156 fi
7157 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
7158 CXXFLAGS=$CXXFLAGS_SAVE
7159 ac_ext=cpp
7160 ac_cpp='$CXXCPP $CPPFLAGS'
7161 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7162 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7163 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7164
7165
7166 fi
7167 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_system" >&5
7168 $as_echo "$ax_cv_boost_system" >&6; }
7169 if test "x$ax_cv_boost_system" = "xyes"; then
7170
7171
7172
7173 $as_echo "#define HAVE_BOOST_SYSTEM /**/" >>confdefs.h
7174
7175 BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'`
7176
7177 LDFLAGS_SAVE=$LDFLAGS
7178 if test "x$ax_boost_user_system_lib" = "x"; then
7179 for libextension in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;'` ; do
7180 ax_lib=${libextension}
7181 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7182 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7183 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7184 if eval \${$as_ac_Lib+:} false; then :
7185 $as_echo_n "(cached) " >&6
7186 else
7187 ac_check_lib_save_LIBS=$LIBS
7188 LIBS="-l$ax_lib $LIBS"
7189 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7190 /* end confdefs.h. */
7191
7192 /* Override any GCC internal prototype to avoid an error.
7193 Use char because int might match the return type of a GCC
7194 builtin and then its argument prototype would still apply. */
7195 #ifdef __cplusplus
7196 extern "C"
7197 #endif
7198 char exit ();
7199 int
7200 main ()
7201 {
7202 return exit ();
7203 ;
7204 return 0;
7205 }
7206 _ACEOF
7207 if ac_fn_cxx_try_link "$LINENO"; then :
7208 eval "$as_ac_Lib=yes"
7209 else
7210 eval "$as_ac_Lib=no"
7211 fi
7212 rm -f core conftest.err conftest.$ac_objext \
7213 conftest$ac_exeext conftest.$ac_ext
7214 LIBS=$ac_check_lib_save_LIBS
7215 fi
7216 eval ac_res=\$$as_ac_Lib
7217 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7218 $as_echo "$ac_res" >&6; }
7219 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7220 BOOST_SYSTEM_LIB="-l$ax_lib"; link_system="yes"; break
7221 else
7222 link_system="no"
7223 fi
7224
7225 done
7226 if test "x$link_system" != "xyes"; then
7227 for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do
7228 ax_lib=${libextension}
7229 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7230 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7231 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7232 if eval \${$as_ac_Lib+:} false; then :
7233 $as_echo_n "(cached) " >&6
7234 else
7235 ac_check_lib_save_LIBS=$LIBS
7236 LIBS="-l$ax_lib $LIBS"
7237 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7238 /* end confdefs.h. */
7239
7240 /* Override any GCC internal prototype to avoid an error.
7241 Use char because int might match the return type of a GCC
7242 builtin and then its argument prototype would still apply. */
7243 #ifdef __cplusplus
7244 extern "C"
7245 #endif
7246 char exit ();
7247 int
7248 main ()
7249 {
7250 return exit ();
7251 ;
7252 return 0;
7253 }
7254 _ACEOF
7255 if ac_fn_cxx_try_link "$LINENO"; then :
7256 eval "$as_ac_Lib=yes"
7257 else
7258 eval "$as_ac_Lib=no"
7259 fi
7260 rm -f core conftest.err conftest.$ac_objext \
7261 conftest$ac_exeext conftest.$ac_ext
7262 LIBS=$ac_check_lib_save_LIBS
7263 fi
7264 eval ac_res=\$$as_ac_Lib
7265 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7266 $as_echo "$ac_res" >&6; }
7267 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7268 BOOST_SYSTEM_LIB="-l$ax_lib"; link_system="yes"; break
7269 else
7270 link_system="no"
7271 fi
7272
7273 done
7274 fi
7275
7276 else
7277 for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
7278 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7279 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7280 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7281 if eval \${$as_ac_Lib+:} false; then :
7282 $as_echo_n "(cached) " >&6
7283 else
7284 ac_check_lib_save_LIBS=$LIBS
7285 LIBS="-l$ax_lib $LIBS"
7286 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7287 /* end confdefs.h. */
7288
7289 /* Override any GCC internal prototype to avoid an error.
7290 Use char because int might match the return type of a GCC
7291 builtin and then its argument prototype would still apply. */
7292 #ifdef __cplusplus
7293 extern "C"
7294 #endif
7295 char exit ();
7296 int
7297 main ()
7298 {
7299 return exit ();
7300 ;
7301 return 0;
7302 }
7303 _ACEOF
7304 if ac_fn_cxx_try_link "$LINENO"; then :
7305 eval "$as_ac_Lib=yes"
7306 else
7307 eval "$as_ac_Lib=no"
7308 fi
7309 rm -f core conftest.err conftest.$ac_objext \
7310 conftest$ac_exeext conftest.$ac_ext
7311 LIBS=$ac_check_lib_save_LIBS
7312 fi
7313 eval ac_res=\$$as_ac_Lib
7314 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7315 $as_echo "$ac_res" >&6; }
7316 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7317 BOOST_SYSTEM_LIB="-l$ax_lib"; link_system="yes"; break
7318 else
7319 link_system="no"
7320 fi
7321
7322 done
7323
7324 fi
7325 if test "x$ax_lib" = "x"; then
7326 as_fn_error $? "Could not find a version of the library!" "$LINENO" 5
7327 fi
7328 if test "x$link_system" = "xno"; then
7329 as_fn_error $? "Could not link against $ax_lib !" "$LINENO" 5
7330 fi
7331 fi
7332
7333 CPPFLAGS="$CPPFLAGS_SAVED"
7334 LDFLAGS="$LDFLAGS_SAVED"
7335 fi
7336
7337
7338
7339 # Check whether --with-boost-filesystem was given.
7340 if test "${with_boost_filesystem+set}" = set; then :
7341 withval=$with_boost_filesystem;
7342 if test "$withval" = "no"; then
7343 want_boost="no"
7344 elif test "$withval" = "yes"; then
7345 want_boost="yes"
7346 ax_boost_user_filesystem_lib=""
7347 else
7348 want_boost="yes"
7349 ax_boost_user_filesystem_lib="$withval"
7350 fi
7351
7352 else
7353 want_boost="yes"
7354
7355 fi
7356
7357
7358 if test "x$want_boost" = "xyes"; then
7359
7360 CPPFLAGS_SAVED="$CPPFLAGS"
7361 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
7362 export CPPFLAGS
7363
7364 LDFLAGS_SAVED="$LDFLAGS"
7365 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
7366 export LDFLAGS
7367
7368 LIBS_SAVED=$LIBS
7369 LIBS="$LIBS $BOOST_SYSTEM_LIB"
7370 export LIBS
7371
7372 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::Filesystem library is available" >&5
7373 $as_echo_n "checking whether the Boost::Filesystem library is available... " >&6; }
7374 if ${ax_cv_boost_filesystem+:} false; then :
7375 $as_echo_n "(cached) " >&6
7376 else
7377 ac_ext=cpp
7378 ac_cpp='$CXXCPP $CPPFLAGS'
7379 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7380 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7381 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7382
7383 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7384 /* end confdefs.h. */
7385 #include <boost/filesystem/path.hpp>
7386 int
7387 main ()
7388 {
7389 using namespace boost::filesystem;
7390 path my_path( "foo/bar/data.txt" );
7391 return 0;
7392 ;
7393 return 0;
7394 }
7395 _ACEOF
7396 if ac_fn_cxx_try_compile "$LINENO"; then :
7397 ax_cv_boost_filesystem=yes
7398 else
7399 ax_cv_boost_filesystem=no
7400 fi
7401 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
7402 ac_ext=cpp
7403 ac_cpp='$CXXCPP $CPPFLAGS'
7404 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
7405 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
7406 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
7407
7408
7409 fi
7410 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_filesystem" >&5
7411 $as_echo "$ax_cv_boost_filesystem" >&6; }
7412 if test "x$ax_cv_boost_filesystem" = "xyes"; then
7413
7414 $as_echo "#define HAVE_BOOST_FILESYSTEM /**/" >>confdefs.h
7415
7416 BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'`
7417 if test "x$ax_boost_user_filesystem_lib" = "x"; then
7418 for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.so* $BOOSTLIBDIR/libboost_filesystem*.dylib* $BOOSTLIBDIR/libboost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib$;\1;'` ; do
7419 ax_lib=${libextension}
7420 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7421 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7422 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7423 if eval \${$as_ac_Lib+:} false; then :
7424 $as_echo_n "(cached) " >&6
7425 else
7426 ac_check_lib_save_LIBS=$LIBS
7427 LIBS="-l$ax_lib $LIBS"
7428 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7429 /* end confdefs.h. */
7430
7431 /* Override any GCC internal prototype to avoid an error.
7432 Use char because int might match the return type of a GCC
7433 builtin and then its argument prototype would still apply. */
7434 #ifdef __cplusplus
7435 extern "C"
7436 #endif
7437 char exit ();
7438 int
7439 main ()
7440 {
7441 return exit ();
7442 ;
7443 return 0;
7444 }
7445 _ACEOF
7446 if ac_fn_cxx_try_link "$LINENO"; then :
7447 eval "$as_ac_Lib=yes"
7448 else
7449 eval "$as_ac_Lib=no"
7450 fi
7451 rm -f core conftest.err conftest.$ac_objext \
7452 conftest$ac_exeext conftest.$ac_ext
7453 LIBS=$ac_check_lib_save_LIBS
7454 fi
7455 eval ac_res=\$$as_ac_Lib
7456 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7457 $as_echo "$ac_res" >&6; }
7458 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7459 BOOST_FILESYSTEM_LIB="-l$ax_lib"; link_filesystem="yes"; break
7460 else
7461 link_filesystem="no"
7462 fi
7463
7464 done
7465 if test "x$link_filesystem" != "xyes"; then
7466 for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a*$;\1;'` ; do
7467 ax_lib=${libextension}
7468 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7469 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7470 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7471 if eval \${$as_ac_Lib+:} false; then :
7472 $as_echo_n "(cached) " >&6
7473 else
7474 ac_check_lib_save_LIBS=$LIBS
7475 LIBS="-l$ax_lib $LIBS"
7476 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7477 /* end confdefs.h. */
7478
7479 /* Override any GCC internal prototype to avoid an error.
7480 Use char because int might match the return type of a GCC
7481 builtin and then its argument prototype would still apply. */
7482 #ifdef __cplusplus
7483 extern "C"
7484 #endif
7485 char exit ();
7486 int
7487 main ()
7488 {
7489 return exit ();
7490 ;
7491 return 0;
7492 }
7493 _ACEOF
7494 if ac_fn_cxx_try_link "$LINENO"; then :
7495 eval "$as_ac_Lib=yes"
7496 else
7497 eval "$as_ac_Lib=no"
7498 fi
7499 rm -f core conftest.err conftest.$ac_objext \
7500 conftest$ac_exeext conftest.$ac_ext
7501 LIBS=$ac_check_lib_save_LIBS
7502 fi
7503 eval ac_res=\$$as_ac_Lib
7504 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7505 $as_echo "$ac_res" >&6; }
7506 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7507 BOOST_FILESYSTEM_LIB="-l$ax_lib"; link_filesystem="yes"; break
7508 else
7509 link_filesystem="no"
7510 fi
7511
7512 done
7513 fi
7514 else
7515 for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do
7516 as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
7517 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
7518 $as_echo_n "checking for exit in -l$ax_lib... " >&6; }
7519 if eval \${$as_ac_Lib+:} false; then :
7520 $as_echo_n "(cached) " >&6
7521 else
7522 ac_check_lib_save_LIBS=$LIBS
7523 LIBS="-l$ax_lib $LIBS"
7524 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
7525 /* end confdefs.h. */
7526
7527 /* Override any GCC internal prototype to avoid an error.
7528 Use char because int might match the return type of a GCC
7529 builtin and then its argument prototype would still apply. */
7530 #ifdef __cplusplus
7531 extern "C"
7532 #endif
7533 char exit ();
7534 int
7535 main ()
7536 {
7537 return exit ();
7538 ;
7539 return 0;
7540 }
7541 _ACEOF
7542 if ac_fn_cxx_try_link "$LINENO"; then :
7543 eval "$as_ac_Lib=yes"
7544 else
7545 eval "$as_ac_Lib=no"
7546 fi
7547 rm -f core conftest.err conftest.$ac_objext \
7548 conftest$ac_exeext conftest.$ac_ext
7549 LIBS=$ac_check_lib_save_LIBS
7550 fi
7551 eval ac_res=\$$as_ac_Lib
7552 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
7553 $as_echo "$ac_res" >&6; }
7554 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
7555 BOOST_FILESYSTEM_LIB="-l$ax_lib"; link_filesystem="yes"; break
7556 else
7557 link_filesystem="no"
7558 fi
7559
7560 done
7561
7562 fi
7563 if test "x$ax_lib" = "x"; then
7564 as_fn_error $? "Could not find a version of the library!" "$LINENO" 5
7565 fi
7566 if test "x$link_filesystem" != "xyes"; then
7567 as_fn_error $? "Could not link against $ax_lib !" "$LINENO" 5
7568 fi
7569 fi
7570
7571 CPPFLAGS="$CPPFLAGS_SAVED"
7572 LDFLAGS="$LDFLAGS_SAVED"
7573 LIBS="$LIBS_SAVED"
7574 fi
7575
7576
7577 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
7578 LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB"
7579
7580 #GLM
7581 ac_fn_cxx_check_header_mongrel "$LINENO" "glm/glm.hpp" "ac_cv_header_glm_glm_hpp" "$ac_includes_default"
7582 if test "x$ac_cv_header_glm_glm_hpp" = xyes; then :
7583
7584 else
7585 as_fn_error $? "GLM headers are required. Please see INSTALL" "$LINENO" 5
7586 fi
7587
68037588
68047589
68057590 #Check for required headers
68077592 if test "x$ac_cv_header_SDL_h" = xyes; then :
68087593
68097594 else
6810 as_fn_error $? "SDL.h is required. Please see INSTALL" "$LINENO" 5
7595 as_fn_error $? "SDL headers are required. Please see INSTALL" "$LINENO" 5
68117596 fi
68127597
68137598
68157600 if test "x$ac_cv_header_SDL_image_h" = xyes; then :
68167601
68177602 else
6818 as_fn_error $? "SDL_image.h is required. Please see INSTALL" "$LINENO" 5
7603 as_fn_error $? "SDL_image headers are required. Please see INSTALL" "$LINENO" 5
68197604 fi
68207605
68217606
68237608 if test "x$ac_cv_header_pcre_h" = xyes; then :
68247609
68257610 else
6826 as_fn_error $? "pcre.h is required. Please see INSTALL" "$LINENO" 5
7611 as_fn_error $? "PCRE headers are required. Please see INSTALL" "$LINENO" 5
68277612 fi
68287613
68297614
68317616 if test "x$ac_cv_header_GL_glew_h" = xyes; then :
68327617
68337618 else
6834 as_fn_error $? "glew.h is required. Please see INSTALL" "$LINENO" 5
7619 as_fn_error $? "GLEW headers are required. Please see INSTALL" "$LINENO" 5
68357620 fi
68367621
68377622
75008285 # report actual input values of CONFIG_FILES etc. instead of their
75018286 # values after options handling.
75028287 ac_log="
7503 This file was extended by Gource $as_me 0.37, which was
8288 This file was extended by Gource $as_me 0.38, which was
75048289 generated by GNU Autoconf 2.68. Invocation command line was
75058290
75068291 CONFIG_FILES = $CONFIG_FILES
75578342 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
75588343 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
75598344 ac_cs_version="\\
7560 Gource config.status 0.37
8345 Gource config.status 0.38
75618346 configured by $0, generated by GNU Autoconf 2.68,
75628347 with options \\"\$ac_cs_config\\"
75638348
22
33 AC_PREREQ(2.61)
44
5 AC_INIT(Gource, 0.37, [acaudwell@gmail.com])
5 AC_INIT(Gource, 0.38, [acaudwell@gmail.com])
66 AC_CONFIG_SRCDIR([src/main.h])
77
88 AM_INIT_AUTOMAKE([dist-bzip2 foreign subdir-objects])
6363 AC_CHECK_LIB([pcre], [pcre_compile],, AC_MSG_ERROR(PCRE is required. Please see INSTALL))
6464
6565 #GLEW
66 AC_CHECK_LIB(GLEW, glewInit, LIBS="$LIBS -lGLEW", AC_MSG_ERROR([GLEW required. Please see INSTALL]))
66 AC_CHECK_LIB(GLEW, glewInit, LIBS="$LIBS -lGLEW", AC_MSG_ERROR([GLEW is required. Please see INSTALL]))
67
68 #BOOST
69 AX_BOOST_BASE([1.46], , AC_MSG_ERROR(Boost Filesystem >= 1.46 is required. Please see INSTALL))
70 AX_BOOST_SYSTEM
71 AX_BOOST_FILESYSTEM
72
73 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
74 LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB"
75
76 #GLM
77 AC_CHECK_HEADER([glm/glm.hpp],, AC_MSG_ERROR(GLM headers are required. Please see INSTALL))
6778
6879 #Check for required headers
69 AC_CHECK_HEADER([SDL.h],, AC_MSG_ERROR(SDL.h is required. Please see INSTALL))
70 AC_CHECK_HEADER([SDL_image.h],, AC_MSG_ERROR(SDL_image.h is required. Please see INSTALL))
71 AC_CHECK_HEADER([pcre.h],, AC_MSG_ERROR(pcre.h is required. Please see INSTALL))
72 AC_CHECK_HEADER([GL/glew.h],, AC_MSG_ERROR(glew.h is required. Please see INSTALL))
80 AC_CHECK_HEADER([SDL.h],, AC_MSG_ERROR(SDL headers are required. Please see INSTALL))
81 AC_CHECK_HEADER([SDL_image.h],, AC_MSG_ERROR(SDL_image headers are required. Please see INSTALL))
82 AC_CHECK_HEADER([pcre.h],, AC_MSG_ERROR(PCRE headers are required. Please see INSTALL))
83 AC_CHECK_HEADER([GL/glew.h],, AC_MSG_ERROR(GLEW headers are required. Please see INSTALL))
7384
7485 #see if ttf-font-dir option is enabled
7586 AC_ARG_ENABLE(ttf-font-dir,[AS_HELP_STRING([--enable-ttf-font-dir=DIR],[directory containing GNU FreeFont TTF fonts])],[gourcefontdir="$enableval"],[gourcefontdir=""])
data/cursor.png less more
Binary diff not shown
Binary diff not shown
Binary diff not shown
6262
6363 Free UCS scalable fonts is free software; you can redistribute it and/or
6464 modify it under the terms of the GNU General Public License as published
65 by the Free Software Foundation; either version 2 of the License, or
65 by the Free Software Foundation; either version 3 of the License, or
6666 (at your option) any later version.
6767
6868 The fonts are distributed in the hope that they will be useful, but
104104 Steve White <stevan.white@googlemail.com>
105105
106106 Free UCS scalable fonts: http://savannah.gnu.org/projects/freefont/
107 $Id: README,v 1.6 2008/12/25 12:51:41 Stevan_White Exp $
107 $Id: README,v 1.7 2009/01/13 08:43:23 Stevan_White Exp $
1616 Help ('\fB-H\fR' for extended help).
1717 .TP
1818 \fB\-WIDTHxHEIGHT, \-\-viewport WIDTHxHEIGHT\fR
19 Set the viewport size. If \-f is also supplied, will attempt to set the video mode to this also.
19 Set the viewport size. If \-f is also supplied, will attempt to set the video mode to this also. Add ! to make the window non-resizable.
2020 .TP
2121 \fB\-f\fR
2222 Fullscreen
7070 Set a title
7171 .TP
7272 \fB\-\-font\-size SIZE\fR
73 Font size.
73 Font size used by the date and title.
7474 .TP
7575 \fB\-\-font\-colour FFFFFF\fR
76 Font colour in hex.
76 Font colour used by the date and title in hex.
7777 .TP
7878 \fB\-\-key\fR
7979 Show file extension key.
9999 \fB\-\-follow\-user USER\fR
100100 Have the camera automatically follow a particular user.
101101 .TP
102 \fB\-\-highlight\-dirs\fR
103 Highlight the names of all directories.
104 .TP
102105 \fB\-\-highlight\-user USER\fR
103106 Highlight the names of a particular user.
104107 .TP
105108 \fB\-\-highlight\-users\fR
106109 Highlight the names of all users.
107110 .TP
108 \fB\-\-highlight\-dirs\fR
109 Highlight the names of all directories.
110 .TP
111111 \fB\-\-highlight\-colour FFFFFF\fR
112 Highlighted text colour in hex.
112 Font colour for highlighted users in hex.
113 .TP
114 \fB\-\-selection\-colour FFFFFF\fR
115 Font colour for selected users and files.
116 .TP
117 \fB\-\-dir\-colour FFFFFF\fR
118 Font colour for directories.
113119 .TP
114120 \fB\-\-file\-extensions\fR
115121 Show filename extensions only.
157163 Max speed users can travel per second.
158164 .TP
159165 \fB\-\-user\-friction SECONDS\fR
160 Time users come to a complete hault.
166 Time users take to come to a halt.
161167 .TP
162168 \fB\-\-user\-scale SCALE\fR
163169 Change scale of users.
212218 \fBpath\fR
213219 Either a supported version control directory, a pre-generated log file (see log commands or the custom log format), a Gource conf file or '-' to read STDIN.
214220
215 If path is ommited, gource will attempt to read a log from the current directory.
221 If path is omitted, gource will attempt to read a log from the current directory.
216222
217223 .SH GIT, BAZAAR, MERCURIAL AND SVN EXAMPLES
218224
219 View the log of the respository in the current path:
225 View the log of the repository in the current path:
220226
221227 .ti 10
222228 \fIgource\fR
285291 .SH INTERFACE
286292 The time shown in the top left of the screen is set initially from the first log entry read and is incremented according to the simulation speed (\-\-seconds\-per\-day).
287293
288 Pressing SPACE at any time will pause/unpause the simulation. While paused you may use the mouse to inspect the detail of individual files and users.
294 Pressing SPACE at any time will pause/resume the simulation. While paused you may use the mouse to inspect the detail of individual files and users.
289295
290296 TAB cycles through selecting the current visible users.
291297
data/no_photo.png less more
Binary diff not shown
88
99 float combined_alpha = 1.0 - (1.0-shadow_alpha)*(1.0-colour_alpha);
1010
11 gl_FragColor = gl_Color * vec4(vec3(colour_alpha / combined_alpha), combined_alpha);
11 if(combined_alpha > 0.0) colour_alpha /= combined_alpha;
12
13 gl_FragColor = gl_Color * vec4(vec3(colour_alpha), combined_alpha);
1214 }
Binary diff not shown
3131 <Add library="glu32" />
3232 <Add library="glew32" />
3333 <Add library="freetype" />
34 <Add library="boost_filesystem-mgw46-mt-1_48" />
35 <Add library="libboost_system-mgw46-mt-1_48" />
3436 </Linker>
3537 <Unit filename="data\shaders\bloom.frag" />
3638 <Unit filename="data\shaders\bloom.vert" />
4042 <Unit filename="data\shaders\text.vert" />
4143 <Unit filename="src\action.cpp" />
4244 <Unit filename="src\action.h" />
43 <Unit filename="src\apache.cpp" />
44 <Unit filename="src\apache.h" />
4545 <Unit filename="src\bloom.cpp" />
4646 <Unit filename="src\bloom.h" />
47 <Unit filename="src\bzr.cpp" />
48 <Unit filename="src\bzr.h" />
49 <Unit filename="src\commitlog.cpp" />
50 <Unit filename="src\commitlog.h" />
5147 <Unit filename="src\core\bounds.h" />
52 <Unit filename="src\core\camera.cpp" />
53 <Unit filename="src\core\camera.h" />
5448 <Unit filename="src\core\conffile.cpp" />
5549 <Unit filename="src\core\conffile.h" />
5650 <Unit filename="src\core\display.cpp" />
8983 <Unit filename="src\core\texture.h" />
9084 <Unit filename="src\core\vbo.cpp" />
9185 <Unit filename="src\core\vbo.h" />
86 <Unit filename="src\core\vectors.cpp" />
9287 <Unit filename="src\core\vectors.h" />
93 <Unit filename="src\custom.cpp" />
94 <Unit filename="src\custom.h" />
95 <Unit filename="src\cvs-exp.cpp" />
96 <Unit filename="src\cvs-exp.h" />
97 <Unit filename="src\cvs2cl.cpp" />
98 <Unit filename="src\cvs2cl.h" />
9988 <Unit filename="src\dirnode.cpp" />
10089 <Unit filename="src\dirnode.h" />
10190 <Unit filename="src\file.cpp" />
10291 <Unit filename="src\file.h" />
103 <Unit filename="src\git.cpp" />
104 <Unit filename="src\git.h" />
105 <Unit filename="src\gitraw.cpp" />
106 <Unit filename="src\gitraw.h" />
92 <Unit filename="src\formats\apache.cpp" />
93 <Unit filename="src\formats\apache.h" />
94 <Unit filename="src\formats\bzr.cpp" />
95 <Unit filename="src\formats\bzr.h" />
96 <Unit filename="src\formats\commitlog.cpp" />
97 <Unit filename="src\formats\commitlog.h" />
98 <Unit filename="src\formats\custom.cpp" />
99 <Unit filename="src\formats\custom.h" />
100 <Unit filename="src\formats\cvs-exp.cpp" />
101 <Unit filename="src\formats\cvs-exp.h" />
102 <Unit filename="src\formats\cvs2cl.cpp" />
103 <Unit filename="src\formats\cvs2cl.h" />
104 <Unit filename="src\formats\git.cpp" />
105 <Unit filename="src\formats\git.h" />
106 <Unit filename="src\formats\gitraw.cpp" />
107 <Unit filename="src\formats\gitraw.h" />
108 <Unit filename="src\formats\hg.cpp" />
109 <Unit filename="src\formats\hg.h" />
110 <Unit filename="src\formats\svn.cpp" />
111 <Unit filename="src\formats\svn.h" />
107112 <Unit filename="src\gource.cpp" />
108113 <Unit filename="src\gource.h" />
109114 <Unit filename="src\gource_settings.cpp" />
110115 <Unit filename="src\gource_settings.h" />
111116 <Unit filename="src\gource_shell.cpp" />
112117 <Unit filename="src\gource_shell.h" />
113 <Unit filename="src\hg.cpp" />
114 <Unit filename="src\hg.h" />
115118 <Unit filename="src\key.cpp" />
116119 <Unit filename="src\key.h" />
120 <Unit filename="src\logmill.cpp" />
121 <Unit filename="src\logmill.h" />
117122 <Unit filename="src\main.cpp" />
118123 <Unit filename="src\main.h" />
119124 <Unit filename="src\pawn.cpp" />
122127 <Unit filename="src\slider.h" />
123128 <Unit filename="src\spline.cpp" />
124129 <Unit filename="src\spline.h" />
125 <Unit filename="src\svn.cpp" />
126 <Unit filename="src\svn.h" />
127130 <Unit filename="src\textbox.cpp" />
128131 <Unit filename="src\textbox.h" />
129132 <Unit filename="src\tinyxml\tinystr.cpp" />
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_boost_base.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
7 #
8 # DESCRIPTION
9 #
10 # Test for the Boost C++ libraries of a particular version (or newer)
11 #
12 # If no path to the installed boost library is given the macro searchs
13 # under /usr, /usr/local, /opt and /opt/local and evaluates the
14 # $BOOST_ROOT environment variable. Further documentation is available at
15 # <http://randspringer.de/boost/index.html>.
16 #
17 # This macro calls:
18 #
19 # AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
20 #
21 # And sets:
22 #
23 # HAVE_BOOST
24 #
25 # LICENSE
26 #
27 # Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
28 # Copyright (c) 2009 Peter Adolphs
29 #
30 # Copying and distribution of this file, with or without modification, are
31 # permitted in any medium without royalty provided the copyright notice
32 # and this notice are preserved. This file is offered as-is, without any
33 # warranty.
34
35 #serial 20
36
37 AC_DEFUN([AX_BOOST_BASE],
38 [
39 AC_ARG_WITH([boost],
40 [AS_HELP_STRING([--with-boost@<:@=ARG@:>@],
41 [use Boost library from a standard location (ARG=yes),
42 from the specified location (ARG=<path>),
43 or disable it (ARG=no)
44 @<:@ARG=yes@:>@ ])],
45 [
46 if test "$withval" = "no"; then
47 want_boost="no"
48 elif test "$withval" = "yes"; then
49 want_boost="yes"
50 ac_boost_path=""
51 else
52 want_boost="yes"
53 ac_boost_path="$withval"
54 fi
55 ],
56 [want_boost="yes"])
57
58
59 AC_ARG_WITH([boost-libdir],
60 AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
61 [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
62 [
63 if test -d "$withval"
64 then
65 ac_boost_lib_path="$withval"
66 else
67 AC_MSG_ERROR(--with-boost-libdir expected directory name)
68 fi
69 ],
70 [ac_boost_lib_path=""]
71 )
72
73 if test "x$want_boost" = "xyes"; then
74 boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
75 boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
76 boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
77 boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
78 boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
79 if test "x$boost_lib_version_req_sub_minor" = "x" ; then
80 boost_lib_version_req_sub_minor="0"
81 fi
82 WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
83 AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
84 succeeded=no
85
86 dnl On 64-bit systems check for system libraries in both lib64 and lib.
87 dnl The former is specified by FHS, but e.g. Debian does not adhere to
88 dnl this (as it rises problems for generic multi-arch support).
89 dnl The last entry in the list is chosen by default when no libraries
90 dnl are found, e.g. when only header-only libraries are installed!
91 libsubdirs="lib"
92 ax_arch=`uname -m`
93 if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then
94 libsubdirs="lib64 lib lib64"
95 fi
96
97 dnl first we check the system location for boost libraries
98 dnl this location ist chosen if boost libraries are installed with the --layout=system option
99 dnl or if you install boost with RPM
100 if test "$ac_boost_path" != ""; then
101 BOOST_CPPFLAGS="-I$ac_boost_path/include"
102 for ac_boost_path_tmp in $libsubdirs; do
103 if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then
104 BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp"
105 break
106 fi
107 done
108 elif test "$cross_compiling" != yes; then
109 for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
110 if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
111 for libsubdir in $libsubdirs ; do
112 if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
113 done
114 BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir"
115 BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
116 break;
117 fi
118 done
119 fi
120
121 dnl overwrite ld flags if we have required special directory with
122 dnl --with-boost-libdir parameter
123 if test "$ac_boost_lib_path" != ""; then
124 BOOST_LDFLAGS="-L$ac_boost_lib_path"
125 fi
126
127 CPPFLAGS_SAVED="$CPPFLAGS"
128 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
129 export CPPFLAGS
130
131 LDFLAGS_SAVED="$LDFLAGS"
132 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
133 export LDFLAGS
134
135 AC_REQUIRE([AC_PROG_CXX])
136 AC_LANG_PUSH(C++)
137 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
138 @%:@include <boost/version.hpp>
139 ]], [[
140 #if BOOST_VERSION >= $WANT_BOOST_VERSION
141 // Everything is okay
142 #else
143 # error Boost version is too old
144 #endif
145 ]])],[
146 AC_MSG_RESULT(yes)
147 succeeded=yes
148 found_system=yes
149 ],[
150 ])
151 AC_LANG_POP([C++])
152
153
154
155 dnl if we found no boost with system layout we search for boost libraries
156 dnl built and installed without the --layout=system option or for a staged(not installed) version
157 if test "x$succeeded" != "xyes"; then
158 _version=0
159 if test "$ac_boost_path" != ""; then
160 if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
161 for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
162 _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
163 V_CHECK=`expr $_version_tmp \> $_version`
164 if test "$V_CHECK" = "1" ; then
165 _version=$_version_tmp
166 fi
167 VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
168 BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
169 done
170 fi
171 else
172 if test "$cross_compiling" != yes; then
173 for ac_boost_path in /usr /usr/local /opt /opt/local ; do
174 if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
175 for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
176 _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
177 V_CHECK=`expr $_version_tmp \> $_version`
178 if test "$V_CHECK" = "1" ; then
179 _version=$_version_tmp
180 best_path=$ac_boost_path
181 fi
182 done
183 fi
184 done
185
186 VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
187 BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
188 if test "$ac_boost_lib_path" = ""; then
189 for libsubdir in $libsubdirs ; do
190 if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
191 done
192 BOOST_LDFLAGS="-L$best_path/$libsubdir"
193 fi
194 fi
195
196 if test "x$BOOST_ROOT" != "x"; then
197 for libsubdir in $libsubdirs ; do
198 if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
199 done
200 if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then
201 version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
202 stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
203 stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
204 V_CHECK=`expr $stage_version_shorten \>\= $_version`
205 if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
206 AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
207 BOOST_CPPFLAGS="-I$BOOST_ROOT"
208 BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
209 fi
210 fi
211 fi
212 fi
213
214 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
215 export CPPFLAGS
216 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
217 export LDFLAGS
218
219 AC_LANG_PUSH(C++)
220 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
221 @%:@include <boost/version.hpp>
222 ]], [[
223 #if BOOST_VERSION >= $WANT_BOOST_VERSION
224 // Everything is okay
225 #else
226 # error Boost version is too old
227 #endif
228 ]])],[
229 AC_MSG_RESULT(yes)
230 succeeded=yes
231 found_system=yes
232 ],[
233 ])
234 AC_LANG_POP([C++])
235 fi
236
237 if test "$succeeded" != "yes" ; then
238 if test "$_version" = "0" ; then
239 AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
240 else
241 AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
242 fi
243 # execute ACTION-IF-NOT-FOUND (if present):
244 ifelse([$3], , :, [$3])
245 else
246 AC_SUBST(BOOST_CPPFLAGS)
247 AC_SUBST(BOOST_LDFLAGS)
248 AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
249 # execute ACTION-IF-FOUND (if present):
250 ifelse([$2], , :, [$2])
251 fi
252
253 CPPFLAGS="$CPPFLAGS_SAVED"
254 LDFLAGS="$LDFLAGS_SAVED"
255 fi
256
257 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_BOOST_FILESYSTEM
7 #
8 # DESCRIPTION
9 #
10 # Test for Filesystem library from the Boost C++ libraries. The macro
11 # requires a preceding call to AX_BOOST_BASE. Further documentation is
12 # available at <http://randspringer.de/boost/index.html>.
13 #
14 # This macro calls:
15 #
16 # AC_SUBST(BOOST_FILESYSTEM_LIB)
17 #
18 # And sets:
19 #
20 # HAVE_BOOST_FILESYSTEM
21 #
22 # LICENSE
23 #
24 # Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
25 # Copyright (c) 2009 Michael Tindal
26 # Copyright (c) 2009 Roman Rybalko <libtorrent@romanr.info>
27 #
28 # Copying and distribution of this file, with or without modification, are
29 # permitted in any medium without royalty provided the copyright notice
30 # and this notice are preserved. This file is offered as-is, without any
31 # warranty.
32
33 #serial 22
34
35 AC_DEFUN([AX_BOOST_FILESYSTEM],
36 [
37 AC_ARG_WITH([boost-filesystem],
38 AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@],
39 [use the Filesystem library from boost - it is possible to specify a certain library for the linker
40 e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]),
41 [
42 if test "$withval" = "no"; then
43 want_boost="no"
44 elif test "$withval" = "yes"; then
45 want_boost="yes"
46 ax_boost_user_filesystem_lib=""
47 else
48 want_boost="yes"
49 ax_boost_user_filesystem_lib="$withval"
50 fi
51 ],
52 [want_boost="yes"]
53 )
54
55 if test "x$want_boost" = "xyes"; then
56 AC_REQUIRE([AC_PROG_CC])
57 CPPFLAGS_SAVED="$CPPFLAGS"
58 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
59 export CPPFLAGS
60
61 LDFLAGS_SAVED="$LDFLAGS"
62 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
63 export LDFLAGS
64
65 LIBS_SAVED=$LIBS
66 LIBS="$LIBS $BOOST_SYSTEM_LIB"
67 export LIBS
68
69 AC_CACHE_CHECK(whether the Boost::Filesystem library is available,
70 ax_cv_boost_filesystem,
71 [AC_LANG_PUSH([C++])
72 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/filesystem/path.hpp>]],
73 [[using namespace boost::filesystem;
74 path my_path( "foo/bar/data.txt" );
75 return 0;]])],
76 ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no)
77 AC_LANG_POP([C++])
78 ])
79 if test "x$ax_cv_boost_filesystem" = "xyes"; then
80 AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available])
81 BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
82 if test "x$ax_boost_user_filesystem_lib" = "x"; then
83 for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.so* $BOOSTLIBDIR/libboost_filesystem*.dylib* $BOOSTLIBDIR/libboost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib$;\1;'` ; do
84 ax_lib=${libextension}
85 AC_CHECK_LIB($ax_lib, exit,
86 [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
87 [link_filesystem="no"])
88 done
89 if test "x$link_filesystem" != "xyes"; then
90 for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a*$;\1;'` ; do
91 ax_lib=${libextension}
92 AC_CHECK_LIB($ax_lib, exit,
93 [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
94 [link_filesystem="no"])
95 done
96 fi
97 else
98 for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do
99 AC_CHECK_LIB($ax_lib, exit,
100 [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
101 [link_filesystem="no"])
102 done
103
104 fi
105 if test "x$ax_lib" = "x"; then
106 AC_MSG_ERROR(Could not find a version of the library!)
107 fi
108 if test "x$link_filesystem" != "xyes"; then
109 AC_MSG_ERROR(Could not link against $ax_lib !)
110 fi
111 fi
112
113 CPPFLAGS="$CPPFLAGS_SAVED"
114 LDFLAGS="$LDFLAGS_SAVED"
115 LIBS="$LIBS_SAVED"
116 fi
117 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_boost_system.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_BOOST_SYSTEM
7 #
8 # DESCRIPTION
9 #
10 # Test for System library from the Boost C++ libraries. The macro requires
11 # a preceding call to AX_BOOST_BASE. Further documentation is available at
12 # <http://randspringer.de/boost/index.html>.
13 #
14 # This macro calls:
15 #
16 # AC_SUBST(BOOST_SYSTEM_LIB)
17 #
18 # And sets:
19 #
20 # HAVE_BOOST_SYSTEM
21 #
22 # LICENSE
23 #
24 # Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
25 # Copyright (c) 2008 Michael Tindal
26 # Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com>
27 #
28 # Copying and distribution of this file, with or without modification, are
29 # permitted in any medium without royalty provided the copyright notice
30 # and this notice are preserved. This file is offered as-is, without any
31 # warranty.
32
33 #serial 14
34
35 AC_DEFUN([AX_BOOST_SYSTEM],
36 [
37 AC_ARG_WITH([boost-system],
38 AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@],
39 [use the System library from boost - it is possible to specify a certain library for the linker
40 e.g. --with-boost-system=boost_system-gcc-mt ]),
41 [
42 if test "$withval" = "no"; then
43 want_boost="no"
44 elif test "$withval" = "yes"; then
45 want_boost="yes"
46 ax_boost_user_system_lib=""
47 else
48 want_boost="yes"
49 ax_boost_user_system_lib="$withval"
50 fi
51 ],
52 [want_boost="yes"]
53 )
54
55 if test "x$want_boost" = "xyes"; then
56 AC_REQUIRE([AC_PROG_CC])
57 AC_REQUIRE([AC_CANONICAL_BUILD])
58 CPPFLAGS_SAVED="$CPPFLAGS"
59 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
60 export CPPFLAGS
61
62 LDFLAGS_SAVED="$LDFLAGS"
63 LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
64 export LDFLAGS
65
66 AC_CACHE_CHECK(whether the Boost::System library is available,
67 ax_cv_boost_system,
68 [AC_LANG_PUSH([C++])
69 CXXFLAGS_SAVE=$CXXFLAGS
70
71 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
72 [[boost::system::system_category]])],
73 ax_cv_boost_system=yes, ax_cv_boost_system=no)
74 CXXFLAGS=$CXXFLAGS_SAVE
75 AC_LANG_POP([C++])
76 ])
77 if test "x$ax_cv_boost_system" = "xyes"; then
78 AC_SUBST(BOOST_CPPFLAGS)
79
80 AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available])
81 BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
82
83 LDFLAGS_SAVE=$LDFLAGS
84 if test "x$ax_boost_user_system_lib" = "x"; then
85 for libextension in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;'` ; do
86 ax_lib=${libextension}
87 AC_CHECK_LIB($ax_lib, exit,
88 [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
89 [link_system="no"])
90 done
91 if test "x$link_system" != "xyes"; then
92 for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do
93 ax_lib=${libextension}
94 AC_CHECK_LIB($ax_lib, exit,
95 [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
96 [link_system="no"])
97 done
98 fi
99
100 else
101 for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
102 AC_CHECK_LIB($ax_lib, exit,
103 [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
104 [link_system="no"])
105 done
106
107 fi
108 if test "x$ax_lib" = "x"; then
109 AC_MSG_ERROR(Could not find a version of the library!)
110 fi
111 if test "x$link_system" = "xno"; then
112 AC_MSG_ERROR(Could not link against $ax_lib !)
113 fi
114 fi
115
116 CPPFLAGS="$CPPFLAGS_SAVED"
117 LDFLAGS="$LDFLAGS_SAVED"
118 fi
119 ])
4141 void RAction::drawToVBO(quadbuf& buffer) const {
4242 if(isFinished()) return;
4343
44 vec2f src = source->getPos();
45 vec2f dest = target->getAbsolutePos();
44 vec2 src = source->getPos();
45 vec2 dest = target->getAbsolutePos();
4646
47 vec2f offset = (dest - src).normal().perpendicular() * target->getSize() * 0.5;
48 vec2f offset_src = offset * 0.3f;
47 //TODO: could use glm::perp
48
49 vec2 n = normalise(dest - src);
50 vec2 perp = vec2(-n.y, n.x);
51
52 vec2 offset = perp * target->getSize() * 0.5f;
53 vec2 offset_src = offset * 0.3f;
4954
5055 float alpha = 1.0 - progress;
5156 float alpha2 = alpha * 0.1;
5257
53 vec4f col1 = vec4f(colour, alpha);
54 vec4f col2 = vec4f(colour, alpha2);
58 vec4 col1 = vec4(colour, alpha);
59 vec4 col2 = vec4(colour, alpha2);
5560
56 quadbuf_vertex v1(src - offset_src, col2, vec2f(0.0f, 0.0f));
57 quadbuf_vertex v2(src + offset_src, col2, vec2f(0.0f, 1.0f));
58 quadbuf_vertex v3(dest + offset, col1, vec2f(1.0f, 1.0f));
59 quadbuf_vertex v4(dest - offset, col1, vec2f(1.0f, 0.0f));
61 quadbuf_vertex v1(src - offset_src, col2, vec2(0.0f, 0.0f));
62 quadbuf_vertex v2(src + offset_src, col2, vec2(0.0f, 1.0f));
63 quadbuf_vertex v3(dest + offset, col1, vec2(1.0f, 1.0f));
64 quadbuf_vertex v4(dest - offset, col1, vec2(1.0f, 0.0f));
6065
6166 buffer.add(0, v1, v2, v3, v4);
6267 }
6469 void RAction::draw(float dt) {
6570 if(isFinished()) return;
6671
67 vec2f src = source->getPos();
68 vec2f dest = target->getAbsolutePos();
72 vec2 src = source->getPos();
73 vec2 dest = target->getAbsolutePos();
6974
70 vec2f offset = (dest - src).normal().perpendicular() * target->getSize() * 0.5;
71 vec2f offset_src = offset * 0.3f;
75 vec2 n = normalise(dest - src);
76 vec2 perp = vec2(-n.y, n.x);
77
78 vec2 offset = perp * target->getSize() * 0.5f;
79 vec2 offset_src = offset * 0.3f;
7280
7381 float alpha = 1.0 - progress;
7482 float alpha2 = alpha * 0.1;
7583
76 vec4f col1 = vec4f(colour, alpha);
77 vec4f col2 = vec4f(colour, alpha2);
84 vec4 col1 = vec4(colour, alpha);
85 vec4 col2 = vec4(colour, alpha2);
7886
7987 glBegin(GL_QUADS);
80 glColor4fv(col2);
88 glColor4fv(glm::value_ptr(col2));
8189 glTexCoord2f(0.0,0.0);
8290 glVertex2f(src.x - offset_src.x, src.y - offset_src.y);
8391 glTexCoord2f(0.0,1.0);
8492 glVertex2f(src.x + offset_src.x, src.y + offset_src.y);
8593
86 glColor4fv(col1);
94 glColor4fv(glm::value_ptr(col1));
8795 glTexCoord2f(1.0,1.0);
8896 glVertex2f(dest.x + offset.x, dest.y + offset.y);
8997 glTexCoord2f(1.0,0.0);
92100 }
93101
94102 CreateAction::CreateAction(RUser* source, RFile* target, float addedtime) : RAction(source, target, addedtime) {
95 colour = vec3f(0.0, 1.0, 0.0);
103 colour = vec3(0.0, 1.0, 0.0);
96104 }
97105
98106 RemoveAction::RemoveAction(RUser* source, RFile* target, float addedtime): RAction(source, target, addedtime) {
99 colour = vec3f(1.0, 0.0, 0.0);
107 colour = vec3(1.0, 0.0, 0.0);
100108 }
101109
102110 void RemoveAction::logic(float dt) {
110118 }
111119
112120 ModifyAction::ModifyAction(RUser* source, RFile* target, float addedtime) : RAction(source, target, addedtime) {
113 colour = vec3f(1.0, 0.7, 0.3);
121 colour = vec3(1.0, 0.7, 0.3);
114122 }
2525
2626 class RAction {
2727 protected:
28 vec3f colour;
28 vec3 colour;
2929 public:
3030 RUser* source;
3131 RFile* target;
+0
-136
src/apache.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "apache.h"
18
19 const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug" , "Sep", "Oct", "Nov", "Dec" };
20 Regex apache_entry_start("^(?:[^ ]+ )?([^ ]+) +[^ ]+ +([^ ]+) +\\[(.*?)\\] +(.*)$");
21 Regex apache_entry_date("(\\d+)/([A-Za-z]+)/(\\d+):(\\d+):(\\d+):(\\d+) ([+-])(\\d+)");
22 Regex apache_entry_request("\"([^ ]+) +([^ ]+) +([^ ]+)\" +([^ ]+) +([^\\s+]+)(.*)");
23 Regex apache_entry_agent(" +\"([^\"]+)\" +\"([^\"]+)\" +\"([^\"]+)\"");
24 Regex apache_hostname_parts("([^.]+)(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?$");
25
26 ApacheCombinedLog::ApacheCombinedLog(const std::string& logfile) : RCommitLog(logfile) {
27 }
28
29 //parse apache access.log entry into components
30 bool ApacheCombinedLog::parseCommit(RCommit& commit) {
31
32 std::string line;
33 std::vector<std::string> matches;
34
35 if(!logf->getNextLine(line)) return false;
36
37 apache_entry_start.match(line, &matches);
38
39 if(matches.size()!=4) {
40 return 0;
41 }
42
43 //get details
44 commit.username = matches[0];
45 //std::string user = matches[1];
46
47 //parse timestamp
48 struct tm time_str;
49
50 std::string request_str = matches[3];
51 std::string datestr = matches[2];
52
53 apache_entry_date.match(datestr, &matches);
54
55 if(matches.size()!=8) {
56 return 0;
57 }
58
59 int day = atoi(matches[0].c_str());
60 int year = atoi(matches[2].c_str());
61 int hour = atoi(matches[3].c_str());
62 int minute = atoi(matches[4].c_str());
63 int second = atoi(matches[5].c_str());
64
65 // int zone = atoi(matches[7].c_str());
66 //negative timezone
67 // if(strcmp(matches[6].c_str(), "-")==0) {
68 // zone = -zone;
69 // }
70
71 int month=0;
72
73 for(int i=0;i<12;i++) {
74 if(matches[1] == months[i]) {
75 month=i;
76 break;
77 }
78 }
79
80 time_str.tm_year = year - 1900;
81 time_str.tm_mon = month;
82 time_str.tm_mday = day;
83 time_str.tm_hour = hour;
84 time_str.tm_min = minute;
85 time_str.tm_sec = second;
86 time_str.tm_isdst = -1;
87
88 commit.timestamp = mktime(&time_str);
89
90 matches.clear();
91 apache_entry_request.match(request_str, &matches);
92
93 if(matches.size() < 5) {
94 return false;
95 }
96
97 std::string rtype = matches[0];
98 std::string file = matches[1];
99 std::string proto = matches[2];
100
101 int code = atoi(matches[3].c_str());
102 int bytes = atol(matches[4].c_str());
103
104 //remove args from url
105 size_t argpos = file.rfind("?");
106 if(argpos != std::string::npos) {
107 file = file.substr(0,argpos);
108 }
109
110 if(file.size()==0) file = "/";
111
112 //name index pages
113 if(file[file.size()-1] == '/') {
114 file += "index.html";
115 }
116
117 std::string action = "A";
118 commit.addFile(file, action);
119
120 std::string refer;
121 std::string agent;
122
123 if(matches.size() > 5) {
124 std::string agentstr = matches[5];
125 matches.clear();
126 apache_entry_agent.match(agentstr, &matches);
127
128 if(matches.size()>1) {
129 refer = matches[0];
130 agent = matches[1];
131 }
132 }
133
134 return true;
135 }
+0
-37
src/apache.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GOURCE_APACHE_H
18 #define GOURCE_APACHE_H
19
20 #include <string>
21 #include <string.h>
22
23 #include <vector>
24 #include <time.h>
25
26 #include "commitlog.h"
27
28 class ApacheCombinedLog : public RCommitLog {
29 protected:
30 bool parseCommit(RCommit& commit);
31 BaseLog* generateLog(const std::string& dir);
32 public:
33 ApacheCombinedLog(const std::string& logfile);
34 };
35
36 #endif
5252 vertex_count = 0;
5353 }
5454
55 void bloombuf::unload() {
56 if(bufferid !=0) glDeleteBuffers(1, &bufferid);
57 bufferid = 0;
58 buffer_size = 0;
59 }
60
5561 size_t bloombuf::vertices() {
5662 return vertex_count;
5763 }
6066 return data_size;
6167 }
6268
63 void bloombuf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord) {
69 void bloombuf::add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord) {
6470
6571 bloom_vertex v1(pos, colour, texcoord);
66 bloom_vertex v2(pos + vec2f(dims.x, 0.0f), colour, texcoord);
72 bloom_vertex v2(pos + vec2(dims.x, 0.0f), colour, texcoord);
6773 bloom_vertex v3(pos + dims, colour, texcoord);
68 bloom_vertex v4(pos + vec2f(0.0f, dims.y), colour, texcoord);
74 bloom_vertex v4(pos + vec2(0.0f, dims.y), colour, texcoord);
6975
7076 int i = vertex_count;
7177
2727 class bloom_vertex {
2828 public:
2929 bloom_vertex() {};
30 bloom_vertex(const vec2f& pos, const vec4f& colour, const vec4f& texcoord) :
30 bloom_vertex(const vec2& pos, const vec4& colour, const vec4& texcoord) :
3131 pos(pos), colour(colour), texcoord(texcoord) {};
3232
33 vec2f pos;
34 vec4f colour;
35 vec4f texcoord;
33 vec2 pos;
34 vec4 colour;
35 vec4 texcoord;
3636 char padding[24];
3737 };
3838
5151 bloombuf(int data_size = 0);
5252 ~bloombuf();
5353
54 void unload();
5455 void reset();
5556
5657 size_t vertices();
5758 size_t capacity();
5859
59 void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord);
60 void add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord);
6061
6162 void update();
6263 void draw();
+0
-111
src/bzr.cpp less more
0 /*
1 Copyright (C) 2010 John Arbash Meinel <john@arbash-meinel.com>
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "bzr.h"
18
19 Regex bzr_commit_regex("^ *([\\d.]+) (.+)\t(\\d{4})-(\\d+)-(\\d+)(?: \\{[^}]+})?(?: \\[merge\\])?$");
20 Regex bzr_file_regex("^ *([AMDR]) (.*[^/])$");
21
22 // parse Bazaar log entries (using the gource.style template)
23
24 std::string gGourceBzrLogCommand() {
25 return std::string("bzr log --verbose -r 1..-1 --short -n0 --forward");
26 }
27
28 BazaarLog::BazaarLog(const std::string& logfile) : RCommitLog(logfile) {
29
30 log_command = gGourceBzrLogCommand();
31
32 //can generate log from directory
33 if(!logf && is_dir) {
34 logf = generateLog(logfile);
35
36 if(logf) {
37 success = true;
38 seekable = true;
39 }
40 }
41 }
42
43 BaseLog* BazaarLog::generateLog(const std::string& dir) {
44
45 //does directory have a .bzr ?
46 std::string bzrdir = dir + std::string("/.bzr");
47 struct stat dirinfo;
48 int stat_rc = stat(bzrdir.c_str(), &dirinfo);
49 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
50 return 0;
51 }
52
53 std::string command = getLogCommand();
54
55 createTempLog();
56
57 if(temp_file.size()==0) return 0;
58
59 char cmd_buff[2048];
60 sprintf(cmd_buff, "%s %s > %s", command.c_str(), dir.c_str(), temp_file.c_str());
61
62 int command_rc = system(cmd_buff);
63
64 if(command_rc != 0) {
65 return 0;
66 }
67
68 BaseLog* seeklog = new SeekLog(temp_file);
69
70 return seeklog;
71 }
72
73 bool BazaarLog::parseCommit(RCommit& commit) {
74
75 std::string line;
76 std::vector<std::string> entries;
77 int year, month, day;
78
79 if(!logf->getNextLine(line)) return false;
80
81 debugLog("read %s\n", line.c_str());
82 if (!bzr_commit_regex.match(line, &entries)) {
83 debugLog("regex failed\n");
84 return false;
85 }
86 commit.username = entries[1];
87
88 year = atoi(entries[2].c_str());
89 month = atoi(entries[3].c_str());
90 day = atoi(entries[4].c_str());
91
92 struct tm time_str;
93
94 time_str.tm_year = year - 1900;
95 time_str.tm_mon = month - 1;
96 time_str.tm_mday = day;
97 time_str.tm_hour = 0;
98 time_str.tm_min = 0;
99 time_str.tm_sec = 0;
100 time_str.tm_isdst = -1;
101
102 commit.timestamp = mktime(&time_str);
103
104 while(logf->getNextLine(line) && line.size()) {
105 if (!bzr_file_regex.match(line, &entries)) continue;
106 commit.addFile(entries[1], entries[0]);
107 }
108
109 return true;
110 }
+0
-34
src/bzr.h less more
0 /*
1 Copyright (C) 2010 John Arbash Meinel <john@arbash-meinel.com>
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef BAZAARLOG_H
18 #define BAZAARLOG_H
19
20 #include "commitlog.h"
21
22 std::string gGourceBzrLogCommand();
23
24 class BazaarLog : public RCommitLog {
25 protected:
26 bool parseCommit(RCommit& commit);
27 BaseLog* generateLog(const std::string& dir);
28 public:
29 BazaarLog(const std::string& logfile);
30 };
31
32 #endif
33
+0
-298
src/commitlog.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "commitlog.h"
18
19 std::string munge_utf8(const std::string& str) {
20
21 std::string munged;
22 try {
23 utf8::replace_invalid(str.begin(), str.end(), back_inserter(munged), '?');
24 }
25 catch(...) {
26 munged = "???";
27 }
28
29 return munged;
30 }
31
32 //RCommitLog
33
34 RCommitLog::RCommitLog(const std::string& logfile, int firstChar) {
35
36 logf = 0;
37 seekable = false;
38 success = false;
39 is_dir = false;
40 buffered = false;
41
42 if(logfile == "-") {
43
44 //check first char
45 if(checkFirstChar(firstChar, std::cin)) {
46 logf = new StreamLog();
47 is_dir = false;
48 seekable = false;
49 success = true;
50 }
51
52 return;
53 }
54
55 struct stat fileinfo;
56 int rc = stat(logfile.c_str(), &fileinfo);
57
58 if(rc==0) {
59 is_dir = (fileinfo.st_mode & S_IFDIR) ? true : false;
60
61 if(!is_dir) {
62
63 //check first char
64 std::ifstream testf(logfile.c_str());
65
66 bool firstOK = checkFirstChar(firstChar, testf);
67
68 testf.close();
69
70 if(firstOK) {
71 logf = new SeekLog(logfile);
72 seekable = true;
73 success = true;
74 }
75 }
76 }
77 }
78
79 RCommitLog::~RCommitLog() {
80 if(logf!=0) delete logf;
81
82 if(!temp_file.empty()) {
83 remove(temp_file.c_str());
84 }
85 }
86
87 //check firstChar of stream is as expected. if no firstChar defined just returns true.
88 bool RCommitLog::checkFirstChar(int firstChar, std::istream& stream) {
89
90 //cant check this
91 if(firstChar == -1) return true;
92
93 int c = stream.peek();
94
95 if(firstChar == c) return true;
96
97 return false;
98 }
99
100 bool RCommitLog::checkFormat() {
101
102 if(!success) return false;
103
104 //read a commit to see if the log is in the correct format
105 if(nextCommit(lastCommit)) {
106
107 if(seekable) {
108 //if the log is seekable, go back to the start
109 ((SeekLog*)logf)->seekTo(0.0);
110 } else {
111 //otherwise set the buffered flag as we have bufferd one commit
112 buffered = true;
113 }
114
115 return true;
116 }
117
118 return false;
119 }
120
121 std::string RCommitLog::getLogCommand() {
122 return log_command;
123 }
124
125 bool RCommitLog::isSeekable() {
126 return seekable;
127 }
128
129 bool RCommitLog::getCommitAt(float percent, RCommit& commit) {
130 if(!seekable) return false;
131
132 SeekLog* seeklog = ((SeekLog*)logf);
133
134 //save settings
135 long currpointer = seeklog->getPointer();
136 std::string currlastline = lastline;
137
138 seekTo(percent);
139 bool success = findNextCommit(commit,500);
140
141 //restore settings
142 seeklog->setPointer(currpointer);
143 lastline = currlastline;
144
145 return success;
146 }
147
148 bool RCommitLog::getNextLine(std::string& line) {
149 if(!lastline.empty()) {
150 line = lastline;
151 lastline = std::string("");
152 return true;
153 }
154
155 return logf->getNextLine(line);
156 }
157
158
159 void RCommitLog::seekTo(float percent) {
160 if(!seekable) return;
161
162 lastline = "";
163
164 ((SeekLog*)logf)->seekTo(percent);
165 }
166
167 float RCommitLog::getPercent() {
168 if(seekable) return ((SeekLog*)logf)->getPercent();
169
170 return 0.0;
171 }
172
173 bool RCommitLog::findNextCommit(RCommit& commit, int attempts) {
174
175 for(int i=0;i<attempts;i++) {
176 RCommit c;
177
178 if(nextCommit(c)) {
179 commit = c;
180 return true;
181 }
182 }
183
184 return false;
185 }
186
187 bool RCommitLog::nextCommit(RCommit& commit) {
188
189 if(buffered) {
190 commit = lastCommit;
191 buffered = false;
192 return true;
193 }
194
195 bool success = parseCommit(commit);
196
197 if(!success) return false;
198
199 return commit.isValid();
200 }
201
202 bool RCommitLog::isFinished() {
203 if(seekable && logf->isFinished()) return true;
204
205 return false;
206 }
207
208 //create temp file
209 void RCommitLog::createTempLog() {
210
211 std::string tempdir;
212
213 #ifdef _WIN32
214 DWORD tmplen = GetTempPath(0, "");
215
216 if(tmplen == 0) return;
217
218 std::vector<TCHAR> temp(tmplen+1);
219
220 tmplen = GetTempPath(static_cast<DWORD>(temp.size()), &temp[0]);
221
222 if(tmplen == 0 || tmplen >= temp.size()) return;
223
224 tempdir = std::string(temp.begin(), temp.begin() + static_cast<std::size_t>(tmplen));
225 tempdir += "\\";
226 #else
227 tempdir = "/tmp/";
228 #endif
229
230 char tmplate[1024];
231 snprintf(tmplate, 1024, "%sgource-XXXXXX", tempdir.c_str());
232
233 #ifdef _WIN32
234 if(mktemp(tmplate) < 0) return;
235 #else
236 if(mkstemp(tmplate) < 0) return;
237 #endif
238
239 temp_file = std::string(tmplate);
240 }
241
242 // RCommitFile
243
244 RCommitFile::RCommitFile(const std::string& filename, const std::string& action, vec3f colour) {
245
246 this->filename = munge_utf8(filename);
247
248 //prepend a root slash
249 if(this->filename[0] != '/') {
250 this->filename.insert(0, 1, '/');
251 }
252
253 this->action = action;
254 this->colour = colour;
255 }
256
257 RCommit::RCommit() {
258 timestamp = 0;
259 }
260
261 vec3f RCommit::fileColour(const std::string& filename) {
262
263 size_t slash = filename.rfind('/');
264 size_t dot = filename.rfind('.');
265
266 if(dot != std::string::npos && dot+1<filename.size() && (slash == std::string::npos || slash < dot)) {
267 std::string file_ext = filename.substr(dot+1);
268
269 return colourHash(file_ext);
270 } else {
271 return vec3f(1.0, 1.0, 1.0);
272 }
273 }
274
275 void RCommit::addFile(const std::string& filename, const std::string& action) {
276 files.push_back(RCommitFile(filename, action, fileColour(filename)));
277 }
278
279 void RCommit::addFile(const std::string& filename, const std::string& action, vec3f colour) {
280 files.push_back(RCommitFile(filename, action, colour));
281 }
282
283 bool RCommit::isValid() {
284
285 username = munge_utf8(username);
286
287 return true;
288 }
289
290 void RCommit::debug() {
291 debugLog("files:\n");
292
293 for(std::list<RCommitFile>::iterator it = files.begin(); it != files.end(); it++) {
294 RCommitFile f = *it;
295 debugLog("%s %s\n", f.action.c_str(), f.filename.c_str());
296 }
297 }
+0
-102
src/commitlog.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef RCOMMIT_LOG_H
18 #define RCOMMIT_LOG_H
19
20
21 #include "core/seeklog.h"
22 #include "core/display.h"
23 #include "core/regex.h"
24 #include "core/stringhash.h"
25 #include "core/utf8/utf8.h"
26
27 #include <time.h>
28 #include <string>
29 #include <list>
30
31 #include "sys/stat.h"
32
33 class RCommitFile {
34 public:
35 std::string filename;
36 std::string action;
37 vec3f colour;
38
39 RCommitFile(const std::string& filename, const std::string& action, vec3f colour);
40 };
41
42 class RCommit {
43 vec3f fileColour(const std::string& filename);
44 public:
45 time_t timestamp;
46 std::string username;
47
48 std::list<RCommitFile> files;
49
50 bool isValid();
51
52 void addFile(const std::string& filename, const std::string& action);
53 void addFile(const std::string& filename, const std::string& action, vec3f colour);
54
55 RCommit();
56 void debug();
57 virtual bool parse(BaseLog* logf) { return false; };
58 };
59
60 class RCommitLog {
61 protected:
62 BaseLog* logf;
63
64 std::string temp_file;
65 std::string log_command;
66
67 std::string lastline;
68
69 bool is_dir;
70 bool success;
71 bool seekable;
72
73 RCommit lastCommit;
74 bool buffered;
75
76 bool checkFirstChar(int firstChar, std::istream& stream);
77
78 void createTempLog();
79
80 bool getNextLine(std::string& line);
81
82 virtual bool parseCommit(RCommit& commit) { return false; };
83 public:
84 RCommitLog(const std::string& logfile, int firstChar = -1);
85 ~RCommitLog();
86
87 void seekTo(float percent);
88
89 bool checkFormat();
90
91 std::string getLogCommand();
92
93 bool getCommitAt(float percent, RCommit& commit);
94 bool findNextCommit(RCommit& commit, int attempts);
95 bool nextCommit(RCommit& commit);
96 bool isFinished();
97 bool isSeekable();
98 float getPercent();
99 };
100
101 #endif
3232
3333 class Bounds2D {
3434 public:
35 vec2f min;
36 vec2f max;
35 vec2 min;
36 vec2 max;
3737 bool first;
3838
39 vec2f centre() const {
39 vec2 centre() const {
4040 return min + (max - min) * 0.5f;
4141 }
4242
5353 }
5454
5555 void reset() {
56 min = vec2f(0.0, 0.0);
57 max = vec2f(0.0, 0.0);
56 min = vec2(0.0, 0.0);
57 max = vec2(0.0, 0.0);
5858 first = true;
5959 }
6060
6262 reset();
6363 }
6464
65 Bounds2D(const vec2f& min, const vec2f& max) {
65 Bounds2D(const vec2& min, const vec2& max) {
6666 reset();
6767 update(min);
6868 update(max);
7979 update(bounds);
8080 }
8181
82 void set(vec2f point) {
82 void set(vec2 point) {
8383 reset();
8484 update(point);
8585 }
8686
87 void set(const vec2f& a, const vec2f& b) {
87 void set(const vec2& a, const vec2& b) {
8888 reset();
8989 update(a);
9090 update(b);
9191 }
9292
93 void update(const vec2f& point) {
93 void update(const vec2& point) {
9494 if(first) {
9595 min = point;
9696 max = point;
104104 if(max.y < point.y) max.y = point.y;
105105 }
106106
107 bool contains(const vec2f& point) const {
107 bool contains(const vec2& point) const {
108108 if(first) return false;
109109
110110 if(min.x<=point.x && min.y<=point.y && max.x >= point.x && max.y >= point.y)
125125
126126 void draw() const{
127127 glBegin(GL_LINE_STRIP);
128 glVertex2fv(min);
128 glVertex2fv(glm::value_ptr(min));
129129 glVertex2f(max.x, min.y);
130 glVertex2fv(max);
130 glVertex2fv(glm::value_ptr(max));
131131 glVertex2f(min.x, max.y);
132 glVertex2fv(min);
132 glVertex2fv(glm::value_ptr(min));
133133 glEnd();
134134 }
135135 };
136136
137137 class Bounds3D {
138138 public:
139 vec3f min;
140 vec3f max;
139 vec3 min;
140 vec3 max;
141141 bool first;
142142
143143 void reset() {
144 min = vec3f(0.0, 0.0, 0.0);
145 max = vec3f(0.0, 0.0, 0.0);
144 min = vec3(0.0, 0.0, 0.0);
145 max = vec3(0.0, 0.0, 0.0);
146146 first = true;
147147 }
148148
150150 reset();
151151 }
152152
153 Bounds3D(vec3f min, vec3f max) {
153 Bounds3D(vec3 min, vec3 max) {
154154 reset();
155155 update(min);
156156 update(max);
172172 return width() * height() * depth();
173173 }
174174
175 vec3f centre() {
176 return min + ((max-min) * 0.5);
177 }
178
179 void update(vec3f point) {
175 vec3 centre() {
176 return min + ((max-min) * 0.5f);
177 }
178
179 void update(vec3 point) {
180180 if(first) {
181181 min = point;
182182 max = point;
192192 if(max.z < point.z) max.z = point.z;
193193 }
194194
195 bool contains(vec3f& point) {
195 bool contains(vec3& point) {
196196 if(first) return false;
197197
198198 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)
204204 void draw() {
205205 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
206206 glBegin(GL_LINES);
207 glVertex3fv(min);
208 glVertex3fv(max);
207 glVertex3fv(glm::value_ptr(min));
208 glVertex3fv(glm::value_ptr(max));
209209 glEnd();
210210 }
211211
+0
-259
src/core/camera.cpp less more
0 /*
1 Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com)
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 3. The name of the author may not be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "camera.h"
28
29 //Light
30
31 Light::Light() {
32 }
33
34 Light::Light(vec3f pos) {
35 this->pos = pos;
36 }
37
38 void Light::lookAt(vec3f target) {
39 gluLookAt( pos.x, pos.y, pos.z,
40 target.x, target.y, target.z,
41 0.0f, 1.0f, 0.0f);
42 }
43
44 void Light::setPos(vec3f pos) {
45 this->pos = pos;
46 }
47
48 vec3f Light::getPos() {
49 return pos;
50 }
51
52 //Camera
53
54 Camera::Camera() {
55 }
56
57 Camera::Camera(vec3f pos, vec3f target) {
58 fov = 90.0f;
59 znear = 0.1f;
60 zfar = 1000.0f;
61
62 up = vec3f(0.0, 1.0, 0.0);
63
64 this->_pos=pos;
65 this->_target=target;
66 reset();
67 }
68
69 void Camera::focus() {
70 display.mode3D(fov, znear, zfar);
71 look();
72 }
73
74 void Camera::focusOn(vec3f p) {
75 display.mode3D(fov, znear, zfar);
76 lookAt(p);
77 }
78
79
80 void Camera::look() {
81 lookAt(target);
82 }
83
84 void Camera::lookAt(vec3f target) {
85 gluLookAt( pos.x, pos.y, pos.z,
86 target.x, target.y, target.z,
87 up.x, up.y, up.z);
88 }
89
90 vec3f Camera::getUp() {
91 return up;
92 }
93
94 float Camera::getZNear() {
95 return znear;
96 }
97
98 float Camera::getZFar() {
99 return zfar;
100 }
101
102 float Camera::getFov() {
103 return fov;
104 }
105
106 void Camera::setUp(vec3f up) {
107 this->up = up;
108 }
109
110 void Camera::setFov(float fov) {
111 this->fov = fov;
112 }
113
114 void Camera::setZNear(float znear) {
115 this->znear = znear;
116 }
117
118 void Camera::setZFar(float zfar) {
119 this->zfar = zfar;
120 }
121
122 void Camera::setPos(vec3f pos, bool keepangle) {
123 if(keepangle) {
124 vec3f dir = target - this->pos;
125 this->pos = pos;
126 this->target = pos + dir;
127 } else {
128 this->pos = pos;
129 }
130 }
131
132 void Camera::setTarget(vec3f target) {
133 this->target = target;
134 }
135
136 vec3f Camera::getPos() {
137 return pos;
138 }
139
140 vec3f Camera::getTarget() {
141 return target;
142 }
143
144 void Camera::reset() {
145 pos = _pos;
146 target = _target;
147 }
148
149 // CameraEvent
150 CameraEvent::CameraEvent() {
151 finished=false;
152 }
153
154 bool CameraEvent::isFinished() {
155 return finished;
156 }
157
158 // CameraMoveEvent
159
160 CameraMoveEvent::CameraMoveEvent(float fov, vec3f pos, vec3f target, float duration) : CameraEvent() {
161 this->fov = fov;
162 this->pos = pos;
163 this->target = target;
164 this->duration = duration;
165 this->elapsed = 0.0;
166 }
167
168 void CameraMoveEvent::prepare(Camera* cam) {
169 this->elapsed = 0.0;
170 this->finished = false;
171 this->old_fov = cam->getFov();
172 this->old_pos = cam->getPos();
173 this->old_target = cam->getTarget();
174 }
175
176 void CameraMoveEvent::logic(float dt, Camera* cam) {
177 elapsed += dt;
178
179 if(duration <= 0.0 || elapsed >= duration) {
180 cam->setFov(fov);
181 cam->setPos(pos);
182 cam->setTarget(target);
183 finished=true;
184 return;
185 }
186
187 float pc = elapsed/duration;
188
189 float f = old_fov * (1.0 - pc) + fov * pc;
190 vec3f p = old_pos * (1.0 - pc) + pos * pc;
191 vec3f t = old_target * (1.0 - pc) + target * pc;
192
193 cam->setFov(f);
194 cam->setPos(p);
195 cam->setTarget(t);
196 }
197
198 // Camera Event Path
199
200 CameraPath::CameraPath(Camera* cam, bool loop) {
201 this->cam = cam;
202 current = 0;
203 current_index = -1;
204 this->loop = loop;
205 finished=false;
206 }
207
208 CameraPath::~CameraPath() {
209 clear();
210 }
211
212 bool CameraPath::isFinished() {
213 return finished;
214 }
215
216 void CameraPath::reset() {
217 finished=false;
218 current_index = -1;
219 current = 0;
220 }
221
222 void CameraPath::clear() {
223 for(std::vector<CameraEvent*>::iterator it = events.begin(); it != events.end(); it++) {
224 delete *it;
225 }
226 events.clear();
227 }
228
229 void CameraPath::addEvent(CameraEvent* ce) {
230 events.push_back(ce);
231 }
232
233 void CameraPath::logic(float dt) {
234 if(finished || events.size() == 0 && current==0) return;
235
236 if(current == 0) {
237 if(loop) {
238 current_index = (current_index + 1) % events.size();
239 } else {
240 current_index++;
241
242 if(current_index >= events.size()) {
243 finished=true;
244 return;
245 }
246 }
247
248 current = events[current_index];
249
250 current->prepare(cam);
251 }
252
253 current->logic(dt, cam);
254
255 if(current->isFinished()) {
256 current = 0;
257 }
258 }
+0
-138
src/core/camera.h less more
0 /*
1 Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com)
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 3. The name of the author may not be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifndef CAMERA_H
28 #define CAMERA_H
29
30 #include "display.h"
31
32 #include <vector>
33
34 class Frustum;
35
36 class Light {
37 vec3f pos;
38 public:
39 Light();
40 Light(vec3f pos);
41 void lookAt(vec3f target);
42
43 void setPos(vec3f pos);
44 vec3f getPos();
45 };
46
47 class Camera {
48 protected:
49 vec3f _pos;
50 vec3f _target;
51 vec3f pos;
52 vec3f target;
53
54 vec3f up;
55
56 float fov;
57 float znear;
58 float zfar;
59
60 public:
61 Camera();
62 Camera(vec3f pos, vec3f target = vec3f(0,0,0));
63
64 void setPos(vec3f pos, bool keepangle = false);
65
66 void setUp(vec3f up);
67 void setFov(float fov);
68 void setZNear(float znear);
69 void setZFar(float zfar);
70
71 void setTarget(vec3f target);
72
73 vec3f getTarget();
74 vec3f getPos();
75
76 vec3f getUp();
77 float getFov();
78 float getZNear();
79 float getZFar();
80
81
82 void reset();
83 void look();
84 void lookAt(vec3f target);
85
86 void focus();
87 void focusOn(vec3f p);
88 };
89
90 class CameraEvent {
91 protected:
92 bool finished;
93 public:
94 CameraEvent();
95 bool isFinished();
96 virtual void prepare(Camera* cam) {};
97 virtual void logic(float dt, Camera* cam) {};
98 };
99
100 class CameraMoveEvent : public CameraEvent {
101
102 float duration;
103 float elapsed;
104
105 float fov;
106 vec3f pos;
107 vec3f target;
108 float old_fov;
109 vec3f old_pos;
110 vec3f old_target;
111
112 public:
113 CameraMoveEvent(float fov, vec3f pos, vec3f target, float duration = 0.0);
114 void prepare(Camera* cam);
115 void logic(float dt, Camera* cam);
116 };
117
118 class CameraPath {
119 Camera* cam;
120 CameraEvent* current;
121 int current_index;
122
123 bool loop;
124 bool finished;
125
126 std::vector<CameraEvent*> events;
127 public:
128 CameraPath(Camera* cam, bool loop = true);
129 ~CameraPath();
130 void addEvent(CameraEvent* ce);
131 void clear();
132 void logic(float dt);
133 void reset();
134 bool isFinished();
135 };
136
137 #endif
2525 // parse key value pair, seperated by an equals sign, removing white space on key and front of the value
2626 Regex ConfFile_key_value("^\\s*([^=\\s]+)\\s*=\\s*([^\\s].*)?$");
2727
28 // vec2f, vec3f, or vec4f with liberal allowance for whitespace
28 // vec2, vec3, or vec4 with liberal allowance for whitespace
2929 Regex ConfFile_vec2_value("^\\s*vec2\\(\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*\\)\\s*$");
3030 Regex ConfFile_vec3_value("^\\s*vec3\\(\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*\\)\\s*$");
3131 Regex ConfFile_vec4_value("^\\s*vec4\\(\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*,\\s*(-?[0-9.]+)\\s*\\)\\s*$");
5858 setFloat(value);
5959 }
6060
61 ConfEntry::ConfEntry(const std::string& name, vec2f value) {
61 ConfEntry::ConfEntry(const std::string& name, vec2 value) {
6262 this->name = name;
6363 setVec2(value);
6464 }
6565
66 ConfEntry::ConfEntry(const std::string& name, vec3f value) {
66 ConfEntry::ConfEntry(const std::string& name, vec3 value) {
6767 this->name = name;
6868 setVec3(value);
6969 }
7070
71 ConfEntry::ConfEntry(const std::string& name, vec4f value) {
71 ConfEntry::ConfEntry(const std::string& name, vec4 value) {
7272 this->name = name;
7373 setVec4(value);
7474 }
9999 this->value = std::string(value ? "yes" : "no");
100100 }
101101
102 void ConfEntry::setVec2(vec2f value) {
102 void ConfEntry::setVec2(vec2 value) {
103103 char vectostr[256];
104104 sprintf(vectostr, "vec2(%.5f, %.5f)", value.x, value.y);
105105
106106 this->value = std::string(vectostr);
107107 }
108108
109 void ConfEntry::setVec3(vec3f value) {
109 void ConfEntry::setVec3(vec3 value) {
110110 char vectostr[256];
111111 sprintf(vectostr, "vec3(%.5f, %.5f, %.5f)", value.x, value.y, value.z);
112112
113113 this->value = std::string(vectostr);
114114 }
115115
116 void ConfEntry::setVec4(vec4f value) {
116 void ConfEntry::setVec4(vec4 value) {
117117 char vectostr[256];
118118 sprintf(vectostr, "vec4(%.5f, %.5f, %.5f, %.5f)", value.x, value.y, value.z, value.w);
119119
176176 return false;
177177 }
178178
179 vec2f ConfEntry::getVec2() {
179 vec2 ConfEntry::getVec2() {
180180
181181 std::vector<std::string> matches;
182182
183183 if(ConfFile_vec2_value.match(value, &matches)) {
184 return vec2f(atof(matches[0].c_str()), atof(matches[1].c_str()));
185 }
186
187 return vec2f(0.0, 0.0);
184 return vec2(atof(matches[0].c_str()), atof(matches[1].c_str()));
185 }
186
187 return vec2(0.0, 0.0);
188188 }
189189
190190 bool ConfEntry::isVec3() {
192192 return false;
193193 }
194194
195 vec3f ConfEntry::getVec3() {
195 vec3 ConfEntry::getVec3() {
196196
197197 std::vector<std::string> matches;
198198
199199 if(ConfFile_vec3_value.match(value, &matches)) {
200 return vec3f(atof(matches[0].c_str()), atof(matches[1].c_str()), atof(matches[2].c_str()));
201 }
202
203 return vec3f(0.0, 0.0, 0.0);
200 return vec3(atof(matches[0].c_str()), atof(matches[1].c_str()), atof(matches[2].c_str()));
201 }
202
203 return vec3(0.0, 0.0, 0.0);
204204 }
205205
206206 bool ConfEntry::isVec4() {
208208 return false;
209209 }
210210
211 vec4f ConfEntry::getVec4() {
211 vec4 ConfEntry::getVec4() {
212212
213213 std::vector<std::string> matches;
214214
215215 if(ConfFile_vec4_value.match(value, &matches)) {
216 return vec4f(atof(matches[0].c_str()), atof(matches[1].c_str()), atof(matches[2].c_str()), atof(matches[3].c_str()) );
217 }
218
219 return vec4f(0.0, 0.0, 0.0, 0.0);
216 return vec4(atof(matches[0].c_str()), atof(matches[1].c_str()), atof(matches[2].c_str()), atof(matches[3].c_str()) );
217 }
218
219 return vec4(0.0, 0.0, 0.0, 0.0);
220220 }
221221
222222 //ConfSection
373373 return false;
374374 }
375375
376 vec3f ConfSection::getVec3(const std::string& key) {
376 vec3 ConfSection::getVec3(const std::string& key) {
377377 ConfEntry* entry = getEntry(key);
378378
379379 if(entry) return entry->getVec3();
380380
381 return vec3f(0.0, 0.0, 0.0);
382 }
383
384 vec4f ConfSection::getVec4(const std::string& key) {
381 return vec3(0.0, 0.0, 0.0);
382 }
383
384 vec4 ConfSection::getVec4(const std::string& key) {
385385 ConfEntry* entry = getEntry(key);
386386
387387 if(entry) return entry->getVec4();
388388
389 return vec4f(0.0, 0.0, 0.0, 0.0);
389 return vec4(0.0, 0.0, 0.0, 0.0);
390390 }
391391
392392 void ConfSection::print(std::ostream& out) {
730730 return false;
731731 }
732732
733 vec3f ConfFile::getVec3(const std::string& section, const std::string& key) {
733 vec3 ConfFile::getVec3(const std::string& section, const std::string& key) {
734734 ConfEntry* entry = getEntry(section, key);
735735
736736 if(entry) return entry->getVec3();
737737
738 return vec3f(0.0, 0.0, 0.0);
739 }
740
741 vec4f ConfFile::getVec4(const std::string& section, const std::string& key) {
738 return vec3(0.0, 0.0, 0.0);
739 }
740
741 vec4 ConfFile::getVec4(const std::string& section, const std::string& key) {
742742 ConfEntry* entry = getEntry(section, key);
743743
744744 if(entry) return entry->getVec4();
745745
746 return vec4f(0.0, 0.0, 0.0, 0.0);
746 return vec4(0.0, 0.0, 0.0, 0.0);
747747 }
748748
749749 void ConfFile::unknownOptionException(ConfEntry* entry) {
5151 ConfEntry(const std::string& name, int value);
5252 ConfEntry(const std::string& name, float value);
5353 ConfEntry(const std::string& name, bool value);
54 ConfEntry(const std::string& name, vec2f value);
55 ConfEntry(const std::string& name, vec3f value);
56 ConfEntry(const std::string& name, vec4f value);
54 ConfEntry(const std::string& name, vec2 value);
55 ConfEntry(const std::string& name, vec3 value);
56 ConfEntry(const std::string& name, vec4 value);
5757
5858 void setName(const std::string& name);
5959
6161 void setFloat(float value);
6262 void setInt(int value);
6363 void setBool(bool value);
64 void setVec2(vec2f value);
65 void setVec3(vec3f value);
66 void setVec4(vec4f value);
64 void setVec2(vec2 value);
65 void setVec3(vec3 value);
66 void setVec4(vec4 value);
6767
6868 bool hasValue();
6969
7474 int getInt();
7575 float getFloat();
7676 bool getBool();
77 vec2f getVec2();
78 vec3f getVec3();
79 vec4f getVec4();
77 vec2 getVec2();
78 vec3 getVec3();
79 vec4 getVec4();
8080
8181 bool isFloat();
8282 bool isInt();
120120 int getInt(const std::string& key);
121121 float getFloat(const std::string& key);
122122 bool getBool(const std::string& key);
123 vec3f getVec3(const std::string& key);
124 vec4f getVec4(const std::string& key);
123 vec3 getVec3(const std::string& key);
124 vec4 getVec4(const std::string& key);
125125
126126 void print(std::ostream& out);
127127
175175 int getInt(const std::string& section, const std::string& key);
176176 float getFloat(const std::string& section, const std::string& key);
177177 bool getBool(const std::string& section, const std::string& key);
178 vec3f getVec3(const std::string& section, const std::string& key);
179 vec4f getVec4(const std::string& section, const std::string& key);
178 vec3 getVec3(const std::string& section, const std::string& key);
179 vec4 getVec4(const std::string& section, const std::string& key);
180180
181181 static void trim(std::string& value);
182182
3232 SDLAppDisplay display;
3333
3434 SDLAppDisplay::SDLAppDisplay() {
35 clearColour = vec4f(0.0f,0.0f,0.0f,1.0f);
35 clearColour = vec4(0.0f,0.0f,0.0f,1.0f);
3636 enable_shaders=false;
3737 enable_alpha=false;
3838 vsync=false;
39 resizable=false;
40 frameless=false;
3941 multi_sample = 0;
42 width = 0;
43 height = 0;
44 desktop_width = 0;
45 desktop_height = 0;
46 windowed_width = 0;
47 windowed_height = 0;
48 #if SDL_VERSION_ATLEAST(1,3,0)
49 sdl_window = 0;
50 gl_context = 0;
51 #else
52 surface = 0;
53 #endif
54
4055 }
4156
4257 SDLAppDisplay::~SDLAppDisplay() {
4358 }
4459
45 void SDLAppDisplay::setClearColour(vec3f colour) {
46 setClearColour(vec4f(colour, enable_alpha ? 0.0f : 1.0f));
47 }
48
49 void SDLAppDisplay::setClearColour(vec4f colour) {
60 void SDLAppDisplay::setClearColour(vec3 colour) {
61 setClearColour(vec4(colour, enable_alpha ? 0.0f : 1.0f));
62 }
63
64 void SDLAppDisplay::setClearColour(vec4 colour) {
5065 clearColour = colour;
5166 }
5267
5368 int SDLAppDisplay::SDLFlags(bool fullscreen) {
5469 int flags = SDL_OPENGL | SDL_HWSURFACE | SDL_ANYFORMAT | SDL_DOUBLEBUF;
70 if (frameless) flags |= SDL_NOFRAME;
71 if (resizable && !fullscreen) flags |= SDL_RESIZABLE;
5572 if (fullscreen) flags |= SDL_FULLSCREEN;
73
74 //SDL 1.3 vsync
75 #ifdef SDL_RENDERER_PRESENTVSYNC
76 if (!vsync) flags |= SDL_RENDERER_PRESENTVSYNC;
77 #endif
78
5679 return flags;
5780 }
5881
6285
6386 void SDLAppDisplay::enableShaders(bool enable) {
6487 enable_shaders = enable;
88 }
89
90 void SDLAppDisplay::enableResize(bool resizable) {
91 this->resizable = resizable;
6592 }
6693
6794 void SDLAppDisplay::enableAlpha(bool enable) {
91118 return value==1;
92119 }
93120
94
95 void SDLAppDisplay::init(std::string window_title, int width, int height, bool fullscreen) {
96
97 this->fullscreen = fullscreen;
121 void SDLAppDisplay::setVideoMode(int width, int height, bool fullscreen) {
122 #if SDL_VERSION_ATLEAST(1,3,0)
123
124 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
125 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
126
127 Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
128 if(resizable && !fullscreen) flags |= SDL_WINDOW_RESIZABLE;
129 if(fullscreen) flags |= SDL_WINDOW_FULLSCREEN;
130
131 if(gl_context != 0) SDL_GL_DeleteContext(gl_context);
132 if(sdl_window != 0) SDL_DestroyWindow(sdl_window);
133
134 sdl_window = SDL_CreateWindow(
135 gSDLAppTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
136 width, height, flags);
137
138
139 if (!sdl_window) {
140 std::string sdlerr(SDL_GetError());
141 throw SDLInitException(sdlerr);
142 }
143
144 gl_context = SDL_GL_CreateContext(sdl_window);
145
146 if(vsync) SDL_GL_SetSwapInterval(1);
147 #else
148 int depth = 32;
98149
99150 int flags = SDLFlags(fullscreen);
100 int depth = 32;
101
102 if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) != 0) {
103 throw SDLInitException(SDL_GetError());
104 }
105
106 atexit(SDL_Quit);
107
108 SDL_EnableUNICODE(1);
109
110 //vsync
151
111152 if(vsync) SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
112153 else SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
113154
152193 throw SDLInitException(sdlerr);
153194 }
154195 }
196 #endif
197
198 setupExtensions();
199 }
200
201 void SDLAppDisplay::toggleFullscreen() {
202
203 int width = this->width;
204 int height = this->height;
205
206 if(!fullscreen) {
207
208 //save windowed width and height
209 windowed_width = width;
210 windowed_height = height;
211
212 int fullscreen_width = desktop_width;
213 int fullscreen_height = desktop_height;
214
215 float aspect_ratio = fullscreen_width / (float) fullscreen_height;
216
217 // if the aspect ratio suggests the person is using multiple monitors
218 // find a supported resolution with a lower aspect ratio with the same
219 // fullscreen height
220
221 #if SDL_VERSION_ATLEAST(1,3,0)
222 // TODO: do something with the 1.3 API here
223 #else
224 if(aspect_ratio >= 2.5) {
225
226 SDL_Rect** modes = SDL_ListModes(0, SDLFlags(true));
227
228 if(modes != (SDL_Rect**)0 && modes != (SDL_Rect**)-1) {
229
230 for (int i=0; modes[i]; i++) {
231 if(modes[i]->h == fullscreen_height && (modes[i]->w/(float)modes[i]->h) < 2.5) {
232 fullscreen_width = modes[i]->w;
233 break;
234 }
235 }
236 }
237 }
238 #endif
239
240 width = fullscreen_width;
241 height = fullscreen_height;
242
243 } else {
244 //switch back to window dimensions, if known
245 if(windowed_width != 0) {
246 width = windowed_width;
247 height = windowed_height;
248 }
249 }
250
251 fullscreen = !fullscreen;
252
253 setVideoMode(width, height, fullscreen);
254
255 int resized_width, resized_height;
256
257 #if SDL_VERSION_ATLEAST(1,3,0)
258 SDL_GetWindowSize(sdl_window, &resized_width, &resized_height);
259 #else
260 const SDL_VideoInfo* display_info = SDL_GetVideoInfo();
261
262 resized_width = display_info->current_w;
263 resized_height = display_info->current_h;
264 #endif
265
266 //set viewport to match what we ended up on
267 glViewport(0, 0, resized_width, resized_height);
268
269 this->width = resized_width;
270 this->height = resized_height;
271 }
272
273 void SDLAppDisplay::resize(int width, int height) {
274
275 int resized_width, resized_height;
276
277 #if SDL_VERSION_ATLEAST(1,3,0)
278 SDL_GetWindowSize(sdl_window, &resized_width, &resized_height);
279 #else
280 setVideoMode(width, height, fullscreen);
281
282 const SDL_VideoInfo* display_info = SDL_GetVideoInfo();
283
284 resized_width = display_info->current_w;
285 resized_height = display_info->current_h;
286 #endif
287
288 //set viewport to match what we ended up on
289 glViewport(0, 0, resized_width, resized_height);
290
291 this->width = resized_width;
292 this->height = resized_height;
293 }
294
295 void SDLAppDisplay::init(std::string window_title, int width, int height, bool fullscreen) {
296
297 if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) != 0) {
298 throw SDLInitException(SDL_GetError());
299 }
300
301 const SDL_VideoInfo* display_info = SDL_GetVideoInfo();
302
303 //save the desktop resolution
304 desktop_width = display_info->current_w;
305 desktop_height = display_info->current_h;
306
307 atexit(SDL_Quit);
308
309 SDL_EnableUNICODE(1);
310
311 #if SDL_VERSION_ATLEAST(1,3,0)
312 #else
313 SDL_WM_SetCaption(window_title.c_str(),0);
314 #endif
315
316 setVideoMode(width, height, fullscreen);
155317
156318 //get actual opengl viewport
157319 GLint viewport[4];
158320 glGetIntegerv( GL_VIEWPORT, viewport );
159321
160 this->width = viewport[2];
161 this->height = viewport[3];
162
163 setupExtensions();
164
165 SDL_WM_SetCaption(window_title.c_str(),0);
322 this->width = viewport[2];
323 this->height = viewport[3];
324 this->fullscreen = fullscreen;
166325 }
167326
168327 void SDLAppDisplay::quit() {
328
329 #if SDL_VERSION_ATLEAST(1,3,0)
330 if(gl_context != 0) SDL_GL_DeleteContext(gl_context);
331 if(sdl_window != 0) SDL_DestroyWindow(sdl_window);
332 #endif
333
169334 texturemanager.purge();
170335 shadermanager.purge();
171336 fontmanager.purge();
173338 }
174339
175340 void SDLAppDisplay::update() {
341 #if SDL_VERSION_ATLEAST(1,3,0)
342 SDL_GL_SwapWindow(sdl_window);
343 #else
176344 SDL_GL_SwapBuffers();
345 #endif
177346 }
178347
179348 void SDLAppDisplay::clear() {
215384 glPopMatrix();
216385 }
217386
218 vec4f SDLAppDisplay::currentColour() {
219 vec4f colour;
220 glGetFloatv(GL_CURRENT_COLOR, colour);
221 return colour;
222 }
223
224 void SDLAppDisplay::checkGLErrors() {
225 //TODO
226 }
227
228 void SDLAppDisplay::fullScreenQuad(bool coord_flip) {
229
230 int y1 = coord_flip ? 0 : 1;
231 int y2 = coord_flip ? 1 : 0;
232
233 glBegin(GL_QUADS);
234 glTexCoord2i(0,y1);
235 glVertex2f(0, 0);
236
237 glTexCoord2i(1,y1);
238 glVertex2i(display.width, 0);
239
240 glTexCoord2i(1,y2);
241 glVertex2i(display.width, display.height);
242
243 glTexCoord2i(0,y2);
244 glVertex2i(0, display.height);
245 glEnd();
246 }
247
248 void SDLAppDisplay::renderToTexture(GLuint target, int width, int height, GLenum format) {
249 glEnable(GL_TEXTURE_2D);
250 glBindTexture(GL_TEXTURE_2D, target);
251 glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, width, height, 0);
252 }
253
254 GLuint SDLAppDisplay::emptyTexture(int width, int height, GLenum format) {
255 GLuint textureid;
256
257 glEnable(GL_TEXTURE_2D);
258
259 glGenTextures(1, &textureid);
260 glBindTexture(GL_TEXTURE_2D, textureid);
261
262 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
263 GL_RGBA, GL_UNSIGNED_BYTE, 0);
264
265 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
266 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
267
268 return textureid;
269 }
270
271 GLuint SDLAppDisplay::createTexture(int width, int height, bool mipmaps, bool clamp, bool trilinear, GLenum format, unsigned int* data) {
272
273 GLuint textureid;
274
275 glGenTextures(1, &textureid);
276 glBindTexture(GL_TEXTURE_2D, textureid);
277
278 if(mipmaps) {
279 gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, format, GL_UNSIGNED_BYTE, data);
280 } else {
281 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, format, GL_UNSIGNED_BYTE, data);
282 }
283
284 //GL_LINEAR_MIPMAP_LINEAR - Trilinear
285 //GL_LINEAR_MIPMAP_NEAREST - Bilinear
286
287 if(trilinear) {
288 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
289 } else {
290 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
291 }
292
293 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST_MIPMAP_NEAREST);
294
295 if(clamp) {
296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
298 }
299
300 return textureid;
301 }
302
303 vec3f SDLAppDisplay::project(vec3f pos) {
387 vec4 SDLAppDisplay::currentColour() {
388 vec4 colour;
389 glGetFloatv(GL_CURRENT_COLOR, glm::value_ptr(colour));
390 return colour;
391 }
392
393 vec3 SDLAppDisplay::project(vec3 pos) {
304394 GLint viewport[4];
305395 GLdouble modelview[16];
306396 GLdouble projection[16];
314404
315405 winY = (float)viewport[3] - winY;
316406
317 return vec3f((float) winX, (float) winY, (float) winZ);
318 }
319
320 vec3f SDLAppDisplay::unproject(vec2f pos) {
407 return vec3((float) winX, (float) winY, (float) winZ);
408 }
409
410 vec3 SDLAppDisplay::unproject(vec2 pos) {
321411 GLint viewport[4];
322412 GLdouble modelview[16];
323413 GLdouble projection[16];
333423 glReadPixels( int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
334424 gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
335425
336 return vec3f((float) posX, (float) posY, (float) posZ);
337 }
426 return vec3((float) posX, (float) posY, (float) posZ);
427 }
5454 };
5555
5656 class SDLAppDisplay {
57 SDL_Surface *surface;
5857
5958 bool enable_shaders;
6059 bool enable_alpha;
60 bool resizable;
61 bool frameless;
6162 bool vsync;
6263
6364 int multi_sample;
6667 void setupExtensions();
6768 public:
6869 int width, height;
70 int desktop_width, desktop_height;
71 int windowed_width, windowed_height;
72
73 #if SDL_VERSION_ATLEAST(1,3,0)
74 SDL_Window* sdl_window;
75 SDL_GLContext gl_context;
76 #else
77 SDL_Surface *surface;
78 #endif
79
6980 bool fullscreen;
70 vec4f clearColour;
81 vec4 clearColour;
7182
7283 SDLAppDisplay();
7384 ~SDLAppDisplay();
7485
75 void init(std::string window_title, int xres, int yres, bool fullscreen);
86 void toggleFullscreen();
87 void resize(int width, int height);
88
89 void init(std::string window_title, int width, int height, bool fullscreen);
90 void setVideoMode(int width, int height, bool fullscreen);
7691
7792 bool multiSamplingEnabled();
7893
8095
8196 void update();
8297 void clear();
83 void enableVsync(bool vsync);
84 void setClearColour(vec3f colour);
85 void setClearColour(vec4f colour);
98
99 void setClearColour(vec3 colour);
100 void setClearColour(vec4 colour);
101
86102
87103 void enableShaders(bool enable);
104 void enableVsync(bool vsync);
105 void enableAlpha(bool enable);
106 void enableResize(bool resizable);
107 void enableFrameless(bool frameless);
88108
89 void enableAlpha(bool enable);
90109 void multiSample(int sample);
91110
92111 void mode3D(float fov, float znear, float zfar);
95114 void push2D();
96115 void pop2D();
97116
98 vec4f currentColour();
117 vec4 currentColour();
99118
100 void fullScreenQuad(bool coord_flip);
101
102 void renderToTexture(GLuint target, int width, int height, GLenum format);
103 GLuint emptyTexture(int width, int height, GLenum format);
104 GLuint createTexture(int width, int height, bool mipmaps, bool clamp, bool trilinear, GLenum format, unsigned int* data);
105
106 vec3f project(vec3f pos);
107 vec3f unproject(vec2f pos);
108
109 void checkGLErrors();
119 vec3 project(vec3 pos);
120 vec3 unproject(vec2 pos);
110121 };
111122
112123 extern SDLAppDisplay display;
3232 Frustum::Frustum() {
3333 }
3434
35 Frustum::Frustum(Camera& camera) {
36 update(camera);
35 Frustum::Frustum(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance) {
36 update(source, target, up, fov, near_distance, far_distance);
3737 }
3838
39 void Frustum::update(Camera& camera) {
40 updatePerspective(camera);
41 updateView(camera);
39 void Frustum::update(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance) {
40 updatePerspective(fov, near_distance, far_distance);
41 updateView(source, target, up);
4242 }
4343
44 void Frustum::updatePerspective(Camera& camera) {
44 void Frustum::updatePerspective(float fov, float near_distance, float far_distance) {
45
46 this->near_distance = near_distance;
47 this->far_distance = far_distance;
48
4549 view_ratio = (float) display.width / (float) display.height;
46 fov = camera.getFov();
47 near_distance = camera.getZNear();
48 far_distance = camera.getZFar();
4950
5051 float toa = (float) tan(fov * 0.5 * DEGREES_TO_RADIANS);
5152
5556 far_half_width = far_half_height * view_ratio;
5657 }
5758
58 void Frustum::updateView(Camera& camera) {
59 vec3f source = camera.getPos();
60 vec3f target = camera.getTarget();
61 vec3f up = camera.getUp();
59 void Frustum::updateView(const vec3& source, const vec3& target, const vec3& up) {
6260
63 vec3f view_ray = target - source;
64 view_ray.normalize();
61 vec3 view_ray = normalise(target - source);
6562
66 vec3f horiz_normal = view_ray.cross(up);
67 horiz_normal.normalize();
63 vec3 horiz_normal = normalise(glm::cross(view_ray,up));
6864
69 vec3f vert_normal = horiz_normal.cross(view_ray);
65 vec3 vert_normal = glm::cross(horiz_normal, view_ray);
7066
7167 //calculate the positions of the 8 points that make up
7268 //the viewing frustum and then use them to create the 6 planes
7369
74 vec3f near_centre = source + view_ray * near_distance;
75 vec3f far_centre = source + view_ray * far_distance;
70 vec3 near_centre = source + view_ray * near_distance;
71 vec3 far_centre = source + view_ray * far_distance;
7672
77 vec3f near_horiz_offset = horiz_normal * near_half_width;
78 vec3f near_vert_offset = vert_normal * near_half_height;
73 vec3 near_horiz_offset = horiz_normal * near_half_width;
74 vec3 near_vert_offset = vert_normal * near_half_height;
7975
8076 near_top_left = near_centre + near_vert_offset - near_horiz_offset;
8177 near_top_right = near_centre + near_vert_offset + near_horiz_offset;
8278 near_bottom_left = near_centre - near_vert_offset - near_horiz_offset;
8379 near_bottom_right = near_centre - near_vert_offset + near_horiz_offset;
8480
85 vec3f far_horiz_offset = horiz_normal * far_half_width;
86 vec3f far_vert_offset = vert_normal * far_half_height;
81 vec3 far_horiz_offset = horiz_normal * far_half_width;
82 vec3 far_vert_offset = vert_normal * far_half_height;
8783
8884 far_top_left = far_centre + far_vert_offset - far_horiz_offset;
8985 far_top_right = far_centre + far_vert_offset + far_horiz_offset;
109105 planes[5] = Plane(far_top_right, far_top_left, far_bottom_left);
110106 }
111107
112 bool Frustum::contains(const vec3f& p) const {
108 bool Frustum::contains(const vec3& p) const {
113109
114110 for(int i=0; i < 6; i++) {
115111 float dist = planes[i].distance(p);
122118
123119 bool Frustum::intersects(const Bounds3D& bounds) const {
124120
125 vec3f corner;
121 vec3 corner;
126122
127123 for(int i=0; i<6; i++) {
128124
139135
140136 bool Frustum::intersects(const Bounds2D& bounds, float z) const {
141137
142 vec3f corner;
138 vec3 corner;
143139
144140 for(int i=0; i<6; i++) {
145141
2727 #ifndef FRUSTUM_H
2828 #define FRUSTUM_H
2929
30 #include "vectors.h"
31 #include "camera.h"
30 #include "gl.h"
3231 #include "plane.h"
3332 #include "pi.h"
3433 #include "bounds.h"
35
36 class Camera;
3734
3835 class Frustum {
3936
4643 float far_half_width;
4744 float far_half_height;
4845
49 vec3f near_top_left, near_top_right;
50 vec3f near_bottom_left, near_bottom_right;
51 vec3f far_top_left, far_top_right;
52 vec3f far_bottom_left, far_bottom_right;
46 vec3 near_top_left, near_top_right;
47 vec3 near_bottom_left, near_bottom_right;
48 vec3 far_top_left, far_top_right;
49 vec3 far_bottom_left, far_bottom_right;
5350
5451 Plane planes[6];
5552 public:
5653 Frustum();
57 Frustum(Camera& camera);
58 void update(Camera& camera);
59 void updatePerspective(Camera& camera);
60 void updateView(Camera& camera);
54 Frustum(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance);
6155
62 bool contains(const vec3f& p) const;
56 void update(const vec3& source, const vec3& target, const vec3& up, float fov, float near_distance, float far_distance);
57
58 void updatePerspective(float fov, float near_distance, float far_distance);
59 void updateView(const vec3& source, const vec3& target, const vec3& up);
60
61 bool contains(const vec3& p) const;
6362
6463 bool intersects(const Bounds3D& bounds) const;
6564 bool intersects(const Bounds2D& bounds, float z = 0.0) const;
6363
6464 FT_Face ftface = set->getFTFace();
6565
66 if(FT_Load_Glyph( ftface, FT_Get_Char_Index( ftface, chr ), FT_LOAD_DEFAULT ))
66 FT_UInt index = FT_Get_Char_Index( ftface, chr );
67
68 //debugLog("FXGlyph %x %d %d", chr, chr, index);
69
70 if(FT_Load_Glyph( ftface, index, FT_LOAD_DEFAULT ))
6771 throw FXFontException(ftface->family_name);
6872
6973 FT_Glyph ftglyph;
7579
7680 glyph_bitmap = (FT_BitmapGlyph)ftglyph;
7781
78 dims = vec2f( glyph_bitmap->bitmap.width, glyph_bitmap->bitmap.rows) + vec2f(2.0f, 2.0f);
79 corner = vec2f( glyph_bitmap->left, -glyph_bitmap->top) + vec2f(0.5, -0.5);
80 advance = vec2f( ftface->glyph->advance.x >> 6, ftface->glyph->advance.y >> 6);
81
82 vertex_positions[0] = vec2f(0.0f, 0.0f);
83 vertex_positions[1] = vec2f(dims.x, 0.0f);
82 dims = vec2( glyph_bitmap->bitmap.width, glyph_bitmap->bitmap.rows) + vec2(2.0f, 2.0f);
83 corner = vec2( glyph_bitmap->left, -glyph_bitmap->top) + vec2(0.5, -0.5);
84 advance = vec2( ftface->glyph->advance.x >> 6, ftface->glyph->advance.y >> 6);
85
86 vertex_positions[0] = vec2(0.0f, 0.0f);
87 vertex_positions[1] = vec2(dims.x, 0.0f);
8488 vertex_positions[2] = dims;
85 vertex_positions[3] = vec2f(0.0f, dims.y);
89 vertex_positions[3] = vec2(0.0f, dims.y);
8690
8791 //call_list = 0;
8892 page = 0;
8993 }
9094
91 void FXGlyph::setPage(FXGlyphPage* page, const vec4f& texcoords) {
95 void FXGlyph::setPage(FXGlyphPage* page, const vec4& texcoords) {
9296 this->page = page;
9397 this->texcoords = texcoords;
9498
95 vertex_texcoords[0] = vec2f(texcoords.x, texcoords.y);
96 vertex_texcoords[1] = vec2f(texcoords.z, texcoords.y);
97 vertex_texcoords[2] = vec2f(texcoords.z, texcoords.w);
98 vertex_texcoords[3] = vec2f(texcoords.x, texcoords.w);
99 }
100
101 void FXGlyph::drawToVBO(quadbuf& buffer, const vec2f& pos, const vec4f& colour) const {
102 buffer.add(page->textureid, pos + corner, dims, colour, texcoords);
103 }
104
105 void FXGlyph::draw(const vec2f& pos) const {
99 vertex_texcoords[0] = vec2(texcoords.x, texcoords.y);
100 vertex_texcoords[1] = vec2(texcoords.z, texcoords.y);
101 vertex_texcoords[2] = vec2(texcoords.z, texcoords.w);
102 vertex_texcoords[3] = vec2(texcoords.x, texcoords.w);
103 }
104
105 void FXGlyph::drawToVBO(quadbuf& buffer, const vec2& pos, const vec4& colour) const {
106 buffer.add(page->texture->textureid, pos + corner, dims, colour, texcoords);
107 }
108
109 void FXGlyph::draw(const vec2& pos) const {
106110 for(int i=0;i<4;i++) {
107 glTexCoord2fv(vertex_texcoords[i]);
108 glVertex2fv(vertex_positions[i] + pos + corner);
111 vec2 pos_offset = vertex_positions[i] + pos + corner;
112
113 glTexCoord2fv(glm::value_ptr(vertex_texcoords[i]));
114 glVertex2fv(glm::value_ptr(pos_offset));
115
109116 }
110117 }
111118
120127 memset(texture_data, 0, page_width * page_height);
121128
122129 needs_update = false;
123 textureid = 0;
124 glGenTextures(1, &textureid);
130 texture = 0;
125131
126132 max_glyph_height = cursor_x = cursor_y = 1;
127133 }
161167
162168 //fprintf(stderr, "corner_x = %d, corner_y = %d\n", corner_x, corner_y);
163169
164 vec4f texcoords = vec4f( (((float)corner_x)-0.5f) / (float) page_width,
170 vec4 texcoords = vec4( (((float)corner_x)-0.5f) / (float) page_width,
165171 (((float)corner_y)-0.5f) / (float) page_height,
166172 (((float)corner_x+bitmap->bitmap.width)+1.5f) / (float) page_width,
167173 (((float)corner_y+bitmap->bitmap.rows)+1.5f) / (float) page_height );
180186 void FXGlyphPage::updateTexture() {
181187 if(!needs_update) return;
182188
183 glBindTexture( GL_TEXTURE_2D, textureid);
184
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
187 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
188 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
189
190 glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, page_width, page_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture_data );
189 if(!texture) {
190 texture = texturemanager.create(page_width, page_height, false, GL_CLAMP_TO_EDGE, GL_ALPHA, texture_data);
191 } else {
192 texture->reload();
193 }
191194
192195 needs_update = false;
193196 }
235238 //add to bitmap without updating textures until the end
236239 pre_caching = true;
237240
238 while (chr = *precache_glyphs++) {
241 while (*precache_glyphs) {
242 chr = *precache_glyphs++;
239243 getGlyph(chr);
240244 }
241245
312316 return width;
313317 }
314318
315 void FXGlyphSet::drawToVBO(vec2f& cursor, const std::string& text, const vec4f& colour) {
319 void FXGlyphSet::drawToVBO(vec2& cursor, const std::string& text, const vec4& colour) {
316320 FTUnicodeStringItr<unsigned char> unicode_text((const unsigned char*)text.c_str());
317321
318322 unsigned int chr;
334338
335339 unsigned int chr;
336340
337 vec2f pos;
341 vec2 pos;
338342
339343 while (*unicode_text) {
340344 chr = *unicode_text++;
341345
342346 FXGlyph* glyph = getGlyph(chr);
343347
344 if(glyph->page->textureid != textureid) {
348 if(glyph->page->texture->textureid != textureid) {
345349 if(textureid != -1) glEnd();
346 textureid = glyph->page->textureid;
350 textureid = glyph->page->texture->textureid;
347351 glBindTexture(GL_TEXTURE_2D, textureid);
348352 glBegin(GL_QUADS);
349353 }
355359 if(textureid != -1) glEnd();
356360 }
357361
362 void FXGlyphSet::drawPages() {
363 vec2 corner = vec2(0.0f);
364
365 glPushMatrix();
366
367 for(std::vector<FXGlyphPage*>::iterator it = pages.begin(); it != pages.end(); it++) {
368 FXGlyphPage* page = *it;
369 page->texture->bind();
370
371 glBegin(GL_QUADS);
372 glTexCoord2f(0.0f, 0.0f);
373 glVertex2f(0.0f, 0.0f);
374
375 glTexCoord2f(1.0f, 0.0f);
376 glVertex2f(page->texture->w, 0.0f);
377
378 glTexCoord2f(1.0f, 1.0f);
379 glVertex2f(page->texture->w, page->texture->h);
380
381 glTexCoord2f(0.0f, 1.0f);
382 glVertex2f(0.0f, page->texture->h);
383 glEnd();
384
385 glTranslatef(page->texture->w, 0.0f, 0.0f);
386 }
387
388 glPopMatrix();
389 }
390
358391 //FXFont
359392
360393 FXFont::FXFont() {
369402 void FXFont::init() {
370403 shadow = false;
371404 shadow_strength = 0.7;
372 shadow_offset = vec2f(1.0, 1.0);
405 shadow_offset = vec2(1.0, 1.0);
373406 round = false;
374407 align_right = false;
375408 align_top = true;
376409
377 colour = vec4f(1.0f, 1.0f, 1.0f, 1.0f);
378 shadow_colour = vec4f(0.0f, 0.0f, 0.0f, shadow_strength);
410 colour = vec4(1.0f, 1.0f, 1.0f, 1.0f);
411 shadow_colour = vec4(0.0f, 0.0f, 0.0f, shadow_strength);
379412 }
380413
381414 void FXFont::roundCoordinates(bool round) {
395428 shadow_colour.w = colour.w * shadow_strength;
396429 }
397430
398 void FXFont::setColour(const vec4f& colour) {
431 void FXFont::setColour(const vec4& colour) {
399432 this->colour = colour;
400433 shadow_colour.w = colour.w * shadow_strength;
401434 }
406439 }
407440
408441 void FXFont::shadowOffset(float x, float y) {
409 shadow_offset = vec2f(x,y);
442 shadow_offset = vec2(x,y);
410443 }
411444
412445 void FXFont::dropShadow(bool shadow) {
433466 return glyphset->getWidth(text);
434467 }
435468
436 void FXFont::render(float x, float y, const std::string& text, const vec4f& colour) const{
469 void FXFont::render(float x, float y, const std::string& text, const vec4& colour) const{
437470
438471 if(fontmanager.use_vbo) {
439 vec2f cursor_start(x,y);
472 vec2 cursor_start(x,y);
440473 glyphset->drawToVBO(cursor_start, text, colour);
441474 return;
442475 }
443476
444 glColor4fv(colour);
477 glColor4fv(glm::value_ptr(colour));
445478
446479 glPushMatrix();
447480
488521 }
489522
490523 render(x, y, text, colour);
524 }
525
526 void FXFont::drawGlyphes() {
527 if(glyphset) glyphset->drawPages();
491528 }
492529
493530 // FXFontManager
501538 use_vbo = false;
502539 }
503540
541 void FXFontManager::unload() {
542 font_vbo.unload();
543 }
544
545 void FXFontManager::reload() {
546 }
547
504548 void FXFontManager::startBuffer() {
505549 font_vbo.reset();
506550 use_vbo = true;
538582 }
539583
540584 FXFont FXFontManager::grab(std::string font_file, int size, int dpi) {
541
542 char buf[256];
543585
544586 if(font_dir.size()>0 && font_file[0] != '/') {
545587 font_file = font_dir + font_file;
5757 #include "vectors.h"
5858 #include "logger.h"
5959 #include "resource.h"
60 #include "texture.h"
6061 #include "vbo.h"
6162
6263 #include <string>
6364 #include <vector>
6465 #include <map>
65
66 #include <ft2build.h>
67 #include FT_FREETYPE_H
68 #include FT_GLYPH_H
69
70 #include "ftgl/FTUnicode.h"
7166
7267 class FXFontException : public ResourceException {
7368 public:
8479 int page_width;
8580 int page_height;
8681 public:
82 TextureResource* texture;
83
8784 FXGlyphPage(int page_width, int page_height);
8885 ~FXGlyphPage();
8986
9188
9289 void updateTexture();
9390
94 GLuint textureid;
95
9691 int cursor_x, cursor_y;
9792 int max_glyph_height;
9893 };
10095 class FXGlyph {
10196 unsigned int chr;
10297
103 vec2f dims;
104 vec2f corner;
105 vec2f advance;
106 public:
107 vec2f vertex_positions[4];
108 vec2f vertex_texcoords[4];
98 vec2 dims;
99 vec2 corner;
100 vec2 advance;
101 public:
102 vec2 vertex_positions[4];
103 vec2 vertex_texcoords[4];
109104
110105 FXGlyphPage* page;
111 vec4f texcoords;
106 vec4 texcoords;
112107 FXGlyphSet* set;
113108 FT_BitmapGlyph glyph_bitmap;
114109
115110 FXGlyph(FXGlyphSet* set, unsigned int chr);
116111
117 const vec2f& getAdvance() const { return advance; };
118 const vec2f& getCorner() const { return corner; };
119 const vec2f& getDimensions() const { return dims; };
120
121 void setPage(FXGlyphPage* page, const vec4f& texcoords);
122
123 void drawToVBO(quadbuf& buffer, const vec2f& offset, const vec4f& colour) const;
124 void draw(const vec2f& pos) const;
112 const vec2& getAdvance() const { return advance; };
113 const vec2& getCorner() const { return corner; };
114 const vec2& getDimensions() const { return dims; };
115
116 void setPage(FXGlyphPage* page, const vec4& texcoords);
117
118 void drawToVBO(quadbuf& buffer, const vec2& offset, const vec4& colour) const;
119 void draw(const vec2& pos) const;
125120 };
126121
127122 class FXGlyphSet {
156151
157152 int getSize() const { return size; };
158153
159 void drawToVBO(vec2f& cursor, const std::string& text, const vec4f& colour);
154 void drawToVBO(vec2& cursor, const std::string& text, const vec4& colour);
160155 void draw(const std::string& text);
156
157 void drawPages();
161158 };
162159
163160 class FXFont {
169166 bool round;
170167
171168 float shadow_strength;
172 vec2f shadow_offset;
173 vec4f shadow_colour;
174 vec4f colour;
169 vec2 shadow_offset;
170 vec4 shadow_colour;
171 vec4 colour;
175172
176173 bool align_right, align_top;
177174
178 void render(float x, float y, const std::string& text, const vec4f& colour) const;
175 void render(float x, float y, const std::string& text, const vec4& colour) const;
179176 void init();
180177 public:
181178 FXFont();
206203 void shadowStrength(float s);
207204 void shadowOffset(float x, float y);
208205
209 void setColour(const vec4f& colour);
206 void setColour(const vec4& colour);
210207 void setAlpha(float alpha);
208
209 void drawGlyphes();
211210 };
212211
213212 typedef std::map<int,FXGlyphSet*> fontSizeMap;
226225
227226 void setDir(std::string font_dir);
228227 void init();
228
229 void unload();
230 void reload();
231
229232 void destroy();
230233 void purge();
231234
55 #define NO_SDL_GLEXT
66 #include "SDL.h"
77 #include "SDL_opengl.h"
8 #endif
89
10 #define PRINT_GL_ERRORS
11
12 #ifdef PRINT_GL_ERRORS
13 #define glCheckError() { \
14 int gl_error = glGetError(); \
15 if(gl_error != GL_NO_ERROR) fprintf(stderr, "GL error %s at %s:%d\n", gluErrorString(gl_error), __FILE__, __LINE__); \
16 }
17 #else
18 #define glCheckError()
919 #endif
20
21 #include <ft2build.h>
22 #include FT_FREETYPE_H
23 #include FT_GLYPH_H
24 #include "ftgl/FTUnicode.h"
25
26 #include "vectors.h"
27
28
2424 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2525 */
2626
27 //#define SDLAPP_DEBUG_LOG "debug.log"
28
2927 #include "logger.h"
3028
31 bool firstEntry = true;
29 std::map<int,std::string> log_levels = boost::assign::map_list_of
30 (LOG_LEVEL_WARN, " WARN" )
31 (LOG_LEVEL_DEBUG, "DEBUG" )
32 (LOG_LEVEL_INFO, " INFO" )
33 (LOG_LEVEL_ERROR, "ERROR" )
34 (LOG_LEVEL_INFINITY, "????" );
3235
33 void debugLog(const char *str, ...) {
34 #ifdef SDLAPP_DEBUG_LOG
36 // LoggerMessage
3537
36 FILE *log;
38 LoggerMessage::LoggerMessage(int level, const std::string& message)
39 : level(level), message(message) {
40 }
3741
38 if (firstEntry) {
42 // Logger
3943
40 log = fopen(SDLAPP_DEBUG_LOG, "w");
44 Logger::Logger(int level, FILE* stream, int hist_capacity) {
45 init(level, stream, hist_capacity);
46 }
4147
42 if(log==0) {
43 fprintf(stderr, "could not create %s\n", SDLAPP_DEBUG_LOG);
44 exit(1);
45 }
48 void Logger::init(int level, FILE* stream, int hist_capacity) {
49 this->level = level;
50 this->stream = stream;
51 this->hist_capacity = hist_capacity;
52 }
4653
47 firstEntry=false;
48 } else {
54 void Logger::message(int level, const std::string& message) {
4955
50 log = fopen(SDLAPP_DEBUG_LOG, "a");
56 if(this->level > level) return;
5157
52 if(log==0) {
53 fprintf(stderr, "could not append to %s\n", SDLAPP_DEBUG_LOG);
54 exit(1);
55 }
58 if(stream != 0) {
59 fprintf(stderr, "%s: %s\n", log_levels[level].c_str(), message.c_str());
5660 }
61
62 if(!hist_capacity) return;
63
64 while(history.size() >= hist_capacity) {
65 history.pop_front();
66 }
67
68 history.push_back(LoggerMessage(level, message));
69 }
70
71 void warnLog(const char *str, ...) {
72
73 if(!logger || logger->getLevel() > LOG_LEVEL_WARN) return;
74
75 char msgbuff[65536];
5776
5877 va_list vl;
5978
6079 va_start(vl, str);
61 vfprintf(log, str, vl);
80 vsnprintf(msgbuff, 65536, str, vl);
6281 va_end(vl);
6382
64 fclose(log);
83 logger->message( LOG_LEVEL_WARN, msgbuff );
84 }
6585
66 #endif
86 void debugLog(const char *str, ...) {
87
88 if(!logger || logger->getLevel() > LOG_LEVEL_DEBUG) return;
89
90 char msgbuff[65536];
91
92 va_list vl;
93
94 va_start(vl, str);
95 vsnprintf(msgbuff, 65536, str, vl);
96 va_end(vl);
97
98 logger->message( LOG_LEVEL_DEBUG, msgbuff );
6799 }
100
101 void infoLog(const char *str, ...) {
102
103 if(!logger || logger->getLevel() > LOG_LEVEL_INFO) return;
104
105 char msgbuff[65536];
106
107 va_list vl;
108
109 va_start(vl, str);
110 vsnprintf(msgbuff, 65536, str, vl);
111 va_end(vl);
112
113 logger->message( LOG_LEVEL_INFO, msgbuff );
114 }
115
116 void errorLog(const char *str, ...) {
117
118 if(!logger || logger->getLevel() > LOG_LEVEL_ERROR) return;
119
120 char msgbuff[65536];
121
122 va_list vl;
123
124 va_start(vl, str);
125 vsnprintf(msgbuff, 65536, str, vl);
126 va_end(vl);
127
128 logger->message( LOG_LEVEL_ERROR, msgbuff );
129 }
130
131 Logger* logger = new Logger(LOG_LEVEL_ERROR, stderr, 0);
2626
2727 #ifndef LOGGER_H
2828 #define LOGGER_H
29
29
30 #include "gl.h"
31
32 #include <map>
33 #include <deque>
34 #include <string>
35
36 #include <boost/assign/list_of.hpp>
37
3038 #include <stdio.h>
3139 #include <stdarg.h>
3240 #include <stdlib.h>
3341
42 enum logger_level { LOG_LEVEL_PEDANTIC, LOG_LEVEL_WARN, LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_ERROR, LOG_LEVEL_INFINITY };
43
44 class LoggerMessage {
45
46 public:
47 LoggerMessage(int level, const std::string& message);
48
49 int level;
50 std::string message;
51 };
52
53 class Logger {
54 protected:
55 std::deque<LoggerMessage> history;
56 int hist_capacity;
57 FILE* stream;
58 int level;
59 public:
60
61 void setLevel(int level) { this->level = level; };
62 int getLevel() const { return level; }
63
64 Logger();
65 Logger(int level, FILE* stream, int history_capacity = 0);
66
67 void init(int level, FILE* stream, int history_capacity);
68
69 void message(int level, const std::string& message);
70 };
71
72 void warnLog(const char *args, ...);
3473 void debugLog(const char *args, ...);
74 void infoLog(const char *args, ...);
75 void errorLog(const char *args, ...);
76
77 extern Logger* logger;
3578
3679 #endif
3232 hidden = false;
3333 timeout = 3.0f;
3434 idle = timeout;
35
36 sdl_default_cursor = SDL_GetCursor();
37
38
39 Uint8 data[4*32];
40 Uint8 mask[4*32];
41
42 memset(data, 0, sizeof(data));
43 memset(mask, 0, sizeof(mask));
44
45 sdl_hidden_cursor = SDL_CreateCursor(data, mask, 32, 32, 0, 0);
46 }
47
48 MouseCursor::~MouseCursor() {
49 SDL_SetCursor(sdl_default_cursor);
50 SDL_FreeCursor(sdl_hidden_cursor);
3551 }
3652
3753 void MouseCursor::useSystemCursor(bool system_cursor) {
3854 this->system_cursor = system_cursor;
3955
4056 if(!hidden) {
41 if(system_cursor) SDL_ShowCursor(true);
42 else SDL_ShowCursor(false);
57 if(system_cursor) SDL_SetCursor(sdl_default_cursor);
58 else SDL_SetCursor(sdl_hidden_cursor);
4359 } else {
44 SDL_ShowCursor(false);
60 SDL_SetCursor(sdl_hidden_cursor);
4561 }
4662 }
4763
5268 if(show) idle = 0.0;
5369
5470 if(system_cursor) {
55 if(show) SDL_ShowCursor(true);
56 else SDL_ShowCursor(false);
71 if(show) SDL_SetCursor(sdl_default_cursor);
72 else SDL_SetCursor(sdl_hidden_cursor);
5773 }
5874 }
5975
90106 }
91107
92108 bool MouseCursor::hasFocus() const {
109 #if SDL_VERSION_ATLEAST(1,3,0)
110 return (SDL_GetMouseFocus() == display.sdl_window);
111 #else
93112 return (SDL_GetAppState() & SDL_APPMOUSEFOCUS);
113 #endif
94114 }
95115
96116 void MouseCursor::setCursorTexture(TextureResource* texture) {
97117 cursortex = texture;
98118 }
99119
100 void MouseCursor::updatePos(const vec2f& pos) {
120 void MouseCursor::updatePos(const vec2& pos) {
101121 mousepos = pos;
102122 idle = 0.0f;
103123 }
115135 glEnable(GL_TEXTURE_2D);
116136 glEnable(GL_BLEND);
117137
118 glBindTexture(GL_TEXTURE_2D, cursortex->textureid);
138 cursortex->bind();
119139
120140 glTranslatef(mousepos.x, mousepos.y, 0.0f);
121141
3131
3232 class MouseCursor {
3333
34 vec2f mousepos;
34 vec2 mousepos;
3535
3636 bool hidden;
3737 bool system_cursor;
3838
3939 float idle;
4040 float timeout;
41
42 SDL_Cursor* sdl_default_cursor;
43 SDL_Cursor* sdl_hidden_cursor;
4144
4245 TextureResource* cursortex;
4346 public:
4447 MouseCursor();
45
46 vec2f getPos() const { return mousepos; }
48 ~MouseCursor();
49
50 vec2 getPos() const { return mousepos; }
4751
4852 bool leftButtonPressed() const;
4953 bool rightButtonPressed() const;
5559 bool isVisible() const;
5660 bool hasFocus() const;
5761
58 void updatePos(const vec2f& pos);
62 void updatePos(const vec2& pos);
5963
6064 void showCursor(bool show);
6165 void useSystemCursor(bool system_cursor);
3030 d = 0.0f;
3131 }
3232
33 Plane::Plane(const vec3f & v1, const vec3f & v2, const vec3f & v3) {
34 vec3f edge1 = v1 - v2;
35 vec3f edge2 = v3 - v2;
33 Plane::Plane(const vec3 & v1, const vec3 & v2, const vec3 & v3) {
34 vec3 edge1 = v1 - v2;
35 vec3 edge2 = v3 - v2;
3636
37 normal = edge2.cross(edge1);
38 normal.normalize();
37 normal = normalise(glm::cross(edge2, edge1));
3938
4039 point = v2;
4140
42 d = -(normal.dot(point));
41 d = -(glm::dot(normal, point));
4342 }
4443
45 float Plane::distance(const vec3f & p) const{
46 return (d + normal.dot(p));
44 float Plane::distance(const vec3 & p) const{
45 return d + glm::dot(normal, p);
4746 }
4847
3232
3333 class Plane {
3434 public:
35 vec3f normal, point;
35 vec3 normal, point;
3636 float d;
3737
3838 Plane();
39 Plane(const vec3f & v1, const vec3f & v2, const vec3f & v3);
39 Plane(const vec3 & v1, const vec3 & v2, const vec3 & v3);
4040
41 float distance(const vec3f & p) const;
41 float distance(const vec3 & p) const;
4242 };
4343
4444 #endif
4646
4747 cond = SDL_CreateCond();
4848 mutex = SDL_CreateMutex();
49
50 #if SDL_VERSION_ATLEAST(1,3,0)
51 thread = SDL_CreateThread( dumper_thread, "frame_exporter", this );
52 #else
4953 thread = SDL_CreateThread( dumper_thread, this );
54 #endif
5055 }
5156
5257 FrameExporter::~FrameExporter() {
53 stopDumpThr();
58 stop();
5459
5560 SDL_KillThread(thread);
5661 SDL_DestroyCond(cond);
6368 delete[] pixels_out;
6469 }
6570
66 void FrameExporter::stopDumpThr() {
67 if(dumper_thread_state == FRAME_EXPORTER_STOPPED) return;
71 void FrameExporter::stop() {
72 if(dumper_thread_state == FRAME_EXPORTER_STOPPED || dumper_thread_state == FRAME_EXPORTER_EXIT) return;
6873
6974 SDL_mutexP(mutex);
7075
160165 }
161166
162167 PPMExporter::~PPMExporter() {
163 stopDumpThr();
168 stop();
164169
165170 if(filename.size()>0)
166171 ((std::fstream*)output)->close();
4949 SDL_cond* cond;
5050 int dumper_thread_state;
5151
52 void stopDumpThr();
5352 public:
5453 FrameExporter();
5554 virtual ~FrameExporter();
55 void stop();
5656 void dump();
5757 void dumpThr();
5858 virtual void dumpImpl() {};
5353 return;
5454 }
5555
56 vec2f average = bounds.centre();
57
58 vec2f middle = average - bounds.min;
59
60 vec2f relmax = bounds.max-bounds.min;
56 vec2 average = bounds.centre();
57
58 vec2 middle = average - bounds.min;
59
60 vec2 relmax = bounds.max-bounds.min;
6161
6262 Bounds2D newbounds;
6363
6464 children.reserve(4);
6565
6666 //top left
67 newbounds = Bounds2D( bounds.min + vec2f(0.0, 0.0), bounds.min + middle );
67 newbounds = Bounds2D( bounds.min + vec2(0.0, 0.0), bounds.min + middle );
6868 children.push_back(new QuadNode(tree, this, newbounds, depth));
6969
7070 //top right
71 newbounds = Bounds2D( bounds.min + vec2f(middle.x, 0.0), bounds.min + vec2f(relmax.x,middle.y) );
71 newbounds = Bounds2D( bounds.min + vec2(middle.x, 0.0), bounds.min + vec2(relmax.x,middle.y) );
7272 children.push_back(new QuadNode(tree, this, newbounds, depth));
7373
7474 //bottom left
75 newbounds = Bounds2D( bounds.min + vec2f(0.0, middle.y), bounds.min + vec2f(middle.x,relmax.y) );
75 newbounds = Bounds2D( bounds.min + vec2(0.0, middle.y), bounds.min + vec2(middle.x,relmax.y) );
7676 children.push_back(new QuadNode(tree, this, newbounds, depth));
7777
7878 //bottom right
184184
185185
186186
187 int QuadNode::getItemsAt(std::set<QuadItem*>& itemset, vec2f pos) {
187 int QuadNode::getItemsAt(std::set<QuadItem*>& itemset, vec2 pos) {
188188
189189 if(!items.empty()) {
190190 int items_added = 0;
262262
263263 }
264264
265 void QuadNode::visitItemsAt(const vec2f & pos, VisitFunctor<QuadItem> & visit){
265 void QuadNode::visitItemsAt(const vec2 & pos, VisitFunctor<QuadItem> & visit){
266266
267267 if(!items.empty()){
268268
283283 }
284284
285285
286 int QuadNode::getChildIndex(const vec2f & pos) const{
286 int QuadNode::getChildIndex(const vec2 & pos) const{
287287
288288 if(children.empty()) return -1;
289289
451451 }
452452
453453
454 int QuadTree::getItemsAt(std::set<QuadItem*>& itemset, vec2f pos) {
454 int QuadTree::getItemsAt(std::set<QuadItem*>& itemset, vec2 pos) {
455455 int return_count = root->getItemsAt(itemset, pos);
456456
457457 return return_count;
472472 }
473473
474474
475 void QuadTree::visitItemsAt(const vec2f & pos, VisitFunctor<QuadItem> & visit){
475 void QuadTree::visitItemsAt(const vec2 & pos, VisitFunctor<QuadItem> & visit){
476476 return root->visitItemsAt(pos, visit);
477477 }
478478
3030 #include <set>
3131 #include <list>
3232
33 #include "vectors.h"
33 #include "gl.h"
3434 #include "bounds.h"
3535 #include "frustum.h"
3636
6161
6262 QuadTree* tree;
6363
64 int getChildIndex(const vec2f & pos) const;
64 int getChildIndex(const vec2 & pos) const;
6565 void addToChild(QuadItem* item);
6666
6767 int depth;
7676
7777 void addItem(QuadItem* item); //if not subdivided, subdivide, add to correct subdivided node.
7878
79 int getItemsAt(std::set<QuadItem*>& itemset, vec2f pos);
79 int getItemsAt(std::set<QuadItem*>& itemset, vec2 pos);
8080 void getLeavesInFrustum(std::set<QuadNode*>& nodeset, Frustum& frustum);
8181 int getItemsInFrustum(std::set<QuadItem*>& itemset, Frustum& frustum);
8282 int getItemsInBounds(std::set<QuadItem*>& itemset, Bounds2D& bounds) const;
8383
8484 void visitItemsInFrustum(const Frustum & frustum, VisitFunctor<QuadItem> & visit);
8585 void visitItemsInBounds(const Bounds2D & bounds, VisitFunctor<QuadItem> & visit);
86 void visitItemsAt(const vec2f & pos, VisitFunctor<QuadItem> & visit);
86 void visitItemsAt(const vec2 & pos, VisitFunctor<QuadItem> & visit);
8787 void visitLeavesInFrustum(const Frustum & frustum, VisitFunctor<QuadNode> & visit);
8888
8989 bool empty();
104104 int max_node_depth;
105105 int max_node_items;
106106
107 int getItemsAt(std::set<QuadItem*>& itemset, vec2f pos);
107 int getItemsAt(std::set<QuadItem*>& itemset, vec2 pos);
108108 void getLeavesInFrustum(std::set<QuadNode*>& nodeset, Frustum& frustum);
109109 int getItemsInFrustum(std::set<QuadItem*>& itemset, Frustum& frustum);
110110 int getItemsInBounds(std::set<QuadItem*>& itemset, Bounds2D& bounds) const;
111111
112 void visitItemsAt(const vec2f & pos, VisitFunctor<QuadItem> & visit);
112 void visitItemsAt(const vec2 & pos, VisitFunctor<QuadItem> & visit);
113113 void visitLeavesInFrustum(const Frustum & frustum, VisitFunctor<QuadNode> & visit);
114114 void visitItemsInFrustum(const Frustum & frustum, VisitFunctor<QuadItem> & visit);
115115 void visitItemsInBounds(const Bounds2D & bounds, VisitFunctor<QuadItem> & visit);
3333 return resource_dir;
3434 }
3535
36 void ResourceManager::setDir(std::string resource_dir) {
36 void ResourceManager::setDir(const std::string& resource_dir) {
3737 this->resource_dir = resource_dir;
3838 }
3939
4949 ResourceManager::~ResourceManager() {
5050 }
5151
52 Resource* ResourceManager::grab(std::string name) {
52 Resource* ResourceManager::grab(const std::string& name) {
5353 //debugLog("grabing %s\n", name.c_str());
5454 Resource* r = resources[name];
5555
6363 }
6464
6565 void ResourceManager::release(Resource* resource) {
66 Resource* r = resources[resource->name];
66 Resource* r = resources[resource->resource_name];
6767
6868 if(r==0) return;
6969
7272
7373 if(r->refcount()<=0) {
7474 //debugLog("no refs to %s, deleting\n", name.c_str());
75 resources.erase(r->name); //sufficient?
75 resources.erase(r->resource_name); //sufficient?
7676 delete r;
7777 }
7878 }
3232 #include <cstring>
3333 #include <stdexcept>
3434
35 #ifdef _WIN32
36 #include "windows.h"
37 #endif
38
3935 class ResourceException : public std::exception {
4036 protected:
4137 std::string resource;
4945 class Resource {
5046 int refs;
5147 public:
52 std::string name;
53 Resource(std::string name) { this->name = name; refs=0; };
48 std::string resource_name;
49 Resource() { refs =0; };
50 Resource(const std::string& resource_name) : resource_name(resource_name), refs(0) {};
51
52 void setResourceName(const std::string& resource_name) {
53 if(this->resource_name.empty()) this->resource_name = resource_name;
54 };
55
5456 int refcount() { return refs; };
5557 void addref() { refs++; };
5658 void deref() { refs--; };
6365 std::string resource_dir;
6466 public:
6567
66 void setDir(std::string resource_dir);
68 void setDir(const std::string& resource_dir);
6769 std::string getDir();
6870
6971 ResourceManager();
7274 void purge();
7375
7476 void release(Resource* resource);
75 Resource* grab(std::string name);
76 virtual Resource* create(std::string name) { return 0; };
77 Resource* grab(const std::string& resource_name);
78 virtual Resource* create(const std::string& name) { return 0; };
7779 };
7880
7981 #endif
4040
4141 #ifdef _WIN32
4242 HWND gSDLAppConsoleWindow = 0;
43 bool using_parent_console = false;
44
45 bool SDLAppAttachToConsole() {
46 if(using_parent_console) return true;
47 if(gSDLAppConsoleWindow != 0) return false;
48
49 // if TERM is set to msys, try and attach to console
50 // could possibly add other supported TERMs here if there are any
51
52 char* term = getenv("TERM");
53 if(!term || strcmp(term, "msys")!=0) return false;
54
55 if(AttachConsole(ATTACH_PARENT_PROCESS)) {
56
57 // send stdout to console unless already redirected
58 if (_fileno(stdout) == -1 || _get_osfhandle(fileno(stdout)) == -1) {
59 freopen("conout$","w", stdout);
60 }
61
62 // send stderr to console unless already redirected
63 if (_fileno(stderr) == -1 || _get_osfhandle(fileno(stderr)) == -1) {
64 freopen("conout$","w", stderr);
65 }
66
67 using_parent_console = true;
68 }
69
70 return using_parent_console;
71 }
4372
4473 void SDLAppCreateWindowsConsole() {
45 if(gSDLAppConsoleWindow !=0) return;
74 if(using_parent_console || gSDLAppConsoleWindow != 0) return;
75
76 //try to attach to the available console if there is one
77
78 if(SDLAppAttachToConsole()) return;
4679
4780 //create a console on Windows so users can see messages
48
4981 //find an available name for our window
82
83 char consoleTitle[512];
5084 int console_suffix = 0;
51 char consoleTitle[512];
5285 sprintf(consoleTitle, "%s Console", gSDLAppTitle.c_str());
5386
5487 while(FindWindow(0, consoleTitle)) {
71104 SDL_Delay(100);
72105 }
73106
74 //disable the close button so the user cant crash gource
107 //disable the close button so the user cant crash the application
75108 HMENU hm = GetSystemMenu(gSDLAppConsoleWindow, false);
76109 DeleteMenu(hm, SC_CLOSE, MF_BYCOMMAND);
77110 }
112145 printf("%s\n", msg.c_str());
113146
114147 #ifdef _WIN32
115 printf("\nPress Enter\n");
116 getchar();
148 if(gSDLAppConsoleWindow) {
149 printf("\nPress Enter\n");
150 getchar();
151 }
117152 #endif
118153
119154 exit(0);
131166 fprintf(stderr, "Try '%s --help' for more information.\n\n", gSDLAppExec.c_str());
132167
133168 #ifdef _WIN32
134 fprintf(stderr, "Press Enter\n");
135 getchar();
169 if(gSDLAppConsoleWindow) {
170 fprintf(stderr, "Press Enter\n");
171 getchar();
172 }
136173 #endif
137174
138175 exit(1);
263300 fps=0;
264301 return_code=0;
265302 appFinished=false;
303 min_delta_msec = 8;
266304 }
267305
268306 void SDLApp::updateFramerate() {
308346
309347 // cant have delta ticks be less than 8ms
310348 buffer_msec += delta_msec;
311 if(buffer_msec < 8) {
349 if(buffer_msec < min_delta_msec) {
312350 SDL_Delay(1);
313351 continue;
314352 }
335373
336374 switch(event.type) {
337375 case SDL_QUIT:
338 appFinished=true;
376 quit();
339377 break;
340378
341379 case SDL_MOUSEMOTION:
342380 mouseMove(&event.motion);
343381 break;
382
383 #if SDL_VERSION_ATLEAST(1,3,0)
384 case SDL_MOUSEWHEEL:
385 mouseWheel(&event.wheel);
386 break;
387
388 case SDL_WINDOWEVENT:
389 if(event.window.event == SDL_WINDOWEVENT_RESIZED) {
390 resize(event.window.data1, event.window.data2);
391 }
392 break;
393 #else
394 case SDL_VIDEORESIZE:
395 resize(event.resize.w, event.resize.h);
396 break;
397 #endif
344398
345399 case SDL_MOUSEBUTTONDOWN:
346400 mouseClick(&event.button);
2727 #ifndef SDLAPP_H
2828 #define SDLAPP_H
2929
30 #ifdef _WIN32
31
32 #ifdef _WIN32_WINNT
33 #undef _WIN32_WINNT
34 #endif
35
36 #define _WIN32_WINNT 0x0501
37 #include "windows.h"
38 #endif
39
3040 #include "display.h"
3141 #include "logger.h"
3242
4151 extern std::string gSDLAppExec;
4252
4353 #ifdef _WIN32
54 extern HWND gSDLAppConsoleWindow;
55
56 bool SDLAppAttachToConsole();
4457 void SDLAppCreateWindowsConsole();
4558 void SDLAppResizeWindowsConsole(int height);
4659 #endif
6275 SDLAppException(const char* str, ...) : showhelp(false) {
6376
6477 va_list vl;
65 char msg[1024];
78 char msg[4096];
6679
6780 va_start(vl, str);
68 vsnprintf(msg, 1024, str, vl);
81 vsnprintf(msg, 4096, str, vl);
6982 va_end(vl);
7083
7184 message = std::string(msg);
8699 int fps_updater;
87100 int return_code;
88101
89
90102 void updateFramerate();
91103 protected:
104 int min_delta_msec;
92105 bool appFinished;
93106 void stop(int return_code);
94107 public:
99112
100113 int run();
101114
115 virtual void resize(int width, int height) {};
116
102117 virtual void update(float t, float dt) {};
103118 virtual void init() {};
104119
105120 virtual void logic(float t, float dt) {};
106121 virtual void draw(float t, float dt) {};
107122
123 virtual void quit() { appFinished = true; };
124
108125 virtual void mouseMove(SDL_MouseMotionEvent *e) {};
109126 virtual void mouseClick(SDL_MouseButtonEvent *e) {};
110127 virtual void keyPress(SDL_KeyboardEvent *e) {};
128
129 #if SDL_VERSION_ATLEAST(1,3,0)
130 virtual void mouseWheel(SDL_MouseWheelEvent *e) {};
131 #endif
111132
112133 int returnCode();
113134 bool isFinished();
4141 int ret = fcntl(STDIN_FILENO, F_GETFL, 0);
4242
4343 if (fcntl (STDIN_FILENO, F_SETFL, ret | O_NONBLOCK) < 0) {
44 debugLog("fcntl(stdin) failed\n");
44 debugLog("fcntl(stdin) failed");
4545 fcntl_fail = true;
4646 }
4747 #endif
213213 bool finished = false;
214214
215215 if(stream->fail() || stream->eof()) {
216 debugLog("stream is finished\n");
216 //debugLog("stream is finished");
217217 finished=true;
218218 }
219219
1717 #include "settings.h"
1818
1919 Regex SDLAppSettings_rect_regex("^([0-9.]+)x([0-9.]+)$");
20 Regex SDLAppSettings_viewport_regex("^([0-9.]+)x([0-9.]+)(!)?$");
2021
2122 SDLAppSettings::SDLAppSettings() {
2223 setDisplayDefaults();
5354
5455 void SDLAppSettings::setDisplayDefaults() {
5556 display_width = 1024;
57 #ifdef __APPLE__
58 display_height = 640;
59 #else
5660 display_height = 768;
61 #endif
5762 fullscreen = false;
5863 multisample = false;
5964 transparent = false;
65 resizable = true;
6066 vsync = true;
6167
6268 output_ppm_filename = "";
6874 ConfSection* section = new ConfSection("display");
6975
7076 char viewportbuff[256];
71 snprintf(viewportbuff, 256, "%dx%d", display_width, display_height);
77 snprintf(viewportbuff, 256, "%dx%d%s", display_width, display_height, resizable ? "" : "!" );
7278
7379 std::string viewport = std::string(viewportbuff);
7480
8187 section->setEntry(new ConfEntry("multi-sampling", multisample));
8288
8389 if(!vsync) {
84 section->setEntry(new ConfEntry("no-vsync", vsync));
85 }
86
90 section->setEntry(new ConfEntry("no-vsync", true));
91 }
92
8793 conf.setSection(section);
8894 }
8995
90 bool SDLAppSettings::parseRectangle(const std::string& value, int* x, int* y) {
96 bool SDLAppSettings::parseRectangle(const std::string& value, int& x, int& y) {
9197
9298 std::vector<std::string> matches;
9399
94100 if(SDLAppSettings_rect_regex.match(value, &matches)) {
95 if(x!=0) *x = atoi(matches[0].c_str());
96 if(y!=0) *y = atoi(matches[1].c_str());
101
102 x = atoi(matches[0].c_str());
103 y = atoi(matches[1].c_str());
104
97105 return true;
98106 }
99107
100108 return false;
101109 }
110
111 bool SDLAppSettings::parseViewport(const std::string& value, int& x, int& y, bool& no_resize) {
112
113 std::vector<std::string> matches;
114
115 if(SDLAppSettings_viewport_regex.match(value, &matches)) {
116 x = atoi(matches[0].c_str());
117 y = atoi(matches[1].c_str());
118
119 if(matches.size()>2) no_resize = true;
120
121 if(x>0 && y>0) return true;
122 }
123
124 return false;
125 }
126
102127
103128 void SDLAppSettings::parseArgs(int argc, char *argv[], ConfFile& conffile, std::vector<std::string>* files) {
104129
148173
149174 int width = 0;
150175 int height = 0;
151
152 if(parseRectangle(displayarg, &width, &height)) {
176 bool no_resize = false;
177
178 if(parseViewport(displayarg, width, height, no_resize)) {
153179 if(width>0 && height>0) {
154180
155181 ConfSection* display_settings = conffile.getSection("display");
158184 display_settings = conffile.addSection("display");
159185 }
160186
161 display_settings->setEntry("viewport", args);
187 display_settings->setEntry("viewport", displayarg);
188
162189 continue;
163190 }
164191 }
230257
231258 std::string viewport = entry->getString();
232259
260
261
233262 int width = 0;
234263 int height = 0;
235
236 size_t x = viewport.rfind("x");
237
238 if(x != std::string::npos && x != 0 && x != viewport.size()-1) {
239 std::string widthstr = viewport.substr(0, x);
240 std::string heightstr = viewport.substr(x+1);
241
242 width = atoi(widthstr.c_str());
243 height = atoi(heightstr.c_str());
244 }
245
246 if(width>0 && height>0) {
247 display_width = width;
248 display_height = height;
264 bool no_resize = false;
265
266 if(parseViewport(viewport, width, height, no_resize)) {
267 display_width = width;
268 display_height = height;
269 if(no_resize) resizable = false;
249270 } else {
250271 conffile.invalidValueException(entry);
251272 }
270291 if(display_settings->getBool("no-vsync")) {
271292 vsync = false;
272293 }
273
294
274295 if((entry = display_settings->getEntry("output-ppm-stream")) != 0) {
275296
276297 if(!entry->hasValue()) {
3131
3232 virtual void commandLineOption(const std::string& name, const std::string& value) {}
3333
34 bool parseRectangle(const std::string& value, int* x=0, int* y=0);
34 bool parseRectangle(const std::string& value, int& x, int& y);
35 bool parseViewport(const std::string& value, int& x, int& y, bool& no_resize);
36
3537 public:
3638 int display_width;
3739 int display_height;
3840 bool multisample;
3941 bool fullscreen;
4042 bool transparent;
43 bool resizable;
4144 bool vsync;
42
45
4346 std::string output_ppm_filename;
4447 int output_framerate;
4548
3030
3131 //ShaderManager
3232
33 Regex Shader_pre_include("\\s*#include\\s*\"([^\"]+)\"");
33 ShaderManager::ShaderManager() {
34 warnings = false;
35 }
36
37 void ShaderManager::enableWarnings(bool warnings) {
38 this->warnings = warnings;
39 }
40
41 Regex Shader_pre_version("^\\s*#version\\s*(\\d+)\\s*$");
42 Regex Shader_pre_extension("^\\s*#extension\\s*([a-zA-Z0-9_]+)\\s+:\\s+(enable|require|warn|disable)\\s*$");
43 Regex Shader_pre_include("^\\s*#include\\s*\"([^\"]+)\"");
44 Regex Shader_uniform_def("^\\s*uniform\\s+(\\w+)\\s+(\\w+)(?:\\[(\\d+)\\])?\\s*;\\s*$");
45 Regex Shader_error_line("\\b\\d*\\((\\d+)\\) : error ");
46 Regex Shader_error2_line("\\bERROR: \\d+:(\\d+):");
47 Regex Shader_warning_line("\\b\\d*\\((\\d+)\\) : warning ");
3448
3549 Shader* ShaderManager::grab(const std::string& shader_prefix) {
3650 Resource* s = resources[shader_prefix];
4559 return (Shader*) s;
4660 }
4761
48 //Shader
49 Shader::Shader(const std::string& prefix) : Resource(prefix) {
50
51 std::string shader_dir = shadermanager.getDir();
52
53 std::string vertexSrc = shader_dir + prefix + std::string(".vert");
54 std::string fragmentSrc = shader_dir + prefix + std::string(".frag");
55
56 vertexShader = load(vertexSrc, GL_VERTEX_SHADER);
57 fragmentShader = load(fragmentSrc, GL_FRAGMENT_SHADER);
58
59 makeProgram();
60 }
61
62 Shader::~Shader() {
63 glDeleteShader(vertexShader);
64 glDeleteShader(fragmentShader);
65 glDeleteProgram(shaderProg);
66 }
67
68 void Shader::makeProgram() {
69 shaderProg = glCreateProgram();
70 glAttachShader(shaderProg,fragmentShader);
71 glAttachShader(shaderProg,vertexShader);
72 glLinkProgram(shaderProg);
73 }
74
75 void Shader::checkError(const std::string& filename, GLenum shaderRef) {
76
77 GLint compile_success;
78 glGetShaderiv(shaderRef, GL_COMPILE_STATUS, &compile_success);
62 void ShaderManager::manage(Shader* shader) {
63
64 if(shader->resource_name.empty()) {
65 throw SDLAppException("Cannot manage shader with no resource name");
66 }
67
68 if(resources[shader->resource_name] != 0) {
69 throw SDLAppException("A shader resource already exists under the name '%s'", shader->resource_name.c_str());
70 }
71
72 resources[shader->resource_name] = shader;
73
74 shader->addref();
75 }
76
77 void ShaderManager::unload() {
78 for(std::map<std::string, Resource*>::iterator it= resources.begin(); it!=resources.end();it++) {
79 ((Shader*)it->second)->unload();
80 }
81 }
82
83 void ShaderManager::reload() {
84 for(std::map<std::string, Resource*>::iterator it= resources.begin(); it!=resources.end();it++) {
85 ((Shader*)it->second)->load();
86 }
87 }
88
89 //ShaderUniform
90
91 ShaderUniform::ShaderUniform(Shader* shader, const std::string& name, int uniform_type, const std::string& type_name)
92 : shader(shader), name(name), location(-1), initialized(false), modified(false), baked(false), uniform_type(uniform_type), type_name(type_name) {
93 }
94
95 void ShaderUniform::unload() {
96 location = -1;
97 }
98
99 const std::string& ShaderUniform::getName() const {
100 return name;
101 }
102
103 GLint ShaderUniform::getLocation() {
104
105 // TODO: (re-)compiling the shader should break the uniform location caching.
106
107 if(location != -1) return location;
108
109 location = glGetUniformLocation( shader->getProgram(), name.c_str() );
110
111 return location;
112 }
113
114 void ShaderUniform::setBaked(bool baked) {
115 if(this->baked == baked) return;
116 this->baked = baked;
117 modified = true;
118 }
119
120
121 //FloatShaderUniform
122
123 FloatShaderUniform::FloatShaderUniform(Shader* shader, const std::string& name, float value) :
124 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_FLOAT, "float") {
125 }
126
127 void FloatShaderUniform::setValue(float value) {
128 if(baked && this->value == value) return;
129
130 this->value = value;
131 modified = true;
132 initialized = true;
133 }
134
135 void FloatShaderUniform::apply() {
136 glUniform1f(getLocation(), value);
137 }
138
139 float FloatShaderUniform::getValue() const {
140 return value;
141 }
142
143 void FloatShaderUniform::write(std::string& content) const {
144
145 char buff[256];
146
147 if(baked) {
148 // snprintf(buff, 256, "const %s %s = %e;\n", type_name.c_str(), name.c_str(), value);
149 snprintf(buff, 256, "#define %s %e\n", name.c_str(), value);
150 } else {
151 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
152 }
153
154 content += buff;
155 }
156
157 //IntShaderUniform
158
159 IntShaderUniform::IntShaderUniform(Shader* shader, const std::string& name, int value) :
160 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_INT, "int") {
161 }
162
163 void IntShaderUniform::setValue(int value) {
164 if(baked && this->value == value) return;
165
166 this->value = value;
167 modified = true;
168 initialized = true;
169 }
170
171 void IntShaderUniform::apply() {
172 glUniform1i(getLocation(), value);
173 }
174
175 float IntShaderUniform::getValue() const {
176 return value;
177 }
178
179 void IntShaderUniform::write(std::string& content) const {
180
181 char buff[256];
182
183 if(baked) {
184 snprintf(buff, 256, "#define %s %d\n", name.c_str(), value);
185 } else {
186 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
187 }
188
189 content += buff;
190 }
191
192 //BoolShaderUniform
193
194 BoolShaderUniform::BoolShaderUniform(Shader* shader, const std::string& name, bool value) :
195 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_BOOL, "bool") {
196 }
197
198 void BoolShaderUniform::setValue(bool value) {
199 if(baked && this->value == value) return;
200
201 this->value = value;
202 modified = true;
203 initialized = true;
204 }
205
206 void BoolShaderUniform::apply() {
207 glUniform1i(getLocation(), value);
208 }
209
210 float BoolShaderUniform::getValue() const {
211 return value;
212 }
213
214 void BoolShaderUniform::write(std::string& content) const {
215
216 char buff[256];
217
218 if(baked) {
219 snprintf(buff, 256, "#define %s %s\n", name.c_str(), value ? "true" : "false");
220 } else {
221 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
222 }
223
224 content += buff;
225 }
226
227 //Sampler1DShaderUniform
228
229 Sampler1DShaderUniform::Sampler1DShaderUniform(Shader* shader, const std::string& name, int value) :
230 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_SAMPLER_1D, "sampler1D") {
231 }
232
233 void Sampler1DShaderUniform::setValue(int value) {
234 if(baked && this->value == value) return;
235
236 this->value = value;
237 modified = true;
238 initialized = true;
239 }
240
241 void Sampler1DShaderUniform::setBaked(bool baked) {
242 }
243
244 void Sampler1DShaderUniform::write(std::string& content) const {
245 char buff[256];
246 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
247 content += buff;
248 }
249
250 void Sampler1DShaderUniform::apply() {
251 glUniform1i(getLocation(), value);
252 }
253
254 float Sampler1DShaderUniform::getValue() const {
255 return value;
256 }
257
258 //Sampler2DShaderUniform
259
260 Sampler2DShaderUniform::Sampler2DShaderUniform(Shader* shader, const std::string& name, int value) :
261 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_SAMPLER_2D, "sampler2D") {
262 }
263
264 void Sampler2DShaderUniform::setValue(int value) {
265 if(baked && this->value == value) return;
266
267 this->value = value;
268 modified = true;
269 initialized = true;
270 }
271
272 void Sampler2DShaderUniform::apply() {
273 glUniform1i(getLocation(), value);
274 }
275
276 float Sampler2DShaderUniform::getValue() const {
277 return value;
278 }
279
280 //cant be baked
281 void Sampler2DShaderUniform::setBaked(bool baked) {
282 }
283
284 void Sampler2DShaderUniform::write(std::string& content) const {
285 char buff[256];
286 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
287 content += buff;
288 }
289
290
291 //Vec2ShaderUniform
292
293 Vec2ShaderUniform::Vec2ShaderUniform(Shader* shader, const std::string& name, const vec2& value) :
294 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_VEC2, "vec2") {
295 }
296
297 void Vec2ShaderUniform::setValue(const vec2& value) {
298 if(baked && this->value == value) return;
299
300 this->value = value;
301 modified = true;
302 initialized = true;
303 }
304
305 void Vec2ShaderUniform::apply() {
306 glUniform2fv(getLocation(), 1, glm::value_ptr(value));
307 }
308
309 const vec2& Vec2ShaderUniform::getValue() const {
310 return value;
311 }
312
313 void Vec2ShaderUniform::write(std::string& content) const {
314
315 char buff[256];
316
317 if(baked) {
318 snprintf(buff, 256, "#define %s vec2(%e, %e)\n", name.c_str(), value.x, value.y);
319 } else {
320 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
321 }
322
323 content += buff;
324 }
325
326 //Vec3ShaderUniform
327
328 Vec3ShaderUniform::Vec3ShaderUniform(Shader* shader, const std::string& name, const vec3& value) :
329 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_VEC3, "vec3") {
330 }
331
332
333 void Vec3ShaderUniform::setValue(const vec3& value) {
334 if(baked && this->value == value) return;
335
336 this->value = value;
337 modified = true;
338 initialized = true;
339 }
340
341 void Vec3ShaderUniform::apply() {
342 glUniform3fv(getLocation(), 1, glm::value_ptr(value));
343 }
344
345
346 const vec3& Vec3ShaderUniform::getValue() const {
347 return value;
348 }
349
350 void Vec3ShaderUniform::write(std::string& content) const {
351
352 char buff[256];
353
354 if(baked) {
355 snprintf(buff, 256, "#define %s vec3(%e, %e, %e)\n", name.c_str(), value.x, value.y, value.z);
356 } else {
357 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
358 }
359
360 content += buff;
361 }
362
363 //Vec4ShaderUniform
364
365 Vec4ShaderUniform::Vec4ShaderUniform(Shader* shader, const std::string& name, const vec4& value) :
366 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_VEC4, "vec4") {
367 }
368
369 void Vec4ShaderUniform::setValue(const vec4& value) {
370 if(baked && this->value == value) return;
371
372 this->value = value;
373 modified = true;
374 initialized = true;
375 }
376
377 void Vec4ShaderUniform::apply() {
378 glUniform4fv(getLocation(), 1, glm::value_ptr(value));
379 }
380
381 const vec4& Vec4ShaderUniform::getValue() const {
382 return value;
383 }
384
385 void Vec4ShaderUniform::write(std::string& content) const {
386
387 char buff[256];
388
389 if(baked) {
390 snprintf(buff, 256, "#define %s vec4(%e, %e, %e, %e)\n", name.c_str(), value.x, value.y, value.z, value.w);
391 } else {
392 snprintf(buff, 256, "uniform %s %s;\n", type_name.c_str(), name.c_str());
393 }
394
395 content += buff;
396 }
397
398 //Mat3ShaderUniform
399
400 Mat3ShaderUniform::Mat3ShaderUniform(Shader* shader, const std::string& name, const mat3& value) :
401 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_MAT3, "mat3") {
402 }
403
404 void Mat3ShaderUniform::setValue(const mat3& value) {
405 if(baked && this->value == value) return;
406
407 this->value = value;
408 modified = true;
409 initialized = true;
410 }
411
412 void Mat3ShaderUniform::apply() {
413 glUniformMatrix3fv(getLocation(), 1, 0, glm::value_ptr(value));
414 }
415
416 const mat3& Mat3ShaderUniform::getValue() const {
417 return value;
418 }
419
420 void Mat3ShaderUniform::write(std::string& content) const {
421
422 char buff[1024];
423
424 if(baked) {
425 snprintf(buff, 1024, "#define %s mat3(%e, %e, %e, %e, %e, %e, %e, %e, %e)\n", name.c_str(),
426 value[0][0], value[0][1], value[0][2],
427 value[1][0], value[1][1], value[1][2],
428 value[2][0], value[2][1], value[2][2]);
429
430 } else {
431 snprintf(buff, 1024, "uniform %s %s;\n", type_name.c_str(), name.c_str());
432 }
433
434 content += buff;
435 }
436
437 //Mat4ShaderUniform
438
439 Mat4ShaderUniform::Mat4ShaderUniform(Shader* shader, const std::string& name, const mat4& value) :
440 value(value), ShaderUniform(shader, name, SHADER_UNIFORM_MAT4, "mat4") {
441 }
442
443 void Mat4ShaderUniform::setValue(const mat4& value) {
444 if(baked && this->value == value) return;
445
446 this->value = value;
447 modified = true;
448 initialized = true;
449 }
450
451 void Mat4ShaderUniform::apply() {
452 glUniformMatrix4fv(getLocation(), 1, 0, glm::value_ptr(value));
453 }
454
455 const mat4& Mat4ShaderUniform::getValue() const {
456 return value;
457 }
458
459 void Mat4ShaderUniform::write(std::string& content) const {
460
461 char buff[1024];
462
463 if(baked) {
464 snprintf(buff, 1024, "#define %s mat4(%e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e, %e)\n", name.c_str(),
465 value[0][0], value[0][1], value[0][2], value[0][3],
466 value[1][0], value[1][1], value[1][2], value[1][3],
467 value[2][0], value[2][1], value[2][2], value[2][3],
468 value[3][0], value[3][1], value[3][2], value[3][3]);
469 } else {
470 snprintf(buff, 1024, "uniform %s %s;\n", type_name.c_str(), name.c_str());
471 }
472
473 content += buff;
474 }
475
476
477 //Vec2ArrayShaderUniform
478
479 Vec2ArrayShaderUniform::Vec2ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec2* value) :
480 length(length), ShaderUniform(shader, name, SHADER_UNIFORM_VEC2_ARRAY, "vec2") {
481 this->value = new vec2[length];
482 if(value != 0) copyValue(value);
483 }
484
485 Vec2ArrayShaderUniform::~Vec2ArrayShaderUniform() {
486 if(value) delete[] value;
487 }
488
489 const vec2* Vec2ArrayShaderUniform::getValue() const {
490 return value;
491 }
492
493 void Vec2ArrayShaderUniform::copyValue(const vec2* value) {
494 for(size_t i=0; i<length; i++) {
495 this->value[i] = value[i];
496 }
497 }
498
499 void Vec2ArrayShaderUniform::copyValue(const std::vector<vec2>& value) {
500 for(size_t i=0; i<length; i++) {
501 this->value[i] = value[i];
502 }
503 }
504
505 void Vec2ArrayShaderUniform::setValue(const vec2* value) {
506 if(baked) {
507 bool match = true;
508
509 for(size_t i=0;i<length;i++) {
510 if(value[i] != this->value[i]) {
511 match = false;
512 break;
513 }
514 }
515
516 if(match) return;
517 }
518
519 copyValue(value);
520
521 modified = true;
522 initialized = true;
523 }
524
525 void Vec2ArrayShaderUniform::setValue(const std::vector<vec2>& value) {
526 if(baked) {
527 bool match = true;
528
529 for(size_t i=0;i<length;i++) {
530 if(value[i] != this->value[i]) {
531 match = false;
532 break;
533 }
534 }
535
536 if(match) return;
537 }
538
539 copyValue(value);
540
541 modified = true;
542 initialized = true;
543 }
544
545 void Vec2ArrayShaderUniform::apply() {
546 glUniform2fv(getLocation(), length, glm::value_ptr(value[0]));
547 }
548
549 void Vec2ArrayShaderUniform::write(std::string& content) const {
550
551 char buff[1024];
552
553 if(baked) {
554 snprintf(buff, 1024, "%s[%ld] %s = %s[] (\n", type_name.c_str(), length, name.c_str(), type_name.c_str());
555
556 content += buff;
557
558 for(size_t i=0; i<length; i++) {
559 snprintf(buff, 1024, " %s(%e, %e)", type_name.c_str(), value[i].x, value[i].y);
560 content += buff;
561 if(i<length-1) content += ",\n";
562 else content += "\n);\n";
563 }
564
565 } else {
566 snprintf(buff, 1024, "uniform %s %s[%ld];\n", type_name.c_str(), name.c_str(), length);
567 content += buff;
568 }
569 }
570
571 //Vec3ArrayShaderUniform
572
573 Vec3ArrayShaderUniform::Vec3ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec3* value) :
574 length(length), ShaderUniform(shader, name, SHADER_UNIFORM_VEC3_ARRAY, "vec3") {
575 this->value = new vec3[length];
576 if(value != 0) copyValue(value);
577 }
578
579 Vec3ArrayShaderUniform::~Vec3ArrayShaderUniform() {
580 if(value) delete[] value;
581 }
582
583 const vec3* Vec3ArrayShaderUniform::getValue() const {
584 return value;
585 }
586
587 void Vec3ArrayShaderUniform::copyValue(const vec3* value) {
588 for(size_t i=0; i<length; i++) {
589 this->value[i] = value[i];
590 }
591 }
592
593 void Vec3ArrayShaderUniform::copyValue(const std::vector<vec3>& value) {
594 for(size_t i=0; i<length; i++) {
595 this->value[i] = value[i];
596 }
597 }
598
599 void Vec3ArrayShaderUniform::setValue(const vec3* value) {
600 if(baked) {
601 bool match = true;
602
603 for(size_t i=0;i<length;i++) {
604 if(value[i] != this->value[i]) {
605 match = false;
606 break;
607 }
608 }
609
610 if(match) return;
611 }
612
613 copyValue(value);
614
615 modified = true;
616 initialized = true;
617 }
618
619 void Vec3ArrayShaderUniform::setValue(const std::vector<vec3>& value) {
620 if(baked) {
621 bool match = true;
622
623 for(size_t i=0;i<length;i++) {
624 if(value[i] != this->value[i]) {
625 match = false;
626 break;
627 }
628 }
629
630 if(match) return;
631 }
632
633 copyValue(value);
634
635 modified = true;
636 initialized = true;
637 }
638
639 void Vec3ArrayShaderUniform::apply() {
640 glUniform3fv(getLocation(), length, glm::value_ptr(value[0]));
641 }
642
643 void Vec3ArrayShaderUniform::write(std::string& content) const {
644
645 char buff[1024];
646
647 if(baked) {
648 snprintf(buff, 1024, "%s[%ld] %s = %s[] (\n", type_name.c_str(), length, name.c_str(), type_name.c_str());
649
650 content += buff;
651
652 for(size_t i=0; i<length; i++) {
653 snprintf(buff, 1024, " %s(%e, %e, %e)", type_name.c_str(), value[i].x, value[i].y, value[i].z);
654 content += buff;
655 if(i<length-1) content += ",\n";
656 else content += "\n);\n";
657 }
658
659 } else {
660 snprintf(buff, 1024, "uniform %s %s[%ld];\n", type_name.c_str(), name.c_str(), length);
661 content += buff;
662 }
663 }
664
665 //Vec4ArrayShaderUniform
666
667 Vec4ArrayShaderUniform::Vec4ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec4* value) :
668 length(length), ShaderUniform(shader, name, SHADER_UNIFORM_VEC4_ARRAY, "vec4") {
669 this->value = new vec4[length];
670 if(value != 0) copyValue(value);
671 }
672
673 Vec4ArrayShaderUniform::~Vec4ArrayShaderUniform() {
674 if(value) delete[] value;
675 }
676
677 const vec4* Vec4ArrayShaderUniform::getValue() const {
678 return value;
679 }
680
681 void Vec4ArrayShaderUniform::copyValue(const std::vector<vec4>& value) {
682 for(size_t i=0; i<length; i++) {
683 this->value[i] = value[i];
684 }
685 }
686
687 void Vec4ArrayShaderUniform::copyValue(const vec4* value) {
688 for(size_t i=0; i<length; i++) {
689 this->value[i] = value[i];
690 }
691 }
692
693 void Vec4ArrayShaderUniform::setValue(const vec4* value) {
694 if(baked) {
695 bool match = true;
696
697 for(size_t i=0;i<length;i++) {
698 if(value[i] != this->value[i]) {
699 match = false;
700 break;
701 }
702 }
703
704 if(match) return;
705 }
706
707 copyValue(value);
708
709 modified = true;
710 initialized = true;
711 }
712
713 void Vec4ArrayShaderUniform::setValue(const std::vector<vec4>& value) {
714 if(baked) {
715 bool match = true;
716
717 for(size_t i=0;i<length;i++) {
718 if(value[i] != this->value[i]) {
719 match = false;
720 break;
721 }
722 }
723
724 if(match) return;
725 }
726
727 copyValue(value);
728
729 modified = true;
730 initialized = true;
731 }
732
733 void Vec4ArrayShaderUniform::apply() {
734 glUniform4fv(getLocation(), length, glm::value_ptr(value[0]));
735 }
736
737 void Vec4ArrayShaderUniform::write(std::string& content) const {
738
739 char buff[1024];
740
741 if(baked) {
742 snprintf(buff, 1024, "%s[%ld] %s = %s[] (\n", type_name.c_str(), length, name.c_str(), type_name.c_str());
743
744 content += buff;
745
746 for(size_t i=0; i<length; i++) {
747 snprintf(buff, 1024, " %s(%e, %e, %e, %e)", type_name.c_str(), value[i].x, value[i].y, value[i].z, value[i].w);
748 content += buff;
749 if(i<length-1) content += ",\n";
750 else content += "\n);\n";
751 }
752
753 } else {
754 snprintf(buff, 1024, "uniform %s %s[%ld];\n", type_name.c_str(), name.c_str(), length);
755 content += buff;
756 }
757
758 }
759
760 //ShaderPass
761
762 ShaderPass::ShaderPass(Shader* parent, GLint shader_object_type, const std::string& shader_object_desc) : parent(parent), shader_object_type(shader_object_type), shader_object_desc(shader_object_desc) {
763 shader_object = 0;
764 version = 0;
765 }
766
767 ShaderPass::~ShaderPass() {
768 unload();
769 }
770
771 void ShaderPass::unload() {
772 if(shader_object!=0) glDeleteShader(shader_object);
773 shader_object = 0;
774 }
775
776 void ShaderPass::attachTo(GLenum program) {
777 glAttachShader(program, shader_object);
778 }
779
780 bool ShaderPass::errorContext(const char* log_message, std::string& context) {
781
782 std::vector<std::string> matches;
783
784 if( !Shader_error_line.match(log_message, &matches)
785 && !Shader_error2_line.match(log_message, &matches)
786 && !(shadermanager.warnings && Shader_warning_line.match(log_message, &matches)))
787 return false;
788
789 int line_no = atoi(matches[0].c_str());
790
791 std::stringstream in(shader_object_source);
792
793 int i = 1;
794 int amount = 3;
795
796 char line_detail[1024];
797
798 std::string line;
799 while( std::getline(in,line) ) {
800
801 if(i==line_no || i<line_no && i+amount>=line_no || i>line_no && i-amount<=line_no) {
802 snprintf(line_detail, 1024, "%s%4d | %s\n", (i==line_no ? "-> ": " "), i, line.c_str());
803 context += line_detail;
804 }
805 i++;
806 }
807
808 return true;
809 }
810
811 void ShaderPass::checkError() {
812 if(!shader_object) return;
813
814 GLint compile_success;
815 glGetShaderiv(shader_object, GL_COMPILE_STATUS, &compile_success);
79816
80817 GLint info_log_length;
81 glGetShaderiv(shaderRef, GL_INFO_LOG_LENGTH, &info_log_length);
818 glGetShaderiv(shader_object, GL_INFO_LOG_LENGTH, &info_log_length);
819
820 const char* resource_desc = !parent->resource_name.empty() ? parent->resource_name.c_str() : "???";
82821
83822 if(info_log_length > 1) {
84823 char info_log[info_log_length];
85824
86 glGetShaderInfoLog(shaderRef, info_log_length, &info_log_length, info_log);
825 glGetShaderInfoLog(shader_object, info_log_length, &info_log_length, info_log);
826
827 std::string context;
828 errorContext(info_log, context);
87829
88830 if(!compile_success) {
89 throw SDLAppException("shader '%s' failed to compile: %s", filename.c_str(), info_log);
90 }
91
92 if(shadermanager.debug) {
93 fprintf(stderr, "%s: %s\n", filename.c_str(), info_log);
831 throw SDLAppException("%s shader '%s' failed to compile:\n%s\n%s",
832 shader_object_desc.c_str(),
833 resource_desc,
834 info_log,
835 context.c_str());
836
837
838
839 }
840
841 if(shadermanager.warnings) {
842 warnLog("%s shader '%s':\n%s\n%s",
843 shader_object_desc.c_str(),
844 resource_desc,
845 info_log,
846 context.c_str());
847
94848 }
95849
96850 return;
97851 }
98
852
99853 if(!compile_success) {
100 throw SDLAppException("shader '%s' failed to compile", filename.c_str());
101 }
102 }
103
104 GLenum Shader::load(const std::string& filename, GLenum shaderType) {
105
106 std::string source;
107 readSource(filename, source);
108
109 if(source.empty()) {
110 throw SDLAppException("could not read shader '%s'", filename.c_str());
111 }
112
113 GLenum shaderRef = glCreateShader(shaderType);
114
115 const char* source_ptr = source.c_str();
116 int source_len = source.size();
117
118 glShaderSource(shaderRef, 1, (const GLchar**) &source_ptr, &source_len);
119
120 glCompileShader(shaderRef);
121
122 checkError(filename, shaderRef);
123
124 return shaderRef;
125 }
126
127
128 bool Shader::preprocess(const std::string& line, std::string& output) {
854 throw SDLAppException("%s shader '%s' failed to compile",
855 shader_object_desc.c_str(),
856 resource_desc);
857 }
858 }
859
860 void ShaderPass::toString(std::string& out) {
861 if(version!=0) {
862 out.append(str(boost::format("#version %d\n") % version));
863 }
864
865 for(std::map<std::string, std::string>::iterator it = extensions.begin(); it != extensions.end(); it++) {
866 out.append(str(boost::format("#extension %s : %s\n") % it->first % it->second));
867 }
868
869 foreach(ShaderUniform* u, uniforms) {
870 u->write(out);
871 }
872
873 out.append(source);
874 }
875
876 void ShaderPass::compile() {
877
878 if(!shader_object) shader_object = glCreateShader(shader_object_type);
879
880 if(source.empty()) return;
881
882 shader_object_source.clear();
883
884 toString(shader_object_source);
885
886 // apply subsitutions
887 parent->applySubstitutions(shader_object_source);
888
889 foreach(ShaderUniform* u, uniforms) {
890 u->setModified(false);
891 }
892
893 //fprintf(stderr, "src:\n%s", shader_object_source.c_str());
894
895 const char* source_ptr = shader_object_source.c_str();
896 int source_len = shader_object_source.size();
897
898 glShaderSource(shader_object, 1, (const GLchar**) &source_ptr, &source_len);
899 glCompileShader(shader_object);
900
901 checkError();
902 }
903
904 //add uniform, unless parent Shader has this in which case link to it
905 ShaderUniform* ShaderPass::addArrayUniform(const std::string& name, const std::string& type, size_t length) {
906
907 ShaderUniform* uniform = 0;
908
909 if((uniform = parent->getUniform(name)) == 0) {
910
911 if(type == "vec2") {
912 uniform = new Vec2ArrayShaderUniform(parent, name, length);
913 } else if(type == "vec3") {
914 uniform = new Vec3ArrayShaderUniform(parent, name, length);
915 } else if(type == "vec4") {
916 uniform = new Vec4ArrayShaderUniform(parent, name, length);
917 } else {
918 throw SDLAppException("shader uniform arrays for type '%s' not implemented", type.c_str());
919 }
920
921 uniform->setInitialized(false);
922
923 parent->addUniform(uniform);
924 }
925
926 uniforms.push_back(uniform);
927
928 return uniform;
929 }
930
931 ShaderUniform* ShaderPass::addUniform(const std::string& name, const std::string& type) {
932
933 ShaderUniform* uniform = 0;
934
935 if((uniform = parent->getUniform(name)) == 0) {
936
937 if(type == "float") {
938 uniform = new FloatShaderUniform(parent, name);
939 } else if(type == "int") {
940 uniform = new IntShaderUniform(parent, name);
941 } else if(type == "bool") {
942 uniform = new BoolShaderUniform(parent, name);
943 } else if(type == "sampler1D") {
944 uniform = new Sampler1DShaderUniform(parent, name);
945 } else if(type == "sampler2D") {
946 uniform = new Sampler2DShaderUniform(parent, name);
947 } else if(type == "vec2") {
948 uniform = new Vec2ShaderUniform(parent, name);
949 } else if(type == "vec3") {
950 uniform = new Vec3ShaderUniform(parent, name);
951 } else if(type == "vec4") {
952 uniform = new Vec4ShaderUniform(parent, name);
953 } else if(type == "mat3") {
954 uniform = new Mat3ShaderUniform(parent, name);
955 } else if(type == "mat4") {
956 uniform = new Mat4ShaderUniform(parent, name);
957 } else {
958 throw SDLAppException("unsupported shader uniform type '%s'", type.c_str());
959 }
960
961 uniform->setInitialized(false);
962
963 parent->addUniform(uniform);
964 }
965
966 uniforms.push_back(uniform);
967
968 return uniform;
969 }
970
971 bool ShaderPass::preprocess(const std::string& line) {
129972
130973 std::vector<std::string> matches;
131974
975 if(Shader_pre_version.match(line, &matches)) {
976 version = atoi(matches[0].c_str());
977 return true;
978 }
979
980 if(Shader_pre_extension.match(line, &matches)) {
981 extensions[matches[0]] = matches[1];
982 return true;
983 }
984
132985 if(Shader_pre_include.match(line, &matches)) {
133986
134987 std::string include_file = shadermanager.getDir() + matches[0];
135988
136 readSource(include_file, output);
989 includeFile(include_file);
137990
138991 return true;
139992 }
140993
994 if(Shader_uniform_def.match(line, &matches)) {
995 std::string uniform_type = matches[0];
996 std::string uniform_name = matches[1];
997
998 if(matches.size() > 2) {
999 size_t uniform_length = atoi(matches[2].c_str());
1000 addArrayUniform(uniform_name, uniform_type, uniform_length);
1001 } else {
1002 addUniform(uniform_name, uniform_type);
1003 }
1004
1005 return true;
1006 }
1007
1411008 return false;
142
143 }
144
145 bool Shader::readSource(const std::string& file, std::string& output) {
1009 }
1010
1011 void ShaderPass::includeFile(const std::string& filename) {
1461012
1471013 // get length
148 std::ifstream in(file.c_str());
1014 std::ifstream in(filename.c_str());
1491015
1501016 if(!in.is_open()) {
151 throw SDLAppException("could not open '%s'", file.c_str());
1017 throw SDLAppException("could not open '%s'", filename.c_str());
1521018 }
1531019
1541020 std::string line;
1551021 while( std::getline(in,line) ) {
156 if(!preprocess(line, output)) {
157 output += line;
158 output += "\n";
1022 if(!preprocess(line)) {
1023 source += line;
1024 source += "\n";
1591025 }
1601026 }
1611027
1621028 in.close();
163
164 return true;
1029 }
1030
1031 void ShaderPass::includeSource(const std::string& string) {
1032
1033 std::stringstream in(string);
1034
1035 std::string line;
1036 while( std::getline(in,line) ) {
1037 if(!preprocess(line)) {
1038 source += line;
1039 source += "\n";
1040 }
1041 }
1042 }
1043
1044 VertexShader::VertexShader(Shader* parent) : ShaderPass(parent, GL_VERTEX_SHADER, "vertex") {
1045 }
1046
1047 FragmentShader::FragmentShader(Shader* parent) : ShaderPass(parent, GL_FRAGMENT_SHADER, "fragment") {
1048 }
1049
1050 GeometryShader::GeometryShader(Shader* parent) : ShaderPass(parent, GL_GEOMETRY_SHADER_ARB, "geometry") {
1051 }
1052
1053 void GeometryShader::attachTo(GLenum program) {
1054 ShaderPass::attachTo(program);
1055 }
1056
1057 //Shader
1058
1059 Shader::Shader(const std::string& prefix) : Resource(prefix) {
1060
1061 setDefaults();
1062
1063 std::string shader_dir = shadermanager.getDir();
1064
1065 std::string vertex_file = shader_dir + prefix + std::string(".vert");
1066 std::string fragment_file = shader_dir + prefix + std::string(".frag");
1067
1068 vertex_shader = new VertexShader(this);
1069 vertex_shader->includeFile(vertex_file);
1070
1071 fragment_shader = new FragmentShader(this);
1072 fragment_shader->includeFile(fragment_file);
1073
1074 load();
1075 }
1076
1077 Shader::Shader() {
1078 setDefaults();
1079 }
1080
1081 void Shader::setDynamicCompile(bool dynamic_compile) {
1082 this->dynamic_compile = dynamic_compile;
1083 }
1084
1085 void Shader::setDefaults() {
1086 vertex_shader = 0;
1087 fragment_shader = 0;
1088 geometry_shader = 0;
1089 program = 0;
1090 dynamic_compile = false;
1091 }
1092
1093 Shader::~Shader() {
1094 clear();
1095 }
1096
1097 void Shader::clear() {
1098 unload();
1099
1100 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1101 delete it->second;
1102 }
1103 uniforms.clear();
1104
1105 if(vertex_shader != 0) delete vertex_shader;
1106 if(geometry_shader != 0) delete geometry_shader;
1107 if(fragment_shader != 0) delete fragment_shader;
1108
1109 vertex_shader = 0;
1110 geometry_shader = 0;
1111 fragment_shader = 0;
1112 }
1113
1114 void Shader::unload() {
1115 if(program != 0) glDeleteProgram(program);
1116 program = 0;
1117
1118 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1119 it->second->unload();
1120 }
1121 }
1122
1123 void Shader::load() {
1124 //fprintf(stderr, "load\n");
1125
1126 if(program !=0) unload();
1127
1128 if(vertex_shader != 0) vertex_shader->compile();
1129 if(geometry_shader != 0) geometry_shader->compile();
1130 if(fragment_shader != 0) fragment_shader->compile();
1131
1132 program = glCreateProgram();
1133
1134 if(vertex_shader!=0) vertex_shader->attachTo(program);
1135 if(geometry_shader!=0) geometry_shader->attachTo(program);
1136 if(fragment_shader!=0) fragment_shader->attachTo(program);
1137
1138 glLinkProgram(program);
1139
1140 checkProgramError();
1141
1142 if(vertex_shader != 0) vertex_shader->unload();
1143 if(geometry_shader != 0) geometry_shader->unload();
1144 if(fragment_shader != 0) fragment_shader->unload();
1145 }
1146
1147 void Shader::checkProgramError() {
1148
1149 GLint link_success;
1150 glGetProgramiv(program, GL_LINK_STATUS, &link_success);
1151
1152 GLint info_log_length;
1153 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
1154
1155 const char* resource_desc = !resource_name.empty() ? resource_name.c_str() : "???";
1156
1157 if(info_log_length > 1) {
1158 char info_log[info_log_length];
1159
1160 glGetProgramInfoLog(program, info_log_length, &info_log_length, info_log);
1161
1162 if(!link_success) {
1163 throw SDLAppException("shader '%s' failed to link:\n%s",
1164 resource_desc,
1165 info_log);
1166 }
1167
1168 if(shadermanager.warnings) {
1169 warnLog("shader '%s':\n%s",
1170 resource_desc,
1171 info_log);
1172 }
1173
1174 return;
1175 }
1176
1177 if(!link_success) {
1178 throw SDLAppException("shader '%s' failed to link",
1179 resource_desc);
1180 }
1181 }
1182
1183 void Shader::bind() {
1184 glUseProgram(program);
1185 }
1186
1187 void Shader::unbind() {
1188 glUseProgram(0);
1651189 }
1661190
1671191 void Shader::use() {
168 glUseProgram(shaderProg);
1192
1193 if(shadermanager.warnings) {
1194 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1195 ShaderUniform* u = it->second;
1196
1197 if(!u->isInitialized()) warnLog("shader '%s': uniform '%s' was never initialized", (!resource_name.empty() ? resource_name.c_str() : "???"), u->getName().c_str());
1198 }
1199 }
1200
1201 if(dynamic_compile && needsCompile()) {
1202 unbind();
1203 load();
1204 infoLog("shader '%s' recompiled", resource_name.c_str());
1205 }
1206
1207 bind();
1208
1209 applyUniforms();
1691210 }
1701211
1711212 GLenum Shader::getProgram() {
172 return shaderProg;
173 }
174
175 GLenum Shader::getVertexShader() {
176 return vertexShader;
177 }
178
179 GLenum Shader::getFragmentShader() {
180 return fragmentShader;
181 }
182
183 GLint Shader::getVarLocation(const std::string& name) {
184
185 GLint loc = varMap[name] - 1;
186
187 if(loc != -1) return loc;
188
189 loc = glGetUniformLocation( shaderProg, name.c_str() );
190
191 varMap[name] = loc + 1;
192
193 return loc;
1213 return program;
1214 }
1215
1216 void Shader::addUniform(ShaderUniform* uniform) {
1217
1218 if(getUniform(uniform->getName()) != 0) {
1219 throw SDLAppException("shader already has a uniform named '%s'", uniform->getName().c_str() );
1220 }
1221
1222 uniforms[uniform->getName()] = uniform;
1223 }
1224
1225 ShaderUniform* Shader::getUniform(const std::string& name) {
1226 std::map<std::string, ShaderUniform*>::iterator it = uniforms.find(name);
1227
1228 if(it != uniforms.end()) {
1229 return it->second;
1230 }
1231 return 0;
1232 }
1233
1234 ShaderPass* Shader::grabShaderPass(GLenum shader_object_type) {
1235
1236 ShaderPass* shader_pass = 0;
1237
1238 switch(shader_object_type) {
1239 case GL_VERTEX_SHADER:
1240 if(!vertex_shader) vertex_shader = new VertexShader(this);
1241 shader_pass = vertex_shader;
1242 break;
1243 case GL_GEOMETRY_SHADER_ARB:
1244 if(!geometry_shader) geometry_shader = new GeometryShader(this);
1245 shader_pass = geometry_shader;
1246 break;
1247 case GL_FRAGMENT_SHADER:
1248 if(!fragment_shader) fragment_shader = new FragmentShader(this);
1249 shader_pass = fragment_shader;
1250 break;
1251 }
1252
1253 return shader_pass;
1254 }
1255
1256
1257 void Shader::includeSource(GLenum shader_object_type, const std::string& source) {
1258
1259 ShaderPass* pass = grabShaderPass(shader_object_type);
1260
1261 pass->includeSource(source);
1262 }
1263
1264 void Shader::includeFile(GLenum shader_object_type, const std::string& filename) {
1265
1266 ShaderPass* pass = grabShaderPass(shader_object_type);
1267
1268 pass->includeFile(filename);
1269 }
1270
1271 void Shader::addSubstitute(const std::string& name, const char *value, ...) {
1272
1273 va_list vl;
1274 char sub[4096];
1275
1276 va_start(vl, value);
1277 vsnprintf(sub, 4096, value, vl);
1278 va_end(vl);
1279
1280 substitutions[name] = sub;
1281 }
1282
1283 void Shader::substitute(std::string& source, const std::string& name, const std::string& value) {
1284
1285 std::string::size_type next_match;
1286
1287 for(next_match = source.find(name);
1288 next_match != std::string::npos;
1289 next_match = source.find(name, next_match)) {
1290 source.replace(next_match, name.length(), value);
1291 next_match += value.length();
1292 }
1293 }
1294
1295 void Shader::applySubstitutions(std::string& source) {
1296
1297 for(std::map<std::string, std::string>::iterator it = substitutions.begin(); it != substitutions.end(); it++) {
1298 substitute(source, it->first, it->second);
1299 }
1300 }
1301
1302 void Shader::setBool (const std::string& name, bool value) {
1303 ShaderUniform* uniform = getUniform(name);
1304
1305 if(!uniform || uniform->getType() != SHADER_UNIFORM_BOOL) return;
1306
1307 ((BoolShaderUniform*)uniform)->setValue(value);
1308 }
1309
1310 void Shader::setInteger (const std::string& name, int value) {
1311 ShaderUniform* uniform = getUniform(name);
1312
1313 if(!uniform || uniform->getType() != SHADER_UNIFORM_INT) return;
1314
1315 ((IntShaderUniform*)uniform)->setValue(value);
1316 }
1317
1318 void Shader::setSampler1D (const std::string& name, int value) {
1319 ShaderUniform* uniform = getUniform(name);
1320
1321 if(!uniform || uniform->getType() != SHADER_UNIFORM_SAMPLER_1D) return;
1322
1323 ((Sampler1DShaderUniform*)uniform)->setValue(value);
1324 }
1325
1326 void Shader::setSampler2D (const std::string& name, int value) {
1327 ShaderUniform* uniform = getUniform(name);
1328
1329 if(!uniform || uniform->getType() != SHADER_UNIFORM_SAMPLER_2D) return;
1330
1331 ((Sampler2DShaderUniform*)uniform)->setValue(value);
1941332 }
1951333
1961334 void Shader::setFloat(const std::string& name, float value) {
197 GLint loc = getVarLocation(name);
198 glUniform1f(loc, value);
199 }
200
201 void Shader::setVec2 (const std::string& name, const vec2f& value) {
202 GLint loc = getVarLocation(name);
203 glUniform2fv(loc, 1, value);
204 }
205
206 void Shader::setVec3 (const std::string& name, const vec3f& value) {
207 GLint loc = getVarLocation(name);
208 glUniform3fv(loc, 1, value);
209 }
210
211 void Shader::setVec4 (const std::string& name, const vec4f& value) {
212 GLint loc = getVarLocation(name);
213 glUniform4fv(loc, 1, value);
214 }
215
216 void Shader::setInteger (const std::string& name, int value) {
217 GLint loc = getVarLocation(name);
218 glUniform1i(loc, value);
219 }
220
221
222
1335 ShaderUniform* uniform = getUniform(name);
1336
1337 if(!uniform || uniform->getType() != SHADER_UNIFORM_FLOAT) return;
1338
1339 ((FloatShaderUniform*)uniform)->setValue(value);
1340 }
1341
1342 void Shader::setVec2 (const std::string& name, const vec2& value) {
1343 ShaderUniform* uniform = getUniform(name);
1344
1345 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC2) return;
1346
1347 ((Vec2ShaderUniform*)uniform)->setValue(value);
1348 }
1349
1350 void Shader::setVec3 (const std::string& name, const vec3& value) {
1351 ShaderUniform* uniform = getUniform(name);
1352
1353 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC3) return;
1354
1355 ((Vec3ShaderUniform*)uniform)->setValue(value);
1356 }
1357
1358 void Shader::setVec2Array (const std::string& name, vec2* value) {
1359 ShaderUniform* uniform = getUniform(name);
1360
1361 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC2_ARRAY) return;
1362
1363 ((Vec2ArrayShaderUniform*)uniform)->setValue(value);
1364 }
1365
1366 void Shader::setVec2Array (const std::string& name, std::vector<vec2>& value) {
1367 ShaderUniform* uniform = getUniform(name);
1368
1369 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC2_ARRAY) return;
1370
1371 ((Vec2ArrayShaderUniform*)uniform)->setValue(value);
1372 }
1373
1374 void Shader::setVec3Array (const std::string& name, vec3* value) {
1375 ShaderUniform* uniform = getUniform(name);
1376
1377 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC3_ARRAY) return;
1378
1379 ((Vec3ArrayShaderUniform*)uniform)->setValue(value);
1380 }
1381
1382 void Shader::setVec3Array (const std::string& name, std::vector<vec3>& value) {
1383 ShaderUniform* uniform = getUniform(name);
1384
1385 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC3_ARRAY) return;
1386
1387 ((Vec3ArrayShaderUniform*)uniform)->setValue(value);
1388 }
1389
1390 void Shader::setVec4Array (const std::string& name, vec4* value) {
1391 ShaderUniform* uniform = getUniform(name);
1392
1393 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC4_ARRAY) return;
1394
1395 ((Vec4ArrayShaderUniform*)uniform)->setValue(value);
1396 }
1397
1398 void Shader::setVec4Array (const std::string& name, std::vector<vec4>& value) {
1399 ShaderUniform* uniform = getUniform(name);
1400
1401 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC4_ARRAY) return;
1402
1403 ((Vec4ArrayShaderUniform*)uniform)->setValue(value);
1404 }
1405
1406 void Shader::setVec4 (const std::string& name, const vec4& value) {
1407 ShaderUniform* uniform = getUniform(name);
1408
1409 if(!uniform || uniform->getType() != SHADER_UNIFORM_VEC4) return;
1410
1411 ((Vec4ShaderUniform*)uniform)->setValue(value);
1412 }
1413
1414 void Shader::setMat3 (const std::string& name, const mat3& value) {
1415 ShaderUniform* uniform = getUniform(name);
1416
1417 if(!uniform || uniform->getType() != SHADER_UNIFORM_MAT3) return;
1418
1419 ((Mat3ShaderUniform*)uniform)->setValue(value);
1420 }
1421
1422 void Shader::setMat4 (const std::string& name, const mat4& value) {
1423 ShaderUniform* uniform = getUniform(name);
1424
1425 if(!uniform || uniform->getType() != SHADER_UNIFORM_MAT4) return;
1426
1427 ((Mat4ShaderUniform*)uniform)->setValue(value);
1428 }
1429
1430 void Shader::setBaked(const std::string& name, bool baked) {
1431 ShaderUniform* uniform = getUniform(name);
1432
1433 if(!uniform) return;
1434
1435 uniform->setBaked(baked);
1436 }
1437
1438 void Shader::setBakedUniforms(bool baked) {
1439 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1440 it->second->setBaked(baked);
1441 }
1442 }
1443
1444
1445 void Shader::applyUniforms() {
1446 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1447 if(!it->second->isBaked()) it->second->apply();
1448 }
1449 }
1450
1451 bool Shader::needsCompile() {
1452
1453 for(std::map<std::string, ShaderUniform*>::iterator it= uniforms.begin(); it!=uniforms.end();it++) {
1454 ShaderUniform* u = it->second;
1455
1456 if(u->isBaked() && u->isModified()) {
1457 //infoLog("baked uniform %s needs update", u->getName().c_str());
1458 return true;
1459 }
1460 }
1461
1462 return false;
1463 }
3333 #include "display.h"
3434 #include "sdlapp.h"
3535 #include "regex.h"
36
36 #include "util.h"
37
38 #include <boost/format.hpp>
39 #include <list>
3740 #include <map>
3841 #include <string>
3942 #include <fstream>
43 #include <sstream>
44
45 enum { SHADER_UNIFORM_FLOAT,
46 SHADER_UNIFORM_BOOL,
47 SHADER_UNIFORM_SAMPLER_1D,
48 SHADER_UNIFORM_SAMPLER_2D,
49 SHADER_UNIFORM_INT,
50 SHADER_UNIFORM_VEC2,
51 SHADER_UNIFORM_VEC3,
52 SHADER_UNIFORM_VEC4,
53 SHADER_UNIFORM_MAT3,
54 SHADER_UNIFORM_MAT4,
55 SHADER_UNIFORM_VEC2_ARRAY,
56 SHADER_UNIFORM_VEC3_ARRAY,
57 SHADER_UNIFORM_VEC4_ARRAY
58 };
59
60 class Shader;
61
62 class ShaderUniform {
63 protected:
64 std::string name;
65 GLint location;
66 Shader* shader;
67 int uniform_type;
68 std::string type_name;
69 bool modified;
70 bool initialized;
71 bool baked;
72 public:
73
74 ShaderUniform(Shader* shader, const std::string& name, int uniform_type, const std::string& type_name);
75
76 virtual void unload();
77
78 int getType() { return uniform_type; };
79
80 virtual void write(std::string& content) const {};
81
82 const std::string& getName() const;
83 bool isInitialized() const { return initialized; };
84 GLint getLocation();
85
86 bool isBaked() const { return baked; };
87 bool isModified() const { return modified; };
88
89 void setInitialized(bool initialized) { this->initialized = initialized; };
90
91 virtual void apply() {};
92
93 virtual void setBaked(bool baked);
94 virtual void setModified(bool modified) { this->modified = modified; };
95 };
96
97 class FloatShaderUniform : public ShaderUniform {
98 float value;
99 public:
100 FloatShaderUniform(Shader* shader, const std::string& name, float value = 0.0f);
101
102 void write(std::string& content) const;
103
104 void apply();
105 void setValue(float value);
106 float getValue() const;
107 };
108
109 class IntShaderUniform : public ShaderUniform {
110 int value;
111 public:
112 IntShaderUniform(Shader* shader, const std::string& name, int value = 0);
113
114 void write(std::string& content) const;
115
116 void apply();
117 void setValue(int value);
118 float getValue() const;
119 };
120
121 class BoolShaderUniform : public ShaderUniform {
122 bool value;
123 public:
124 BoolShaderUniform(Shader* shader, const std::string& name, bool value = false);
125
126 void write(std::string& content) const;
127
128 void apply();
129 void setValue(bool value);
130 float getValue() const;
131 };
132
133 class Sampler1DShaderUniform : public ShaderUniform {
134 int value;
135 public:
136 Sampler1DShaderUniform(Shader* shader, const std::string& name, int value = 0);
137
138 void write(std::string& content) const;
139
140 void setBaked(bool baked);
141
142 void apply();
143 void setValue(int value);
144 float getValue() const;
145 };
146
147 class Sampler2DShaderUniform : public ShaderUniform {
148 int value;
149 public:
150 Sampler2DShaderUniform(Shader* shader, const std::string& name, int value = 0);
151
152 void write(std::string& content) const;
153
154 void setBaked(bool baked);
155
156 void apply();
157 void setValue(int value);
158 float getValue() const;
159 };
160
161 class Vec2ShaderUniform : public ShaderUniform {
162 vec2 value;
163 public:
164 Vec2ShaderUniform(Shader* shader, const std::string& name, const vec2& value = vec2(0.0f)) ;
165
166 void write(std::string& content) const;
167
168 void apply();
169 void setValue(const vec2& value);
170 const vec2& getValue() const;
171 };
172
173 class Vec3ShaderUniform : public ShaderUniform {
174 vec3 value;
175 public:
176 Vec3ShaderUniform(Shader* shader, const std::string& name, const vec3& value = vec3(0.0f));
177
178 void write(std::string& content) const;
179
180 void apply();
181 void setValue(const vec3& value);
182 const vec3& getValue() const;
183 };
184
185 class Vec4ShaderUniform : public ShaderUniform {
186 vec4 value;
187 public:
188 Vec4ShaderUniform(Shader* shader, const std::string& name, const vec4& value = vec4(0.0f));
189
190 void write(std::string& content) const;
191
192 void apply();
193 void setValue(const vec4& value);
194 const vec4& getValue() const;
195 };
196
197 class Mat3ShaderUniform : public ShaderUniform {
198 mat3 value;
199 public:
200 Mat3ShaderUniform(Shader* shader, const std::string& name, const mat3& value = mat3(1.0f));
201
202 void write(std::string& content) const;
203
204 void apply();
205 void setValue(const mat3& value);
206 const mat3& getValue() const;
207 };
208
209 class Mat4ShaderUniform : public ShaderUniform {
210 mat4 value;
211 public:
212 Mat4ShaderUniform(Shader* shader, const std::string& name, const mat4& value = mat4(1.0f));
213
214 void write(std::string& content) const;
215
216 void apply();
217 void setValue(const mat4& value);
218 const mat4& getValue() const;
219 };
220
221 class Vec2ArrayShaderUniform : public ShaderUniform {
222 vec2* value;
223 size_t length;
224
225 void copyValue(const vec2* value);
226 void copyValue(const std::vector<vec2>& value);
227 public:
228 Vec2ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec2* value = 0);
229 ~Vec2ArrayShaderUniform();
230
231 void write(std::string& content) const;
232
233 void apply();
234
235 void setValue(const vec2* value);
236 void setValue(const std::vector<vec2>& value);
237
238 const vec2* getValue() const;
239 };
240
241 class Vec3ArrayShaderUniform : public ShaderUniform {
242 vec3* value;
243 size_t length;
244
245 void copyValue(const vec3* value);
246 void copyValue(const std::vector<vec3>& value);
247 public:
248 Vec3ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec3* value = 0);
249 ~Vec3ArrayShaderUniform();
250
251 void write(std::string& content) const;
252
253 void apply();
254
255 void setValue(const vec3* value);
256 void setValue(const std::vector<vec3>& value);
257
258 const vec3* getValue() const;
259 };
260
261 class Vec4ArrayShaderUniform : public ShaderUniform {
262 vec4* value;
263 size_t length;
264
265 void copyValue(const vec4* value);
266 void copyValue(const std::vector<vec4>& value);
267 public:
268 Vec4ArrayShaderUniform(Shader* shader, const std::string& name, size_t length, const vec4* value = 0);
269 ~Vec4ArrayShaderUniform();
270
271 void write(std::string& content) const;
272
273 void apply();
274
275 void setValue(const vec4* value);
276 void setValue(const std::vector<vec4>& value);
277
278 const vec4* getValue() const;
279 };
280
281 class ShaderPass {
282 GLint shader_object_type;
283 std::string shader_object_desc;
284 GLenum shader_object;
285
286 int version;
287 std::map<std::string,std::string> extensions;
288
289 Shader* parent;
290
291 std::string source;
292 std::string shader_object_source;
293
294 std::list<ShaderUniform*> uniforms;
295
296 bool errorContext(const char* log_message, std::string& context);
297
298 bool preprocess(const std::string& line);
299 public:
300 ShaderPass(Shader* parent, GLint shader_object_type, const std::string& shader_object_desc);
301 virtual ~ShaderPass();
302
303 GLint getType() { return shader_object_type; };
304
305 void toString(std::string& out);
306
307 void unload();
308 void compile();
309
310 void checkError();
311
312 ShaderUniform* addArrayUniform(const std::string& name, const std::string& type, size_t length);
313 ShaderUniform* addUniform(const std::string& name, const std::string& type);
314
315 virtual void attachTo(GLenum program);
316
317 void includeSource(const std::string& source);
318 void includeFile(const std::string& filename);
319 };
320
321 class VertexShader : public ShaderPass {
322 public:
323 VertexShader(Shader* parent);
324 };
325
326 class FragmentShader : public ShaderPass {
327 public:
328 FragmentShader(Shader* parent);
329 };
330
331 class GeometryShader : public ShaderPass {
332 public:
333 GeometryShader(Shader* parent);
334
335 void attachTo(GLenum program);
336 };
40337
41338 class Shader : public Resource {
42339
43 std::map<std::string, GLint> varMap;
44
45 GLenum shaderProg;
46 GLenum vertexShader;
47 GLenum fragmentShader;
48
49 GLint getVarLocation(const std::string& name);
50
51 bool preprocess(const std::string& line, std::string& output);
52 bool readSource(const std::string& filename, std::string& output);
53 GLenum load(const std::string& filename, GLenum shaderType);
54 void makeProgram();
55
56 void checkError(const std::string& filename, GLenum shaderRef);
57 public:
340 std::map<std::string, ShaderUniform*> uniforms;
341 std::map<std::string,std::string> substitutions;
342
343 GLenum program;
344 bool dynamic_compile;
345
346 void checkProgramError();
347
348 void setDefaults();
349 public:
350 VertexShader* vertex_shader;
351 GeometryShader* geometry_shader;
352 FragmentShader* fragment_shader;
353
354 Shader();
58355 Shader(const std::string& prefix);
59356 ~Shader();
60357
61358 GLenum getProgram();
62 GLenum getVertexShader();
63 GLenum getFragmentShader();
64
359
360 void clear();
361
362 void load();
363 void unload();
364
365 ShaderPass* grabShaderPass(GLenum shader_object_type);
366
367 void includeSource(GLenum shader_object_type, const std::string& source);
368 void includeFile(GLenum shader_object_type, const std::string& filename);
369
370 static void substitute(std::string& source, const std::string& name, const std::string& value);
371
372 void addSubstitute(const std::string& name, const char *value, ...);
373 void applySubstitutions(std::string& source);
374
375 void addUniform(ShaderUniform* uniform);
376 ShaderUniform* getUniform(const std::string& name);
377
378 void setDynamicCompile(bool dynamic_compile);
379 bool needsCompile();
380
381 void applyUniforms();
382
383 void setBool(const std::string& name, bool value);
65384 void setInteger (const std::string& name, int value);
385 void setSampler1D(const std::string& name, int value);
386 void setSampler2D(const std::string& name, int value);
66387 void setFloat(const std::string& name, float value);
67 void setVec2 (const std::string& name, const vec2f& value);
68 void setVec3 (const std::string& name, const vec3f& value);
69 void setVec4 (const std::string& name, const vec4f& value);
388 void setVec2 (const std::string& name, const vec2& value);
389 void setVec3 (const std::string& name, const vec3& value);
390 void setVec4 (const std::string& name, const vec4& value);
391 void setMat3 (const std::string& name, const mat3& value);
392 void setMat4 (const std::string& name, const mat4& value);
393
394 void setVec2Array(const std::string& name, vec2* value);
395 void setVec2Array(const std::string& name, std::vector<vec2>& value);
396
397 void setVec3Array(const std::string& name, vec3* value);
398 void setVec3Array(const std::string& name, std::vector<vec3>& value);
399
400 void setVec4Array(const std::string& name, vec4* value);
401 void setVec4Array(const std::string& name, std::vector<vec4>& value);
402
403 void setBaked(const std::string& name, bool baked);
404 void setBakedUniforms(bool baked);
405
406 void bind();
407 void unbind();
70408
71409 void use();
72410 };
73411
74412 class ShaderManager : public ResourceManager {
75413 public:
76 bool debug;
77 ShaderManager() {
78 debug = false;
79 }
414 bool warnings;
415
416 ShaderManager();
80417 Shader* grab(const std::string& shader_prefix);
418
419 void enableWarnings(bool warnings);
420
421 void manage(Shader* shader);
422
423 void unload();
424 void reload();
81425 };
82426
83427 extern ShaderManager shadermanager;
4444 return val;
4545 }
4646
47 vec2f vec2Hash(std::string& str) {
47 vec2 vec2Hash(std::string& str) {
4848 int hash = stringHash(str);
4949
5050 int x = ((hash/7) % 255) - 127;
5151 int y = ((hash/3) % 255) - 127;
5252
53 vec2f v = vec2f(x, y);
54 v.normalize();
53 vec2 v = normalise(vec2(x, y));
5554
5655 return v;
5756 }
5857
59 vec3f vec3Hash(std::string& str) {
58 vec3 vec3Hash(std::string& str) {
6059 int hash = stringHash(str);
6160
6261 int x = ((hash/7) % 255) - 127;
6362 int y = ((hash/3) % 255) - 127;
6463 int z = hash % 255;
6564
66 vec3f v = vec3f(x, y, z);
67 v.normalize();
65 vec3 v = normalise(vec3(x, y, z));
6866
6967 return v;
7068 }
7169
72 vec3f colourHash(std::string& str) {
70 vec3 colourHash(std::string& str) {
7371 int hash = stringHash(str);
7472
7573 int r = (hash/7) % 255;
7876 if(g<0) g=0;
7977 int b = hash % 255;
8078
81 vec3f colour = vec3f(r, g, b);
82 colour.normalize();
79 vec3 colour = normalise(vec3(r, g, b));
8380
8481 return colour;
8582 }
3333
3434 //basic string hash algorithm
3535 int stringHash(std::string& str);
36 vec2f vec2Hash(std::string& str);
37 vec3f vec3Hash(std::string& str);
38 vec3f colourHash(std::string& str);
39 vec3f stylizedColourHash(std::string& str);
36 vec2 vec2Hash(std::string& str);
37 vec3 vec3Hash(std::string& str);
38 vec3 colourHash(std::string& str);
39 vec3 stylizedColourHash(std::string& str);
4040
4141 extern int gStringHashSeed;
4242
2525 */
2626
2727 #include "texture.h"
28 #include "display.h"
2829
2930 TextureManager texturemanager;
3031
3132 // texture manager
3233
3334 TextureManager::TextureManager() : ResourceManager() {
34 }
35
36 TextureResource* TextureManager::grabFile(std::string name, bool mipmaps, bool clamp, bool trilinear) {
37 return grab(name, mipmaps, clamp, trilinear, true);
38 }
39
40 TextureResource* TextureManager::grab(std::string name, bool mipmaps, bool clamp, bool trilinear, bool external_file) {
41
42 Resource* r = resources[name];
43
44 if(r==0) {
45 r = new TextureResource(name, mipmaps, clamp, trilinear, external_file);
46
47 resources[name] = r;
48 }
35 resource_seq = 0;
36 trilinear = true;
37 }
38
39 TextureResource* TextureManager::grabFile(const std::string& filename, bool mipmaps, GLint wrap) {
40 return grab(filename, mipmaps, wrap, true);
41 }
42
43 TextureResource* TextureManager::grab(const std::string& filename, bool mipmaps, GLint wrap, bool external) {
44
45 TextureResource* r = 0;
46
47 //look up this resource
48 if((r = (TextureResource*) resources[filename]) != 0) {
49 r->addref();
50 return r;
51 }
52
53 r = new TextureResource(filename, mipmaps, wrap, external);
54 r->load();
55
56 addResource(r);
57
58 return r;
59 }
60
61 void TextureManager::addResource(TextureResource* r) {
62
63 if(r->resource_name.empty()) {
64 char res_name[256];
65 snprintf(res_name, 256, "__texture_resource_%d", ++resource_seq);
66
67 std::string resource_name(res_name);
68
69 r->setResourceName(resource_name);
70 }
71
72 resources[r->resource_name] = r;
4973 r->addref();
74 }
75
76 TextureResource* TextureManager::create(GLenum target) {
77
78 TextureResource* r = new TextureResource();
79 r->target = target;
80
81 r->load();
82
83 addResource(r);
5084
5185 return (TextureResource*)r;
52 }
53
54 // texture resource
55
56 TextureResource::TextureResource(std::string file, bool mipmaps, bool clamp, bool trilinear, bool external_file) : Resource(file) {
86
87 }
88
89 TextureResource* TextureManager::create(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data) {
90
91 TextureResource* r = new TextureResource(width, height, mipmaps, wrap, format, data);
92 r->load();
93
94 addResource(r);
95
96 return (TextureResource*)r;
97
98
99 }
100
101 void TextureManager::unload() {
102 for(std::map<std::string, Resource*>::iterator it= resources.begin(); it!=resources.end();it++) {
103 ((TextureResource*)it->second)->unload();
104 }
105 }
106
107 void TextureManager::reload() {
108 for(std::map<std::string, Resource*>::iterator it= resources.begin(); it!=resources.end();it++) {
109 ((TextureResource*)it->second)->load();
110 }
111 }
112
113 // TextureResource
114
115 TextureResource::TextureResource() {
116 textureid = 0;
117 w = 0;
118 h = 0;
119 format = 0;
120 data = 0;
121 wrap = GL_CLAMP_TO_EDGE;
122 target = GL_TEXTURE_2D;
123 mipmaps = false;
124
125 setDefaultFiltering();
126 }
127
128 TextureResource::TextureResource(const std::string& filename, bool mipmaps, GLint wrap, bool external) : Resource(filename) {
129
130 this->mipmaps = mipmaps;
131 this->wrap = wrap;
132
133 data = 0;
134 format = 0;
135 textureid = 0;
136 target = GL_TEXTURE_2D;
57137
58138 //if doesnt have an absolute path, look in resource dir
59 if(!external_file && !(file.size() > 2 && file[1] == ':') && !(file.size() > 1 && file[0] == '/')) {
60 file = texturemanager.getDir() + file;
61 }
62
63 debugLog("creating texture from %s\n", file.c_str());
64
65 SDL_Surface *surface = IMG_Load(file.c_str());
66
67 if(surface==0) throw TextureException(file);
68
69 w = surface->w;
70 h = surface->h;
71
72 //figure out image colour order
73 int format = colourFormat(surface);
74
75 if(format==0) throw TextureException(file);
76
77 textureid = display.createTexture(w, h, mipmaps, clamp, trilinear, format, (unsigned int*) surface->pixels);
78
79 SDL_FreeSurface(surface);
80 }
81
82 int TextureResource::colourFormat(SDL_Surface* surface) {
139 if(!external && !(filename.size() > 2 && filename[1] == ':') && !(filename.size() > 1 && filename[0] == '/')) {
140 this->filename = texturemanager.getDir() + filename;
141 } else {
142 this->filename = filename;
143 }
144
145 setDefaultFiltering();
146 }
147
148 TextureResource::TextureResource(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data) {
149 this->w = width;
150 this->h = height;
151 this->data = data;
152 this->format = format;
153 this->mipmaps = mipmaps;
154 this->wrap = wrap;
155 this->target = GL_TEXTURE_2D;
156
157 textureid = 0;
158
159 setDefaultFiltering();
160 }
161
162 TextureResource::~TextureResource() {
163 unload();
164 }
165
166 void TextureResource::setDefaultFiltering() {
167
168 if(mipmaps) {
169
170 if(texturemanager.trilinear) {
171 min_filter = GL_LINEAR_MIPMAP_LINEAR;
172 } else {
173 min_filter = GL_LINEAR_MIPMAP_NEAREST;
174 }
175
176 mag_filter = GL_LINEAR;
177
178 } else {
179 min_filter = GL_LINEAR;
180 mag_filter = GL_LINEAR;
181 }
182
183 }
184
185 void TextureResource::setFiltering(GLint min_filter, GLint mag_filter) {
186
187 this->min_filter = min_filter;
188 this->mag_filter = mag_filter;
189
190 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter);
191 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filter);
192 }
193
194 void TextureResource::setWrapStyle(GLint wrap) {
195
196 this->wrap = wrap;
197
198 glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
199 glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
200 }
201
202
203 void TextureResource::unload() {
204 if(textureid!=0) glDeleteTextures(1, &textureid);
205 textureid=0;
206 }
207
208 void TextureResource::createTexture() {
209
210 if(!textureid) glGenTextures(1, &textureid);
211
212 glBindTexture(target, textureid);
213
214 if(w != 0 && format != 0) {
215
216 GLint internalFormat = 0;
217
218 switch(format) {
219 case GL_ALPHA:
220 internalFormat = GL_ALPHA;
221 break;
222 case GL_LUMINANCE:
223 internalFormat = GL_LUMINANCE;
224 break;
225 default:
226 internalFormat = GL_RGBA;
227 break;
228 }
229
230 if(mipmaps) {
231 gluBuild2DMipmaps(target, internalFormat, w, h, format, GL_UNSIGNED_BYTE, data);
232 } else {
233 glTexImage2D(target, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_BYTE, data);
234 }
235 }
236
237 setFiltering(min_filter, mag_filter);
238 setWrapStyle(wrap);
239 }
240
241 void TextureResource::reload() {
242 load(true);
243 }
244
245 void TextureResource::load(bool reload) {
246
247 if(textureid != 0) {
248 if(!reload) return;
249 debugLog("texture %d is being reloaded", textureid);
250 }
251
252 SDL_Surface *surface = 0;
253
254 if(!filename.empty()) {
255 debugLog("creating texture from %s", filename.c_str());
256
257 surface = IMG_Load(filename.c_str());
258
259 if(surface==0) throw TextureException(filename);
260
261 w = surface->w;
262 h = surface->h;
263
264 //figure out image colour order
265 format = colourFormat(surface);
266
267 data = (GLubyte*) surface->pixels;
268
269 if(format==0) throw TextureException(filename);
270 }
271
272 createTexture();
273
274 if(surface != 0) {
275 SDL_FreeSurface(surface);
276 data = 0;
277 }
278 }
279
280 GLenum TextureResource::colourFormat(SDL_Surface* surface) {
83281
84282 int colours = surface->format->BytesPerPixel;
85283 int format = 0;
100298 return format;
101299 }
102300
103 TextureResource::~TextureResource() {
104 if(textureid!=0) glDeleteTextures(1, &textureid);
105 }
301 void TextureResource::bind() {
302
303 if(!textureid) load();
304 glBindTexture(target, textureid);
305 }
3030 #include "SDL_image.h"
3131
3232 #include "resource.h"
33 #include "display.h"
33 #include "gl.h"
3434
3535 class TextureException : public ResourceException {
3636 public:
3838 };
3939
4040 class TextureResource : public Resource {
41 int colourFormat(SDL_Surface* surface);
42 void loadTexture(std::string file, bool mipmaps, bool clamp, bool trilinear, bool external_file);
41 bool mipmaps;
42 GLint wrap;
43 GLint min_filter;
44 GLint mag_filter;
45 std::string filename;
46
47 GLenum colourFormat(SDL_Surface* surface);
4348 public:
44 int w, h;
49 int w, h;
50 GLenum target;
51 GLenum format;
4552 GLuint textureid;
46 TextureResource(std::string name, bool mipmaps, bool clamp, bool trilinear, bool external_file);
53 GLubyte* data;
54
55 TextureResource();
56 TextureResource(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data = 0);
57 TextureResource(const std::string& filename, bool mipmaps, GLint wrap, bool external);
58
59 void setWrapStyle(GLint wrap);
60
61 void setFiltering(GLint min_filter, GLint mag_filter);
62 void setDefaultFiltering();
63
64 void bind();
65
66 void createTexture();
67
68 void reload();
69
70 void load(bool reload = false);
71
72 void unload();
73
4774 ~TextureResource();
4875 };
4976
5077 class TextureManager : public ResourceManager {
78 int resource_seq;
79
80 void addResource(TextureResource* r);
5181 public:
82 bool trilinear;
83
5284 TextureManager();
53 TextureResource* grabFile(std::string name, bool mipmaps=true, bool clamp=true, bool trilinear=false);
54 TextureResource* grab(std::string file, bool mipmaps=true, bool clamp=true, bool trilinear=false, bool external_file = false);
85
86 TextureResource* grabFile(const std::string& filename, bool mipmaps = true, GLint wrap = GL_CLAMP_TO_EDGE);
87 TextureResource* grab(const std::string& filename, bool mipmaps = true, GLint wrap = GL_CLAMP_TO_EDGE, bool external_file = false);
88
89 TextureResource* create(int width, int height, bool mipmaps, GLint wrap, GLenum format, GLubyte* data = 0);
90 TextureResource* create(GLenum target = GL_TEXTURE_2D);
91
92 void unload();
93 void reload();
5594 };
5695
5796 extern TextureManager texturemanager;
6363 };
6464
6565 /// The library API - functions intended to be called by the users
66
67 template <typename octet_iterator>
68 octet_iterator append(uint32_t cp, octet_iterator result)
69 {
70 if (!internal::is_code_point_valid(cp))
71 throw invalid_code_point(cp);
72
73 if (cp < 0x80) // one octet
74 *(result++) = static_cast<uint8_t>(cp);
75 else if (cp < 0x800) { // two octets
76 *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
77 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
78 }
79 else if (cp < 0x10000) { // three octets
80 *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
81 *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
82 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
83 }
84 else if (cp <= internal::CODE_POINT_MAX) { // four octets
85 *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
86 *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
87 *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
88 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
89 }
90 else
91 throw invalid_code_point(cp);
92
93 return result;
94 }
6695
6796 template <typename octet_iterator, typename output_iterator>
6897 output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
103132 }
104133
105134 template <typename octet_iterator>
106 octet_iterator append(uint32_t cp, octet_iterator result)
107 {
108 if (!internal::is_code_point_valid(cp))
109 throw invalid_code_point(cp);
110
111 if (cp < 0x80) // one octet
112 *(result++) = static_cast<uint8_t>(cp);
113 else if (cp < 0x800) { // two octets
114 *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
115 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
116 }
117 else if (cp < 0x10000) { // three octets
118 *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
119 *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
120 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
121 }
122 else if (cp <= internal::CODE_POINT_MAX) { // four octets
123 *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
124 *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
125 *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
126 *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
127 }
128 else
129 throw invalid_code_point(cp);
130
131 return result;
132 }
133
134 template <typename octet_iterator>
135135 uint32_t next(octet_iterator& it, octet_iterator end)
136136 {
137137 uint32_t cp = 0;
0 #ifndef CORE_UTIL_H
1 #define CORE_UTIL_H
2
3 #include <boost/foreach.hpp>
4
5 #define foreach BOOST_FOREACH
6
7 #endif
2828
2929 //quadbuf
3030
31 quadbuf::quadbuf(int data_size) : data_size(data_size) {
31 quadbuf::quadbuf(int vertex_capacity) : vertex_capacity(vertex_capacity) {
3232 vertex_count = 0;
33 curr_buffer =-1;
3433
35 buffers.resize(1);
36
37 data = data_size > 0 ? new quadbuf_vertex[data_size] : 0;
34 data = vertex_capacity > 0 ? new quadbuf_vertex[vertex_capacity] : 0;
3835
3936 //fprintf(stderr, "size of quadbuf_vertex = %d\n", sizeof(quadbuf_vertex));
4037 }
4340 if(data!=0) delete[] data;
4441 }
4542
43 void quadbuf::unload() {
44 buf.unload();
45 }
46
4647 void quadbuf::resize(int new_size) {
4748
4849 quadbuf_vertex* _data = data;
4950
5051 data = new quadbuf_vertex[new_size];
5152
52 for(int i=0;i<data_size;i++) {
53 for(int i=0;i<vertex_capacity;i++) {
5354 data[i] = _data[i];
5455 }
5556
56 data_size = new_size;
57 vertex_capacity = new_size;
5758
5859 if(_data != 0) delete[] _data;
5960 }
6869 }
6970
7071 size_t quadbuf::capacity() {
71 return data_size;
72 return vertex_capacity;
7273 }
7374
7475 size_t quadbuf::texture_changes() {
7576 return textures.size();
7677 }
7778
78 vec4f quadbuf_default_texcoord(0.0f, 0.0f, 1.0f, 1.0f);
79 vec4 quadbuf_default_texcoord(0.0f, 0.0f, 1.0f, 1.0f);
7980
80 void quadbuf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour) {
81 void quadbuf::add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour) {
8182 add(textureid, pos, dims, colour, quadbuf_default_texcoord);
8283 }
8384
84 void quadbuf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord) {
85 void quadbuf::add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord) {
8586 //debugLog("%d: %.2f, %.2f, %.2f, %.2f\n", i, pos.x, pos.y, dims.x, dims.y);
8687
87 quadbuf_vertex v1(pos, colour, vec2f(texcoord.x, texcoord.y));
88 quadbuf_vertex v2(pos + vec2f(dims.x, 0.0f), colour, vec2f(texcoord.z, texcoord.y));
89 quadbuf_vertex v3(pos + dims, colour, vec2f(texcoord.z, texcoord.w));
90 quadbuf_vertex v4(pos + vec2f(0.0f, dims.y), colour, vec2f(texcoord.x, texcoord.w));
88 quadbuf_vertex v1(pos, colour, vec2(texcoord.x, texcoord.y));
89 quadbuf_vertex v2(pos + vec2(dims.x, 0.0f), colour, vec2(texcoord.z, texcoord.y));
90 quadbuf_vertex v3(pos + dims, colour, vec2(texcoord.z, texcoord.w));
91 quadbuf_vertex v4(pos + vec2(0.0f, dims.y), colour, vec2(texcoord.x, texcoord.w));
9192
9293 int i = vertex_count;
9394
9495 vertex_count += 4;
9596
96 if(vertex_count > data_size) {
97 if(vertex_count > vertex_capacity) {
9798 resize(vertex_count*2);
9899 }
99100
113114
114115 vertex_count += 4;
115116
116 if(vertex_count > data_size) {
117 if(vertex_count > vertex_capacity) {
117118 resize(vertex_count*2);
118119 }
119120
130131 void quadbuf::update() {
131132 if(vertex_count==0) return;
132133
133 curr_buffer = (curr_buffer + 1) % buffers.size();
134
135 quadbuf_buffer* buf = &(buffers[curr_buffer]);
136
137 if(!buf->id) {
138 glGenBuffers(1, &(buf->id));
139 }
140
141 glBindBuffer(GL_ARRAY_BUFFER, buf->id);
134 buf.bind();
142135
143136 //recreate buffer if less than the vertex_count
144 if(buf->size < vertex_count) {
145 buf->size = data_size;
146 glBufferData(GL_ARRAY_BUFFER, buf->size*sizeof(quadbuf_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW);
147 } else {
148 glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(quadbuf_vertex), &(data[0].pos.x));
149 }
150
151 glBindBuffer(GL_ARRAY_BUFFER, 0);
137 buf.buffer( vertex_count, sizeof(quadbuf_vertex), vertex_capacity, &(data[0].pos.x), GL_DYNAMIC_DRAW );
138
139 buf.unbind();
152140 }
153141
154142 void quadbuf::draw() {
155 if(vertex_count==0 || curr_buffer==-1) return;
156
157 glBindBuffer(GL_ARRAY_BUFFER, buffers[curr_buffer].id);
143 if(vertex_count==0) return;
144
145 buf.bind();
158146
159147 glEnableClientState(GL_VERTEX_ARRAY);
160148 glEnableClientState(GL_COLOR_ARRAY);
195183 glDisableClientState(GL_COLOR_ARRAY);
196184 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
197185
198 glBindBuffer(GL_ARRAY_BUFFER, 0);
186 buf.unbind();
199187 }
3939 class quadbuf_vertex {
4040 public:
4141 quadbuf_vertex() {};
42 quadbuf_vertex(const vec2f& pos, const vec4f& colour, const vec2f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {};
42 quadbuf_vertex(const vec2& pos, const vec4& colour, const vec2& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {};
4343
44 vec2f pos;
45 vec4f colour;
46 vec2f texcoord;
44 vec2 pos;
45 vec4 colour;
46 vec2 texcoord;
4747 };
4848
4949 //maintain ranges corresponding to each texture
5757
5858 class quadbuf_buffer {
5959 public:
60 GLuint id;
61 int capacity;
62
6063 quadbuf_buffer() {
6164 id = 0;
62 size = 0;
65 capacity = 0;
6366 }
6467 ~quadbuf_buffer() {
65 if(id !=0) glDeleteBuffers(1, &id);
68 unload();
6669 }
6770
68 GLuint id;
69 int size;
71 void init() {
72 if(!id) glGenBuffers(1, &id);
73 }
74
75 void unload() {
76 capacity = 0;
77 if(id != 0) {
78 glDeleteBuffers(1, &id);
79 id = 0;
80 }
81 }
82
83 void bind() {
84 if(!id) init();
85 glBindBuffer(GL_ARRAY_BUFFER, id);
86 }
87
88 void buffer(int item_count, int item_size, int item_capacity, GLvoid* data, GLenum usage) {
89
90 if(capacity < item_count) {
91 capacity = item_capacity;
92 glBufferData(GL_ARRAY_BUFFER, capacity * item_size, data, usage);
93 } else {
94 glBufferSubData(GL_ARRAY_BUFFER, 0, item_count * item_size, data);
95 }
96 }
97
98 void unbind() {
99 glBindBuffer(GL_ARRAY_BUFFER, 0);
100 }
70101 };
71102
72103 class quadbuf {
73104
74105 quadbuf_vertex* data;
75 int data_size;
106 int vertex_capacity;
76107
77108 std::vector<quadbuf_tex> textures;
78109
79 std::vector<quadbuf_buffer> buffers;
80 int curr_buffer;
110 quadbuf_buffer buf;
81111
82112 int vertex_count;
83113
86116 quadbuf(int data_size = 0);
87117 ~quadbuf();
88118
119 void unload();
89120 void reset();
90121
91122 size_t vertices();
92123 size_t capacity();
93124 size_t texture_changes();
94125
95 void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour);
96 void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord);
126 void add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour);
127 void add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord);
97128 void add(GLuint textureid, const quadbuf_vertex& v1, const quadbuf_vertex& v2, const quadbuf_vertex& v3, const quadbuf_vertex& v4);
98129
99130 void update();
0 #include "vectors.h"
1
2 vec2 rotate_vec2(const vec2& v, float s, float c) {
3 return vec2( v.x * c - v.y * s, v.x * s + v.y * c );
4 }
5
6 vec2 normalise(const vec2& v) {
7 float l = glm::length(v);
8 if(l > 0.0) return v / l;
9 return v;
10 }
11
12 vec3 normalise(const vec3& v) {
13 float l = glm::length(v);
14 if(l > 0.0) return v / l;
15 return v;
16 }
17
18 vec4 normalise(const vec4& v) {
19 float l = glm::length(v);
20 if(l > 0.0) return v / l;
21 return v;
22 }
2727 #ifndef VECTORS_H
2828 #define VECTORS_H
2929
30 #include <cmath>
30 #include <glm/glm.hpp>
31 #include <glm/gtc/type_ptr.hpp>
32 #include <glm/gtc/matrix_transform.hpp>
33 #include <glm/gtc/matrix_access.hpp>
34 #include <glm/gtx/norm.hpp>
3135
32 template<class T> class vec2 {
36 using glm::vec2;
37 using glm::vec3;
38 using glm::vec4;
39 using glm::mat3;
40 using glm::mat4;
41
42 vec2 rotate_vec2(const vec2& v, float s, float c);
43
44 vec2 normalise(const vec2& v);
45 vec3 normalise(const vec3& v);
46 vec4 normalise(const vec4& v);
47
48 class lerp2 : public glm::vec2 {
3349 public:
34 T x;
35 T y;
50 vec2 p;
51 vec2 l;
3652
37 vec2(const vec2<T>& vec) {
38 this->x = vec.x;
39 this->y = vec.y;
53 lerp2() : vec2(), p(), l() {
4054 }
4155
42 vec2(T x = 0, T y = 0) {
43 this->x = x;
44 this->y = y;
45 }
46
47 vec2<T> perpendicular() const {
48 return vec2<T>(y * -1.0f, x);
49 }
50
51
52 T dot(const vec2<T> &vec) const {
53 return x*vec.x + y*vec.y;
54 }
55
56 T operator* (const vec2<T> &vec) const {
57 return x*vec.x + y*vec.y;
58 }
59
60 vec2<T> operator+ (const vec2<T> &vec) const {
61 return vec2<T>(x+vec.x, y+vec.y);
62 }
63
64 vec2<T> operator- (const vec2<T> &vec) const {
65 return vec2<T>(x-vec.x, y-vec.y);
66 }
67
68 vec2<T> operator* (const T n) const {
69 return vec2<T>(x*n, y*n);
70 }
71
72 vec2<T> operator/ (const T n) const {
73 return vec2<T>(x/n, y/n);
74 }
75
76 friend vec2<T> operator* (T n, const vec2<T>& vec) {
77 return vec2<T>(vec.x*n, vec.y*n);
78 }
79
80 bool operator== (const vec2<T> &vec) const {
81 return (vec.x==x && vec.y==y);
82 }
83
84 bool operator!= (const vec2<T> &vec) const {
85 return (vec.x!=x || vec.y!=y);
86 }
87
88 T length2() const {
89 return x*x + y*y;
90 }
91
92 T length() const {
93 return sqrt(x*x + y*y);
94 }
95
96 void normalize() {
97 T len = length();
98 if(len == 0) return;
99
100 *this *= (1.0/len);
101 }
102
103 vec2<T> normal() const {
104 vec2<T> v(x,y);
105 v.normalize();
106 return v;
107 }
108
109 vec2<T> rotate(float angle) const {
110
111 float s = sinf(angle);
112 float c = cosf(angle);
113
114 return vec2<T>( x * c - y * s, x * s + y * c );
115 }
116
117 vec2<T> rotate(float s, float c) const {
118 return vec2<T>( x * c - y * s, x * s + y * c );
119 }
120
121 vec2<T> rotate(const vec2<T> &centre, float angle) const {
122 vec2<T> v = *this - centre;
123
124 float s = sinf(angle);
125 float c = cosf(angle);
126
127 v = vec2<T>( v.x * c - v.y * s, v.x * s + v.y * c );
128
129 return v + centre;
130 }
131
132 vec2<T> rotate(const vec2<T> &centre, float s, float c) const {
133 vec2<T> v = *this - centre;
134
135 v = vec2<T>( v.x * c - v.y * s, v.x * s + v.y * c );
136
137 return v + centre;
138 }
139
140
141 operator T*() const {
142 return (T*) &x;
143 }
144
145 vec2<T>& operator= (const vec2<T> &vec) {
146 x = vec.x;
147 y = vec.y;
56 const lerp2& snap() {
57 p = *this;
14858 return *this;
14959 }
15060
151 void operator+= (const vec2<T> &vec) {
152 x += vec.x;
153 y += vec.y;
61 static vec2 lerp(const vec2& a, const vec2& b, float n) {
62 return a + (b - a) * n;
15463 }
15564
156 void operator-= (const vec2<T> &vec) {
157 x -= vec.x;
158 y -= vec.y;
65 const vec2& lerp(float n) {
66 l = p + (*this - p) * n;
67 return l;
15968 }
160
161 void operator*= (T n) {
162 x *= n;
163 y *= n;
164 }
165
166 void operator/= (T n) {
167 x /= n;
168 y /= n;
69
70 const lerp2& operator= (const vec2& vec) {
71 this->x = vec.x;
72 this->y = vec.y;
73 return *this;
16974 }
17075 };
17176
172 template<class T> class vec3 {
77 class lerp3 : public vec3 {
17378 public:
174 T x;
175 T y;
176 T z;
79 vec3 p;
80 vec3 l;
17781
178 vec3(const vec3<T>& vec) {
82 lerp3() : vec3(), p(), l() {
83 }
84
85 const lerp3& snap() {
86 p = *this;
87 return *this;
88 }
89
90 static vec3 lerp(const vec3& a, const vec3& b, float n) {
91 return a + (b - a) * n;
92 }
93
94 const vec3& lerp(float n) {
95 l = p + (*this - p) * n;
96 return l;
97 }
98
99 const lerp3& operator= (const vec3& vec) {
179100 this->x = vec.x;
180101 this->y = vec.y;
181102 this->z = vec.z;
182 }
183
184 vec3(const vec2<T>& vec, float z) {
185 this->x = vec.x;
186 this->y = vec.y;
187 this->z = z;
188 }
189
190 vec3(T x = 0, T y = 0, T z = 0) {
191 this->x = x;
192 this->y = y;
193 this->z = z;
194 }
195
196 vec3<T> cross(const vec3<T>& vec) const {
197 return vec3<T>(y*vec.z-z*vec.y, z*vec.x-x*vec.z, x*vec.y-y*vec.x);
198 }
199
200 T dot(const vec3<T>& vec) const {
201 return x*vec.x + y*vec.y + z*vec.z;
202 }
203
204 T operator* (const vec3<T> &vec) const {
205 return x*vec.x + y*vec.y + z*vec.z;
206 }
207
208 vec3<T> operator+ (const vec3<T> &vec) const {
209 return vec3<T>(x+vec.x,y+vec.y,z+vec.z);
210 }
211
212 vec3<T> operator- (const vec3<T> &vec) const {
213 return vec3<T>(x-vec.x,y-vec.y,z-vec.z);
214 }
215
216 vec3<T> operator* (T n) const {
217 return vec3<T>(x*n,y*n,z*n);
218 }
219
220 vec3<T> operator/ (const T n) const {
221 return vec3<T>(x/n, y/n, z/n);
222 }
223
224 friend vec3<T> operator* (T n, const vec3<T>& vec) {
225 return vec3<T>(vec.x*n,vec.y*n,vec.z*n);
226 }
227
228 bool operator== (vec3<T> &vec) const {
229 return (vec.x==x && vec.y==y && vec.z==z);
230 }
231
232 bool operator!= (vec3<T> &vec) const {
233 return (vec.x!=x || vec.y!=y || vec.z!=z);
234 }
235
236 T length2() const {
237 return x*x + y*y + z*z;
238 }
239
240 T length() const {
241 return sqrt(x*x + y*y + z*z);
242 }
243
244 void normalize() {
245 T len = length();
246 if(len == 0) return;
247
248 *this *= (1.0/len);
249 }
250
251 vec3<T> normal() const {
252 vec3<T> v(x,y,z);
253 v.normalize();
254 return v;
255 }
256
257 vec2<T> truncate() const {
258 return vec2<T>(x, y);
259 }
260
261 operator T*() const {
262 return (T*) &x;
263 }
264
265 vec3<T>& operator= (const vec3<T> &vec) {
266 x = vec.x;
267 y = vec.y;
268 z = vec.z;
269103 return *this;
270 }
271
272 void operator+= (const vec3<T> &vec) {
273 x += vec.x;
274 y += vec.y;
275 z += vec.z;
276 }
277
278 void operator-= (const vec3<T> &vec) {
279 x -= vec.x;
280 y -= vec.y;
281 z -= vec.z;
282 }
283
284 void operator*= (T n) {
285 x *= n;
286 y *= n;
287 z *= n;
288 }
289
290 void operator/= (T n) {
291 x /= n;
292 y /= n;
293 z /= n;
294104 }
295105 };
296106
297 template<class T> class lerp3 : public vec3<T> {
298 public:
299 vec3<T> p;
300 vec3<T> l;
301
302 lerp3() : vec3<T>(), p(), l() {
303 }
304
305 lerp3(const vec3<T>& vec) : vec3<T>(vec) {
306 }
307
308 void snap() {
309 p = (vec3<T>) *this;
310 }
311
312 const vec3<T>& lerp(T n) {
313 l = p * n + *this * (1.0-n);
314 return l;
315 }
316 };
317
318 template<class T> class vec4 {
319 public:
320 T x;
321 T y;
322 T z;
323 T w;
324
325 vec4(T x = 0, T y = 0, T z = 0, T w = 0) {
326 this->x = x;
327 this->y = y;
328 this->z = z;
329 this->w = w;
330 }
331
332 vec4(const vec4<T>& vec) {
333 this->x = vec.x;
334 this->y = vec.y;
335 this->z = vec.z;
336 this->w = vec.w;
337 }
338
339 vec4(const vec3<T>& vec, T w) {
340 this->x = vec.x;
341 this->y = vec.y;
342 this->z = vec.z;
343 this->w = w;
344 }
345
346 vec4<T>& operator= (const vec4<T> &vec) {
347 x = vec.x;
348 y = vec.y;
349 z = vec.z;
350 w = vec.w;
351 return *this;
352 }
353
354 T dot(const vec4<T>& vec) const {
355 return x*vec.x + y*vec.y + z*vec.z + w*vec.w;
356 }
357
358 vec4<T> operator+ (const vec4<T> &vec) const {
359 return vec4<T>(x+vec.x, y+vec.y, z+vec.z, w+vec.w);
360 }
361
362 vec4<T> operator- (const vec4<T> &vec) const {
363 return vec4<T>(x-vec.x, y-vec.y, z-vec.z, w-vec.w);
364 }
365
366 vec4<T> operator* (T n) const {
367 return vec4<T>(x*n, y*n, z*n, w*n);
368 }
369
370 vec4<T> operator/ (const T n) const {
371 return vec4<T>(x/n, y/n, z/n, w/n);
372 }
373
374 T operator* (const vec4<T> &vec) const {
375 return x*vec.x + y*vec.y + z*vec.z + w*vec.w;
376 }
377
378 friend vec4<T> operator* (T n, const vec4<T>& vec) {
379 return vec4<T>(vec.x*n, vec.y*n, vec.z*n, vec.w*n);
380 }
381
382 bool operator== (const vec4<T> &vec) const {
383 return (vec.x==x && vec.y==y && vec.z==z && vec.w==w);
384 }
385
386 bool operator!= (const vec4<T> &vec) const {
387 return (vec.x!=x || vec.y!=y || vec.z!=z || vec.w!=w);
388 }
389
390 T length2() const {
391 return x*x + y*y + z*z + w*w;
392 }
393
394 T length() const {
395 return sqrt(x*x + y*y + z*z + w*w);
396 }
397
398 void normalize() {
399 T len = length();
400 if(len == 0) return;
401
402 *this *= (1.0/len);
403 }
404
405 vec4<T> normal() const {
406 vec4<T> v(x,y,z,w);
407 v.normalize();
408 return v;
409 }
410
411 vec3<T> truncate() const {
412 return vec3<T>(x, y, z);
413 }
414
415 operator T*() const {
416 return (T*) &x;
417 }
418
419 void operator+= (const vec4<T> &vec) {
420 x += vec.x;
421 y += vec.y;
422 z += vec.z;
423 w += vec.w;
424 }
425
426 void operator-= (const vec4<T> &vec) {
427 x -= vec.x;
428 y -= vec.y;
429 z -= vec.z;
430 w -= vec.w;
431 }
432
433 void operator*= (T n) {
434 x *= n;
435 y *= n;
436 z *= n;
437 w *= n;
438 }
439
440 void operator/= (T n) {
441 x /= n;
442 y /= n;
443 z /= n;
444 w /= n;
445 }
446 };
447
448 typedef vec2<float> vec2f;
449 typedef vec3<float> vec3f;
450 typedef vec4<float> vec4f;
451
452 typedef lerp3<float> lerp3f;
453
454 typedef vec2<int> vec2i;
455 typedef vec3<int> vec3i;
456 typedef vec4<int> vec4i;
457
458107 #endif
+0
-93
src/custom.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "custom.h"
18
19 Regex custom_regex("^([0-9]+)\\|([^|]*)\\|([ADM]?)\\|([^|]+)(?:\\|#?([A-F0-9]{6}))?");
20
21 CustomLog::CustomLog(const std::string& logfile) : RCommitLog(logfile) {
22 }
23
24 vec3f CustomLog::parseColour(const std::string& cstr) {
25 debugLog("parseColour\n");
26 vec3f colour;
27 int r,g,b;
28
29 if(sscanf(cstr.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
30
31 colour = vec3f( r, g, b );
32 colour /= 255.0f;
33
34 debugLog("colour %.2f %.2f %.2f\n", colour.x,colour.y,colour.z);
35 }
36
37 return colour;
38 }
39
40 // parse modified cvs format log entries
41
42 bool CustomLog::parseCommit(RCommit& commit) {
43
44 while(parseCommitEntry(commit));
45
46 return !commit.files.empty();
47 }
48
49 bool CustomLog::parseCommitEntry(RCommit& commit) {
50
51 std::string line;
52 std::vector<std::string> entries;
53
54 if(!getNextLine(line)) return false;
55
56 //custom line
57 if(!custom_regex.match(line, &entries)) return false;
58
59 long timestamp = atol(entries[0].c_str());
60
61 std::string username = (entries[1].size()>0) ? entries[1] : "Unknown";
62 std::string action = (entries[2].size()>0) ? entries[2] : "A";
63
64 //if this file is for the same person and timestamp
65 //we add to the commit, else we save the lastline
66 //and return false
67 if(commit.files.empty()) {
68 commit.timestamp = timestamp;
69 commit.username = username;
70 } else {
71 if(commit.timestamp != timestamp || commit.username != username) {
72 lastline = line;
73 return false;
74 }
75 }
76
77 bool has_colour = false;
78 vec3f colour;
79
80 if(entries.size()>=5 && entries[4].size()>0) {
81 has_colour = true;
82 colour = parseColour(entries[4]);
83 }
84
85 if(has_colour) {
86 commit.addFile(entries[3], action, colour);
87 } else {
88 commit.addFile(entries[3], action);
89 }
90
91 return true;
92 }
+0
-32
src/custom.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CUSTOMLOG_H
18 #define CUSTOMLOG_H
19
20 #include "commitlog.h"
21
22 class CustomLog : public RCommitLog {
23 protected:
24 bool parseCommit(RCommit& commit);
25 bool parseCommitEntry(RCommit& commit);
26 vec3f parseColour(const std::string& cstr);
27 public:
28 CustomLog(const std::string& logfile);
29 };
30
31 #endif
+0
-135
src/cvs-exp.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "cvs-exp.h"
18
19 Regex cvsexp_commitno_regex("^([0-9]{6}):");
20 Regex cvsexp_branch_regex("^BRANCH \\[(.+)\\]$");
21 Regex cvsexp_date_regex("^\\(date: ([0-9]{4})[-/]([0-9]{2})[-/]([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})(?: [+-][0-9]{4})?;(.+)$");
22 Regex cvsexp_detail_regex("author: ([^;]+); state: ([^;]+);(.+)$");
23 //Regex cvsexp_lines_regex("lines: \\+([0-9]+) -([0-9]+)");
24 Regex cvsexp_entry_regex("\\| (.+),v:([0-9.]+),?");
25 Regex cvsexp_end_regex("^(=+)$");
26
27 std::string gGourceCvsExpLogCommand = "cvs-exp.pl -notree";
28
29 CVSEXPCommitLog::CVSEXPCommitLog(const std::string& logfile) : RCommitLog(logfile) {
30 }
31
32 // parse modified cvs format log entries
33
34 bool CVSEXPCommitLog::parseCommit(RCommit& commit) {
35
36 std::string line;
37 std::vector<std::string> entries;
38
39 if(!logf->getNextLine(line)) return false;
40
41 //skip empty line if there is one
42 if(line.size() == 0) {
43 if(!logf->getNextLine(line)) return false;
44 }
45
46 //read commit no
47 if(!cvsexp_commitno_regex.match(line, &entries)) return false;
48
49 //int commitno = atoi(entries[0].c_str());
50 //debugLog("commitno matched\n");
51
52 if(!logf->getNextLine(line)) return false;
53
54 //should be a branch
55 if(cvsexp_branch_regex.match(line, &entries)) {
56
57 //read next blank line
58 if(!logf->getNextLine(line)) return false;
59 if(line.size()) return false;
60 if(!logf->getNextLine(line)) return false;
61 }
62
63 //parse date
64 if(!cvsexp_date_regex.match(line, &entries)) return false;
65
66 //debugLog("date matched\n");
67
68 struct tm time_str;
69
70 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
71 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
72 time_str.tm_mday = atoi(entries[2].c_str());
73 time_str.tm_hour = atoi(entries[3].c_str());
74 time_str.tm_min = atoi(entries[4].c_str());
75 time_str.tm_sec = atoi(entries[5].c_str());
76 time_str.tm_isdst = -1;
77
78 commit.timestamp = mktime(&time_str);
79
80 //parse author,state
81 std::string rest = entries[6];
82 if(!cvsexp_detail_regex.match(rest, &entries)) return false;
83
84 //debugLog("author/state matched\n");
85
86 commit.username = entries[0];
87
88 std::string commit_state = entries[1];
89
90 /* not used
91 //if rest is not ')' parse lines
92 rest = entries[2];
93
94 // need to parse lines
95 if(rest.size() > 2) {
96 if(!cvsexp_lines_regex.match(rest, &entries)) return false;
97 }
98 */
99
100 if(!logf->getNextLine(line)) return false;
101
102 std::string commit_action = (commit_state == "dead") ? "D" : "M";
103
104 while(cvsexp_entry_regex.match(line, &entries)) {
105
106 //ignore files in Attic - previously deleted file
107 if(entries[0].find("/Attic/") == std::string::npos) {
108 commit.addFile(entries[0], commit_action);
109 }
110
111 if(!logf->getNextLine(line)) return false;
112 }
113
114 //read blank line
115 if(!logf->getNextLine(line)) return false;
116
117 //std::string message;
118
119 //read commit message
120 while(logf->getNextLine(line) && line.size()) {
121 //if(message.size()) message += std::string("\n");
122 //message += line;
123 }
124
125 //read until end of commit or eof
126 while(logf->getNextLine(line)) {
127 if(cvsexp_end_regex.match(line,&entries)) {
128 //debugLog("read end of commit %s\n", entries[0].c_str());
129 break;
130 }
131 }
132
133 return true;
134 }
+0
-32
src/cvs-exp.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CVSLOG_EXP_H
18 #define CVSLOG_EXP_H
19
20 #include "commitlog.h"
21
22 class CVSEXPCommitLog : public RCommitLog {
23 protected:
24 bool parseCommit(RCommit& commit);
25 public:
26 CVSEXPCommitLog(const std::string& logfile);
27 };
28
29 extern std::string gGourceCvsExpLogCommand;
30
31 #endif
+0
-155
src/cvs2cl.cpp less more
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "cvs2cl.h"
18
19 Regex cvs2cl_xml_tag("^<\\??xml");
20 Regex cvs2cl_logentry_start("^<entry");
21 Regex cvs2cl_logentry_end("^</entry>");
22 Regex cvs2cl_logentry_timestamp("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})Z");
23
24 std::string gGourceCVS2CLLogCommand = "cvs2cl --chrono --stdout --xml -g-q";
25
26 CVS2CLCommitLog::CVS2CLCommitLog(const std::string& logfile) : RCommitLog(logfile, '<') {
27 }
28
29 bool CVS2CLCommitLog::parseCommit(RCommit& commit) {
30
31 //fprintf(stderr,"parsing cvs2cl log\n");
32
33 std::string line;
34
35 if(!getNextLine(line)) return false;
36
37 //start of log entry
38 if(!cvs2cl_logentry_start.match(line)) {
39
40 //is this the start of the document
41 if(!cvs2cl_xml_tag.match(line)) return false;
42
43 //fprintf(stderr,"found xml tag\n");
44
45 //if so find the first logentry tag
46
47 bool found_logentry = false;
48
49 while(getNextLine(line)) {
50 if(cvs2cl_logentry_start.match(line)) {
51 found_logentry = true;
52 break;
53 }
54 }
55
56 if(!found_logentry) return false;
57 }
58
59 //fprintf(stderr,"found logentry\n");
60
61 logentry.clear();
62
63 logentry.append(line);
64 logentry.append("\n");
65
66 //fprintf(stderr,"found opening tag\n");
67
68 bool endfound = false;
69
70 while(getNextLine(line)) {
71 logentry.append(line);
72 logentry.append("\n");
73 if(cvs2cl_logentry_end.match(line)) {
74 //fprintf(stderr,"found closing tag\n");
75 endfound=true;
76 break;
77 }
78 }
79
80 //incomplete commit
81 if(!endfound) return false;
82
83 //fprintf(stderr,"read logentry\n");
84
85 TiXmlDocument doc;
86
87 if(!doc.Parse(logentry.c_str())) return false;
88
89 //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
90
91 TiXmlElement* leE = doc.FirstChildElement( "entry" );
92
93 std::vector<std::string> entries;
94
95 if(!leE) return false;
96
97 //parse date
98 TiXmlElement* dateE = leE->FirstChildElement( "isoDate" );
99
100 if(!dateE) return false;
101
102 std::string timestamp_str(dateE->GetText());
103
104 if(!cvs2cl_logentry_timestamp.match(timestamp_str, &entries))
105 return false;
106
107 struct tm time_str;
108
109 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
110 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
111 time_str.tm_mday = atoi(entries[2].c_str());
112 time_str.tm_hour = atoi(entries[3].c_str());
113 time_str.tm_min = atoi(entries[4].c_str());
114 time_str.tm_sec = atoi(entries[5].c_str());
115 time_str.tm_isdst = -1;
116
117 commit.timestamp = mktime(&time_str);
118
119 //parse author
120 TiXmlElement* authorE = leE->FirstChildElement("author");
121
122 if(authorE != 0) {
123
124 std::string author(authorE->GetText());
125
126 if(author.empty()) author = "Unknown";
127
128 commit.username = author;
129 }
130
131 //parse changes
132
133 for(TiXmlElement* fileE = leE->FirstChildElement("file"); fileE != 0; fileE = fileE->NextSiblingElement()) {
134
135 TiXmlElement* state = fileE->FirstChildElement("cvsstate");
136 TiXmlElement* name = fileE->FirstChildElement("name");
137
138 //check for state
139 if(name == 0 || state == 0) continue;
140
141 std::string status = strcmp(state->GetText(), "dead") == 0 ? "D" : "M";
142 std::string file(name->GetText());
143
144 if(file.empty()) continue;
145
146 commit.addFile(file, status);
147 }
148
149 //fprintf(stderr,"parsed logentry\n");
150
151 //read files
152
153 return true;
154 }
+0
-47
src/cvs2cl.h less more
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CVS2CL_H
18 #define CVS2CL_H
19
20 #include "gource_settings.h"
21
22 #include "commitlog.h"
23
24 #include <sstream>
25
26 #ifdef HAVE_LIBTINYXML
27 #include <tinyxml.h>
28 #else
29 #include "tinyxml/tinyxml.h"
30 #endif
31
32
33 #include <unistd.h>
34
35 extern std::string gGourceCVS2CLLogCommand;
36
37 class CVS2CLCommitLog : public RCommitLog {
38 protected:
39 bool parseCommit(RCommit& commit);
40
41 std::string logentry;
42 public:
43 CVS2CLCommitLog(const std::string& logfile);
44 };
45
46 #endif
3737 parent = 0;
3838 setParent(parent);
3939
40 accel = spos = prev_accel = vel = vec2(0.0f);
41
42 //NOTE: parent is always being set to 0 so this never gets called ...
43
4044 //figure out starting position
4145 if(parent !=0) {
42 vec2f parentPos = parent->getPos();
43 vec2f offset;
46 vec2 parentPos = parent->getPos();
47 vec2 offset;
4448
4549 RDirNode* parentP = parent->getParent();
4650
4751 pos = parentPos;
4852 } else {
49 pos = vec2f(0.0f, 0.0f);
53 pos = vec2(0.0f, 0.0f);
5054 }
5155
5256 float padded_file_radius = gGourceFileDiameter * 0.5;
113117 void RDirNode::rotate(float s, float c) {
114118
115119 if(parent != 0) {
116 pos = pos.rotate(s, c);
117 spos = spos.rotate(s, c);
120 pos = rotate_vec2(pos, s, c);
121 spos = rotate_vec2(spos, s, c);
118122 }
119123
120124 for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) {
123127 }
124128 }
125129
126 void RDirNode::setPos(const vec2f & pos) {
130 void RDirNode::setPos(const vec2 & pos) {
127131 this->pos = pos;
128132 }
129133
145149 return parent;
146150 }
147151
152
153 bool RDirNode::isDir(const std::string& path) const {
154
155 if(prefixedBy(path)) return true;
156
157 if(path.find(abspath) != 0) return false;
158
159 for(std::list<RDirNode*>::const_iterator it = children.begin(); it != children.end(); it++) {
160 if((*it)->isDir(path)) return true;
161 }
162
163 return false;
164 }
148165
149166 //finds directories closest to the root directory prefixed by path (eg foo/ may match just foo/ or could also match foo/bar1, foo/bar2, ... if foo/ doesn't exist).
150167 void RDirNode::findDirs(const std::string& path, std::list<RDirNode*>& dirs) {
368385 //simply change path of node and add this to it
369386 if( parent==0 && abspath == "/"
370387 && f->path.compare(abspath) != 0 && noFiles() && noDirs()) {
371 debugLog("modifying root path to %s\n", f->path.c_str());
388 debugLog("modifying root path to %s", f->path.c_str());
372389 changePath(f->path);
373390 }
374391
401418 //do we have a file in this directory thats fullpath is a prefix of this file, if so
402419 //that file is actually a directory - the file should be removed, and a directory with that path added
403420 //if this is the root node we do this regardless of if the file was added to a child node
421
404422 for(std::list<RFile*>::const_iterator it = files.begin(); it != files.end(); it++) {
405423 RFile* file = (*it);
406
424
407425 if(f->path.find(file->fullpath) == 0) {
408426 //fprintf(stderr, "removing %s as is actually the directory of %s\n", file->fullpath.c_str(), f->fullpath.c_str());
409427 file->remove(true);
425443 // if so create another node, and move those nodes there
426444
427445 std::string commonpath;
428 vec2f commonPos;
446 vec2 commonPos;
429447 for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) {
430448 RDirNode* child = (*it);
431449
475493 return dir_radius_sqrt;
476494 }
477495
478 vec3f RDirNode::averageFileColour() const{
479
480 vec3f av;
496 vec3 RDirNode::averageFileColour() const{
497
498 vec3 av;
481499 int count = 0;
482500
483501 for(std::list<RFile*>::const_iterator it = files.begin(); it != files.end(); it++) {
506524 return av;
507525 }
508526
509 const vec4f & RDirNode::getColour() const{
527 const vec4 & RDirNode::getColour() const{
510528 return col;
511529 }
512530
515533 // make branch brighter if recently accessed
516534 float brightness = std::max(0.6f, 1.0f - std::min(1.0f, since_last_node_change / 3.0f));
517535
518 col = vec4f(brightness, brightness, brightness, 1.0);
536 col = vec4(brightness, brightness, brightness, 1.0);
519537
520538 int fcount = 0;
521539
524542
525543 if(file->isHidden()) continue;;
526544
527 vec3f filecol = file->getColour() * brightness;
545 vec3 filecol = file->getColour() * brightness;
528546 float a = file->getAlpha();
529547
530 col += vec4f(filecol.x, filecol.y, filecol.z, a);
548 col += vec4(filecol.x, filecol.y, filecol.z, a);
531549
532550 fcount++;
533551 }
563581
564582 float RDirNode::distanceToParent() const{
565583
566 float posd = (parent->getPos() - pos).length();
584 float posd = glm::length(parent->getPos() - pos);
567585 float distance = posd - (dir_radius + parent->getParentRadius());
568
586
569587 return distance;
570588 }
571589
572590 void RDirNode::applyForceDir(RDirNode* node) {
573591 if(node == this) return;
574592
575 vec2f dir = node->getPos() - pos;
576
577 float posd2 = dir.length2();
593 vec2 dir = node->getPos() - pos;
594
595 float posd2 = glm::length2(dir);
578596 float myradius = getRadius();
579597 float your_radius = node->getRadius();
580
598
581599 float sumradius = (myradius + your_radius);
582600
583601 float distance2 = posd2 - sumradius*sumradius;
590608
591609 //resolve overlap
592610 if(posd < 0.00001) {
593 accel += vec2f( (rand() % 100) - 50, (rand() % 100) - 50).normal();
611 accel += normalise(vec2( (rand() % 100) - 50, (rand() % 100) - 50));
594612 return;
595613 }
596614
597 accel += distance * dir.normal();
598 }
599
600 const vec2f & RDirNode::getPos() const{
615 accel += distance * normalise(dir);
616 }
617
618 const vec2 & RDirNode::getPos() const{
601619 return pos;
602620 }
603621
636654 // * dirs should attract to sit on the radius of the parent dir ie:
637655 // should attract to distance_to_parent * normal_to_parent
638656
639 accel += gGourceForceGravity * parent_dist * (parent->getPos() - pos).normal();
640
657
658
659 accel += gGourceForceGravity * parent_dist * normalise(parent->getPos() - pos);
660
641661 // * dirs should be pushed along the parent_parent to parent normal by a force smaller than the parent radius force
642662 RDirNode* pparent = parent->getParent();
643663
644664 if(pparent != 0) {
645 vec2f parent_edge = (parent->getPos() - pparent->getPos());
646 vec2f parent_edge_normal = parent_edge.normal();
647
648 vec2f dest = (parent->getPos() + (parent->getRadius() + getRadius()) * parent_edge_normal) - pos;
665 vec2 parent_edge = (parent->getPos() - pparent->getPos());
666 vec2 parent_edge_normal = normalise(parent_edge);
667
668 vec2 dest = (parent->getPos() + (parent->getRadius() + getRadius()) * parent_edge_normal) - pos;
649669
650670 accel += dest;
651671 }
653673 // * dirs should repulse from other dirs of this parent
654674 const std::list<RDirNode*> & siblings = parent->getChildren();
655675 if(!siblings.empty()) {
656 vec2f sib_accel;
676 vec2 sib_accel;
657677
658678 int visible = 1;
659679
665685
666686 visible++;
667687
668 sib_accel -= (node->getPos() - pos).normal();
688 sib_accel -= normalise(node->getPos() - pos);
669689 }
670690
671691 //parent circumfrence divided by the number of visible child nodes
683703 std::string indentstr;
684704 while(indentstr.size() < indent) indentstr += " ";
685705
686 debugLog("%s%s\n", indentstr.c_str(), abspath.c_str());
706 debugLog("%s%s", indentstr.c_str(), abspath.c_str());
687707
688708 for(std::list<RDirNode*>::const_iterator it = children.begin(); it != children.end(); it++) {
689709 RDirNode* node = (*it);
729749 if(parent == 0) return;
730750
731751 //update the spline point
732 vec2f td = (parent->getPos() - pos) * 0.5;
733
734 vec2f mid = pos + td;// - td.perpendicular() * pos.normal();// * 10.0;
735
736 vec2f delta = (mid - spos);
752 vec2 td = (parent->getPos() - pos) * 0.5f;
753
754 vec2 mid = pos + td;// - td.perpendicular() * pos.normal();// * 10.0;
755
756 vec2 delta = (mid - spos);
737757
738758 //dont let spos get more than half the length of the distance behind
739 if(delta.length2() > td.length2()) {
740 spos += delta.normal() * (delta.length() - td.length());
741 }
742
743 spos += delta * std::min(1.0, dt * 2.0);
759 if(glm::length2(delta) > glm::length2(td)) {
760 spos += normalise(delta) * (glm::length(delta) - glm::length(td));
761 }
762
763 spos += delta * std::min(1.0f, dt * 2.0f);
744764 }
745765
746766 void RDirNode::setInitialPosition() {
750770
751771 //offset position by some pseudo-randomness
752772 if(parentP != 0) {
753 pos += ((parent->getPos() - parentP->getPos()).normal() * 2.0 + vec2Hash(abspath)).normal();
773 //pos += ((parent->getPos() - parentP->getPos()).normal() * 2.0 + vec2Hash(abspath)).normal();
774 pos += normalise(normalise(parent->getPos() - parentP->getPos()) * 2.0f + vec2Hash(abspath));
775
754776 } else {
755777 pos += vec2Hash(abspath);
756778 }
757
779
758780 //the spline point
759 spos = pos - (parent->getPos() - pos) * 0.5;
781 spos = pos - (parent->getPos() - pos) * 0.5f;
760782 position_initialized=true;
761783 }
762784
764786
765787 //the root node is the centre of the world
766788 if(parent == 0) {
767 pos = vec2f(0.0, 0.0);
789 pos = vec2(0.0f);
768790 return;
769791 }
770792
776798 pos += accel * dt;
777799
778800 if(gGourceSettings.elasticity>0.0) {
779 vec2f diff = (accel - prev_accel);
801 vec2 diff = (accel - prev_accel);
780802
781803 float m = dt * gGourceSettings.elasticity;
782804
783 vec2f accel3 = prev_accel * (1.0-m) + diff * m;
805 vec2 accel3 = prev_accel * (1.0f-m) + diff * m;
784806 pos += accel3;
785807 prev_accel = accel3;
786808 }
787809
788810 //accel = accel * std::max(0.0f, (1.0f - dt*10.0f));
789 accel = vec2f(0.0, 0.0);
790 }
791
792 const vec2f & RDirNode::getNodeNormal() const{
811 accel = vec2(0.0, 0.0);
812 }
813
814 const vec2 & RDirNode::getNodeNormal() const{
793815 return node_normal;
794816 }
795817
796 vec2f RDirNode::calcFileDest(int max_files, int file_no) {
818 vec2 RDirNode::calcFileDest(int max_files, int file_no) {
797819
798820 float arc = 1.0/(float)max_files;
799821
800822 float frac = arc * 0.5 + arc * file_no;
801823
802 vec2f dest = vec2f(sinf(frac*PI*2.0), cosf(frac*PI*2.0));
824 vec2 dest = vec2(sinf(frac*PI*2.0), cosf(frac*PI*2.0));
803825
804826 return dest;
805827 }
817839 RFile* f = *it;
818840
819841 if(f->isHidden()) {
820 f->setDest(vec2f(0.0,0.0));
842 f->setDest(vec2(0.0,0.0));
821843 f->setDistance(0.0f);
822844 continue;
823845 }
824846
825 vec2f dest = calcFileDest(max_files, file_no);
847 vec2 dest = calcFileDest(max_files, file_no);
826848
827849 f->setDest(dest);
828850 f->setDistance(d);
865887
866888 //update node normal
867889 if(parent != 0) {
868 node_normal = (pos - parent->getPos()).normal();
890 node_normal = normalise(pos - parent->getPos());
869891 }
870892
871893 //update files
900922
901923 float alpha = gGourceSettings.highlight_dirs ? 1.0 : std::max(0.0f, 5.0f - since_last_node_change) / 5.0f;
902924
903 vec2f mid = spline.getMidPoint();
925 vec2 mid = spline.getMidPoint();
904926
905927 dirfont.setAlpha(alpha);
906928 dirfont.draw(mid.x, mid.y, path_token);
920942 projected_spos.x = screen_x;
921943 projected_spos.y = screen_y;
922944
923 static vec2f selected_offset(5.5f, -2.0f);
924 static vec2f unselected_offset(5.5f, -1.0f);
945 static vec2 selected_offset(5.5f, -2.0f);
946 static vec2 unselected_offset(5.5f, -1.0f);
925947
926948 if(!gGourceSettings.hide_filenames) {
927949
10041026
10051027 if(f->isHidden()) continue;
10061028
1007 vec3f col = f->getColour();
1029 vec3 col = f->getColour();
10081030 float alpha = f->getAlpha();
10091031
1010 buffer.add(f->graphic->textureid, f->getAbsolutePos() - f->dims*0.5f, f->dims, vec4f(col.x, col.y, col.z, alpha));
1032 buffer.add(f->graphic->textureid, f->getAbsolutePos() - f->dims*0.5f, f->dims, vec4(col.x, col.y, col.z, alpha));
10111033 }
10121034 }
10131035
10231045
10241046 float bloom_radius = dir_radius * 2.0 * gGourceSettings.bloom_multiplier;
10251047 float bloom_diameter = bloom_radius * 2.0;
1026 vec4f bloom_col = col * gGourceSettings.bloom_intensity;
1027
1028 vec4f bloom_texcoords(bloom_radius, pos.x, pos.y, 0.0f);
1029
1030 vec2f bloom_dims(bloom_diameter, bloom_diameter);
1031
1032 buffer.add(0, pos - bloom_dims*0.5f,bloom_dims, vec4f(bloom_col.x, bloom_col.y, bloom_col.z, 1.0f), bloom_texcoords);
1048 vec4 bloom_col = col * gGourceSettings.bloom_intensity;
1049
1050 vec4 bloom_texcoords(bloom_radius, pos.x, pos.y, 0.0f);
1051
1052 vec2 bloom_dims(bloom_diameter, bloom_diameter);
1053
1054 buffer.add(0, pos - bloom_dims*0.5f,bloom_dims, vec4(bloom_col.x, bloom_col.y, bloom_col.z, 1.0f), bloom_texcoords);
10331055 }
10341056
10351057 for(std::list<RDirNode*>::const_iterator it = children.begin(); it != children.end(); it++) {
10421064
10431065 if(in_frustum) {
10441066
1045 vec4f col = getColour();
1067 vec4 col = getColour();
10461068
10471069 glPushMatrix();
10481070 glTranslatef(pos.x, pos.y, 0.0);
10651087 }
10661088 }
10671089
1068 const vec2f & RDirNode::getSPos() const{
1090 const vec2 & RDirNode::getSPos() const{
10691091 return projected_spos;
10701092 }
10711093
1072 const vec2f & RDirNode::getProjectedPos() const{
1094 const vec2 & RDirNode::getProjectedPos() const{
10731095 return projected_pos;
10741096 }
10751097
11201142
11211143 float bloom_radius = dir_radius * 2.0 * gGourceSettings.bloom_multiplier;
11221144
1123 vec4f bloom_col = col * gGourceSettings.bloom_intensity;
1145 vec4 bloom_col = col * gGourceSettings.bloom_intensity;
11241146
11251147 glColor4f(bloom_col.x, bloom_col.y, bloom_col.z, 1.0);
11261148
11491171 void RDirNode::updateQuadItemBounds() {
11501172 float radius = getRadius();
11511173
1152 vec2f radoffset(radius, radius);
1174 vec2 radoffset(radius, radius);
11531175
11541176 //set bounds
11551177 quadItemBounds.set(pos - radoffset, pos + radoffset);
4646
4747 SplineEdge spline;
4848
49 vec4f col;
50
51 vec2f spos;
52
53 vec2f projected_pos;
54 vec2f projected_spos;
55
56 vec2f pos;
57 vec2f vel;
58 vec2f accel, prev_accel;
49 vec4 col;
50
51 vec2 spos;
52
53 vec2 projected_pos;
54 vec2 projected_spos;
55
56 vec2 pos;
57 vec2 vel;
58 vec2 accel, prev_accel;
5959
6060 float dir_area;
6161
7676
7777 int visible_count;
7878
79 vec3f screenpos;
80 vec2f node_normal;
79 vec3 screenpos;
80 vec2 node_normal;
8181
8282 void calcRadius();
8383 void calcColour();
9292 void updateSplinePoint(float dt);
9393 void move(float dt);
9494
95 vec2f calcFileDest(int layer_no, int file_no);
95 vec2 calcFileDest(int layer_no, int file_no);
9696 void updateFilePositions();
9797
9898 void adjustPath();
132132
133133 const std::string & getPath() const;
134134
135 const vec2f & getNodeNormal() const;
135 const vec2 & getNodeNormal() const;
136136
137137 bool isParent(RDirNode* node) const;
138138
152152 const std::list<RFile*>* getFiles() const { return &files; };
153153 void getFilesRecursive(std::list<RFile*>& files) const;
154154
155 vec3f averageFileColour() const;
156
157 const vec4f & getColour() const;
155 vec3 averageFileColour() const;
156
157 const vec4 & getColour() const;
158158
159159 RDirNode* getParent() const;
160160
161 bool isDir(const std::string& path) const;
161162 void findDirs(const std::string& path, std::list<RDirNode*>& dirs);
162163
163 const vec2f & getPos() const;
164 const vec2 & getPos() const;
164165
165166 void calcEdges();
166167
167 const vec2f & getProjectedPos() const;
168 const vec2f & getSPos() const;
169
170 void setPos(const vec2f & pos);
168 const vec2 & getProjectedPos() const;
169 const vec2 & getSPos() const;
170
171 void setPos(const vec2 & pos);
171172
172173 void rotate(float s, float c);
173174
2323 FXFont file_selected_font;
2424 FXFont file_font;
2525
26 RFile::RFile(const std::string & name, const vec3f & colour, const vec2f & pos, int tagid) : Pawn(name,pos,tagid) {
26 RFile::RFile(const std::string & name, const vec3 & colour, const vec2 & pos, int tagid) : Pawn(name,pos,tagid) {
2727 hidden = true;
28 size = gGourceFileDiameter;
28 size = gGourceFileDiameter * 1.05;
2929 radius = size * 0.5;
3030
3131 setGraphic(gGourceSettings.file_graphic);
3434 nametime = 4.0;
3535 name_interval = nametime;
3636
37 namecol = vec3f(1.0, 1.0, 1.0);
37 namecol = vec3(1.0, 1.0, 1.0);
3838 file_colour = colour;
3939
4040 last_action = 0.0;
5151 file_selected_font = fontmanager.grab("FreeSans.ttf", 18);
5252 file_selected_font.dropShadow(true);
5353 file_selected_font.roundCoordinates(false);
54 file_selected_font.setColour(vec4f(1.0f, 1.0f, 0.0f, 1.0f));
54 file_selected_font.setColour(vec4(gGourceSettings.selection_colour, 1.0f));
5555 }
5656
5757 if(!file_font.initialized()) {
5858 file_font = fontmanager.grab("FreeSans.ttf", 14);
5959 file_font.dropShadow(true);
6060 file_font.roundCoordinates(false);
61 file_font.setColour(vec4f(1.0f, 1.0f, 1.0f, 1.0f));
61 file_font.setColour(vec4(1.0f, 1.0f, 1.0f, 1.0f));
6262 }
6363
6464 //namelist = glGenLists(1);
8585 return dir;
8686 }
8787
88 vec2f RFile::getAbsolutePos() const{
88 vec2 RFile::getAbsolutePos() const{
8989 return pos + dir->getPos();
9090 }
9191
92 bool RFile::overlaps(const vec2f& pos) const {
93
94 vec2f abs_pos = getAbsolutePos();
92 bool RFile::overlaps(const vec2& pos) const {
93
94 vec2 abs_pos = getAbsolutePos();
9595
9696 float halfsize_x = size * 0.5f;
97 vec2f halfsize ( halfsize_x, halfsize_x * graphic_ratio );
97 vec2 halfsize ( halfsize_x, halfsize_x * graphic_ratio );
9898
9999 Bounds2D file_bounds(abs_pos - halfsize, abs_pos + halfsize);
100100
153153 }
154154
155155 void RFile::colourize() {
156 file_colour = ext.size() ? colourHash(ext) : vec3f(1.0f, 1.0f, 1.0f);
157 }
158
159 const vec3f& RFile::getNameColour() const{
160 return selected ? selectedcol : namecol;
161 }
162
163 const vec3f & RFile::getFileColour() const{
156 file_colour = ext.size() ? colourHash(ext) : vec3(1.0f, 1.0f, 1.0f);
157 }
158
159 const vec3& RFile::getNameColour() const{
160 return selected ? gGourceSettings.selection_colour : namecol;
161 }
162
163 const vec3 & RFile::getFileColour() const{
164164 return file_colour;
165165 }
166166
167 vec3f RFile::getColour() const{
168 if(selected) return vec3f(1.0, 1.0, 1.0);
167 vec3 RFile::getColour() const{
168 if(selected) return vec3(1.0f);
169169
170170 float lc = elapsed - last_action;
171171
172 if(lc<1.0) {
173 return touch_colour * (1.0-lc) + file_colour * lc;
172 if(lc<1.0f) {
173 return touch_colour * (1.0f-lc) + file_colour * lc;
174174 }
175175
176176 return file_colour;
190190 void RFile::logic(float dt) {
191191 Pawn::logic(dt);
192192
193 vec2f dest_pos = dest;
193 vec2 dest_pos = dest;
194194 /*
195195 if(dir->getParent() != 0 && dir->noDirs()) {
196 vec2f dirnorm = dir->getNodeNormal();
196 vec2 dirnorm = dir->getNodeNormal();
197197 dest_pos = dirnorm + dest;
198198 }*/
199199
204204 accel = dest_pos - pos;
205205
206206 // apply accel
207 vec2f accel2 = accel * speed * dt;
208
209 if(accel2.length2() > accel.length2()) {
207 vec2 accel2 = accel * speed * dt;
208
209 if(glm::length2(accel2) > glm::length2(accel)) {
210210 accel2 = accel;
211211 }
212212
213213 pos += accel2;
214214
215215 //files have no momentum
216 accel = vec2f(0.0f, 0.0f);
216 accel = vec2(0.0f, 0.0f);
217217
218218 // has completely faded out
219219 if(!expiring && elapsed - last_action >= gGourceSettings.file_idle_time + 1.0) {
238238 if(isHidden() && !removing) elapsed = 0.0;
239239 }
240240
241 void RFile::touch(const vec3f & colour) {
241 void RFile::touch(const vec3 & colour) {
242242 if(removing) return;
243243
244244 //fprintf(stderr, "touch %s\n", fullpath.c_str());
275275
276276 static GLdouble screen_x, screen_y, screen_z;
277277
278 vec2f text_pos = getAbsolutePos();
278 vec2 text_pos = getAbsolutePos();
279279 text_pos.x += 5.5f;
280280
281281 if(selected)
1717 #ifndef RFILE_H
1818 #define RFILE_H
1919
20 #include "core/stringhash.h"
21
2220 #include "pawn.h"
2321 #include "dirnode.h"
22 #include "core/stringhash.h"
2423
2524 class RDirNode;
2625
2726 class RFile : public Pawn {
28 vec3f file_colour;
29 vec3f touch_colour;
27 vec3 file_colour;
28 vec3 touch_colour;
3029
3130 RDirNode* dir;
3231
3736
3837 float radius;
3938
40 vec2f dest;
39 vec2 dest;
4140 float distance;
4241
4342 // FXLabel* label;
4645
4746 void setFilename(const std::string& abs_file_path);
4847
49 const vec3f& getNameColour() const;
48 const vec3& getNameColour() const;
5049 void drawNameText(float alpha);
5150 public:
5251 std::string path;
5352 std::string fullpath;
5453 std::string ext;
5554
56 RFile(const std::string & name, const vec3f & colour, const vec2f & pos, int tagid);
55 RFile(const std::string & name, const vec3 & colour, const vec2 & pos, int tagid);
5756 ~RFile();
5857
5958 bool isExpiring() const { return expiring; }
6059 bool isRemoving() const { return removing; }
6160
62 bool overlaps(const vec2f& pos) const;
61 bool overlaps(const vec2& pos) const;
6362
64 const vec3f & getFileColour() const;
65 vec3f getColour() const;
63 const vec3 & getFileColour() const;
64 vec3 getColour() const;
6665 void colourize();
6766
6867 float getAlpha() const;
6968
70 void touch(const vec3f & colour);
69 void touch(const vec3 & colour);
7170
7271 void setSelected(bool selected);
7372
7574
7675 void setHidden(bool hidden);
7776
78 void setDest(const vec2f & dest){ this->dest = dest; }
77 void setDest(const vec2 & dest){ this->dest = dest; }
7978 void setDistance(float distance){ this->distance = distance; }
8079
8180 void calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection);
8584
8685 void remove(bool force=false);
8786
88 vec2f getAbsolutePos() const;
87 vec2 getAbsolutePos() const;
8988
9089 RDirNode* getDir() const;
9190 void setDir(RDirNode* dir);
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "apache.h"
18
19 const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug" , "Sep", "Oct", "Nov", "Dec" };
20 Regex apache_entry_start("^(?:[^ ]+ )?([^ ]+) +[^ ]+ +([^ ]+) +\\[(.*?)\\] +(.*)$");
21 Regex apache_entry_date("(\\d+)/([A-Za-z]+)/(\\d+):(\\d+):(\\d+):(\\d+) ([+-])(\\d+)");
22 Regex apache_entry_request("\"([^ ]+) +([^ ]+) +([^ ]+)\" +([^ ]+) +([^\\s+]+)(.*)");
23 Regex apache_entry_agent(" +\"([^\"]+)\" +\"([^\"]+)\" +\"([^\"]+)\"");
24 Regex apache_hostname_parts("([^.]+)(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?(?:\\.([^.]+))?$");
25
26 ApacheCombinedLog::ApacheCombinedLog(const std::string& logfile) : RCommitLog(logfile) {
27 }
28
29 //parse apache access.log entry into components
30 bool ApacheCombinedLog::parseCommit(RCommit& commit) {
31
32 std::string line;
33 std::vector<std::string> matches;
34
35 if(!logf->getNextLine(line)) return false;
36
37 apache_entry_start.match(line, &matches);
38
39 if(matches.size()!=4) {
40 return 0;
41 }
42
43 //get details
44 commit.username = matches[0];
45 //std::string user = matches[1];
46
47 //parse timestamp
48 struct tm time_str;
49
50 std::string request_str = matches[3];
51 std::string datestr = matches[2];
52
53 apache_entry_date.match(datestr, &matches);
54
55 if(matches.size()!=8) {
56 return 0;
57 }
58
59 int day = atoi(matches[0].c_str());
60 int year = atoi(matches[2].c_str());
61 int hour = atoi(matches[3].c_str());
62 int minute = atoi(matches[4].c_str());
63 int second = atoi(matches[5].c_str());
64
65 // int zone = atoi(matches[7].c_str());
66 //negative timezone
67 // if(strcmp(matches[6].c_str(), "-")==0) {
68 // zone = -zone;
69 // }
70
71 int month=0;
72
73 for(int i=0;i<12;i++) {
74 if(matches[1] == months[i]) {
75 month=i;
76 break;
77 }
78 }
79
80 time_str.tm_year = year - 1900;
81 time_str.tm_mon = month;
82 time_str.tm_mday = day;
83 time_str.tm_hour = hour;
84 time_str.tm_min = minute;
85 time_str.tm_sec = second;
86 time_str.tm_isdst = -1;
87
88 commit.timestamp = mktime(&time_str);
89
90 matches.clear();
91 apache_entry_request.match(request_str, &matches);
92
93 if(matches.size() < 5) {
94 return false;
95 }
96
97 std::string rtype = matches[0];
98 std::string file = matches[1];
99 std::string proto = matches[2];
100
101 int code = atoi(matches[3].c_str());
102 int bytes = atol(matches[4].c_str());
103
104 //remove args from url
105 size_t argpos = file.rfind("?");
106 if(argpos != std::string::npos) {
107 file = file.substr(0,argpos);
108 }
109
110 if(file.size()==0) file = "/";
111
112 //name index pages
113 if(file[file.size()-1] == '/') {
114 file += "index.html";
115 }
116
117 std::string action = "A";
118 commit.addFile(file, action);
119
120 std::string refer;
121 std::string agent;
122
123 if(matches.size() > 5) {
124 std::string agentstr = matches[5];
125 matches.clear();
126 apache_entry_agent.match(agentstr, &matches);
127
128 if(matches.size()>1) {
129 refer = matches[0];
130 agent = matches[1];
131 }
132 }
133
134 return true;
135 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GOURCE_APACHE_H
18 #define GOURCE_APACHE_H
19
20 #include <string>
21 #include <string.h>
22
23 #include <vector>
24 #include <time.h>
25
26 #include "commitlog.h"
27
28 class ApacheCombinedLog : public RCommitLog {
29 protected:
30 bool parseCommit(RCommit& commit);
31 BaseLog* generateLog(const std::string& dir);
32 public:
33 ApacheCombinedLog(const std::string& logfile);
34 };
35
36 #endif
0 /*
1 Copyright (C) 2010 John Arbash Meinel <john@arbash-meinel.com>
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "bzr.h"
18
19 Regex bzr_commit_regex("^ *([\\d.]+) (.+)\t(\\d{4})-(\\d+)-(\\d+)(?: \\{[^}]+})?(?: \\[merge\\])?$");
20 Regex bzr_file_regex("^ *([AMDR]) (.*[^/])$");
21
22 // parse Bazaar log entries (using the gource.style template)
23
24 std::string gGourceBzrLogCommand() {
25 return std::string("bzr log --verbose -r 1..-1 --short -n0 --forward");
26 }
27
28 BazaarLog::BazaarLog(const std::string& logfile) : RCommitLog(logfile) {
29
30 log_command = gGourceBzrLogCommand();
31
32 //can generate log from directory
33 if(!logf && is_dir) {
34 logf = generateLog(logfile);
35
36 if(logf) {
37 success = true;
38 seekable = true;
39 }
40 }
41 }
42
43 BaseLog* BazaarLog::generateLog(const std::string& dir) {
44
45 //does directory have a .bzr ?
46 std::string bzrdir = dir + std::string("/.bzr");
47 struct stat dirinfo;
48 int stat_rc = stat(bzrdir.c_str(), &dirinfo);
49 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
50 return 0;
51 }
52
53 std::string command = getLogCommand();
54
55 // do we have this client installed
56 requireExecutable("bzr");
57
58 createTempLog();
59
60 if(temp_file.size()==0) return 0;
61
62 char cmd_buff[2048];
63 sprintf(cmd_buff, "%s %s > %s", command.c_str(), dir.c_str(), temp_file.c_str());
64
65 int command_rc = systemCommand(cmd_buff);
66
67 if(command_rc != 0) {
68 return 0;
69 }
70
71 BaseLog* seeklog = new SeekLog(temp_file);
72
73 return seeklog;
74 }
75
76 bool BazaarLog::parseCommit(RCommit& commit) {
77
78 std::string line;
79 std::vector<std::string> entries;
80 int year, month, day;
81
82 if(!logf->getNextLine(line)) return false;
83
84 debugLog("read %s\n", line.c_str());
85 if (!bzr_commit_regex.match(line, &entries)) {
86 debugLog("regex failed\n");
87 return false;
88 }
89 commit.username = entries[1];
90
91 year = atoi(entries[2].c_str());
92 month = atoi(entries[3].c_str());
93 day = atoi(entries[4].c_str());
94
95 struct tm time_str;
96
97 time_str.tm_year = year - 1900;
98 time_str.tm_mon = month - 1;
99 time_str.tm_mday = day;
100 time_str.tm_hour = 0;
101 time_str.tm_min = 0;
102 time_str.tm_sec = 0;
103 time_str.tm_isdst = -1;
104
105 commit.timestamp = mktime(&time_str);
106
107 while(logf->getNextLine(line) && line.size()) {
108 if (!bzr_file_regex.match(line, &entries)) continue;
109 commit.addFile(entries[1], entries[0]);
110 }
111
112 return true;
113 }
0 /*
1 Copyright (C) 2010 John Arbash Meinel <john@arbash-meinel.com>
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef BAZAARLOG_H
18 #define BAZAARLOG_H
19
20 #include "commitlog.h"
21
22 std::string gGourceBzrLogCommand();
23
24 class BazaarLog : public RCommitLog {
25 protected:
26 bool parseCommit(RCommit& commit);
27 BaseLog* generateLog(const std::string& dir);
28 public:
29 BazaarLog(const std::string& logfile);
30 };
31
32 #endif
33
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "commitlog.h"
18 #include "../gource_settings.h"
19
20 std::string munge_utf8(const std::string& str) {
21
22 std::string munged;
23 try {
24 utf8::replace_invalid(str.begin(), str.end(), back_inserter(munged), '?');
25 }
26 catch(...) {
27 munged = "???";
28 }
29
30 return munged;
31 }
32
33 //RCommitLog
34
35 RCommitLog::RCommitLog(const std::string& logfile, int firstChar) {
36
37 logf = 0;
38 seekable = false;
39 success = false;
40 is_dir = false;
41 buffered = false;
42
43 if(logfile == "-") {
44
45 //check first char
46 if(checkFirstChar(firstChar, std::cin)) {
47 logf = new StreamLog();
48 is_dir = false;
49 seekable = false;
50 success = true;
51 }
52
53 return;
54 }
55
56 struct stat fileinfo;
57 int rc = stat(logfile.c_str(), &fileinfo);
58
59 if(rc==0) {
60 is_dir = (fileinfo.st_mode & S_IFDIR) ? true : false;
61
62 if(!is_dir) {
63
64 //check first char
65 std::ifstream testf(logfile.c_str());
66
67 bool firstOK = checkFirstChar(firstChar, testf);
68
69 testf.close();
70
71 if(firstOK) {
72 logf = new SeekLog(logfile);
73 seekable = true;
74 success = true;
75 }
76 }
77 }
78 }
79
80 RCommitLog::~RCommitLog() {
81 if(logf!=0) delete logf;
82
83 if(!temp_file.empty()) {
84 remove(temp_file.c_str());
85 }
86 }
87
88 int RCommitLog::systemCommand(const std::string& command) {
89 #ifdef _WIN32
90 SDLAppCreateWindowsConsole();
91 #endif
92 return system(command.c_str());
93 }
94
95 // TODO: implement check for 'nix OSs
96 void RCommitLog::requireExecutable(const std::string& exename) {
97
98 #ifdef _WIN32
99 TCHAR exePath[MAX_PATH];
100 DWORD result = SearchPath(0, exename.c_str(), ".exe", MAX_PATH, exePath, 0);
101
102 if(result) return;
103
104 throw SDLAppException("unable to find %s.exe", exename.c_str());
105 #endif
106 }
107
108 //check firstChar of stream is as expected. if no firstChar defined just returns true.
109 bool RCommitLog::checkFirstChar(int firstChar, std::istream& stream) {
110
111 //cant check this
112 if(firstChar == -1) return true;
113
114 int c = stream.peek();
115
116 if(firstChar == c) return true;
117
118 return false;
119 }
120
121 bool RCommitLog::checkFormat() {
122
123 if(!success) return false;
124
125 //read a commit to see if the log is in the correct format
126 if(nextCommit(lastCommit, false)) {
127
128 if(seekable) {
129 //if the log is seekable, go back to the start
130 ((SeekLog*)logf)->seekTo(0.0);
131 } else {
132 //otherwise set the buffered flag as we have bufferd one commit
133 buffered = true;
134 }
135
136 return true;
137 }
138
139 return false;
140 }
141
142 std::string RCommitLog::getLogCommand() {
143 return log_command;
144 }
145
146 bool RCommitLog::isSeekable() {
147 return seekable;
148 }
149
150 bool RCommitLog::getCommitAt(float percent, RCommit& commit) {
151 if(!seekable) return false;
152
153 SeekLog* seeklog = ((SeekLog*)logf);
154
155 //save settings
156 long currpointer = seeklog->getPointer();
157 std::string currlastline = lastline;
158
159 seekTo(percent);
160 bool success = findNextCommit(commit,500);
161
162 //restore settings
163 seeklog->setPointer(currpointer);
164 lastline = currlastline;
165
166 return success;
167 }
168
169 bool RCommitLog::getNextLine(std::string& line) {
170 if(!lastline.empty()) {
171 line = lastline;
172 lastline = std::string("");
173 return true;
174 }
175
176 return logf->getNextLine(line);
177 }
178
179
180 void RCommitLog::seekTo(float percent) {
181 if(!seekable) return;
182
183 lastline = "";
184
185 ((SeekLog*)logf)->seekTo(percent);
186 }
187
188 float RCommitLog::getPercent() {
189 if(seekable) return ((SeekLog*)logf)->getPercent();
190
191 return 0.0;
192 }
193
194 bool RCommitLog::findNextCommit(RCommit& commit, int attempts) {
195
196 for(int i=0;i<attempts;i++) {
197 RCommit c;
198
199 if(nextCommit(c)) {
200 commit = c;
201 return true;
202 }
203 }
204
205 return false;
206 }
207
208 bool RCommitLog::nextCommit(RCommit& commit, bool validate) {
209
210 if(buffered) {
211 commit = lastCommit;
212 buffered = false;
213 return true;
214 }
215
216 bool success = parseCommit(commit);
217
218 if(!success) return false;
219
220 commit.postprocess();
221
222 if(validate) return commit.isValid();
223
224 return true;
225 }
226
227 bool RCommitLog::isFinished() {
228 if(seekable && logf->isFinished()) return true;
229
230 return false;
231 }
232
233 //create temp file
234 void RCommitLog::createTempLog() {
235
236 std::string tempdir;
237
238 #ifdef _WIN32
239 DWORD tmplen = GetTempPath(0, "");
240
241 if(tmplen == 0) return;
242
243 std::vector<TCHAR> temp(tmplen+1);
244
245 tmplen = GetTempPath(static_cast<DWORD>(temp.size()), &temp[0]);
246
247 if(tmplen == 0 || tmplen >= temp.size()) return;
248
249 tempdir = std::string(temp.begin(), temp.begin() + static_cast<std::size_t>(tmplen));
250 tempdir += "\\";
251 #else
252 tempdir = "/tmp/";
253 #endif
254
255 char tmplate[1024];
256 snprintf(tmplate, 1024, "%sgource-XXXXXX", tempdir.c_str());
257
258 #ifdef _WIN32
259 if(mktemp(tmplate) < 0) return;
260 #else
261 if(mkstemp(tmplate) < 0) return;
262 #endif
263
264 temp_file = std::string(tmplate);
265 }
266
267 // RCommitFile
268
269 RCommitFile::RCommitFile(const std::string& filename, const std::string& action, vec3 colour) {
270
271 this->filename = munge_utf8(filename);
272
273 //prepend a root slash
274 if(this->filename[0] != '/') {
275 this->filename.insert(0, 1, '/');
276 }
277
278 this->action = action;
279 this->colour = colour;
280 }
281
282 RCommit::RCommit() {
283 timestamp = 0;
284 }
285
286 vec3 RCommit::fileColour(const std::string& filename) {
287
288 size_t slash = filename.rfind('/');
289 size_t dot = filename.rfind('.');
290
291 if(dot != std::string::npos && dot+1<filename.size() && (slash == std::string::npos || slash < dot)) {
292 std::string file_ext = filename.substr(dot+1);
293
294 return colourHash(file_ext);
295 } else {
296 return vec3(1.0, 1.0, 1.0);
297 }
298 }
299
300 void RCommit::addFile(const std::string& filename, const std::string& action) {
301 addFile(filename, action, fileColour(filename));
302 }
303
304 void RCommit::addFile(const std::string& filename, const std::string& action, const vec3& colour) {
305 //check filename against filters
306 if(!gGourceSettings.file_filters.empty()) {
307
308 for(std::vector<Regex*>::iterator ri = gGourceSettings.file_filters.begin(); ri != gGourceSettings.file_filters.end(); ri++) {
309 Regex* r = *ri;
310
311 if(r->match(filename)) {
312 return;
313 }
314 }
315 }
316
317 files.push_back(RCommitFile(filename, action, colour));
318 }
319
320 void RCommit::postprocess() {
321 username = munge_utf8(username);
322 }
323
324 bool RCommit::isValid() {
325
326 //check user against filters, if found, discard commit
327 if(!gGourceSettings.user_filters.empty()) {
328 for(std::vector<Regex*>::iterator ri = gGourceSettings.user_filters.begin(); ri != gGourceSettings.user_filters.end(); ri++) {
329 Regex* r = *ri;
330
331 if(r->match(username)) {
332 return false;
333 }
334 }
335 }
336
337 return !files.empty();
338 }
339
340 void RCommit::debug() {
341 debugLog("files:\n");
342
343 for(std::list<RCommitFile>::iterator it = files.begin(); it != files.end(); it++) {
344 RCommitFile f = *it;
345 debugLog("%s %s\n", f.action.c_str(), f.filename.c_str());
346 }
347 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef RCOMMIT_LOG_H
18 #define RCOMMIT_LOG_H
19
20
21 #include "../core/seeklog.h"
22 #include "../core/display.h"
23 #include "../core/regex.h"
24 #include "../core/stringhash.h"
25 #include "../core/utf8/utf8.h"
26
27 #include <time.h>
28 #include <string>
29 #include <list>
30
31 #include "sys/stat.h"
32
33 class RCommitFile {
34 public:
35 std::string filename;
36 std::string action;
37 vec3 colour;
38
39 RCommitFile(const std::string& filename, const std::string& action, vec3 colour);
40 };
41
42 class RCommit {
43 vec3 fileColour(const std::string& filename);
44 public:
45 time_t timestamp;
46 std::string username;
47
48 std::list<RCommitFile> files;
49
50 void postprocess();
51 bool isValid();
52
53 void addFile(const std::string& filename, const std::string& action);
54 void addFile(const std::string& filename, const std::string& action, const vec3& colour);
55
56 RCommit();
57 void debug();
58 virtual bool parse(BaseLog* logf) { return false; };
59 };
60
61 class RCommitLog {
62 protected:
63 BaseLog* logf;
64
65 std::string temp_file;
66 std::string log_command;
67
68 std::string lastline;
69
70 bool is_dir;
71 bool success;
72 bool seekable;
73
74 RCommit lastCommit;
75 bool buffered;
76
77 bool checkFirstChar(int firstChar, std::istream& stream);
78
79 void createTempLog();
80
81 bool getNextLine(std::string& line);
82
83 virtual bool parseCommit(RCommit& commit) { return false; };
84 public:
85 RCommitLog(const std::string& logfile, int firstChar = -1);
86 ~RCommitLog();
87
88 void seekTo(float percent);
89
90 bool checkFormat();
91
92 std::string getLogCommand();
93
94 int systemCommand(const std::string& command);
95 void requireExecutable(const std::string& exename);
96
97 bool getCommitAt(float percent, RCommit& commit);
98 bool findNextCommit(RCommit& commit, int attempts);
99 bool nextCommit(RCommit& commit, bool validate = true);
100 bool isFinished();
101 bool isSeekable();
102 float getPercent();
103 };
104
105 #endif
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "custom.h"
18
19 Regex custom_regex("^(-?[0-9]+)\\|([^|]*)\\|([ADM]?)\\|([^|]+)(?:\\|#?([A-F0-9]{6}))?");
20
21 CustomLog::CustomLog(const std::string& logfile) : RCommitLog(logfile) {
22 }
23
24 vec3 CustomLog::parseColour(const std::string& cstr) {
25 debugLog("parseColour\n");
26 vec3 colour;
27 int r,g,b;
28
29 if(sscanf(cstr.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
30
31 colour = vec3( r, g, b );
32 colour /= 255.0f;
33
34 debugLog("colour %.2f %.2f %.2f\n", colour.x,colour.y,colour.z);
35 }
36
37 return colour;
38 }
39
40 // parse modified cvs format log entries
41
42 bool CustomLog::parseCommit(RCommit& commit) {
43
44 while(parseCommitEntry(commit));
45
46 return !commit.files.empty();
47 }
48
49 bool CustomLog::parseCommitEntry(RCommit& commit) {
50
51 std::string line;
52 std::vector<std::string> entries;
53
54 if(!getNextLine(line)) return false;
55
56 //custom line
57 if(!custom_regex.match(line, &entries)) return false;
58
59 long timestamp = atol(entries[0].c_str());
60
61 std::string username = (entries[1].size()>0) ? entries[1] : "Unknown";
62 std::string action = (entries[2].size()>0) ? entries[2] : "A";
63
64 //if this file is for the same person and timestamp
65 //we add to the commit, else we save the lastline
66 //and return false
67 if(commit.files.empty()) {
68 commit.timestamp = timestamp;
69 commit.username = username;
70 } else {
71 if(commit.timestamp != timestamp || commit.username != username) {
72 lastline = line;
73 return false;
74 }
75 }
76
77 bool has_colour = false;
78 vec3 colour;
79
80 if(entries.size()>=5 && entries[4].size()>0) {
81 has_colour = true;
82 colour = parseColour(entries[4]);
83 }
84
85 if(has_colour) {
86 commit.addFile(entries[3], action, colour);
87 } else {
88 commit.addFile(entries[3], action);
89 }
90
91 return true;
92 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CUSTOMLOG_H
18 #define CUSTOMLOG_H
19
20 #include "commitlog.h"
21
22 class CustomLog : public RCommitLog {
23 protected:
24 bool parseCommit(RCommit& commit);
25 bool parseCommitEntry(RCommit& commit);
26 vec3 parseColour(const std::string& cstr);
27 public:
28 CustomLog(const std::string& logfile);
29 };
30
31 #endif
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "cvs-exp.h"
18
19 Regex cvsexp_commitno_regex("^([0-9]{6}):");
20 Regex cvsexp_branch_regex("^BRANCH \\[(.+)\\]$");
21 Regex cvsexp_date_regex("^\\(date: ([0-9]{4})[-/]([0-9]{2})[-/]([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})(?: [+-][0-9]{4})?;(.+)$");
22 Regex cvsexp_detail_regex("author: ([^;]+); state: ([^;]+);(.+)$");
23 //Regex cvsexp_lines_regex("lines: \\+([0-9]+) -([0-9]+)");
24 Regex cvsexp_entry_regex("\\| (.+),v:([0-9.]+),?");
25 Regex cvsexp_end_regex("^(=+)$");
26
27 std::string gGourceCvsExpLogCommand = "cvs-exp.pl -notree";
28
29 CVSEXPCommitLog::CVSEXPCommitLog(const std::string& logfile) : RCommitLog(logfile) {
30 }
31
32 // parse modified cvs format log entries
33
34 bool CVSEXPCommitLog::parseCommit(RCommit& commit) {
35
36 std::string line;
37 std::vector<std::string> entries;
38
39 if(!logf->getNextLine(line)) return false;
40
41 //skip empty line if there is one
42 if(line.size() == 0) {
43 if(!logf->getNextLine(line)) return false;
44 }
45
46 //read commit no
47 if(!cvsexp_commitno_regex.match(line, &entries)) return false;
48
49 //int commitno = atoi(entries[0].c_str());
50 //debugLog("commitno matched\n");
51
52 if(!logf->getNextLine(line)) return false;
53
54 //should be a branch
55 if(cvsexp_branch_regex.match(line, &entries)) {
56
57 //read next blank line
58 if(!logf->getNextLine(line)) return false;
59 if(line.size()) return false;
60 if(!logf->getNextLine(line)) return false;
61 }
62
63 //parse date
64 if(!cvsexp_date_regex.match(line, &entries)) return false;
65
66 //debugLog("date matched\n");
67
68 struct tm time_str;
69
70 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
71 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
72 time_str.tm_mday = atoi(entries[2].c_str());
73 time_str.tm_hour = atoi(entries[3].c_str());
74 time_str.tm_min = atoi(entries[4].c_str());
75 time_str.tm_sec = atoi(entries[5].c_str());
76 time_str.tm_isdst = -1;
77
78 commit.timestamp = mktime(&time_str);
79
80 //parse author,state
81 std::string rest = entries[6];
82 if(!cvsexp_detail_regex.match(rest, &entries)) return false;
83
84 //debugLog("author/state matched\n");
85
86 commit.username = entries[0];
87
88 std::string commit_state = entries[1];
89
90 /* not used
91 //if rest is not ')' parse lines
92 rest = entries[2];
93
94 // need to parse lines
95 if(rest.size() > 2) {
96 if(!cvsexp_lines_regex.match(rest, &entries)) return false;
97 }
98 */
99
100 if(!logf->getNextLine(line)) return false;
101
102 std::string commit_action = (commit_state == "dead") ? "D" : "M";
103
104 while(cvsexp_entry_regex.match(line, &entries)) {
105
106 //ignore files in Attic - previously deleted file
107 if(entries[0].find("/Attic/") == std::string::npos) {
108 commit.addFile(entries[0], commit_action);
109 }
110
111 if(!logf->getNextLine(line)) return false;
112 }
113
114 //read blank line
115 if(!logf->getNextLine(line)) return false;
116
117 //std::string message;
118
119 //read commit message
120 while(logf->getNextLine(line) && line.size()) {
121 //if(message.size()) message += std::string("\n");
122 //message += line;
123 }
124
125 //read until end of commit or eof
126 while(logf->getNextLine(line)) {
127 if(cvsexp_end_regex.match(line,&entries)) {
128 //debugLog("read end of commit %s\n", entries[0].c_str());
129 break;
130 }
131 }
132
133 return true;
134 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CVSLOG_EXP_H
18 #define CVSLOG_EXP_H
19
20 #include "commitlog.h"
21
22 class CVSEXPCommitLog : public RCommitLog {
23 protected:
24 bool parseCommit(RCommit& commit);
25 public:
26 CVSEXPCommitLog(const std::string& logfile);
27 };
28
29 extern std::string gGourceCvsExpLogCommand;
30
31 #endif
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "cvs2cl.h"
18
19 Regex cvs2cl_xml_tag("^<\\??xml");
20 Regex cvs2cl_logentry_start("^<entry");
21 Regex cvs2cl_logentry_end("^</entry>");
22 Regex cvs2cl_logentry_timestamp("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})Z");
23
24 std::string gGourceCVS2CLLogCommand = "cvs2cl --chrono --stdout --xml -g-q";
25
26 CVS2CLCommitLog::CVS2CLCommitLog(const std::string& logfile) : RCommitLog(logfile, '<') {
27 }
28
29 bool CVS2CLCommitLog::parseCommit(RCommit& commit) {
30
31 //fprintf(stderr,"parsing cvs2cl log\n");
32
33 std::string line;
34
35 if(!getNextLine(line)) return false;
36
37 //start of log entry
38 if(!cvs2cl_logentry_start.match(line)) {
39
40 //is this the start of the document
41 if(!cvs2cl_xml_tag.match(line)) return false;
42
43 //fprintf(stderr,"found xml tag\n");
44
45 //if so find the first logentry tag
46
47 bool found_logentry = false;
48
49 while(getNextLine(line)) {
50 if(cvs2cl_logentry_start.match(line)) {
51 found_logentry = true;
52 break;
53 }
54 }
55
56 if(!found_logentry) return false;
57 }
58
59 //fprintf(stderr,"found logentry\n");
60
61 logentry.clear();
62
63 logentry.append(line);
64 logentry.append("\n");
65
66 //fprintf(stderr,"found opening tag\n");
67
68 bool endfound = false;
69
70 while(getNextLine(line)) {
71 logentry.append(line);
72 logentry.append("\n");
73 if(cvs2cl_logentry_end.match(line)) {
74 //fprintf(stderr,"found closing tag\n");
75 endfound=true;
76 break;
77 }
78 }
79
80 //incomplete commit
81 if(!endfound) return false;
82
83 //fprintf(stderr,"read logentry\n");
84
85 TiXmlDocument doc;
86
87 if(!doc.Parse(logentry.c_str())) return false;
88
89 //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
90
91 TiXmlElement* leE = doc.FirstChildElement( "entry" );
92
93 std::vector<std::string> entries;
94
95 if(!leE) return false;
96
97 //parse date
98 TiXmlElement* dateE = leE->FirstChildElement( "isoDate" );
99
100 if(!dateE) return false;
101
102 std::string timestamp_str(dateE->GetText());
103
104 if(!cvs2cl_logentry_timestamp.match(timestamp_str, &entries))
105 return false;
106
107 struct tm time_str;
108
109 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
110 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
111 time_str.tm_mday = atoi(entries[2].c_str());
112 time_str.tm_hour = atoi(entries[3].c_str());
113 time_str.tm_min = atoi(entries[4].c_str());
114 time_str.tm_sec = atoi(entries[5].c_str());
115 time_str.tm_isdst = -1;
116
117 commit.timestamp = mktime(&time_str);
118
119 //parse author
120 TiXmlElement* authorE = leE->FirstChildElement("author");
121
122 if(authorE != 0) {
123
124 std::string author(authorE->GetText());
125
126 if(author.empty()) author = "Unknown";
127
128 commit.username = author;
129 }
130
131 //parse changes
132
133 for(TiXmlElement* fileE = leE->FirstChildElement("file"); fileE != 0; fileE = fileE->NextSiblingElement()) {
134
135 TiXmlElement* state = fileE->FirstChildElement("cvsstate");
136 TiXmlElement* name = fileE->FirstChildElement("name");
137
138 //check for state
139 if(name == 0 || state == 0) continue;
140
141 std::string status = strcmp(state->GetText(), "dead") == 0 ? "D" : "M";
142 std::string file(name->GetText());
143
144 if(file.empty()) continue;
145
146 commit.addFile(file, status);
147 }
148
149 //fprintf(stderr,"parsed logentry\n");
150
151 //read files
152
153 return true;
154 }
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef CVS2CL_H
18 #define CVS2CL_H
19
20 #include "../gource_settings.h"
21 #include "commitlog.h"
22
23 #include <sstream>
24
25 #ifdef HAVE_LIBTINYXML
26 #include <tinyxml.h>
27 #else
28 #include "../tinyxml/tinyxml.h"
29 #endif
30
31
32 #include <unistd.h>
33
34 extern std::string gGourceCVS2CLLogCommand;
35
36 class CVS2CLCommitLog : public RCommitLog {
37 protected:
38 bool parseCommit(RCommit& commit);
39
40 std::string logentry;
41 public:
42 CVS2CLCommitLog(const std::string& logfile);
43 };
44
45 #endif
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "git.h"
18
19 // parse git log entries
20
21 //git-log command notes:
22 // - no single quotes on WIN32 as system call treats them differently
23 // - 'user:' prefix allows us to quickly tell if the log is the wrong format
24 // and try a different format (eg cvs-exp)
25
26 std::string gGourceGitLogCommand = "git log "
27 "--pretty=format:user:%aN%n%ct "
28 "--reverse --raw --encoding=UTF-8 "
29 "--no-renames";
30
31 GitCommitLog::GitCommitLog(const std::string& logfile) : RCommitLog(logfile, 'u') {
32
33 log_command = gGourceGitLogCommand;
34
35 if(gGourceSettings.git_branch.size()>0) {
36 log_command += " ";
37 log_command += gGourceSettings.git_branch;
38 }
39
40 //can generate log from directory
41 if(!logf && is_dir) {
42 logf = generateLog(logfile);
43
44 if(logf) {
45 success = true;
46 seekable = true;
47 }
48 }
49 }
50
51 BaseLog* GitCommitLog::generateLog(const std::string& dir) {
52 //get working directory
53 char cwd_buff[1024];
54
55 if(getcwd(cwd_buff, 1024) != cwd_buff) {
56 return 0;
57 }
58
59 //does directory have a .git ?
60 std::string gitdir = dir + std::string("/.git");
61 struct stat dirinfo;
62 int stat_rc = stat(gitdir.c_str(), &dirinfo);
63 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
64 return 0;
65 }
66
67 // do we have this client installed
68 requireExecutable("git");
69
70 std::string command = getLogCommand();
71
72 //create temp file
73 createTempLog();
74
75 if(temp_file.size()==0) return 0;
76
77 if(chdir(dir.c_str()) != 0) {
78 return 0;
79 }
80
81 char cmd_buff[2048];
82 sprintf(cmd_buff, "%s > %s", command.c_str(), temp_file.c_str());
83
84 int command_rc = systemCommand(cmd_buff);
85
86 if(command_rc != 0) {
87 chdir(cwd_buff);
88 return 0;
89 }
90
91 // check for new-enough Git version
92 // if %aN does not appear to be supported try %an
93 std::ifstream in(temp_file.c_str());
94 char firstBytes[9];
95 in.read(firstBytes, 8);
96 in.close();
97 firstBytes[8] = '\0';
98 if(!strcmp(firstBytes, "user:%aN")) {
99 char *pos = strstr(cmd_buff, "%aN");
100 pos[2] = 'n';
101 command_rc = systemCommand(cmd_buff);
102 }
103
104 //change back to original directoy
105 chdir(cwd_buff);
106
107 if(command_rc != 0) {
108 return 0;
109 }
110
111 BaseLog* seeklog = new SeekLog(temp_file);
112
113 return seeklog;
114 }
115
116 // parse modified git format log entries
117
118 bool GitCommitLog::parseCommit(RCommit& commit) {
119
120 std::string line;
121
122 commit.username = "";
123
124 while(logf->getNextLine(line) && line.size()) {
125
126 if(line.find("user:") == 0) {
127
128 //username follows user prefix
129 commit.username = line.substr(5);
130
131 if(!logf->getNextLine(line)) return false;
132
133 commit.timestamp = atol(line.c_str());
134
135 //this isnt a commit we are parsing, abort
136 if(commit.timestamp == 0) return false;
137
138 continue;
139 }
140
141 //should see username before files
142 if(commit.username.empty()) return false;
143
144 size_t tab = line.find('\t');
145
146 //incorrect log format
147 if(tab == std::string::npos || tab == 0 || tab == line.size()-1) continue;
148
149 std::string status = line.substr(tab - 1, 1);
150 std::string file = line.substr(tab + 1);
151
152 if(file.empty()) continue;
153
154 //check for and remove double quotes
155 if(file.find('"') == 0 && file.rfind('"') == file.size()-1) {
156 if(file.size()<=2) continue;
157
158 file = file.substr(1,file.size()-2);
159 }
160
161 commit.addFile(file, status);
162 }
163
164 //check we at least got a username
165 if(commit.username.empty()) return false;
166
167 return true;
168 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GITLOG_H
18 #define GITLOG_H
19
20 #include "../gource_settings.h"
21 #include "commitlog.h"
22
23 #include <unistd.h>
24
25 extern std::string gGourceGitLogCommand;
26
27 class GitCommitLog : public RCommitLog {
28 protected:
29 bool parseCommit(RCommit& commit);
30 BaseLog* generateLog(const std::string& dir);
31 public:
32 GitCommitLog(const std::string& logfile);
33 };
34
35 #endif
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "gitraw.h"
18
19 Regex git_raw_commit("^commit ([0-9a-z]+)");
20 Regex git_raw_tree("^tree ([0-9a-z]+)");
21 Regex git_raw_parent("^parent ([0-9a-z]+)");
22 Regex git_raw_author("^author (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
23 Regex git_raw_committer("^committer (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
24 Regex git_raw_file("^:[0-9]+ [0-9]+ [0-9a-z]+\\.* ([0-9a-z]+)\\.* ([A-Z])[ \\t]+(.+)");
25
26 // parse git log entries
27
28 std::string gGourceGitRawLogCommand = "git log --reverse --raw --pretty=raw";
29
30 GitRawCommitLog::GitRawCommitLog(const std::string& logfile) : RCommitLog(logfile, 'c') {
31
32 log_command = gGourceGitRawLogCommand;
33 }
34
35 // parse modified cvs format log entries
36
37 bool GitRawCommitLog::parseCommit(RCommit& commit) {
38
39 std::string line;
40 std::vector<std::string> entries;
41
42 //read commit ref/ branch
43 if(!logf->getNextLine(line)) return false;
44
45 //commit
46 if(!git_raw_commit.match(line, &entries)) return false;
47
48 if(!logf->getNextLine(line)) return false;
49
50 //tree
51 if(!git_raw_tree.match(line, &entries)) return false;
52
53 if(!logf->getNextLine(line)) return false;
54
55 //0 or more parents
56 while(git_raw_parent.match(line, &entries)) {
57 if(!logf->getNextLine(line)) return false;
58 }
59
60 //author - used for display name
61 if(!git_raw_author.match(line, &entries)) return false;
62
63 commit.username = entries[0];
64
65 if(!logf->getNextLine(line)) return false;
66
67 //committer - used for time (most likely cronological)
68 if(!git_raw_committer.match(line, &entries)) return false;
69
70 commit.timestamp = atol(entries[3].c_str());
71
72 //blank line before message
73 if(!logf->getNextLine(line)) return false;
74
75 //read commit message
76 while(logf->getNextLine(line) && line.size()) {
77 }
78
79 //read files
80 while(logf->getNextLine(line) && line.size()) {
81 //debugLog("file??? %s\n", line.c_str());
82
83 if(git_raw_file.match(line, &entries)) {
84 commit.addFile(entries[2], entries[1]);
85 }
86 }
87
88 // commit.debug();
89
90 return true;
91 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GITLOG_RAW_H
18 #define GITLOG_RAW_H
19
20 #include "commitlog.h"
21
22 #include <unistd.h>
23
24 extern std::string gGourceGitRawLogCommand;
25
26 class GitRawCommitLog : public RCommitLog {
27 protected:
28 bool parseCommit(RCommit& commit);
29 public:
30 GitRawCommitLog(const std::string& logfile);
31 };
32
33 #endif
34
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "hg.h"
18
19 Regex hg_regex("^([0-9]+) -?[0-9]+\\|([^|]+)\\|([ADM]?)\\|(.+)$");
20
21 // parse Mercurial log entries (using the gource.style template)
22
23 std::string gGourceMercurialCommand() {
24
25 std::string gource_style_path = gSDLAppResourceDir + std::string("gource.style");
26
27 return std::string("hg log -r 0:tip --style \"") + gource_style_path + std::string("\"");
28 }
29
30 MercurialLog::MercurialLog(const std::string& logfile) : RCommitLog(logfile) {
31
32 log_command = gGourceMercurialCommand();
33
34 //can generate log from directory
35 if(!logf && is_dir) {
36 logf = generateLog(logfile);
37
38 if(logf) {
39 success = true;
40 seekable = true;
41 }
42 }
43 }
44
45 BaseLog* MercurialLog::generateLog(const std::string& dir) {
46
47 //does directory have a .hg ?
48 std::string hgdir = dir + std::string("/.hg");
49 struct stat dirinfo;
50 int stat_rc = stat(hgdir.c_str(), &dirinfo);
51 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
52 return 0;
53 }
54
55 // do we have this client installed
56 requireExecutable("hg");
57
58 std::string command = getLogCommand();
59
60 createTempLog();
61
62 if(temp_file.size()==0) return 0;
63
64 char cmd_buff[2048];
65 sprintf(cmd_buff, "%s -R \"%s\" > %s", command.c_str(), dir.c_str(), temp_file.c_str());
66
67 int command_rc = systemCommand(cmd_buff);
68
69 if(command_rc != 0) {
70 return 0;
71 }
72
73 BaseLog* seeklog = new SeekLog(temp_file);
74
75 return seeklog;
76 }
77
78
79 bool MercurialLog::parseCommit(RCommit& commit) {
80
81 while(parseCommitEntry(commit));
82
83 return !commit.files.empty();
84 }
85
86 bool MercurialLog::parseCommitEntry(RCommit& commit) {
87
88 std::string line;
89 std::vector<std::string> entries;
90
91 if(!logf->getNextLine(line)) return false;
92
93 //custom line
94 if(!hg_regex.match(line, &entries)) return false;
95
96 time_t timestamp = atol(entries[0].c_str());
97 std::string username = entries[1];
98
99 //if this file is for the same person and timestamp
100 //we add to the commit, else we save the lastline
101 //and return false
102 if(commit.files.empty()) {
103 commit.timestamp = timestamp;
104 commit.username = username;
105 } else {
106 if(commit.timestamp != timestamp || commit.username != username) {
107 lastline = line;
108 return false;
109 }
110 }
111
112 std::string action = "A";
113
114 if(!entries[2].empty()) {
115 action = entries[2];
116 }
117
118 commit.addFile(entries[3], action);
119
120 //commit.debug();
121
122 return true;
123 }
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef MERCURIALLOG_H
18 #define MERCURIALLOG_H
19
20 #include "commitlog.h"
21
22 std::string gGourceMercurialCommand();
23
24 class MercurialLog : public RCommitLog {
25 protected:
26 bool parseCommit(RCommit& commit);
27 bool parseCommitEntry(RCommit& commit);
28 BaseLog* generateLog(const std::string& dir);
29 public:
30 MercurialLog(const std::string& logfile);
31 };
32
33 #endif
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "svn.h"
18
19 Regex svn_xml_tag("^<\\??xml");
20 Regex svn_logentry_start("^<logentry");
21 Regex svn_logentry_end("^</logentry>");
22 Regex svn_logentry_timestamp("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})");
23
24 std::string gGourceSVNLogCommand = "svn log -r 1:HEAD --xml --verbose --quiet";
25
26 SVNCommitLog::SVNCommitLog(const std::string& logfile) : RCommitLog(logfile, '<') {
27
28 log_command = gGourceSVNLogCommand;
29
30 //can generate log from directory
31 if(!logf && is_dir) {
32 logf = generateLog(logfile);
33
34 if(logf) {
35 success = true;
36 seekable = true;
37 }
38 }
39
40 logentry.reserve(1024);
41 }
42
43
44 BaseLog* SVNCommitLog::generateLog(const std::string& dir) {
45 //get working directory
46 char cwd_buff[1024];
47
48 if(getcwd(cwd_buff, 1024) != cwd_buff) {
49 return 0;
50 }
51
52 //does directory have a .svn ?
53 std::string gitdir = dir + std::string("/.svn");
54 struct stat dirinfo;
55 int stat_rc = stat(gitdir.c_str(), &dirinfo);
56 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
57 return 0;
58 }
59
60 // do we have this client installed
61 requireExecutable("svn");
62
63 std::string command = getLogCommand();
64
65 //create temp file
66 createTempLog();
67
68 if(temp_file.size()==0) return 0;
69
70 if(chdir(dir.c_str()) != 0) {
71 return 0;
72 }
73
74 char cmd_buff[2048];
75 sprintf(cmd_buff, "%s > %s", command.c_str(), temp_file.c_str());
76
77 int command_rc = systemCommand(cmd_buff);
78
79 chdir(cwd_buff);
80
81 if(command_rc != 0) {
82 return 0;
83 }
84
85 BaseLog* seeklog = new SeekLog(temp_file);
86
87 return seeklog;
88 }
89
90 #ifndef HAVE_TIMEGM
91
92 std::string system_tz;
93 bool system_tz_init = false;
94
95 time_t __timegm_hack(struct tm* tm) {
96
97 if(!system_tz_init) {
98 char* current_tz_env = getenv("TZ");
99
100 if(current_tz_env != 0) {
101 system_tz = std::string("TZ=") + current_tz_env;
102 }
103
104 system_tz_init = true;
105 }
106
107 putenv((char*)"TZ=UTC");
108 tzset();
109
110 time_t timestamp = mktime(tm);
111
112 if(!system_tz.empty()) {
113 putenv((char*)system_tz.c_str());
114 } else {
115 #ifdef HAVE_UNSETENV
116 unsetenv("TZ");
117 #else
118 putenv((char*)"TZ=");
119 #endif
120 }
121 tzset();
122
123 return timestamp;
124 }
125 #endif
126
127 bool SVNCommitLog::parseCommit(RCommit& commit) {
128
129 //fprintf(stderr,"parsing svn log\n");
130
131 std::string line;
132
133 if(!getNextLine(line)) return false;
134
135 //start of log entry
136 if(!svn_logentry_start.match(line)) {
137
138 //is this the start of the document
139 if(!svn_xml_tag.match(line)) return false;
140
141 //fprintf(stderr,"found xml tag\n");
142
143 //if so find the first logentry tag
144
145 bool found_logentry = false;
146
147 while(getNextLine(line)) {
148 if(svn_logentry_start.match(line)) {
149 found_logentry = true;
150 break;
151 }
152 }
153
154 if(!found_logentry) return false;
155 }
156
157 //fprintf(stderr,"found logentry\n");
158
159 logentry.clear();
160
161 logentry.append(line);
162 logentry.append("\n");
163
164 //fprintf(stderr,"found opening tag\n");
165
166 bool endfound = false;
167
168 while(getNextLine(line)) {
169 logentry.append(line);
170 logentry.append("\n");
171 if(svn_logentry_end.match(line)) {
172 //fprintf(stderr,"found closing tag\n");
173 endfound=true;
174 break;
175 }
176 }
177
178 //incomplete commit
179 if(!endfound) return false;
180
181 //fprintf(stderr,"read logentry\n");
182
183 TiXmlDocument doc;
184
185 if(!doc.Parse(logentry.c_str())) return false;
186
187 //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
188
189 TiXmlElement* leE = doc.FirstChildElement( "logentry" );
190
191 std::vector<std::string> entries;
192
193 if(!leE) return false;
194
195 //parse date
196 TiXmlElement* dateE = leE->FirstChildElement( "date" );
197
198 if(!dateE) return false;
199
200 std::string timestamp_str(dateE->GetText());
201
202 if(!svn_logentry_timestamp.match(timestamp_str, &entries))
203 return false;
204
205 struct tm time_str;
206
207 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
208 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
209 time_str.tm_mday = atoi(entries[2].c_str());
210 time_str.tm_hour = atoi(entries[3].c_str());
211 time_str.tm_min = atoi(entries[4].c_str());
212 time_str.tm_sec = atoi(entries[5].c_str());
213 time_str.tm_isdst = -1;
214
215 #ifdef HAVE_TIMEGM
216 commit.timestamp = timegm(&time_str);
217 #else
218 commit.timestamp = __timegm_hack(&time_str);
219 #endif
220
221 //parse author
222 TiXmlElement* authorE = leE->FirstChildElement("author");
223
224 if(authorE != 0) {
225
226 std::string author(authorE->GetText());
227
228 if(author.empty()) author = "Unknown";
229
230 commit.username = author;
231 }
232
233 TiXmlElement* pathsE = leE->FirstChildElement( "paths" );
234
235 //log entries sometimes dont have any paths
236 if(!pathsE) return true;
237
238 //parse changes
239
240 for(TiXmlElement* pathE = pathsE->FirstChildElement("path"); pathE != 0; pathE = pathE->NextSiblingElement()) {
241 //parse path
242
243 const char* kind = pathE->Attribute("kind");
244 const char* action = pathE->Attribute("action");
245
246 //check for action
247 if(action == 0) continue;
248
249 bool is_dir = false;
250
251 //if has the 'kind' attribute (old versions of svn dont have this), check if it is a dir
252 if(kind != 0 && strcmp(kind,"dir") == 0) {
253
254 //accept only deletes for directories
255 if(strcmp(action, "D") != 0) continue;
256
257 is_dir = true;
258 }
259
260 std::string file(pathE->GetText());
261 std::string status(action);
262
263 if(file.empty()) continue;
264 if(status.empty()) continue;
265
266 //append trailing slash if is directory
267 if(is_dir && file[file.size()-1] != '/') {
268 file = file + std::string("/");
269 }
270
271 commit.addFile(file, status);
272 }
273
274 //fprintf(stderr,"parsed logentry\n");
275
276 //read files
277
278 return true;
279 }
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef SVNLOG_H
18 #define SVNLOG_H
19
20 #include "../gource_settings.h"
21
22 #include "commitlog.h"
23
24 #include <sstream>
25
26 #ifdef HAVE_LIBTINYXML
27 #include <tinyxml.h>
28 #else
29 #include "../tinyxml/tinyxml.h"
30 #endif
31
32 #include <unistd.h>
33
34 extern std::string gGourceSVNLogCommand;
35
36 class SVNCommitLog : public RCommitLog {
37 protected:
38 bool parseCommit(RCommit& commit);
39 BaseLog* generateLog(const std::string& dir);
40
41 std::string logentry;
42 public:
43 SVNCommitLog(const std::string& logfile);
44 };
45
46 #endif
+0
-166
src/git.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "git.h"
18
19 // parse git log entries
20
21 //git-log command notes:
22 // - no single quotes on WIN32 as system call treats them differently
23 // - 'user:' prefix allows us to quickly tell if the log is the wrong format
24 // and try a different format (eg cvs-exp)
25
26 std::string gGourceGitLogCommand = "git log "
27 "--pretty=format:user:%aN%n%ct "
28 "--reverse --raw --encoding=UTF-8 "
29 "--no-renames";
30
31 GitCommitLog::GitCommitLog(const std::string& logfile) : RCommitLog(logfile, 'u') {
32
33 log_command = gGourceGitLogCommand;
34
35 if(gGourceSettings.git_branch.size()>0) {
36 log_command += " ";
37 log_command += gGourceSettings.git_branch;
38 }
39
40 //can generate log from directory
41 if(!logf && is_dir) {
42 logf = generateLog(logfile);
43
44 if(logf) {
45 success = true;
46 seekable = true;
47 }
48 }
49 }
50
51 BaseLog* GitCommitLog::generateLog(const std::string& dir) {
52 //get working directory
53 char cwd_buff[1024];
54
55 if(getcwd(cwd_buff, 1024) != cwd_buff) {
56 return 0;
57 }
58
59 //does directory have a .git ?
60 std::string gitdir = dir + std::string("/.git");
61 struct stat dirinfo;
62 int stat_rc = stat(gitdir.c_str(), &dirinfo);
63 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
64 return 0;
65 }
66
67 std::string command = getLogCommand();
68
69 //create temp file
70 createTempLog();
71
72 if(temp_file.size()==0) return 0;
73
74 if(chdir(dir.c_str()) != 0) {
75 return 0;
76 }
77
78 char cmd_buff[2048];
79 sprintf(cmd_buff, "%s > %s", command.c_str(), temp_file.c_str());
80
81 int command_rc = system(cmd_buff);
82
83 if(command_rc != 0) {
84 chdir(cwd_buff);
85 return 0;
86 }
87
88 // check for new-enough Git version
89 // if %aN does not appear to be supported try %an
90 std::ifstream in(temp_file.c_str());
91 char firstBytes[9];
92 in.read(firstBytes, 8);
93 in.close();
94 firstBytes[8] = '\0';
95 if(!strcmp(firstBytes, "user:%aN")) {
96 char *pos = strstr(cmd_buff, "%aN");
97 pos[2] = 'n';
98 command_rc = system(cmd_buff);
99 }
100
101 //change back to original directoy
102 chdir(cwd_buff);
103
104 if(command_rc != 0) {
105 return 0;
106 }
107
108 BaseLog* seeklog = new SeekLog(temp_file);
109
110 return seeklog;
111 }
112
113 // parse modified git format log entries
114
115 bool GitCommitLog::parseCommit(RCommit& commit) {
116
117 std::string line;
118
119 commit.username = "";
120
121 while(logf->getNextLine(line) && line.size()) {
122
123 if(line.find("user:") == 0) {
124
125 //username follows user prefix
126 commit.username = line.substr(5);
127
128 if(!logf->getNextLine(line)) return false;
129
130 commit.timestamp = atol(line.c_str());
131
132 //this isnt a commit we are parsing, abort
133 if(commit.timestamp == 0) return false;
134
135 continue;
136 }
137
138 //should see username before files
139 if(commit.username.size() == 0) return false;
140
141 size_t tab = line.find('\t');
142
143 //incorrect log format
144 if(tab == std::string::npos || tab == 0 || tab == line.size()-1) continue;
145
146 std::string status = line.substr(tab - 1, 1);
147 std::string file = line.substr(tab + 1);
148
149 if(file.empty()) continue;
150
151 //check for and remove double quotes
152 if(file.find('"') == 0 && file.rfind('"') == file.size()-1) {
153 if(file.size()<=2) continue;
154
155 file = file.substr(1,file.size()-2);
156 }
157
158 commit.addFile(file, status);
159 }
160
161 //check we at least got a username
162 if(commit.username.size()==0) return false;
163
164 return true;
165 }
+0
-37
src/git.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GITLOG_H
18 #define GITLOG_H
19
20 #include "gource_settings.h"
21
22 #include "commitlog.h"
23
24 #include <unistd.h>
25
26 extern std::string gGourceGitLogCommand;
27
28 class GitCommitLog : public RCommitLog {
29 protected:
30 bool parseCommit(RCommit& commit);
31 BaseLog* generateLog(const std::string& dir);
32 public:
33 GitCommitLog(const std::string& logfile);
34 };
35
36 #endif
+0
-92
src/gitraw.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "gitraw.h"
18
19 Regex git_raw_commit("^commit ([0-9a-z]+)");
20 Regex git_raw_tree("^tree ([0-9a-z]+)");
21 Regex git_raw_parent("^parent ([0-9a-z]+)");
22 Regex git_raw_author("^author (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
23 Regex git_raw_committer("^committer (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
24 Regex git_raw_file("^:[0-9]+ [0-9]+ [0-9a-z]+\\.* ([0-9a-z]+)\\.* ([A-Z])[ \\t]+(.+)");
25
26 // parse git log entries
27
28 std::string gGourceGitRawLogCommand = "git log --reverse --raw --pretty=raw";
29
30 GitRawCommitLog::GitRawCommitLog(const std::string& logfile) : RCommitLog(logfile, 'c') {
31
32 log_command = gGourceGitRawLogCommand;
33 }
34
35 // parse modified cvs format log entries
36
37 bool GitRawCommitLog::parseCommit(RCommit& commit) {
38
39 std::string line;
40 std::vector<std::string> entries;
41
42 //read commit ref/ branch
43 if(!logf->getNextLine(line)) return false;
44
45 //commit
46 if(!git_raw_commit.match(line, &entries)) return false;
47
48 if(!logf->getNextLine(line)) return false;
49
50 //tree
51 if(!git_raw_tree.match(line, &entries)) return false;
52
53 if(!logf->getNextLine(line)) return false;
54
55 //0 or more parents
56 while(git_raw_parent.match(line, &entries)) {
57 if(!logf->getNextLine(line)) return false;
58 }
59
60 //author - used for display name
61 if(!git_raw_author.match(line, &entries)) return false;
62
63 commit.username = entries[0];
64
65 if(!logf->getNextLine(line)) return false;
66
67 //committer - used for time (most likely cronological)
68 if(!git_raw_committer.match(line, &entries)) return false;
69
70 commit.timestamp = atol(entries[3].c_str());
71
72 //blank line before message
73 if(!logf->getNextLine(line)) return false;
74
75 //read commit message
76 while(logf->getNextLine(line) && line.size()) {
77 }
78
79 //read files
80 while(logf->getNextLine(line) && line.size()) {
81 //debugLog("file??? %s\n", line.c_str());
82
83 if(git_raw_file.match(line, &entries)) {
84 commit.addFile(entries[2], entries[1]);
85 }
86 }
87
88 // commit.debug();
89
90 return true;
91 }
+0
-35
src/gitraw.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef GITLOG_RAW_H
18 #define GITLOG_RAW_H
19
20 #include "commitlog.h"
21
22 #include <unistd.h>
23
24 extern std::string gGourceGitRawLogCommand;
25
26 class GitRawCommitLog : public RCommitLog {
27 protected:
28 bool parseCommit(RCommit& commit);
29 public:
30 GitRawCommitLog(const std::string& logfile);
31 };
32
33 #endif
34
3131 if(!GLEW_VERSION_2_0) gGourceSettings.ffp = true;
3232
3333 if(!gGourceSettings.file_graphic) {
34 gGourceSettings.file_graphic = texturemanager.grab("file.png");
34 gGourceSettings.file_graphic = texturemanager.grab("file.png", true, GL_CLAMP_TO_EDGE);
3535 }
3636
3737 fontlarge = fontmanager.grab("FreeSans.ttf", 42);
5151
5252 bloomtex = texturemanager.grab(bloom_tga);
5353 beamtex = texturemanager.grab("beam.png");
54 usertex = texturemanager.grab("no_photo.png");
54 usertex = texturemanager.grab("user.png", true, GL_CLAMP_TO_EDGE);
5555
5656 shadow_shader = text_shader = bloom_shader = 0;
5757
8383
8484 paused = false;
8585 first_read = true;
86 draw_loading = true;
8786
8887 grab_mouse = false;
8988 mousemoved = false;
9089 mousedragged = false;
9190 mouseclicked = false;
9291
93 cursor.setCursorTexture(texturemanager.grab("cursor.png"));
94 cursor.useSystemCursor(false);
95
9692 if(gGourceSettings.hide_mouse) {
9793 cursor.showCursor(false);
9894 }
120116
121117 file_key = FileKey(1.0f);
122118
123 camera = ZoomCamera(vec3f(0,0, -300), vec3f(0.0, 0.0, 0.0), 250.0, 5000.0);
119 camera = ZoomCamera(vec3(0,0, -300), vec3(0.0, 0.0, 0.0), gGourceSettings.camera_zoom_default, gGourceSettings.camera_zoom_max);
124120 camera.setPadding(gGourceSettings.padding);
125121
126122 setCameraMode(gGourceSettings.camera_mode);
135131
136132 reset();
137133
134 logmill = new RLogMill(logfile);
135
136 shutdown = false;
137
138138 if(exporter!=0) setFrameExporter(exporter, gGourceSettings.output_framerate);
139139
140140 //if recording a video or in demo mode, or multiple repos, the slider is initially hidden
142142 }
143143
144144 void Gource::writeCustomLog(const std::string& logfile, const std::string& output_file) {
145 RCommitLog* commitlog = determineFormat(logfile);
146
147 if(!commitlog) return;
145
146 RLogMill logmill(logfile);
147 RCommitLog* commitlog = logmill.getLog();
148
149 // TODO: exception handling
150
151 if(!commitlog) {
152 std::string error = logmill.getError();
153 if(!error.empty()) SDLAppQuit(error);
154 return;
155 }
148156
149157 RCommit commit;
150158
178186 if(output_file != "-") fclose(fh);
179187 }
180188
181 RCommitLog* Gource::determineFormat(const std::string& logfile) {
182 debugLog("determineFormat(%s)\n", logfile.c_str());
183
184 RCommitLog* clog = 0;
185
186 //we've been told what format to use
187 if(gGourceSettings.log_format.size() > 0) {
188 debugLog("--log-format = %s\n", gGourceSettings.log_format.c_str());
189
190 if(gGourceSettings.log_format == "git") {
191 clog = new GitCommitLog(logfile);
192 if(clog->checkFormat()) return clog;
193 delete clog;
194
195 clog = new GitRawCommitLog(logfile);
196 if(clog->checkFormat()) return clog;
197 delete clog;
198 }
199
200 if(gGourceSettings.log_format == "hg") {
201 clog = new MercurialLog(logfile);
202 if(clog->checkFormat()) return clog;
203 delete clog;
204 }
205 if(gGourceSettings.log_format == "bzr") {
206 clog = new BazaarLog(logfile);
207 if(clog->checkFormat()) return clog;
208 delete clog;
209 }
210
211 if(gGourceSettings.log_format == "cvs") {
212 clog = new CVSEXPCommitLog(logfile);
213 if(clog->checkFormat()) return clog;
214 delete clog;
215 }
216
217 if(gGourceSettings.log_format == "custom") {
218 clog = new CustomLog(logfile);
219 if(clog->checkFormat()) return clog;
220 delete clog;
221 }
222
223 if(gGourceSettings.log_format == "apache") {
224 clog = new ApacheCombinedLog(logfile);
225 if(clog->checkFormat()) return clog;
226 delete clog;
227 }
228
229 if(gGourceSettings.log_format == "svn") {
230 clog = new SVNCommitLog(logfile);
231 if(clog->checkFormat()) return clog;
232 delete clog;
233 }
234
235 if(gGourceSettings.log_format == "cvs2cl") {
236 clog = new CVS2CLCommitLog(logfile);
237 if(clog->checkFormat()) return clog;
238 delete clog;
239 }
240
241 return 0;
242 }
243
244 //git
245 debugLog("trying git...\n");
246 clog = new GitCommitLog(logfile);
247 if(clog->checkFormat()) return clog;
248
249 delete clog;
250
251 //mercurial
252 debugLog("trying mercurial...\n");
253 clog = new MercurialLog(logfile);
254 if(clog->checkFormat()) return clog;
255
256 delete clog;
257
258 //bzr
259 debugLog("trying bzr...\n");
260 clog = new BazaarLog(logfile);
261 if(clog->checkFormat()) return clog;
262
263 delete clog;
264
265 //git raw
266 debugLog("trying git raw...\n");
267 clog = new GitRawCommitLog(logfile);
268 if(clog->checkFormat()) return clog;
269
270 delete clog;
271
272 //cvs exp
273 debugLog("trying cvs-exp...\n");
274 clog = new CVSEXPCommitLog(logfile);
275 if(clog->checkFormat()) return clog;
276
277 delete clog;
278
279 //svn
280 debugLog("trying svn...\n");
281 clog = new SVNCommitLog(logfile);
282 if(clog->checkFormat()) return clog;
283
284 delete clog;
285
286 //cvs2cl
287 debugLog("trying cvs2cl...\n");
288 clog = new CVS2CLCommitLog(logfile);
289 if(clog->checkFormat()) return clog;
290
291 delete clog;
292
293 //custom
294 debugLog("trying custom...\n");
295 clog = new CustomLog(logfile);
296 if(clog->checkFormat()) return clog;
297
298 delete clog;
299
300 //apache
301 debugLog("trying apache combined...\n");
302 clog = new ApacheCombinedLog(logfile);
303 if(clog->checkFormat()) return clog;
304
305 delete clog;
306
307 return 0;
308 }
309
310189 Gource::~Gource() {
311190 reset();
312191
313 if(commitlog!=0) delete commitlog;
314 if(root!=0) delete root;
192 if(logmill!=0) delete logmill;
193 if(root!=0) delete root;
315194
316195 //reset settings
317196 gGourceSettings.setGourceDefaults();
318197 }
319198
320199 void Gource::init() {
200 }
201
202 void Gource::unload() {
203
204 file_vbo.unload();
205 user_vbo.unload();
206 edge_vbo.unload();
207 action_vbo.unload();
208 bloom_vbo.unload();
209
210 }
211
212 void Gource::reload() {
213
214 slider.resize();
215 }
216
217 void Gource::quit() {
218 shutdown = true;
321219 }
322220
323221 void Gource::update(float t, float dt) {
346244 draw(runtime, scaled_dt);
347245
348246 //extract frames based on frameskip setting if frameExporter defined
349 if(frameExporter != 0) {
247 if(frameExporter != 0 && commitlog && !shutdown) {
350248 if(framecount % (frameskip+1) == 0) {
351249 frameExporter->dump();
352250 }
387285
388286 bool rightmouse = cursor.rightButtonPressed();
389287
288 #if not SDL_VERSION_ATLEAST(1,3,0)
390289 if(grab_mouse) {
391290 int warp_x = display.width/2;
392291 int warp_y = display.height/2;
396295
397296 SDL_WarpMouse(warp_x, warp_y);
398297 }
298 #endif
399299
400300 //move camera in direction the user dragged the mouse
401301 if(mousedragged || rightmouse) {
402 vec2f mag( e->xrel, e->yrel );
302 vec2 mag( e->xrel, e->yrel );
403303
404304 //if right mouse button is held while dragging, rotate tree instead of
405305 //moving camera
424324
425325 if(grab_mouse) return;
426326
427 mousepos = vec2f(e->x, e->y);
327 mousepos = vec2(e->x, e->y);
428328 mousemoved=true;
429329
430330 cursor.updatePos(mousepos);
449349 if(zoomin) {
450350 distance /= zoom_multi;
451351
452 if(distance < 100.0f) distance = 100.0f;
352 if(distance < gGourceSettings.camera_zoom_min) distance = gGourceSettings.camera_zoom_min;
453353 } else {
454354 distance *= zoom_multi;
455355
456 if(distance > 4999.0f) distance = 4999.0f;
356 if(distance > gGourceSettings.camera_zoom_max) distance = gGourceSettings.camera_zoom_max;
457357 }
458358
459359 camera.setDistance(distance);
460360 }
361
362 #if SDL_VERSION_ATLEAST(1,3,0)
363 void Gource::mouseWheel(SDL_MouseWheelEvent *e) {
364
365 int mouse_x, mouse_y;
366 SDL_GetMouseState(&mouse_x, &mouse_y);
367
368 vec2 mousepos(mouse_x, mouse_y);
369
370 if(e->y > 0) {
371 zoom(true);
372 }
373
374 if(e->y < 0) {
375 zoom(false);
376 }
377 }
378
379 #endif
461380
462381 void Gource::mouseClick(SDL_MouseButtonEvent *e) {
463382 if(commitlog==0) return;
476395
477396 if(e->button == SDL_BUTTON_LEFT || e->button == SDL_BUTTON_RIGHT) {
478397 if(!cursor.buttonPressed()) {
398 grab_mouse=false;
399 #if SDL_VERSION_ATLEAST(1,3,0)
400 SDL_SetRelativeMouseMode(SDL_FALSE);
401 SDL_WarpMouseInWindow(display.sdl_window, mousepos.x, mousepos.y);
402 #else
403 SDL_WarpMouse(mousepos.x, mousepos.y);
404 #endif
479405 cursor.showCursor(true);
480 grab_mouse=false;
481 SDL_WarpMouse(mousepos.x, mousepos.y);
482406 }
483407 }
484408 }
506430 if(e->button == SDL_BUTTON_RIGHT) {
507431 cursor.showCursor(false);
508432 grab_mouse=true;
433 #if SDL_VERSION_ATLEAST(1,3,0)
434 SDL_SetRelativeMouseMode(SDL_TRUE);
435 #endif
509436 return;
510437 }
511438
512439 if(e->button == SDL_BUTTON_LEFT) {
513440
514 //mousepos = vec2f(e->x, e->y);
441 //mousepos = vec2(e->x, e->y);
515442 mouseclicked=true;
516443
517444 if(canSeek()) {
681608 if (e->type == SDL_KEYUP) return;
682609
683610 if (e->type == SDL_KEYDOWN) {
684 if (e->keysym.unicode == SDLK_ESCAPE) {
685 appFinished=true;
611
612 #if SDL_VERSION_ATLEAST(1,3,0)
613 bool key_escape = e->keysym.scancode == SDL_SCANCODE_ESCAPE;
614 bool key_tab = e->keysym.scancode == SDL_SCANCODE_TAB;
615 bool key_space = e->keysym.scancode == SDL_SCANCODE_SPACE;
616 bool key_plus = e->keysym.scancode == SDL_SCANCODE_EQUALS;
617 bool key_equals = e->keysym.scancode == SDL_SCANCODE_EQUALS;
618 bool key_minus = e->keysym.scancode == SDL_SCANCODE_MINUS;
619 bool key_leftbracket = e->keysym.scancode == SDL_SCANCODE_LEFTBRACKET;
620 bool key_rightbracket = e->keysym.scancode == SDL_SCANCODE_RIGHTBRACKET;
621 bool key_comma = e->keysym.scancode == SDL_SCANCODE_COMMA;
622 bool key_period = e->keysym.scancode == SDL_SCANCODE_PERIOD;
623 bool key_slash = e->keysym.scancode == SDL_SCANCODE_SLASH;
624 #else
625 bool key_escape = e->keysym.unicode == SDLK_ESCAPE;
626 bool key_tab = e->keysym.unicode == SDLK_TAB;
627 bool key_space = e->keysym.unicode == SDLK_SPACE;
628 bool key_plus = e->keysym.unicode == SDLK_PLUS;
629 bool key_equals = e->keysym.unicode == SDLK_EQUALS;
630 bool key_minus = e->keysym.unicode == SDLK_MINUS;
631 bool key_leftbracket = e->keysym.unicode == SDLK_LEFTBRACKET;
632 bool key_rightbracket = e->keysym.unicode == SDLK_RIGHTBRACKET;
633 bool key_comma = e->keysym.unicode == SDLK_COMMA;
634 bool key_period = e->keysym.unicode == SDLK_PERIOD;
635 bool key_slash = e->keysym.unicode == SDLK_SLASH;
636 #endif
637
638 if (key_escape) {
639 quit();
686640 }
687641
688642 if(commitlog==0) return;
808762 recolour=true;
809763 }
810764
811 if(e->keysym.unicode == SDLK_TAB) {
765 if(key_tab) {
812766 selectNextUser();
813767 }
814768
815 if (e->keysym.unicode == SDLK_SPACE) {
769 if (key_space) {
816770 paused = !paused;
817771 }
818772
819 if (e->keysym.unicode == SDLK_EQUALS || e->keysym.unicode == SDLK_PLUS) {
773 if (key_equals || key_plus) {
820774 if(gGourceSettings.days_per_second>=1.0) {
821775 gGourceSettings.days_per_second = std::min(30.0f, floorf(gGourceSettings.days_per_second) + 1.0f);
822776 } else {
824778 }
825779 }
826780
827 if (e->keysym.unicode == SDLK_MINUS) {
781 if (key_minus) {
828782 if(gGourceSettings.days_per_second>1.0) {
829783 gGourceSettings.days_per_second = std::max(0.0f, floorf(gGourceSettings.days_per_second) - 1.0f);
830784 } else {
840794 zoom(false);
841795 }
842796
843 if(e->keysym.unicode == SDLK_LEFTBRACKET) {
797 if(key_leftbracket) {
844798 gGourceForceGravity /= 1.1;
845799 }
846800
847 if(e->keysym.unicode == SDLK_RIGHTBRACKET) {
801 if(key_rightbracket) {
848802 gGourceForceGravity *= 1.1;
849803 }
850804
851 if(e->keysym.unicode == SDLK_PERIOD) {
805 if(key_period) {
852806
853807 if(gGourceSettings.time_scale>=1.0) {
854808 gGourceSettings.time_scale = std::min(4.0f, floorf(gGourceSettings.time_scale) + 1.0f);
857811 }
858812 }
859813
860 if(e->keysym.unicode == SDLK_COMMA) {
814 if(key_comma) {
861815
862816 if(gGourceSettings.time_scale>1.0) {
863817 gGourceSettings.time_scale = std::max(0.0f, floorf(gGourceSettings.time_scale) - 1.0f);
866820 }
867821 }
868822
869 if(e->keysym.unicode == SDLK_SLASH) {
823 if(key_slash) {
870824 gGourceSettings.time_scale = 1.0f;
871825 }
872826 }
903857
904858 message_timer = 0.0f;
905859
906 cursor_move = vec2f(0.0f, 0.0f);
860 cursor_move = vec2(0.0f, 0.0f);
907861
908862 selectedUser = 0;
909863 hoverUser = 0;
915869 mouseclicked=false;
916870 mousemoved=false;
917871 mousedragged = false;
872
873 commitqueue_max_size = 100;
918874
919875 rotate_angle = 0.0f;
920876
979935
980936 RFile* Gource::addFile(const RCommitFile& cf) {
981937
938 //if we already have max files in circulation
939 //we cant add any more
940 if(gGourceSettings.max_files > 0 && files.size() >= gGourceSettings.max_files) return 0;
941
942 //see if this is a directory
943 std::string file_as_dir = cf.filename;
944 if(file_as_dir[file_as_dir.size()-1] != '/') file_as_dir.append("/");
945
946 if(root->isDir(file_as_dir)) return 0;
947
982948 int tagid = tag_seq++;
983949
984 RFile* file = new RFile(cf.filename, cf.colour, vec2f(0.0,0.0), tagid);
950 RFile* file = new RFile(cf.filename, cf.colour, vec2(0.0,0.0), tagid);
985951
986952 files[cf.filename] = file;
987953 tagfilemap[tagid] = file;
991957 file_key.inc(file);
992958
993959 while(root->getParent() != 0) {
994 debugLog("parent changed to %s\n", root->getPath().c_str());
960 debugLog("parent changed to %s", root->getPath().c_str());
995961 root = root->getParent();
996962 }
997963
1000966
1001967 RUser* Gource::addUser(const std::string& username) {
1002968
1003 vec2f pos;
969 vec2 pos;
1004970
1005971 if(dir_bounds.area() > 0) {
1006972 pos = dir_bounds.centre();
1007973 } else {
1008 pos = vec2f(0,0);
974 pos = vec2(0,0);
1009975 }
1010976
1011977 int tagid = tag_seq++;
10621028
10631029 //debugLog("readLog()\n");
10641030
1065 while(!commitlog->isFinished() && commitqueue.size() < 1) {
1031 // read commits until either we are ahead of currtime
1032 while(!commitlog->isFinished() && (commitqueue.empty() || commitqueue.back().timestamp <= currtime && commitqueue.size() < commitqueue_max_size)) {
10661033
10671034 RCommit commit;
10681035
10731040 continue;
10741041 }
10751042
1076 //ignore blank commits
1077 if(commit.files.size() > 0) {
1078 commitqueue.push_back(commit);
1079 }
1080 }
1081
1082 if(first_read && commitqueue.size()==0) {
1043 commitqueue.push_back(commit);
1044 }
1045
1046 if(first_read && commitqueue.empty()) {
1047 fprintf(stderr, "no files on first read\n");
10831048 throw SDLAppException("no commits found");
10841049 }
10851050
11031068
11041069 void Gource::processCommit(RCommit& commit, float t) {
11051070
1106 //check user against filters, if found, discard commit
1107 if(!gGourceSettings.user_filters.empty()) {
1108 for(std::vector<Regex*>::iterator ri = gGourceSettings.user_filters.begin(); ri != gGourceSettings.user_filters.end(); ri++) {
1109 Regex* r = *ri;
1110
1111 if(r->match(commit.username)) {
1112 return;
1113 }
1114 }
1115 }
1116
11171071 //find files of this commit or create it
11181072 for(std::list<RCommitFile>::iterator it = commit.files.begin(); it != commit.files.end(); it++) {
11191073
11201074 RCommitFile& cf = *it;
11211075 RFile* file = 0;
11221076
1123 //check filename against filters
1124 if(!gGourceSettings.file_filters.empty()) {
1125
1126 bool filtered_filename = false;
1127
1128 for(std::vector<Regex*>::iterator ri = gGourceSettings.file_filters.begin(); ri != gGourceSettings.file_filters.end(); ri++) {
1129 Regex* r = *ri;
1130
1131 if(r->match(cf.filename)) {
1132 filtered_filename = true;
1133 break;
1134 }
1135 }
1136
1137 if(filtered_filename) continue;
1138 }
1139
11401077 //is this a directory (ends in slash)
11411078 //deleting a directory - find directory: then for each file, remove each file
11421079
11541091 for(std::list<RDirNode*>::iterator it = dirs.begin(); it != dirs.end(); it++) {
11551092
11561093 RDirNode* dir = (*it);
1157
1094
11581095 //fprintf(stderr, "deleting everything under %s because of %s\n", dir->getPath().c_str(), cf.filename.c_str());
11591096
11601097 //foreach dir files
11681105 addFileAction(commit.username, cf.action, file, t);
11691106 }
11701107 }
1171
1108
11721109 return;
11731110 }
11741111
11771114
11781115 if(file == 0) {
11791116
1180 //if we already have max files in circulation
1181 //we cant add any more
1182 if(gGourceSettings.max_files > 0 && files.size() >= gGourceSettings.max_files)
1183 continue;
1184
11851117 file = addFile(cf);
1118
1119 if(!file) continue;
11861120 }
11871121
11881122 addFileAction(commit.username, cf.action, file, t);
12031137 if(user == 0) {
12041138 user = addUser(username);
12051139
1206 // set the highlighted flag if name matches a highlighted user
1207 for(std::vector<std::string>::iterator hi = gGourceSettings.highlight_users.begin(); hi != gGourceSettings.highlight_users.end(); hi++) {
1208 std::string highlight = *hi;
1209
1210 if(highlight.size() && user->getName() == highlight) {
1211 user->setHighlighted(true);
1212 break;
1140 if(gGourceSettings.highlight_all_users) user->setHighlighted(true);
1141 else {
1142
1143 // set the highlighted flag if name matches a highlighted user
1144 for(std::vector<std::string>::iterator hi = gGourceSettings.highlight_users.begin(); hi != gGourceSettings.highlight_users.end(); hi++) {
1145 std::string highlight = *hi;
1146
1147 if(!highlight.empty() && user->getName() == highlight) {
1148 user->setHighlighted(true);
1149 break;
1150 }
12131151 }
12141152 }
12151153 }
12391177 // update quad tree
12401178 Bounds2D quadtreebounds = user_bounds;
12411179
1242 quadtreebounds.min -= vec2f(1.0f, 1.0f);
1243 quadtreebounds.max += vec2f(1.0f, 1.0f);
1180 quadtreebounds.min -= vec2(1.0f, 1.0f);
1181 quadtreebounds.max += vec2(1.0f, 1.0f);
12441182
12451183 update_user_tree_time = SDL_GetTicks();
12461184
13641302 // update quad tree
13651303 Bounds2D quadtreebounds = dir_bounds;
13661304
1367 quadtreebounds.min -= vec2f(1.0f, 1.0f);
1368 quadtreebounds.max += vec2f(1.0f, 1.0f);
1305 quadtreebounds.min -= vec2(1.0f, 1.0f);
1306 quadtreebounds.max += vec2(1.0f, 1.0f);
13691307
13701308 update_dir_tree_time = SDL_GetTicks();
13711309
14261364
14271365 if(manual_camera) {
14281366
1429 if(cursor_move.length2() > 0.0f) {
1367 if(glm::length2(cursor_move) > 0.0f) {
14301368
14311369 float cam_rate = ( -camera.getPos().z ) / ( 5000.0f );
14321370
1433 vec3f cam_pos = camera.getPos();
1434
1435 vec2f cursor_delta = cursor_move * cam_rate * 400.0f * dt;
1371 vec3 cam_pos = camera.getPos();
1372
1373 vec2 cursor_delta = cursor_move * cam_rate * 400.0f * dt;
14361374
14371375 cam_pos.x += cursor_delta.x;
14381376 cam_pos.y += cursor_delta.y;
14421380
14431381 auto_rotate = false;
14441382
1445 cursor_move = vec2f(0.0f, 0.0f);
1383 cursor_move = vec2(0.0f, 0.0f);
14461384 }
14471385
14481386 } else {
14521390 if(track_users && (selectedFile !=0 || selectedUser !=0)) {
14531391 Bounds2D focusbounds;
14541392
1455 vec3f camerapos = camera.getPos();
1393 vec3 camerapos = camera.getPos();
14561394
14571395 if(selectedUser !=0) focusbounds.update(selectedUser->getPos());
14581396 if(selectedFile !=0) focusbounds.update(selectedFile->getAbsolutePos());
14831421
14841422 } else if(!cursor.rightButtonPressed() && dir_bounds.area() > 10000.0f) {
14851423
1486 float ratio = dir_bounds.width() / dir_bounds.height();
1487
1488 if(ratio < 0.67f) {
1424 float aspect_ratio = display.width / (float) display.height;
1425
1426 float bounds_ratio = (aspect_ratio > 1.0f) ? dir_bounds.width() / dir_bounds.height() : dir_bounds.height() / dir_bounds.width();
1427
1428 if(bounds_ratio < 0.67f) {
14891429 rotation_remaining_angle = 90.0f;
14901430 }
14911431 }
15121452
15131453 void Gource::logic(float t, float dt) {
15141454
1515 if(draw_loading) return;
1516
1455 if(shutdown && logmill->isFinished()) {
1456 appFinished=true;
1457 return;
1458 }
1459
15171460 if(message_timer>0.0f) message_timer -= dt;
15181461 if(splash>0.0f) splash -= dt;
15191462
15201463 //init log file
15211464 if(commitlog == 0) {
15221465
1523 try {
1524
1525 commitlog = determineFormat(logfile);
1526
1527 } catch(SeekLogException& exception) {
1528 throw SDLAppException("unable to read log file");
1529 }
1530
1531 if(commitlog == 0) {
1532 //if not in a git dir and no log file, show help
1533 if(logfile.size() == 0 || logfile == ".") {
1466 if(!logmill->isFinished()) return;
1467
1468 commitlog = logmill->getLog();
1469
1470 std::string error = logmill->getError();
1471
1472 if(!commitlog) {
1473
1474 if(!error.empty()) {
1475 throw SDLAppException(error);
1476 } else {
1477
1478 if(frameExporter!=0) frameExporter->stop();
1479
15341480 SDL_Quit();
15351481
15361482 SDLAppException exception("");
15371483 exception.setShowHelp(true);
1484
15381485 throw exception;
1539 } else if(SDLAppDirExists(logfile)) {
1540 throw SDLAppException("directory not supported");
1541 } else {
1542 throw SDLAppException("unsupported log format (you may need to regenerate your log file)");
15431486 }
15441487 }
15451488
15521495
15531496 slider.logic(dt);
15541497
1498 bool right = false;
1499 bool left = false;
1500 bool up = false;
1501 bool down = false;
1502
1503 #if SDL_VERSION_ATLEAST(1,3,0)
1504 Uint8 *keystate = SDL_GetKeyboardState(0);
1505
1506 right = keystate[SDL_SCANCODE_RIGHT];
1507 left = keystate[SDL_SCANCODE_LEFT];
1508 up = keystate[SDL_SCANCODE_UP];
1509 down = keystate[SDL_SCANCODE_DOWN];
1510 #else
15551511 Uint8 *keystate = SDL_GetKeyState(0);
15561512
1557 if(keystate[SDLK_RIGHT]) {
1513 right = keystate[SDLK_RIGHT];
1514 left = keystate[SDLK_LEFT];
1515 up = keystate[SDLK_UP];
1516 down = keystate[SDLK_DOWN];
1517 #endif
1518
1519 if(right) {
15581520 cursor_move.x = 10.0;
15591521 manual_camera = true;
15601522 }
15611523
1562 if(keystate[SDLK_LEFT]) {
1524 if(left) {
15631525 cursor_move.x = -10.0;
15641526 manual_camera = true;
15651527 }
15661528
1567 if(keystate[SDLK_UP]) {
1529 if(up) {
15681530 cursor_move.y = -10.0;
15691531 manual_camera = true;
15701532 }
15711533
1572 if(keystate[SDLK_DOWN]) {
1534 if(down) {
15731535 cursor_move.y = 10.0;
15741536 manual_camera = true;
15751537 }
15851547 for(std::map<std::string,RUser*>::iterator it = users.begin(); it!=users.end(); it++) {
15861548 RUser* user = it->second;
15871549
1588 vec2f userpos = user->getPos();
1589
1590 user->setPos(userpos.rotate(s, c));
1550 vec2 userpos = user->getPos();
1551
1552 user->setPos(rotate_vec2(userpos, s, c));
15911553 }
15921554
15931555 rotate_angle = 0.0f;
16151577 }
16161578
16171579 // get more entries
1618 if(commitqueue.size() == 0) {
1580 if(commitqueue.empty()) {
16191581 readLog();
16201582 }
16211583
16221584 //loop in attempt to find commits
1623 if(commitqueue.size()==0 && commitlog->isSeekable() && gGourceSettings.loop) {
1585 if(commitqueue.empty() && commitlog->isSeekable() && gGourceSettings.loop) {
16241586 first_read=true;
16251587 seekTo(0.0);
16261588 readLog();
16271589 }
16281590
1629 if(currtime==0 && commitqueue.size()) {
1591 if(currtime==0 && !commitqueue.empty()) {
16301592 currtime = lasttime = commitqueue[0].timestamp;
16311593 subseconds = 0.0;
16321594 }
16531615
16541616
16551617 //add commits up until the current time
1656 while(commitqueue.size() > 0) {
1657
1658 RCommit commit = commitqueue[0];
1618 while(!commitqueue.empty()) {
1619
1620 RCommit commit = commitqueue.front();
16591621
16601622 //auto skip ahead, unless stop_position_reached
16611623 if(gGourceSettings.auto_skip_seconds>=0.0 && idle_time >= gGourceSettings.auto_skip_seconds && !stop_position_reached) {
16881650
16891651 updateCamera(dt);
16901652
1691 updateTime(commitqueue.size() > 0 ? currtime : lasttime);
1653 updateTime(!commitqueue.empty() ? currtime : lasttime);
16921654 }
16931655
16941656 void Gource::mousetrace(float dt) {
16951657
1696 vec3f cam_pos = camera.getPos();
1697
1698 vec2f projected_mouse = vec2f( -(mousepos.x * 2.0f - ((float)display.width)) / ((float)display.height),
1658 vec3 cam_pos = camera.getPos();
1659
1660 vec2 projected_mouse = vec2( -(mousepos.x * 2.0f - ((float)display.width)) / ((float)display.height),
16991661 (1.0f - (2.0f * mousepos.y) / ((float)display.height)))
17001662 * cam_pos.z;
17011663 projected_mouse.x += cam_pos.x;
18121774
18131775 glColor4f(1.0, 1.0, 1.0, 1.0);
18141776
1815 std::string loading_message("Reading Log...");
1816 int width = font.getWidth(loading_message);
1817
1818 font.print(display.width/2 - width/2, display.height/2 - 10, "%s", loading_message.c_str());
1777 const char* progress;
1778
1779 switch(int(runtime*3.0f)%4) {
1780 case 0:
1781 progress = "";
1782 break;
1783 case 1:
1784 progress = ".";
1785 break;
1786 case 2:
1787 progress = "..";
1788 break;
1789 case 3:
1790 progress = "...";
1791 break;
1792 }
1793
1794 const char* action = !shutdown ? "Reading Log" : "Aborting";
1795
1796 int width = font.getWidth(action);
1797 font.setColour(vec4(1.0f));
1798 font.print(display.width/2 - width/2, display.height/2 - 10, "%s%s", action, progress);
18191799 }
18201800
18211801 void Gource::drawBackground(float dt) {
18221802 if(!gGourceDrawBackground) return;
18231803
1824 display.setClearColour(vec4f(gGourceSettings.background_colour, gGourceSettings.transparent ? 0.0f : 1.0f));
1804 display.setClearColour(vec4(gGourceSettings.background_colour, gGourceSettings.transparent ? 0.0f : 1.0f));
18251805 display.clear();
18261806
18271807 if(backgroundtex!=0) {
18651845
18661846 draw_edges_time = SDL_GetTicks() - draw_edges_time;
18671847
1868 //draw shadows
1848 //draw file shadows
18691849
18701850 draw_shadows_time = SDL_GetTicks();
18711851
1852 drawFileShadows(dt);
1853
1854 draw_shadows_time = SDL_GetTicks() - draw_shadows_time;
1855
1856 //draw actions
1857
1858 draw_actions_time = SDL_GetTicks();
1859
1860 drawActions(dt);
1861
1862 draw_actions_time = SDL_GetTicks() - draw_actions_time;
1863
1864 //draw files
1865
1866 draw_files_time = SDL_GetTicks();
1867
1868 drawFiles(dt);
1869
1870 draw_files_time = SDL_GetTicks() - draw_files_time;
1871
1872 //draw users
1873
1874 draw_users_time = SDL_GetTicks();
1875
18721876 drawUserShadows(dt);
1873
1874 drawFileShadows(dt);
1875
1876 draw_shadows_time = SDL_GetTicks() - draw_shadows_time;
1877
1878 //draw actions
1879
1880 draw_actions_time = SDL_GetTicks();
1881
1882 drawActions(dt);
1883
1884 draw_actions_time = SDL_GetTicks() - draw_actions_time;
1885
1886 //draw files
1887
1888 draw_files_time = SDL_GetTicks();
1889
1890 drawFiles(dt);
1891
1892 draw_files_time = SDL_GetTicks() - draw_files_time;
1893
1894 //draw users
1895
1896 draw_users_time = SDL_GetTicks();
18971877
18981878 drawUsers(dt);
18991879
19411921 shadow_shader->use();
19421922 shadow_shader->setFloat("shadow_strength", 0.5);
19431923
1944 vec2f shadow_offset = vec2f(2.0, 2.0);
1924 vec2 shadow_offset = vec2(2.0, 2.0);
19451925
19461926 glPushMatrix();
19471927 glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f);
20842064 RUser* user = it->second;
20852065
20862066 float alpha = user->getAlpha();
2087 vec3f col = user->getColour();
2088
2089 user_vbo.add(user->graphic->textureid, user->getPos() - user->dims*0.5f, user->dims, vec4f(col.x, col.y, col.z, alpha));
2067 vec3 col = user->getColour();
2068
2069 user_vbo.add(user->graphic->textureid, user->getPos() - user->dims*0.5f, user->dims, vec4(col.x, col.y, col.z, alpha));
20902070
20912071 //draw actions
20922072 user->updateActionsVBO(action_vbo);
21462126 shadow_shader->use();
21472127 shadow_shader->setFloat("shadow_strength", 0.5);
21482128
2149 vec2f shadow_offset = vec2f(2.0, 2.0) * gGourceSettings.user_scale;
2129 vec2 shadow_offset = vec2(2.0, 2.0) * gGourceSettings.user_scale;
21502130
21512131 glPushMatrix();
21522132 glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f);
22162196
22172197 drawBackground(dt);
22182198
2219 if(draw_loading) {
2199 if(!commitlog) {
22202200 loadingScreen();
2221 draw_loading = false;
22222201 return;
22232202 }
22242203
2225 Frustum frustum(camera);
2204 Frustum frustum(camera.getPos(), camera.getTarget(), camera.getUp(), camera.getFOV(), camera.getZNear(), camera.getZFar());
22262205
22272206 trace_time = SDL_GetTicks();
22282207
23042283 fontmanager.startBuffer();
23052284 }
23062285
2307 font.roundCoordinates(false);
2286 font.roundCoordinates(false);
2287 font.setColour(vec4(gGourceSettings.dir_colour, 1.0f));
23082288
23092289 root->drawNames(font);
23102290
23892369 glEnable(GL_BLEND);
23902370 glEnable(GL_TEXTURE_2D);
23912371
2392 vec3f campos = camera.getPos();
2372 vec3 campos = camera.getPos();
23932373
23942374 if(logotex!=0) {
23952375 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
24002380
24012381 glBindTexture(GL_TEXTURE_2D, logotex->textureid);
24022382
2403 vec2f logopos = vec2f(display.width, display.height) - vec2f(logotex->w, logotex->h) - gGourceSettings.logo_offset;
2383 vec2 logopos = vec2(display.width, display.height) - vec2(logotex->w, logotex->h) - gGourceSettings.logo_offset;
24042384
24052385 glPushMatrix();
24062386
24312411 int cwidth = font.getWidth("Software Version Control Visualization");
24322412 int awidth = font.getWidth("(C) 2009 Andrew Caudwell");
24332413
2434 vec2f corner(display.width/2 - logowidth/2 - 30.0f, display.height/2 - 40);
2414 vec2 corner(display.width/2 - logowidth/2 - 30.0f, display.height/2 - 40);
24352415
24362416 glDisable(GL_TEXTURE_2D);
24372417 glColor4f(0.0f, 0.5f, 1.0f, splash * 0.015f);
24442424
24452425 glEnable(GL_TEXTURE_2D);
24462426
2447 glColor4f(1.0,1.0,1.0,1.0);
2427 fontlarge.setColour(vec4(1.0f));
24482428 fontlarge.draw(display.width/2 - logowidth/2,display.height/2 - 30, "Gource");
2429
2430 font.setColour(vec4(1.0f));
24492431 font.draw(display.width/2 - cwidth/2,display.height/2 + 10, "Software Version Control Visualization");
24502432 font.draw(display.width/2 - awidth/2,display.height/2 + 30, "(C) 2009 Andrew Caudwell");
24512433 }
24522434
24532435 // text using the specified font goes here
24542436
2455 fontmedium.setColour(vec4f(gGourceSettings.font_colour, 1.0f));
2456
2437 fontmedium.setColour(vec4(gGourceSettings.font_colour, 1.0f));
2438
24572439 if(!gGourceSettings.hide_date) {
24582440 fontmedium.draw(display.width/2 - date_x_offset, 20, displaydate);
24592441 }
25012483 //debug info
25022484
25032485 if(debug) {
2504 font.setAlpha(1.0f);
2486 font.setColour(vec4(1.0f));
25052487
25062488 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
25072489 glEnable(GL_BLEND);
25082490 glEnable(GL_TEXTURE_2D);
25092491
2510
25112492 font.print(1,20, "FPS: %.2f", fps);
25122493 font.print(1,40,"Days Per Second: %.2f",
25132494 gGourceSettings.days_per_second);
2514 font.print(1,60,"Time Scale: %.2f", gGourceSettings.time_scale);
2495 font.print(1,60,"Commit Queue: %d", commitqueue.size());
25152496 font.print(1,80,"Users: %d", users.size());
25162497 font.print(1,100,"Files: %d", files.size());
25172498 font.print(1,120,"Dirs: %d", gGourceDirMap.size());
3737
3838 #include "gource_settings.h"
3939
40 #include "git.h"
41 #include "hg.h"
42 #include "bzr.h"
43 #include "gitraw.h"
44 #include "cvs2cl.h"
45 #include "cvs-exp.h"
46 #include "custom.h"
47 #include "apache.h"
48 #include "svn.h"
40 #include "logmill.h"
4941
5042 #include "core/vbo.h"
5143 #include "bloom.h"
6355
6456 FrameExporter* frameExporter;
6557
58 RLogMill* logmill;
59 bool shutdown;
60
6661 RCommitLog* commitlog;
6762 PositionSlider slider;
6863 ZoomCamera camera;
8479 bool mouseclicked;
8580 bool mousedragged;
8681
87 vec2f cursor_move;
82 vec2 cursor_move;
8883
8984 bool recolour;
9085
9590
9691 float rotate_angle;
9792
98 vec2f mousepos;
93 vec2 mousepos;
9994
10095 float last_percent;
10196
142137 FXFont font, fontlarge, fontmedium;
143138
144139 bool first_read;
145 bool draw_loading;
146140 bool paused;
147141
148142 float max_tick_rate;
182176 Bounds2D user_bounds;
183177 Bounds2D active_user_bounds;
184178
179 int commitqueue_max_size;
180
185181 std::deque<RCommit> commitqueue;
186182 std::map<std::string, RUser*> users;
187183 std::map<std::string, RFile*> files;
195191 float message_timer;
196192
197193 void setMessage(const char* str, ...);
198
194
199195 void reset();
200196
201197 RUser* addUser(const std::string& username);
211207
212208 void readLog();
213209
210 void logReadingError(const std::string& error);
211
214212 void processCommit(RCommit& commit, float t);
215213 void addFileAction(const std::string& username, const std::string& action, RFile* file, float t);
216214
218216
219217 void toggleCameraMode();
220218
221 static RCommitLog* determineFormat(const std::string& logfile);
222
223219 void updateCamera(float dt);
224220
225221 void updateUsers(float t, float dt);
243239 void drawBackground(float dt);
244240
245241 void drawScene(float dt);
246
242
247243 void updateVBOs(float dt);
248244
249245 void updateAndDrawEdges();
250
246
251247 void drawFileShadows(float dt);
252248 void drawUserShadows(float dt);
253249 void drawActions(float dt);
270266
271267 void showSplash();
272268
269 bool isBusy();
270
273271 void logic(float t, float dt);
274272 void draw(float t, float dt);
275273
276274 void init();
275
276 void unload();
277 void reload();
278
279 void quit();
280
277281 void update(float t, float dt);
278282 void keyPress(SDL_KeyboardEvent *e);
279283 void mouseMove(SDL_MouseMotionEvent *e);
280284 void mouseClick(SDL_MouseButtonEvent *e);
285 #if SDL_VERSION_ATLEAST(1,3,0)
286 void mouseWheel(SDL_MouseWheelEvent *e);
287 #endif
281288 };
282289
283290 #endif
5050 printf(" --disable-auto-skip Disable auto skip\n");
5151 printf(" -s, --seconds-per-day SECONDS Speed in seconds per day (default: 10)\n");
5252 printf(" --realtime Realtime playback speed\n");
53 printf(" -c, --time-scale SCALE Change simuation time scale (default: 1.0)\n");
53 printf(" -c, --time-scale SCALE Change simulation time scale (default: 1.0)\n");
5454 printf(" -e, --elasticity FLOAT Elasticity of nodes\n\n");
5555
5656 printf(" --key Show file extension key\n\n");
9292
9393 printf(" --date-format FORMAT Specify display date string (strftime format)\n\n");
9494
95 printf(" --font-size SIZE Font size\n");
96 printf(" --font-colour FFFFFF Font colour in hex\n\n");
95 printf(" --font-size SIZE Font size used by date and title\n");
96 printf(" --font-colour FFFFFF Font colour used by date and title in hex\n\n");
9797
9898 printf(" --file-extensions Show filename extensions only\n\n");
9999
112112 printf(" --user-filter REGEX Ignore usernames matching this regex\n");
113113 printf(" --file-filter REGEX Ignore files matching this regex\n\n");
114114
115 printf(" --user-friction SECONDS Time users come to a complete hault (default: 0.67)\n");
115 printf(" --user-friction SECONDS Change the rate users slow down (default: 0.67)\n");
116116 printf(" --user-scale SCALE Change scale of users (default: 1.0)\n");
117117 printf(" --max-user-speed UNITS Speed users can travel per second (default: 500)\n\n");
118118
119119 printf(" --follow-user USER Camera will automatically follow this user\n");
120 printf(" --highlight-dirs Highlight the names of all directories\n");
120121 printf(" --highlight-user USER Highlight the names of a particular user\n");
121122 printf(" --highlight-users Highlight the names of all users\n\n");
122 printf(" --highlight-dirs Highlight the names of all directories\n");
123 printf(" --highlight-colour Font colour for highlighted text\n\n");
123 printf(" --highlight-colour Font colour for highlighted users in hex.\n");
124 printf(" --selection-colour Font colour for selected users and files.\n");
125 printf(" --dir-colour Font colour for directories.\n\n");
124126
125127 printf(" --hash-seed SEED Change the seed of hash function\n\n");
126128
136138 }
137139
138140 #ifdef _WIN32
139 printf("Press Enter\n");
140 getchar();
141 if(gSDLAppConsoleWindow) {
142 printf("Press Enter\n");
143 getchar();
144 }
141145 #endif
142146
143147 exit(0);
181185 conf_sections["load-config"] = "command-line";
182186 conf_sections["save-config"] = "command-line";
183187 conf_sections["output-custom-log"] = "command-line";
188 conf_sections["log-level"] = "command-line";
184189
185190 //boolean args
186191 arg_types["help"] = "bool";
238243 arg_types["follow-user"] = "multi-value";
239244 arg_types["highlight-user"] = "multi-value";
240245
246 arg_types["log-level"] = "string";
241247 arg_types["background-image"] = "string";
242248 arg_types["logo"] = "string";
243249 arg_types["logo-offset"] = "string";
264270 arg_types["title"] = "string";
265271 arg_types["font-colour"] = "string";
266272 arg_types["highlight-colour"] = "string";
273 arg_types["selection-colour"] = "string";
274 arg_types["dir-colour"] = "string";
275
267276 }
268277
269278 void GourceSettings::setGourceDefaults() {
303312 loop = false;
304313
305314 logo = "";
306 logo_offset = vec2f(20.0f,20.0f);
315 logo_offset = vec2(20.0f,20.0f);
307316
308317 colour_user_images = false;
309318 default_user_image = "";
310319 user_image_dir = "";
311320 user_image_map.clear();
312321
322 camera_zoom_min = 50.0f;
323 camera_zoom_default = 100.0f;
324 camera_zoom_max = 10000.0f;
325
313326 camera_mode = "overview";
314327 padding = 1.1f;
315328
319332 bloom_multiplier = 1.0f;
320333 bloom_intensity = 0.75f;
321334
322 background_colour = vec3f(0.1f, 0.1f, 0.1f);
335 background_colour = vec3(0.1f, 0.1f, 0.1f);
323336 background_image = "";
324337
325338 title = "";
326339
327340 font_size = 16;
328 font_colour = vec3f(1.0f, 1.0f, 1.0f);
329 highlight_colour = vec3f(1.0f, 1.0f, 0.3f);
341 dir_colour = vec3(1.0f);
342 font_colour = vec3(1.0f);
343 highlight_colour = vec3(1.0f);
344 selection_colour = vec3(1.0, 1.0, 0.3f);
330345
331346 elasticity = 0.0f;
332347
350365
351366 gStringHashSeed = 31;
352367
368 log_level = LOG_LEVEL_ERROR;
369
353370 //delete file filters
354371 for(std::vector<Regex*>::iterator it = file_filters.begin(); it != file_filters.end(); it++) {
355372 delete (*it);
422439
423440 if(name == "output-custom-log" && value.size() > 0) {
424441 output_custom_filename = value;
442 return;
443 }
444
445 if(name == "log-level") {
446 if(value == "warn") {
447 log_level = LOG_LEVEL_WARN;
448 } else if(value == "debug") {
449 log_level = LOG_LEVEL_DEBUG;
450 } else if(value == "info") {
451 log_level = LOG_LEVEL_INFO;
452 } else if(value == "error") {
453 log_level = LOG_LEVEL_ERROR;
454 }
425455 return;
426456 }
427457
717747 if(entry->isVec3()) {
718748 font_colour = entry->getVec3();
719749 } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
720 font_colour = vec3f(r,g,b);
750 font_colour = vec3(r,g,b);
721751 font_colour /= 255.0f;
722752 } else {
723753 conffile.invalidValueException(entry);
735765 if(entry->isVec3()) {
736766 background_colour = entry->getVec3();
737767 } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
738 background_colour = vec3f(r,g,b);
768 background_colour = vec3(r,g,b);
739769 background_colour /= 255.0f;
740770 } else {
741771 conffile.invalidValueException(entry);
753783 if(entry->isVec3()) {
754784 highlight_colour = entry->getVec3();
755785 } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
756 highlight_colour = vec3f(r,g,b);
786 highlight_colour = vec3(r,g,b);
757787 highlight_colour /= 255.0f;
758788 } else {
759789 conffile.invalidValueException(entry);
760790 }
761791 }
792
793 if((entry = gource_settings->getEntry("selection-colour")) != 0) {
794
795 if(!entry->hasValue()) conffile.entryException(entry, "specify selection colour (FFFFFF)");
796
797 int r,g,b;
798
799 std::string colstring = entry->getString();
800
801 if(entry->isVec3()) {
802 selection_colour = entry->getVec3();
803 } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
804 selection_colour = vec3(r,g,b);
805 selection_colour /= 255.0f;
806 } else {
807 conffile.invalidValueException(entry);
808 }
809 }
810
811 if((entry = gource_settings->getEntry("dir-colour")) != 0) {
812
813 if(!entry->hasValue()) conffile.entryException(entry, "specify dir colour (FFFFFF)");
814
815 int r,g,b;
816
817 std::string colstring = entry->getString();
818
819 if(entry->isVec3()) {
820 dir_colour = entry->getVec3();
821 } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
822 dir_colour = vec3(r,g,b);
823 dir_colour /= 255.0f;
824 } else {
825 conffile.invalidValueException(entry);
826 }
827 }
762828
763829 if((entry = gource_settings->getEntry("background-image")) != 0) {
764830
790856 int posx = 0;
791857 int posy = 0;
792858
793 if(parseRectangle(logo_offset_str, &posx, &posy)) {
794 logo_offset = vec2f(posx, posy);
859 if(parseRectangle(logo_offset_str, posx, posy)) {
860 logo_offset = vec2(posx, posy);
795861 } else {
796862 conffile.invalidValueException(entry);
797863 }
10931159 }
10941160 }
10951161
1096
1097
1098
10991162 //validate path
11001163 if(gource_settings->hasValue("path")) {
11011164 path = gource_settings->getString("path");
1717 #ifndef GOURCE_SETTINGS_H
1818 #define GOURCE_SETTINGS_H
1919
20 #define GOURCE_VERSION "0.37"
20 #define GOURCE_VERSION "0.38"
2121
2222 #include <dirent.h>
2323
24 #include "hg.h"
25 #include "git.h"
26 #include "bzr.h"
27 #include "cvs-exp.h"
28 #include "cvs2cl.h"
29 #include "svn.h"
24 #include "formats/hg.h"
25 #include "formats/git.h"
26 #include "formats/bzr.h"
27 #include "formats/cvs-exp.h"
28 #include "formats/cvs2cl.h"
29 #include "formats/svn.h"
3030
3131 #include "core/settings.h"
3232 #include "core/regex.h"
5858 std::string path;
5959
6060 std::string logo;
61 vec2f logo_offset;
61 vec2 logo_offset;
6262
6363 float start_position;
6464 float stop_position;
8181 std::string user_image_dir;
8282 std::map<std::string, std::string> user_image_map;
8383
84 float camera_zoom_min;
85 float camera_zoom_max;
86 float camera_zoom_default;
87
8488 std::string camera_mode;
8589 float padding;
8690
9094 float bloom_multiplier;
9195 float bloom_intensity;
9296
93 vec3f background_colour;
97 vec3 background_colour;
9498 std::string background_image;
9599
96100 std::string title;
97101
98102 int font_size;
99 vec3f font_colour;
103 vec3 font_colour;
100104
101105 float elasticity;
102106
116120
117121 bool highlight_dirs;
118122 bool highlight_all_users;
119 vec3f highlight_colour;
120123
124 vec3 dir_colour;
125 vec3 highlight_colour;
126 vec3 selection_colour;
127
121128 std::vector<std::string> highlight_users;
122129 std::vector<std::string> follow_users;
123130 std::vector<Regex*> file_filters;
127134 std::string output_custom_filename;
128135
129136 TextureResource* file_graphic;
137
138 int log_level;
130139
131140 GourceSettings();
132141
1616
1717 #include "gource_shell.h"
1818
19 GourceShell* gGourceShell = 0;
20
1921 // GourceShell
2022
2123 GourceShell::GourceShell(ConfFile* conf, FrameExporter* exporter) {
2325 this->conf = conf;
2426 this->exporter = exporter;
2527
28 min_delta_msec = 16;
29
2630 next = false;
2731
32 shutdown = false;
33
2834 gource = 0;
2935 gource_settings = conf->getSections("gource")->begin();
3036
3440 transition_interval = 0.0f;
3541
3642 if(strstr((const char *)glGetString(GL_EXTENSIONS), "GL_ARB_texture_non_power_of_two" )) {
37 transition_texture = display.emptyTexture(display.width, display.height, GL_RGBA);
38 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
39 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
43
44 transition_texture = texturemanager.create(display.width, display.height, false, GL_CLAMP_TO_EDGE, GL_RGBA);
4045 }
4146 }
4247
4348 GourceShell::~GourceShell() {
4449 if(gource!=0) delete gource;
45 if(transition_texture!=0) glDeleteTextures(1, &transition_texture);
50 if(transition_texture!=0) texturemanager.release(transition_texture);
51 }
52
53 void GourceShell::toggleFullscreen() {
54
55 if(exporter != 0) return;
56
57 texturemanager.unload();
58 shadermanager.unload();
59 fontmanager.unload();
60
61 if(gource!=0) gource->unload();
62
63 //recreate gl context
64 display.toggleFullscreen();
65
66 texturemanager.reload();
67 shadermanager.reload();
68 fontmanager.reload();
69
70 if(gource!=0) gource->reload();
71 }
72
73 void GourceShell::resize(int width, int height) {
74
75 texturemanager.unload();
76 shadermanager.unload();
77 fontmanager.unload();
78
79 if(gource!=0) gource->unload();
80
81 //recreate gl context
82 display.resize(width, height);
83
84 texturemanager.reload();
85 shadermanager.reload();
86 fontmanager.reload();
87
88 if(gource!=0) gource->reload();
4689 }
4790
4891 void GourceShell::keyPress(SDL_KeyboardEvent *e) {
4992
5093 //Quit demo if the user presses ESC
5194 if (e->type == SDL_KEYDOWN) {
52 if (e->keysym.unicode == SDLK_ESCAPE) {
53 appFinished=true;
54 }
55
56 if (e->keysym.unicode == SDLK_RETURN) {
57 if(gGourceSettings.repo_count>1)
58 next = true;
59 }
60
95
96 #if SDL_VERSION_ATLEAST(1,3,0)
97 bool key_escape = e->keysym.scancode == SDL_SCANCODE_ESCAPE;
98 bool key_return = e->keysym.scancode == SDL_SCANCODE_RETURN;
99 #else
100 bool key_escape = e->keysym.unicode == SDLK_ESCAPE;
101 bool key_return = e->keysym.unicode == SDLK_RETURN;
102 #endif
103
104 if (key_escape) {
105 quit();
106 }
107
108 if(key_return) {
109
110 #if SDL_VERSION_ATLEAST(1,3,0)
111 Uint8* keystate = SDL_GetKeyboardState(NULL);
112 if(keystate[SDL_SCANCODE_RALT] || keystate[SDL_SCANCODE_LALT]) {
113 #else
114 Uint8* keystate = SDL_GetKeyState(NULL);
115 if(keystate[SDLK_RALT] || keystate[SDLK_LALT]) {
116 #endif
117
118 toggleFullscreen();
119
120 } else {
121 if(gGourceSettings.repo_count>1)
122 next = true;
123 }
124 }
61125 }
62126
63127 if(gource!=0) gource->keyPress(e);
67131 if(gource!=0) gource->mouseMove(e);
68132 }
69133
134 #if SDL_VERSION_ATLEAST(1,3,0)
135 void GourceShell::mouseWheel(SDL_MouseWheelEvent *e) {
136 if(gource!=0) gource->mouseWheel(e);
137 }
138 #endif
139
70140 void GourceShell::mouseClick(SDL_MouseButtonEvent *e) {
71141 if(gource!=0) gource->mouseClick(e);
72142 }
73143
144 void GourceShell::quit() {
145 if(gource!=0) gource->quit();
146 shutdown=true;
147 }
148
74149 Gource* GourceShell::getNext() {
75150
76151 if(gource!=0) {
77 delete gource;
78 gource = 0;
79
80152 transition_interval = 1.0f;
81153 }
82
83 if(gource_settings == conf->getSections("gource")->end()) {
154
155 if(shutdown || gource_settings == conf->getSections("gource")->end()) {
156
157 // if we are done, delete gource and replace it with nothing
158 if(gource != 0) {
159 Gource* gource_tmp = gource;
160 gource = 0;
161 delete gource_tmp;
162 }
163
84164 return 0;
85165 }
86166
111191 }
112192 }
113193
114 Gource* gource = new Gource(exporter);
115
194 // replace gource
195
196 Gource* gource_tmp = gource;
197 gource = new Gource(exporter);
198 delete gource_tmp;
199
116200 next = false;
117
201
118202 return gource;
119203 }
120204
127211 glEnable(GL_BLEND);
128212 glEnable(GL_TEXTURE_2D);
129213
130 glBindTexture(GL_TEXTURE_2D, transition_texture);
214 transition_texture->bind();
131215
132216 glColor4f(1.0, 1.0, 1.0, transition_interval);
133217
151235 void GourceShell::update(float t, float dt) {
152236
153237 if(gource == 0 || gource->isFinished()) {
154 gource = getNext();
155
156 if(gource==0) appFinished=true;
238 if(!getNext()) appFinished=true;
239
157240 return;
158241 }
159242
162245
163246 //copy last frame
164247 if( (next|| gource->isFinished()) && transition_texture!=0) {
165 display.renderToTexture(transition_texture, display.width, display.height, GL_RGBA);
248
249 glEnable(GL_TEXTURE_2D);
250 transition_texture->bind();
251 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, display.width, display.height, 0);
252
166253 } else {
167254 //blend last frame of previous scene
168255 blendLastFrame(dt);
2525
2626 Gource* gource;
2727
28 bool shutdown;
2829 bool next;
2930
30 GLuint transition_texture;
31 TextureResource* transition_texture;
3132 float transition_interval;
3233
3334 FrameExporter* exporter;
4243
4344 void update(float t, float dt);
4445
46 void resize(int width, int height);
47
48 void toggleFullscreen();
49
50 void quit();
51
4552 void keyPress(SDL_KeyboardEvent *e);
4653 void mouseMove(SDL_MouseMotionEvent *e);
4754 void mouseClick(SDL_MouseButtonEvent *e);
48
55 #if SDL_VERSION_ATLEAST(1,3,0)
56 void mouseWheel(SDL_MouseWheelEvent *e);
57 #endif
4958 };
5059
5160 #endif
61
62 extern GourceShell* gGourceShell;
+0
-121
src/hg.cpp less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "hg.h"
18
19 Regex hg_regex("^([0-9]+) -?[0-9]+\\|([^|]+)\\|([ADM]?)\\|(.+)$");
20
21 // parse Mercurial log entries (using the gource.style template)
22
23 std::string gGourceMercurialCommand() {
24
25 std::string gource_style_path = gSDLAppResourceDir + std::string("gource.style");
26
27 return std::string("hg log -r 0:tip --style \"") + gource_style_path + std::string("\"");
28 }
29
30 MercurialLog::MercurialLog(const std::string& logfile) : RCommitLog(logfile) {
31
32 log_command = gGourceMercurialCommand();
33
34 //can generate log from directory
35 if(!logf && is_dir) {
36 logf = generateLog(logfile);
37
38 if(logf) {
39 success = true;
40 seekable = true;
41 }
42 }
43 }
44
45 BaseLog* MercurialLog::generateLog(const std::string& dir) {
46
47 //does directory have a .hg ?
48 std::string hgdir = dir + std::string("/.hg");
49 struct stat dirinfo;
50 int stat_rc = stat(hgdir.c_str(), &dirinfo);
51 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
52 return 0;
53 }
54
55 std::string command = getLogCommand();
56
57 createTempLog();
58
59 if(temp_file.size()==0) return 0;
60
61 char cmd_buff[2048];
62 sprintf(cmd_buff, "%s -R \"%s\" > %s", command.c_str(), dir.c_str(), temp_file.c_str());
63
64 int command_rc = system(cmd_buff);
65
66 if(command_rc != 0) {
67 return 0;
68 }
69
70 BaseLog* seeklog = new SeekLog(temp_file);
71
72 return seeklog;
73 }
74
75
76 bool MercurialLog::parseCommit(RCommit& commit) {
77
78 while(parseCommitEntry(commit));
79
80 return !commit.files.empty();
81 }
82
83 bool MercurialLog::parseCommitEntry(RCommit& commit) {
84
85 std::string line;
86 std::vector<std::string> entries;
87
88 if(!logf->getNextLine(line)) return false;
89
90 //custom line
91 if(!hg_regex.match(line, &entries)) return false;
92
93 time_t timestamp = atol(entries[0].c_str());
94 std::string username = entries[1];
95
96 //if this file is for the same person and timestamp
97 //we add to the commit, else we save the lastline
98 //and return false
99 if(commit.files.empty()) {
100 commit.timestamp = timestamp;
101 commit.username = username;
102 } else {
103 if(commit.timestamp != timestamp || commit.username != username) {
104 lastline = line;
105 return false;
106 }
107 }
108
109 std::string action = "A";
110
111 if(!entries[2].empty()) {
112 action = entries[2];
113 }
114
115 commit.addFile(entries[3], action);
116
117 //commit.debug();
118
119 return true;
120 }
+0
-34
src/hg.h less more
0 /*
1 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef MERCURIALLOG_H
18 #define MERCURIALLOG_H
19
20 #include "commitlog.h"
21
22 std::string gGourceMercurialCommand();
23
24 class MercurialLog : public RCommitLog {
25 protected:
26 bool parseCommit(RCommit& commit);
27 bool parseCommitEntry(RCommit& commit);
28 BaseLog* generateLog(const std::string& dir);
29 public:
30 MercurialLog(const std::string& logfile);
31 };
32
33 #endif
33 // File Key Entry
44 // a string for the file ext and a colour
55
6 FileKeyEntry::FileKeyEntry(const FXFont& font, const std::string& ext, const vec3f& colour) {
6 FileKeyEntry::FileKeyEntry(const FXFont& font, const std::string& ext, const vec3& colour) {
77 this->ext = ext;
88 this->colour = colour;
99 this->pos_y = -1.0f;
1111 this->font = font;
1212 this->font.dropShadow(false);
1313
14 shadow = vec2f(3.0, 3.0);
14 shadow = vec2(3.0, 3.0);
1515
1616 width = 90.0f;
1717 height = 18.0f;
2727 show = true;
2828
2929 display_ext = ext;
30
30
3131 bool truncated = false;
32
32
3333 while(font.getWidth(display_ext) > width - 15.0f) {
3434 display_ext.resize(display_ext.size()-1);
3535 truncated = true;
3636 }
37
37
3838 if(truncated) {
3939 display_ext += std::string("...");
4040 }
4141 }
4242
43 const vec3f& FileKeyEntry::getColour() const {
43 const vec3& FileKeyEntry::getColour() const {
4444 return colour;
4545 }
4646
5757 }
5858
5959 void FileKeyEntry::colourize() {
60 colour = ext.empty() ? vec3f(1.0f, 1.0f, 1.0f) : colourHash(ext);
60 colour = ext.empty() ? vec3(1.0f, 1.0f, 1.0f) : colourHash(ext);
6161 }
6262
6363 void FileKeyEntry::inc() {
106106 }
107107 }
108108
109 pos = vec2f(alpha * left_margin, pos_y);
109 pos = vec2(alpha * left_margin, pos_y);
110110 }
111111
112112 void FileKeyEntry::draw() {
141141
142142 glEnable(GL_TEXTURE_2D);
143143
144 font.setColour(vec4f(1.0f, 1.0f, 1.0f, alpha));
144 font.setColour(vec4(1.0f, 1.0f, 1.0f, alpha));
145145
146146 font.dropShadow(false);
147147 font.draw((int)pos.x+2, (int)pos.y+3, display_ext.c_str());
272272 std::sort(active_keys.begin(), active_keys.end(), file_key_entry_sort);
273273
274274 //limit to entries we can put onto the screen
275 int max_visible_entries = (display.height - 150.0f) / 20.0f;
275 int max_visible_entries = std::max(0, (int)((display.height - 150.0f) / 20.0f));
276276
277277 if (active_keys.size() > max_visible_entries) {
278278 active_keys.resize(max_visible_entries);
2828
2929 class FileKeyEntry {
3030 FXFont font;
31 vec3f colour;
31 vec3 colour;
3232 std::string ext;
3333 std::string display_ext;
3434 float alpha;
4141 float left_margin;
4242 float width;
4343 float height;
44 vec2f pos;
45 vec2f shadow;
44 vec2 pos;
45 vec2 shadow;
4646 bool show;
4747 public:
48 FileKeyEntry(const FXFont& font, const std::string& ext, const vec3f& colour);
48 FileKeyEntry(const FXFont& font, const std::string& ext, const vec3& colour);
4949
50 const vec3f& getColour() const;
50 const vec3& getColour() const;
5151 const std::string& getExt() const;
5252
5353 void setDestY(float dest_y);
0 /*
1 Copyright (C) 2012 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "logmill.h"
18 #include "gource_settings.h"
19
20 #include "formats/git.h"
21 #include "formats/gitraw.h"
22 #include "formats/custom.h"
23 #include "formats/hg.h"
24 #include "formats/bzr.h"
25 #include "formats/svn.h"
26 #include "formats/apache.h"
27
28 extern "C" {
29
30 static int logmill_thread(void *lmill) {
31
32 RLogMill *logmill = static_cast<RLogMill*> (lmill);
33 logmill->run();
34
35 return 0;
36 }
37
38 };
39
40 RLogMill::RLogMill(const std::string& logfile)
41 : logfile(logfile) {
42
43 logmill_thread_state = LOGMILL_STATE_STARTUP;
44 clog = 0;
45
46 #if SDL_VERSION_ATLEAST(1,3,0)
47 thread = SDL_CreateThread( logmill_thread, "logmill", this );
48 #else
49 thread = SDL_CreateThread( logmill_thread, this );
50 #endif
51 }
52
53 RLogMill::~RLogMill() {
54
55 abort();
56
57 if(thread) SDL_KillThread(thread);
58 if(clog) delete clog;
59 }
60
61 void RLogMill::run() {
62 logmill_thread_state = LOGMILL_STATE_FETCHING;
63
64 #if defined(HAVE_PTHREAD) && !defined(_WIN32)
65 sigset_t mask;
66 sigemptyset(&mask);
67
68 // unblock SIGINT so user can cancel
69 // NOTE: assumes SDL is using pthreads
70
71 sigaddset(&mask, SIGINT);
72 pthread_sigmask(SIG_UNBLOCK, &mask, 0);
73 #endif
74
75 std::string log_format = gGourceSettings.log_format;
76
77 try {
78
79 clog = fetchLog(log_format);
80
81 } catch(SeekLogException& exception) {
82 error = "unable to read log file";
83 } catch(SDLAppException& exception) {
84 error = exception.what();
85 }
86
87 if(!clog && error.empty()) {
88 if(SDLAppDirExists(logfile)) {
89 if(!log_format.empty()) {
90 error = "failed to generate log file";
91 } else {
92 error = "directory not supported";
93 }
94 } else {
95 error = "unsupported log format (you may need to regenerate your log file)";
96 }
97 }
98
99 logmill_thread_state = clog ? LOGMILL_STATE_SUCCESS : LOGMILL_STATE_FAILURE;
100 }
101
102 void RLogMill::abort() {
103 // TODO: make abort nicer by notifying the log process
104 // we want to shutdown
105
106 while(logmill_thread_state <= LOGMILL_STATE_FETCHING) {
107 SDL_Delay(100);
108 }
109 }
110
111 bool RLogMill::isFinished() {
112 return logmill_thread_state > LOGMILL_STATE_FETCHING;
113 }
114
115 int RLogMill::getStatus() {
116 return logmill_thread_state;
117 }
118
119 std::string RLogMill::getError() {
120 return error;
121 }
122
123
124 RCommitLog* RLogMill::getLog() {
125
126 while(logmill_thread_state <= LOGMILL_STATE_FETCHING) {
127 SDL_Delay(100);
128 }
129
130 return clog;
131 }
132
133 bool RLogMill::findRepository(boost::filesystem::path& dir, std::string& log_format) {
134
135 dir = absolute(dir);
136
137 //fprintf(stderr, "find repository from initial path: %s\n", dir.string().c_str());
138
139 while(is_directory(dir)) {
140
141 if(is_directory(dir / ".git")) log_format = "git";
142 else if(is_directory(dir / ".hg")) log_format = "hg";
143 else if(is_directory(dir / ".bzr")) log_format = "bzr";
144 else if(is_directory(dir / ".svn")) log_format = "svn";
145
146 if(!log_format.empty()) {
147 //fprintf(stderr, "found '%s' repository at: %s\n", log_format.c_str(), dir.string().c_str());
148 return true;
149 }
150
151 if(!dir.has_parent_path()) return false;
152
153 dir = dir.parent_path();
154 }
155
156 return false;
157 }
158
159
160 RCommitLog* RLogMill::fetchLog(std::string& log_format) {
161
162 RCommitLog* clog = 0;
163
164 //if the log format is not specified and 'logfile' is a directory, recursively look for a version control repository.
165 //this method allows for something strange like someone who having an svn repository inside a git repository
166 //(in which case it would pick the svn directory as it would encounter that first)
167
168 if(log_format.empty() && logfile != "-") {
169
170 try {
171 boost::filesystem::path repo_path(logfile);
172
173 if(is_directory(repo_path)) {
174 if(findRepository(repo_path, log_format)) {
175 logfile = repo_path.string();
176 }
177 }
178 } catch(boost::filesystem3::filesystem_error& error) {
179 }
180 }
181
182 //we've been told what format to use
183 if(log_format.size() > 0) {
184 debugLog("log-format = %s", log_format.c_str());
185
186 if(log_format == "git") {
187 clog = new GitCommitLog(logfile);
188 if(clog->checkFormat()) return clog;
189 delete clog;
190
191 clog = new GitRawCommitLog(logfile);
192 if(clog->checkFormat()) return clog;
193 delete clog;
194 }
195
196 if(log_format == "hg") {
197 clog = new MercurialLog(logfile);
198 if(clog->checkFormat()) return clog;
199 delete clog;
200 }
201
202 if(log_format == "bzr") {
203 clog = new BazaarLog(logfile);
204 if(clog->checkFormat()) return clog;
205 delete clog;
206 }
207
208 if(log_format == "cvs") {
209 clog = new CVSEXPCommitLog(logfile);
210 if(clog->checkFormat()) return clog;
211 delete clog;
212 }
213
214 if(log_format == "custom") {
215 clog = new CustomLog(logfile);
216 if(clog->checkFormat()) return clog;
217 delete clog;
218 }
219
220 if(log_format == "apache") {
221 clog = new ApacheCombinedLog(logfile);
222 if(clog->checkFormat()) return clog;
223 delete clog;
224 }
225
226 if(log_format == "svn") {
227 clog = new SVNCommitLog(logfile);
228 if(clog->checkFormat()) return clog;
229 delete clog;
230 }
231
232 if(log_format == "cvs2cl") {
233 clog = new CVS2CLCommitLog(logfile);
234 if(clog->checkFormat()) return clog;
235 delete clog;
236 }
237
238 return 0;
239 }
240
241 // try different formats until one works
242
243 //git
244 debugLog("trying git...");
245 clog = new GitCommitLog(logfile);
246 if(clog->checkFormat()) return clog;
247
248 delete clog;
249
250 //mercurial
251 debugLog("trying mercurial...");
252 clog = new MercurialLog(logfile);
253 if(clog->checkFormat()) return clog;
254
255 delete clog;
256
257 //bzr
258 debugLog("trying bzr...");
259 clog = new BazaarLog(logfile);
260 if(clog->checkFormat()) return clog;
261
262 delete clog;
263
264 //git raw
265 debugLog("trying git raw...");
266 clog = new GitRawCommitLog(logfile);
267 if(clog->checkFormat()) return clog;
268
269 delete clog;
270
271 //cvs exp
272 debugLog("trying cvs-exp...");
273 clog = new CVSEXPCommitLog(logfile);
274 if(clog->checkFormat()) return clog;
275
276 delete clog;
277
278 //svn
279 debugLog("trying svn...");
280 clog = new SVNCommitLog(logfile);
281 if(clog->checkFormat()) return clog;
282
283 delete clog;
284
285 //cvs2cl
286 debugLog("trying cvs2cl...");
287 clog = new CVS2CLCommitLog(logfile);
288 if(clog->checkFormat()) return clog;
289
290 delete clog;
291
292 //custom
293 debugLog("trying custom...");
294 clog = new CustomLog(logfile);
295 if(clog->checkFormat()) return clog;
296
297 delete clog;
298
299 //apache
300 debugLog("trying apache combined...");
301 clog = new ApacheCombinedLog(logfile);
302 if(clog->checkFormat()) return clog;
303
304 delete clog;
305
306 return 0;
307 }
0 /*
1 Copyright (C) 2012 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef LOGMILL_H
18 #define LOGMILL_H
19
20 #include <boost/filesystem.hpp>
21
22 #include "SDL_thread.h"
23
24 #include "core/sdlapp.h"
25 #include "core/display.h"
26
27 #include "formats/commitlog.h"
28
29 #if defined(HAVE_PTHREAD) && !defined(_WIN32)
30 #include <signal.h>
31 #endif
32
33 enum {
34 LOGMILL_STATE_STARTUP,
35 LOGMILL_STATE_FETCHING,
36 LOGMILL_STATE_SUCCESS,
37 LOGMILL_STATE_FAILURE
38 };
39
40 class RLogMill {
41 SDL_Thread* thread;
42 SDL_mutex* mutex;
43 SDL_cond* cond;
44
45 int logmill_thread_state;
46
47 std::string logfile;
48 RCommitLog* clog;
49
50 std::string error;
51
52 bool findRepository(boost::filesystem::path& dir, std::string& log_format);
53 RCommitLog* fetchLog(std::string& log_format);
54 public:
55 RLogMill(const std::string& logfile);
56 ~RLogMill();
57
58 void run();
59
60 void abort();
61
62 std::string getError();
63
64 int getStatus();
65 bool isFinished();
66
67 RCommitLog* getLog();
68 };
69
70 #endif
3535 for(std::vector<std::string>::iterator fit = files.begin(); fit != files.end(); fit++) {
3636 std::string file = *fit;
3737
38 if( file.rfind(".conf") == file.size()-5
39 || file.rfind(".cfg") == file.size()-4
40 || file.rfind(".ini") == file.size()-4) {
38 int file_length = file.size();
39
40 if( file.rfind(".conf") == (file_length-5) && file_length > 5
41 || file.rfind(".cfg") == (file_length-4) && file_length > 4
42 || file.rfind(".ini") == (file_length-4) && file_length > 4) {
4143
4244 bool is_conf=true;
4345
5658 }
5759 }
5860 }
61
62 //set log level
63 logger->setLevel(gGourceSettings.log_level);
5964
6065 //load config
6166 if(!gGourceSettings.load_config.empty()) {
116121 //enable vsync
117122 display.enableVsync(gGourceSettings.vsync);
118123
124 //allow resizing window if we are not recording
125 if(gGourceSettings.resizable && gGourceSettings.output_ppm_filename.empty()) {
126 display.enableResize(true);
127 }
128
119129 try {
120130
121131 display.init("Gource", gGourceSettings.display_width, gGourceSettings.display_height, gGourceSettings.fullscreen);
127137
128138 SDLAppQuit(errormsg);
129139 }
140
141 #ifdef _WIN32
142 SDLAppAttachToConsole();
143 #endif
130144
131145 //init frame exporter
132146 FrameExporter* exporter = 0;
153167 GourceShell* gourcesh = 0;
154168
155169 try {
156 gourcesh = new GourceShell(&conf, exporter);
170 gourcesh = gGourceShell = new GourceShell(&conf, exporter);
157171 gourcesh->run();
158172
159173 } catch(ResourceException& exception) {
170184 } else {
171185 SDLAppQuit(exception.what());
172186 }
173
174187 }
188
189 gGourceShell = 0;
175190
176191 if(gourcesh != 0) delete gourcesh;
177192 if(exporter != 0) delete exporter;
1818
1919 float gGourceShadowStrength = 0.5;
2020
21 Pawn::Pawn(const std::string& name, vec2f pos, int tagid) {
21 Pawn::Pawn(const std::string& name, vec2 pos, int tagid) {
2222 this->name = name;
2323 this->pos = pos;
2424 this->tagid = tagid;
3232
3333 namewidth = 0;
3434
35 this->shadowOffset = vec2f(2.0, 2.0);
35 this->shadowOffset = vec2(2.0, 2.0);
3636 this->elapsed = 0.0;
3737 this->fadetime = 1.0;
3838 this->nametime = 5.0;
3939 this->name_interval = 0.0;
40 this->namecol = vec3f(1.0, 1.0, 1.0);
41
42 this->selectedcol = gGourceSettings.highlight_colour;
40 this->namecol = vec3(1.0, 1.0, 1.0);
4341
4442 this->graphic = 0;
4543 this->graphic_ratio = 1.0;
4947 return size;
5048 }
5149
52 void Pawn::setPos(vec2f pos) {
50 void Pawn::setPos(vec2 pos) {
5351 this->pos = pos;
5452 }
5553
6563
6664 float halfsize_x = size * 0.5f;
6765
68 vec2f halfsize ( halfsize_x, halfsize_x * graphic_ratio );
66 vec2 halfsize ( halfsize_x, halfsize_x * graphic_ratio );
6967
7068 //set bounds
7169 quadItemBounds.set(pos - halfsize, pos + halfsize);
8886 }
8987
9088 this->graphic = graphic;
91 this->dims = vec2f(size, size*graphic_ratio);
89 this->dims = vec2(size, size*graphic_ratio);
9290 }
9391
9492
10199 this->selected = selected;
102100 }
103101
104 const vec3f& Pawn::getNameColour() const {
102 const vec3& Pawn::getNameColour() const {
105103 return namecol;
106104 }
107105
108 void Pawn::calcScreenPos(const vec2f& offset) {
109 screenpos = display.project(vec3f(pos.x+offset.x, pos.y+offset.y, 0.0f));
106 void Pawn::calcScreenPos(const vec2& offset) {
107 screenpos = display.project(vec3(pos.x+offset.x, pos.y+offset.y, 0.0f));
110108 }
111109
112110 bool Pawn::nameVisible() const {
131129 if(isHidden() || !shadow) return;
132130
133131 float halfsize = size * 0.5f;
134 vec2f offsetpos = pos - vec2f(halfsize, halfsize*graphic_ratio) + shadowOffset;
132 vec2 offsetpos = pos - vec2(halfsize, halfsize*graphic_ratio) + shadowOffset;
135133
136134 float alpha = getAlpha();
137135
162160 if(hidden) return;
163161
164162 float halfsize = size * 0.5f;
165 vec2f offsetpos = pos - vec2f(halfsize, halfsize*graphic_ratio);
163 vec2 offsetpos = pos - vec2(halfsize, halfsize*graphic_ratio);
166164
167165 float alpha = getAlpha();
168166
169 vec3f col = getColour();
167 vec3 col = getColour();
170168
171169 glBindTexture(GL_TEXTURE_2D, graphic->textureid);
172170
2828
2929 class Pawn : public QuadItem {
3030 protected:
31 vec2f pos;
32 vec2f shadowOffset;
31 vec2 pos;
32 vec2 shadowOffset;
3333
3434 std::string name;
3535 float namewidth;
36 vec2f accel;
36 vec2 accel;
3737 float speed;
3838
3939 float elapsed;
4141
4242 float nametime;
4343 float name_interval;
44 vec3f namecol;
45 vec3f selectedcol;
44 vec3 namecol;
4645
4746 bool shadow;
4847
5756 virtual bool nameVisible() const;
5857
5958 virtual void drawNameText(float alpha) {};
60 virtual const vec3f& getNameColour() const;
59 virtual const vec3& getNameColour() const;
6160 protected:
6261 bool selected;
6362 public:
6463 float size;
6564 float graphic_ratio;
6665 TextureResource* graphic;
67 vec3f screenpos;
68 vec2f dims;
66 vec3 screenpos;
67 vec2 dims;
6968
70 Pawn(const std::string& name, vec2f pos, int tagid);
71 const vec2f & getPos() const { return pos; }
72 void setPos(vec2f pos);
69 Pawn(const std::string& name, vec2 pos, int tagid);
70 const vec2 & getPos() const { return pos; }
71 void setPos(vec2 pos);
7372
74 void calcScreenPos(const vec2f& offset);
73 void calcScreenPos(const vec2& offset);
7574
7675 void updateQuadItemBounds();
7776
9190 bool isHidden() const { return hidden; }
9291
9392 virtual float getAlpha() const{ return std::min(elapsed/fadetime, 1.0f); }
94 virtual vec3f getColour() const { return vec3f(1.0, 1.0, 1.0); }
93 virtual vec3 getColour() const { return vec3(1.0, 1.0, 1.0); }
9594
9695 void setGraphic(TextureResource* graphic);
9796
2424 font = fontmanager.grab("FreeSans.ttf", 16);
2525 font.dropShadow(true);
2626
27 int gap = display.width / 30;
28
29 bounds.update(vec2f(gap, display.height - gap*2));
30 bounds.update(vec2f(display.width - gap, display.height - gap));
31
32 slidercol = vec3f(1.0, 1.0, 1.0);
27 slidercol = vec3(1.0, 1.0, 1.0);
3328
3429 mouseover = -1.0;
3530
3631 mouseover_elapsed = 1.0;
3732 fade_time = 1.0;
3833 alpha = 0.0;
34
35 resize();
3936 }
4037
41 void PositionSlider::setColour(vec3f col) {
38 void PositionSlider::resize() {
39 int gap = display.width / 30;
40
41 bounds.reset();
42 bounds.update(vec2(gap, display.height - gap*2));
43 bounds.update(vec2(display.width - gap, display.height - gap));
44 }
45
46 void PositionSlider::setColour(vec3 col) {
4247 slidercol = col;
4348 }
4449
4651 mouseover_elapsed = 0.0;
4752 }
4853
49 bool PositionSlider::mouseOver(vec2f pos, float* percent_ptr) {
54 bool PositionSlider::mouseOver(vec2 pos, float* percent_ptr) {
5055 if(bounds.contains(pos)) {
5156
5257 mouseover_elapsed = 0;
6469 return false;
6570 }
6671
67 bool PositionSlider::click(vec2f pos, float* percent_ptr) {
72 bool PositionSlider::click(vec2 pos, float* percent_ptr) {
6873 if(mouseOver(pos, &percent)) {
6974
7075 if(percent_ptr != 0) {
3232 float fade_time;
3333 float alpha;
3434
35 vec3f slidercol;
35 vec3 slidercol;
3636
3737 float capwidth;
3838 std::string caption;
3939 public:
4040 PositionSlider(float percent = 0.0f);
4141
42 void setColour(vec3f col);
42 void setColour(vec3 col);
4343
4444 void setCaption(const std::string& cap);
4545
4646 void setPercent(float percent);
4747
48 void resize();
49
4850 void show();
4951
50 bool mouseOver(vec2f pos, float* percent_ptr);
51 bool click(vec2f pos, float* percent_ptr);
52 bool mouseOver(vec2 pos, float* percent_ptr);
53 bool click(vec2 pos, float* percent_ptr);
5254 void logic(float dt);
5355 void draw(float dt);
5456 };
1919 SplineEdge::SplineEdge() {
2020 }
2121
22 void SplineEdge::update(const vec2f& pos1, const vec4f& col1, const vec2f& pos2, const vec4f& col2, const vec2f& spos) {
22 void SplineEdge::update(const vec2& pos1, const vec4& col1, const vec2& pos2, const vec4& col2, const vec2& spos) {
2323
24 vec2f pt_last;
25 vec4f col_last;
24 vec2 pt_last;
25 vec4 col_last;
2626
27 vec2f mid = (pos1 - pos2) * 0.5;
28 vec2f to = vec2f(pos1 - spos);
27 vec2 mid = (pos1 - pos2) * 0.5f;
28 vec2 to = vec2(pos1 - spos);
2929
30 float dp = std::min(1.0f, to.normal().dot(mid.normal()));
30 //TODO: not sure this makes any sense
31 //float dp = std::min(1.0f, to.normal().dot(mid.normal()));
32 float dp = std::min(1.0f, glm::dot(normalise(to), normalise(mid)) );
3133
3234 float ang = acos(dp) / PI;
3335
4648 float t = (float)i/edge_detail;
4749 float tt = 1.0f-t;
4850
49 vec2f p0 = pos1 * t + spos * tt;
50 vec2f p1 = spos * t + pos2 * tt;
51 vec2 p0 = pos1 * t + spos * tt;
52 vec2 p1 = spos * t + pos2 * tt;
5153
52 vec2f pt = p0 * t + p1 * tt;
54 vec2 pt = p0 * t + p1 * tt;
5355
54 vec4f coln = col1 * t + col2 * tt;
56 vec4 coln = col1 * t + col2 * tt;
5557
5658 spline_point.push_back(pt);
5759 spline_colour.push_back(coln);
5860 }
5961
60 midpoint = pos1 * 0.25 + pos2 * 0.25 + spos * 0.5;
62 midpoint = pos1 * 0.25f + pos2 * 0.25f + spos * 0.5f;
6163 }
6264
63 const vec2f& SplineEdge::getMidPoint() const {
65 const vec2& SplineEdge::getMidPoint() const {
6466 return midpoint;
6567 }
6668
7072
7173 for(int i=0; i < edges_count; i++) {
7274
73 vec2f perp = (spline_point[i] - spline_point[i+1]).perpendicular().normal() * 2.5f;
75 //vec2 perp = (spline_point[i] - spline_point[i+1]).perpendicular().normal() * 2.5f;
7476
75 quadbuf_vertex v1(spline_point[i] + perp, spline_colour[i], vec2f(1.0f, 0.0f));
76 quadbuf_vertex v2(spline_point[i] - perp, spline_colour[i], vec2f(0.0f, 0.0f));
77 quadbuf_vertex v3(spline_point[i+1] - perp, spline_colour[i+1], vec2f(0.0f, 0.0f));
78 quadbuf_vertex v4(spline_point[i+1] + perp, spline_colour[i+1], vec2f(1.0f, 0.0f));
77 vec2 perp = (spline_point[i] - spline_point[i+1]);
78 perp = normalise(vec2(-perp.y, perp.x)) * 2.5f;
79
80 quadbuf_vertex v1(spline_point[i] + perp, spline_colour[i], vec2(1.0f, 0.0f));
81 quadbuf_vertex v2(spline_point[i] - perp, spline_colour[i], vec2(0.0f, 0.0f));
82 quadbuf_vertex v3(spline_point[i+1] - perp, spline_colour[i+1], vec2(0.0f, 0.0f));
83 quadbuf_vertex v4(spline_point[i+1] + perp, spline_colour[i+1], vec2(1.0f, 0.0f));
7984
8085 buffer.add(0, v1, v2, v3, v4);
8186 }
8287 }
8388
84 void SplineEdge::drawBeam(const vec2f & pos1, const vec4f & col1, const vec2f & pos2, const vec4f & col2, float radius, bool first) const{
89 void SplineEdge::drawBeam(const vec2 & pos1, const vec4 & col1, const vec2 & pos2, const vec4 & col2, float radius, bool first) const{
8590
86 vec2f perp = (pos1 - pos2).perpendicular().normal() * radius;
91 //vec2 perp = (pos1 - pos2).perpendicular().normal() * radius;
8792
93 vec2 perp = (pos1 - pos2);
94 perp = normalise(vec2(-perp.y, perp.x)) * radius;
95
96
8897 // src point
8998 if(first) {
90 glColor4fv(col1);
99 glColor4fv(glm::value_ptr(col1));
91100 glTexCoord2f(1.0,0.0);
92101 glVertex2f(pos1.x + perp.x, pos1.y + perp.y);
93102 glTexCoord2f(0.0,0.0);
95104 }
96105
97106 // dest point
98 glColor4fv(col2);
107 glColor4fv(glm::value_ptr(col2));
99108 glTexCoord2f(1.0,0.0);
100109 glVertex2f(pos2.x + perp.x, pos2.y + perp.y);
101110 glTexCoord2f(0.0,0.0);
106115
107116 int edges_count = spline_point.size() - 1;
108117
109 vec2f offset(2.0, 2.0);
118 vec2 offset(2.0, 2.0);
110119
111120 glBegin(GL_QUAD_STRIP);
112121
113122 for(int i=0;i<edges_count;i++) {
114 drawBeam(spline_point[i] + offset, vec4f(0.0, 0.0, 0.0, gGourceShadowStrength), spline_point[i+1] + offset, vec4f(0.0, 0.0, 0.0, gGourceShadowStrength), 2.5, i==0);
123 drawBeam(spline_point[i] + offset, vec4(0.0, 0.0, 0.0, gGourceShadowStrength), spline_point[i+1] + offset, vec4(0.0, 0.0, 0.0, gGourceShadowStrength), 2.5, i==0);
115124 }
116125
117126 glEnd();
2727
2828 class SplineEdge {
2929
30 std::vector<vec2f> spline_point;
31 std::vector<vec4f> spline_colour;
30 std::vector<vec2> spline_point;
31 std::vector<vec4> spline_colour;
3232
33 vec2f midpoint;
33 vec2 midpoint;
3434
35 void drawBeam(const vec2f & pos1, const vec4f & col1, const vec2f & pos2, const vec4f & col2, float radius, bool first) const;
35 void drawBeam(const vec2 & pos1, const vec4 & col1, const vec2 & pos2, const vec4 & col2, float radius, bool first) const;
3636 public:
3737 SplineEdge();
3838
39 const vec2f& getMidPoint() const;
39 const vec2& getMidPoint() const;
4040
41 void update(const vec2f& pos1, const vec4f& col1, const vec2f& pos2, const vec4f& col2, const vec2f& spos);
41 void update(const vec2& pos1, const vec4& col1, const vec2& pos2, const vec4& col2, const vec2& spos);
4242
4343 void drawToVBO(quadbuf& buffer) const;
4444
+0
-277
src/svn.cpp less more
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "svn.h"
18
19 Regex svn_xml_tag("^<\\??xml");
20 Regex svn_logentry_start("^<logentry");
21 Regex svn_logentry_end("^</logentry>");
22 Regex svn_logentry_timestamp("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})");
23
24 std::string gGourceSVNLogCommand = "svn log -r 1:HEAD --xml --verbose --quiet";
25
26 SVNCommitLog::SVNCommitLog(const std::string& logfile) : RCommitLog(logfile, '<') {
27
28 log_command = gGourceSVNLogCommand;
29
30 //can generate log from directory
31 if(!logf && is_dir) {
32 logf = generateLog(logfile);
33
34 if(logf) {
35 success = true;
36 seekable = true;
37 }
38 }
39
40 logentry.reserve(1024);
41 }
42
43
44 BaseLog* SVNCommitLog::generateLog(const std::string& dir) {
45 //get working directory
46 char cwd_buff[1024];
47
48 if(getcwd(cwd_buff, 1024) != cwd_buff) {
49 return 0;
50 }
51
52 //does directory have a .svn ?
53 std::string gitdir = dir + std::string("/.svn");
54 struct stat dirinfo;
55 int stat_rc = stat(gitdir.c_str(), &dirinfo);
56 if(stat_rc!=0 || !(dirinfo.st_mode & S_IFDIR)) {
57 return 0;
58 }
59
60 std::string command = getLogCommand();
61
62 //create temp file
63 createTempLog();
64
65 if(temp_file.size()==0) return 0;
66
67 if(chdir(dir.c_str()) != 0) {
68 return 0;
69 }
70
71 char cmd_buff[2048];
72 sprintf(cmd_buff, "%s > %s", command.c_str(), temp_file.c_str());
73
74 int command_rc = system(cmd_buff);
75
76 chdir(cwd_buff);
77
78 if(command_rc != 0) {
79 return 0;
80 }
81
82 BaseLog* seeklog = new SeekLog(temp_file);
83
84 return seeklog;
85 }
86
87 #ifndef HAVE_TIMEGM
88
89 std::string system_tz;
90 bool system_tz_init = false;
91
92 time_t __timegm_hack(struct tm* tm) {
93
94 if(!system_tz_init) {
95 char* current_tz_env = getenv("TZ");
96
97 if(current_tz_env != 0) {
98 system_tz = std::string("TZ=") + current_tz_env;
99 }
100
101 system_tz_init = true;
102 }
103
104 putenv((char*)"TZ=UTC");
105 tzset();
106
107 time_t timestamp = mktime(tm);
108
109 if(!system_tz.empty()) {
110 putenv((char*)system_tz.c_str());
111 } else {
112 #ifdef HAVE_UNSETENV
113 unsetenv("TZ");
114 #else
115 putenv((char*)"TZ=");
116 #endif
117 }
118 tzset();
119
120 return timestamp;
121 }
122 #endif
123
124 bool SVNCommitLog::parseCommit(RCommit& commit) {
125
126 //fprintf(stderr,"parsing svn log\n");
127
128 std::string line;
129
130 if(!getNextLine(line)) return false;
131
132 //start of log entry
133 if(!svn_logentry_start.match(line)) {
134
135 //is this the start of the document
136 if(!svn_xml_tag.match(line)) return false;
137
138 //fprintf(stderr,"found xml tag\n");
139
140 //if so find the first logentry tag
141
142 bool found_logentry = false;
143
144 while(getNextLine(line)) {
145 if(svn_logentry_start.match(line)) {
146 found_logentry = true;
147 break;
148 }
149 }
150
151 if(!found_logentry) return false;
152 }
153
154 //fprintf(stderr,"found logentry\n");
155
156 logentry.clear();
157
158 logentry.append(line);
159 logentry.append("\n");
160
161 //fprintf(stderr,"found opening tag\n");
162
163 bool endfound = false;
164
165 while(getNextLine(line)) {
166 logentry.append(line);
167 logentry.append("\n");
168 if(svn_logentry_end.match(line)) {
169 //fprintf(stderr,"found closing tag\n");
170 endfound=true;
171 break;
172 }
173 }
174
175 //incomplete commit
176 if(!endfound) return false;
177
178 //fprintf(stderr,"read logentry\n");
179
180 TiXmlDocument doc;
181
182 if(!doc.Parse(logentry.c_str())) return false;
183
184 //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
185
186 TiXmlElement* leE = doc.FirstChildElement( "logentry" );
187
188 std::vector<std::string> entries;
189
190 if(!leE) return false;
191
192 //parse date
193 TiXmlElement* dateE = leE->FirstChildElement( "date" );
194
195 if(!dateE) return false;
196
197 std::string timestamp_str(dateE->GetText());
198
199 if(!svn_logentry_timestamp.match(timestamp_str, &entries))
200 return false;
201
202 struct tm time_str;
203
204 time_str.tm_year = atoi(entries[0].c_str()) - 1900;
205 time_str.tm_mon = atoi(entries[1].c_str()) - 1;
206 time_str.tm_mday = atoi(entries[2].c_str());
207 time_str.tm_hour = atoi(entries[3].c_str());
208 time_str.tm_min = atoi(entries[4].c_str());
209 time_str.tm_sec = atoi(entries[5].c_str());
210 time_str.tm_isdst = -1;
211
212 #ifdef HAVE_TIMEGM
213 commit.timestamp = timegm(&time_str);
214 #else
215 commit.timestamp = __timegm_hack(&time_str);
216 #endif
217
218 //parse author
219 TiXmlElement* authorE = leE->FirstChildElement("author");
220
221 if(authorE != 0) {
222
223 std::string author(authorE->GetText());
224
225 if(author.empty()) author = "Unknown";
226
227 commit.username = author;
228 }
229
230 TiXmlElement* pathsE = leE->FirstChildElement( "paths" );
231
232 //log entries sometimes dont have any paths
233 if(!pathsE) return true;
234
235 //parse changes
236
237 for(TiXmlElement* pathE = pathsE->FirstChildElement("path"); pathE != 0; pathE = pathE->NextSiblingElement()) {
238 //parse path
239
240 const char* kind = pathE->Attribute("kind");
241 const char* action = pathE->Attribute("action");
242
243 //check for action
244 if(action == 0) continue;
245
246 bool is_dir = false;
247
248 //if has the 'kind' attribute (old versions of svn dont have this), check if it is a dir
249 if(kind != 0 && strcmp(kind,"dir") == 0) {
250
251 //accept only deletes for directories
252 if(strcmp(action, "D") != 0) continue;
253
254 is_dir = true;
255 }
256
257 std::string file(pathE->GetText());
258 std::string status(action);
259
260 if(file.empty()) continue;
261 if(status.empty()) continue;
262
263 //append trailing slash if is directory
264 if(is_dir && file[file.size()-1] != '/') {
265 file = file + std::string("/");
266 }
267
268 commit.addFile(file, status);
269 }
270
271 //fprintf(stderr,"parsed logentry\n");
272
273 //read files
274
275 return true;
276 }
+0
-47
src/svn.h less more
0 /*
1 Copyright (C) 2010 Andrew Caudwell (acaudwell@gmail.com)
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version
6 3 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef SVNLOG_H
18 #define SVNLOG_H
19
20 #include "gource_settings.h"
21
22 #include "commitlog.h"
23
24 #include <sstream>
25
26 #ifdef HAVE_LIBTINYXML
27 #include <tinyxml.h>
28 #else
29 #include "tinyxml/tinyxml.h"
30 #endif
31
32 #include <unistd.h>
33
34 extern std::string gGourceSVNLogCommand;
35
36 class SVNCommitLog : public RCommitLog {
37 protected:
38 bool parseCommit(RCommit& commit);
39 BaseLog* generateLog(const std::string& dir);
40
41 std::string logentry;
42 public:
43 SVNCommitLog(const std::string& logfile);
44 };
45
46 #endif
2222 TextBox::TextBox(const FXFont& font) {
2323 this->font = font;
2424
25 shadow = vec2f(3.0f, 3.0f);
25 shadow = vec2(3.0f, 3.0f);
2626
27 colour = vec3f(0.7f, 0.7f, 0.7f);
28 corner = vec2f(0.0f,0.0f);
27 colour = vec3(0.7f, 0.7f, 0.7f);
28 corner = vec2(0.0f,0.0f);
2929 alpha = 1.0f;
3030 brightness = 1.0f;
3131 max_width_chars = 1024;
4646 this->brightness = brightness;
4747 }
4848
49 void TextBox::setColour(const vec3f& colour) {
49 void TextBox::setColour(const vec3& colour) {
5050 this->colour = colour;
5151 }
5252
9191 }
9292 }
9393
94 void TextBox::setPos(const vec2f& pos, bool adjust) {
94 void TextBox::setPos(const vec2& pos, bool adjust) {
9595
9696 corner = pos;
9797
2727
2828 std::vector<std::string> content;
2929
30 vec3f colour;
30 vec3 colour;
3131 float alpha;
3232 float brightness;
33 vec2f corner;
34 vec2f shadow;
33 vec2 corner;
34 vec2 shadow;
3535 FXFont font;
3636 int max_width_chars;
3737 int rect_width;
4747
4848 void clear();
4949
50 void setPos(const vec2f& pos, bool adjust = false);
51 void setColour(const vec3f& colour);
50 void setPos(const vec2& pos, bool adjust = false);
51 void setColour(const vec3& colour);
5252 void setAlpha(float alpha);
5353 void setBrightness(float brightness);
5454
2020 float gGourceActionDist = 50.0;
2121 float gGourcePersonalSpaceDist = 100.0;
2222
23 RUser::RUser(const std::string& name, vec2f pos, int tagid) : Pawn(name,pos,tagid) {
23 RUser::RUser(const std::string& name, vec2 pos, int tagid) : Pawn(name,pos,tagid) {
2424
2525 this->name = name;
2626
2727 speed = gGourceSettings.max_user_speed;
2828 size = 20.0 * gGourceSettings.user_scale;
2929
30 shadowOffset = vec2f(2.0, 2.0) * gGourceSettings.user_scale;
30 shadowOffset = vec2(2.0, 2.0) * gGourceSettings.user_scale;
3131
3232 shadow = true;
3333
8888
8989 if(u==this) return;
9090
91 vec2f u_pos = u->getPos();
92
93 vec2f dir = u_pos - pos;
94
95 float dist = dir.length();
91 vec2 u_pos = u->getPos();
92
93 vec2 dir = u_pos - pos;
94
95 float dist = glm::length(dir);
9696
9797 //different repelling force depending on how busy the user is
9898 float desired_dist = getActionCount() == 0 ?
102102 //resolve overlap
103103 if(dist < 0.001) {
104104
105 accel += 1.0f * vec2f( (rand() % 100) - 50, (rand() % 100) - 50).normal();
105 accel += 1.0f * normalise(vec2( (rand() % 100) - 50, (rand() % 100) - 50));
106106
107107 return;
108108 }
109109
110110 //repelling force
111111 if(dist < desired_dist) {
112 accel -= (desired_dist-dist) * dir.normal();
112 accel -= (desired_dist-dist) * normalise(dir);
113113 }
114114 }
115115
116116 void RUser::applyForceAction(RAction* action) {
117117 RFile* f = action->target;
118118
119 vec2f f_pos = f->getAbsolutePos();
120 vec2f dir = f_pos - pos;
121 float dist = dir.length();
119 vec2 f_pos = f->getAbsolutePos();
120 vec2 dir = f_pos - pos;
121 float dist = glm::length(dir);
122122
123123 float desired_dist = gGourceActionDist;
124124
125125 //resolve overlap
126126 if(dist < 0.001) {
127 accel += vec2f( (rand() % 100) - 50, (rand() % 100) - 50).normal();
127 accel += normalise(vec2( (rand() % 100) - 50, (rand() % 100) - 50));
128128 return;
129129 }
130130
131131 //repelling force
132132 if(dist < desired_dist) {
133 accel -= (desired_dist - dist) * dir.normal();
133 accel -= (desired_dist - dist) * normalise(dir);
134134 return;
135135 }
136136
137137 if(dist > gGourceBeamDist) {
138 accel += (dist-gGourceBeamDist) * dir.normal();
138 accel += (dist-gGourceBeamDist) * normalise(dir);
139139 }
140140 }
141141
197197 if(findimage != gGourceSettings.user_image_map.end()) {
198198 std::string imagefile = findimage->second;
199199
200 if(!gGourceSettings.colour_user_images) usercol = vec3f(1.0, 1.0, 1.0);
201
202 graphic = texturemanager.grabFile(imagefile);
203 }
204 }
200 if(!gGourceSettings.colour_user_images) usercol = vec3(1.0, 1.0, 1.0);
201
202 graphic = texturemanager.grabFile(imagefile, true, GL_CLAMP_TO_EDGE);
203 }
204 }
205
206
207 //TODO: trilinear probably should be an attribute of the texture
208 // perhaps the mipmap option should be an enum: eg TEX_MIPMAP_TRILINEAR
205209
206210 //nope
207211 if(!graphic) {
208212 if(gGourceSettings.default_user_image.size() > 0) {
209 if(!gGourceSettings.colour_user_images) usercol = vec3f(1.0, 1.0, 1.0);
210 graphic = texturemanager.grabFile(gGourceSettings.default_user_image);
213 if(!gGourceSettings.colour_user_images) usercol = vec3(1.0, 1.0, 1.0);
214 graphic = texturemanager.grabFile(gGourceSettings.default_user_image, true, GL_CLAMP_TO_EDGE);
211215 } else {
212 graphic = texturemanager.grab("no_photo.png");
216 graphic = texturemanager.grab("user.png", true, GL_CLAMP_TO_EDGE);
213217 }
214218 }
215219
216220 setGraphic(graphic);
217221
218 usercol = usercol * 0.6 + vec3f(1.0, 1.0, 1.0) * 0.4;
219 usercol *= 0.9;
222 usercol = usercol * 0.6f + vec3(1.0f) * 0.4f;
223 usercol *= 0.9f;
220224 }
221225
222226 int RUser::getActionCount() {
254258
255259 if(!find_nearby_action) break;
256260
257 float action_dist = (action->target->getAbsolutePos() - pos).length();
261 float action_dist = glm::length(action->target->getAbsolutePos() - pos);
258262
259263 //queue first action in range
260264 if(action_dist < gGourceBeamDist) {
291295 it++;
292296 }
293297
294 if(accel.length2() > speed * speed) {
295 accel = accel.normal() * speed;
298 if(glm::length2(accel) > speed * speed) {
299 accel = normalise(accel) * speed;
296300 }
297301
298302 pos += accel * dt;
299303
300304 accel = accel * std::max(0.0f, (1.0f - gGourceSettings.user_friction*dt));
301
302 //ensure characters dont crawl
303 // float accel_amount = accel.length();
304 // if(!actions.empty() && accel_amount > 0.0 && accel_amount < min_units_ps) {
305 // accel = accel.normal() * min_units_ps;
306 // }
307
308 // move(dt);
309305 }
310306
311307 void RUser::updateFont() {
333329 updateFont();
334330 }
335331
336 const vec3f& RUser::getNameColour() const {
337 return (selected||highlighted) ? selectedcol : namecol;
338 }
339
340 vec3f RUser::getColour() const{
341 if(selected) return vec3f(1.0, 1.0, 1.0);
332 const vec3& RUser::getNameColour() const {
333 return selected ? gGourceSettings.selection_colour : highlighted ? gGourceSettings.highlight_colour : namecol;
334 }
335
336 vec3 RUser::getColour() const{
337 if(selected) return vec3(1.0, 1.0, 1.0);
342338
343339 return usercol;
344340 }
377373
378374 static GLdouble screen_x, screen_y, screen_z;
379375
380 vec2f text_pos = pos;
376 vec2 text_pos = pos;
381377 text_pos.y -= dims.y * 0.5f;
382378
383379 gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z);
392388 float user_alpha = getAlpha();
393389
394390 if(gGourceSettings.highlight_all_users || highlighted || selected || alpha>0.0) {
395 vec3f name_col = getNameColour();
391 vec3 name_col = getNameColour();
396392 float name_alpha = (selected||highlighted||gGourceSettings.highlight_all_users) ? user_alpha : alpha;
397393
398 font.setColour(vec4f(name_col.x, name_col.y, name_col.z, name_alpha));
394 font.setColour(vec4(name_col.x, name_col.y, name_col.z, name_alpha));
399395 font.draw(screenpos.x, screenpos.y, name);
400396 }
401397 }
4747 float min_units_ps;
4848
4949 std::string name;
50 vec3f usercol;
50 vec3 usercol;
5151
5252 bool highlighted;
5353
5454 bool nameVisible() const;
5555
5656 void updateFont();
57 const vec3f& getNameColour() const;
57 const vec3& getNameColour() const;
5858 void drawNameText(float alpha);
5959 public:
60 RUser(const std::string& name, vec2f pos, int tagid);
60 RUser(const std::string& name, vec2 pos, int tagid);
6161
62 vec3f getColour() const;
62 vec3 getColour() const;
6363 void colourize();
6464
6565 const std::string& getName() const;
1919 ZoomCamera::ZoomCamera() {
2020 }
2121
22 ZoomCamera::ZoomCamera(vec3f start, vec3f target, float min_distance, float max_distance) : Camera(start,target) {
23 dest = start;
24 up = vec3f(0.0f, -1.0f, 0.0f);
22 ZoomCamera::ZoomCamera(vec3 pos, vec3 target, float min_distance, float max_distance) :
23 pos(pos), _pos(pos), target(target), _target(target), dest(pos), fov(90.0f) {
24
25 znear = 0.1;
26
27 up = vec3(0.0f, -1.0f, 0.0f);
2528
2629 setMinDistance(min_distance);
2730 setMaxDistance(max_distance);
3437 }
3538
3639 void ZoomCamera::reset() {
37 Camera::reset();
40 pos = _pos;
41 target = _target;
3842 }
3943
4044 float ZoomCamera::getMaxDistance() { return max_distance; }
6266 this->lockon = lockon;
6367 }
6468
69 void ZoomCamera::look() {
70 lookAt(target);
71 }
72
73 void ZoomCamera::lookAt(const vec3& target) {
74 gluLookAt( pos.x, pos.y, pos.z,
75 target.x, target.y, target.z,
76 up.x, up.y, up.z);
77 }
78
79 void ZoomCamera::focus() {
80 display.mode3D(fov, znear, zfar);
81 look();
82 }
83
6584 void ZoomCamera::stop() {
6685 this->dest = pos;
6786 }
7796
7897 //center camera on bounds
7998
80 vec2f centre = bounds.centre();
99 vec2 centre = bounds.centre();
81100
82101 //adjust by screen ratio
83102 dest.x = centre.x;
89108 float width = bounds.width() * padding;
90109 float height = bounds.height() * padding;
91110
92 float dratio = display.height / (float) display.width;
111 float aspect_ratio = display.width / (float) display.height;
93112
94 if(dratio > 1.0) {
95 height /= dratio;
96 } else {
97 width *= dratio;
98 }
113 if(aspect_ratio < 1.0) {
114 height /= aspect_ratio;
115 } else {
116 width /= aspect_ratio;
117 }
99118
100119 //calc visible width of the opposite wall at a distance of 1 this fov
101 float toa = tan( getFov() * 0.5f * DEGREES_TO_RADIANS ) * 2.0;
120 float toa = tan( fov * 0.5f * DEGREES_TO_RADIANS ) * 2.0;
102121
103122 float distance;
104123
107126
108127 //cropping: vertical, horizontal or none
109128 if(gGourceSettings.crop_vertical) {
110 distance = width / toa ;
111129
130 distance = width / toa;
131
132
112133 } else if (gGourceSettings.crop_horizontal) {
113 distance = height / toa ;
114134
135 distance = height / toa;
136
115137 } else {
116138
117 if(width > height) {
118 distance = width / toa ;
139 if(width >= height) {
140 distance = width / toa;
119141 } else {
120 distance = height / toa ;
142 distance = height / toa;
121143 }
122144 }
123145
134156 dest.z = -distance;
135157 }
136158
159 void ZoomCamera::setPos(const vec3& pos, bool keep_angle) {
160 if(keep_angle) {
161 vec3 dir = target - this->pos;
162 this->pos = pos;
163 this->target = pos + dir;
164 } else {
165 this->pos = pos;
166 }
167 }
168
137169 void ZoomCamera::logic(float dt) {
138 vec3f dp = (dest - pos);
170 vec3 dp = (dest - pos);
139171
140 vec3f dpt = dp * dt * speed;
172 vec3 dpt = dp * dt * speed;
141173
142174 if(lockon) {
143 dpt = dpt * lockon_time + dp * (1.0-lockon_time);
175 dpt = dpt * lockon_time + dp * (1.0f-lockon_time);
144176
145177 if(lockon_time>0.0) {
146178 lockon_time = std::max(0.0f, lockon_time-dt*0.5f);
147179 }
148180 }
149181
150 if(dpt.length2() > dp.length2()) dpt = dp;
182 if(glm::length2(dpt) > glm::length2(dp)) dpt = dp;
151183
152184 pos += dpt;
153185
154 target = vec3f(pos.x, pos.y, 0.0);
186 target = vec3(pos.x, pos.y, 0.0);
155187 }
1717 #ifndef ZOOM_CAMERA_H
1818 #define ZOOM_CAMERA_H
1919
20 #include "core/camera.h"
2120 #include "core/bounds.h"
2221 #include "core/frustum.h"
2322
2423 #include "gource_settings.h"
2524
26 class ZoomCamera : public Camera {
27 vec3f dest;
25 class ZoomCamera {
26 vec3 pos;
27 vec3 dest;
28 vec3 target;
29 vec3 up;
30 vec3 _pos;
31 vec3 _target;
32
2833 bool lockon;
2934 float speed;
3035 float lockon_time;
3136
3237 float padding;
38
3339 float min_distance, max_distance;
40
41 float fov;
42 float znear, zfar;
3443 public:
3544 ZoomCamera();
36 ZoomCamera(vec3f start, vec3f target, float min_distance, float max_distance);
45 ZoomCamera(vec3 start, vec3 target, float min_distance, float max_distance);
3746
3847 void setSpeed(float speed);
3948
4049 void lockOn(bool lockon);
4150
42 vec3f getDest() { return dest; }
51 void look();
52 void lookAt(const vec3& target);
53 void focus();
54
55 const vec3& getPos() const { return pos; };
56 const vec3& getUp() const { return up; };
57 const vec3& getTarget() const { return target; };
58 const vec3& getDest() const { return dest; };
4359
60 float getFOV() { return fov; };
61 float getZNear() { return znear; };
62 float getZFar() { return zfar; };
63
64 void setPos(const vec3& pos, bool keep_angle = false);
65
4466 float getMinDistance();
4567 float getMaxDistance();
4668