From 2ae68a5c85863c70ea6dc0233b4eeb7eecace5eb Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Sun, 8 Oct 2023 20:21:07 -0700 Subject: [PATCH] Separate from WorldSpawn --- Makefile | 6 - README.md | 93 +- {tools/common => common}/aselib.c | 0 {tools/common => common}/aselib.h | 0 {tools/common => common}/bspfile.c | 0 {tools/common => common}/bspfile.h | 0 {tools/common => common}/cmdlib.c | 0 {tools/common => common}/cmdlib.h | 0 {tools/common => common}/imagelib.c | 0 {tools/common => common}/imagelib.h | 0 {tools/common => common}/inout.c | 0 {tools/common => common}/inout.h | 0 {tools/common => common}/jpeg.c | 0 {tools/common => common}/l3dslib.c | 0 {tools/common => common}/l3dslib.h | 0 {tools/common => common}/matlib.c | 0 {tools/common => common}/matlib.h | 0 {tools/common => common}/md4.c | 0 {tools/common => common}/md4.h | 0 {tools/common => common}/mutex.c | 0 {tools/common => common}/mutex.h | 0 {tools/common => common}/polylib.c | 0 {tools/common => common}/polylib.h | 0 {tools/common => common}/polyset.h | 0 {tools/common => common}/qfiles.h | 0 {tools/common => common}/qthreads.h | 0 {tools/common => common}/scriplib.c | 0 {tools/common => common}/scriplib.h | 0 {tools/common => common}/surfaceflags.h | 0 {tools/common => common}/threads.c | 0 {tools/common => common}/trilib.c | 0 {tools/common => common}/trilib.h | 0 {tools/common => common}/vfs.c | 0 {tools/common => common}/vfs.h | 0 icon.png | Bin 65969 -> 0 bytes libs/Makefile | 36 - libs/_.cpp | 1 - libs/archivelib.h | 224 - libs/bytestreamutils.h | 159 - libs/character.h | 44 - libs/cmdlib.h | 101 - libs/cmdlib/Makefile | 20 - libs/cmdlib/cmdlib.cpp | 138 - libs/container/Makefile | 21 - libs/container/array.cpp | 37 - libs/container/array.h | 170 - libs/container/cache.h | 178 - libs/container/container.h | 330 - libs/container/hashfunc.h | 402 - libs/container/hashtable.cpp | 63 - libs/container/hashtable.h | 410 - libs/container/stack.h | 211 - libs/convert.h | 266 - libs/debugging/Makefile | 20 - libs/debugging/debugging.cpp | 27 - libs/debugging/debugging.h | 129 - libs/dragplanes.h | 228 - libs/eclasslib.h | 306 - libs/entitylib.h | 718 - libs/entityxml.h | 98 - libs/fs_filesystem.h | 160 - libs/fs_path.h | 82 - libs/generic/Makefile | 23 - libs/generic/arrayrange.h | 70 - libs/generic/bitfield.h | 115 - libs/generic/callback.cpp | 255 - libs/generic/callback.h | 349 - libs/generic/constant.cpp | 41 - libs/generic/constant.h | 50 - libs/generic/enumeration.h | 56 - libs/generic/functional.h | 214 - libs/generic/object.cpp | 39 - libs/generic/object.h | 90 - libs/generic/reference.h | 103 - libs/generic/referencecounted.h | 180 - libs/generic/static.cpp | 125 - libs/generic/static.h | 140 - libs/generic/vector.h | 212 - libs/gtkutil/Makefile | 60 - libs/gtkutil/accelerator.cpp | 609 - libs/gtkutil/accelerator.h | 164 - libs/gtkutil/button.cpp | 160 - libs/gtkutil/button.h | 52 - libs/gtkutil/clipboard.cpp | 155 - libs/gtkutil/clipboard.h | 37 - libs/gtkutil/closure.h | 77 - libs/gtkutil/container.h | 32 - libs/gtkutil/cursor.cpp | 131 - libs/gtkutil/cursor.h | 146 - libs/gtkutil/dialog.cpp | 293 - libs/gtkutil/dialog.h | 148 - libs/gtkutil/entry.cpp | 37 - libs/gtkutil/entry.h | 39 - libs/gtkutil/filechooser.cpp | 287 - libs/gtkutil/filechooser.h | 40 - libs/gtkutil/frame.cpp | 35 - libs/gtkutil/frame.h | 29 - libs/gtkutil/glfont.cpp | 362 - libs/gtkutil/glfont.h | 45 - libs/gtkutil/glwidget.cpp | 304 - libs/gtkutil/glwidget.h | 41 - libs/gtkutil/idledraw.h | 70 - libs/gtkutil/image.cpp | 82 - libs/gtkutil/image.h | 40 - libs/gtkutil/menu.cpp | 275 - libs/gtkutil/menu.h | 65 - libs/gtkutil/messagebox.cpp | 195 - libs/gtkutil/messagebox.h | 32 - libs/gtkutil/nonmodal.cpp | 112 - libs/gtkutil/nonmodal.h | 91 - libs/gtkutil/paned.cpp | 97 - libs/gtkutil/paned.h | 29 - libs/gtkutil/pointer.h | 40 - libs/gtkutil/toolbar.cpp | 80 - libs/gtkutil/toolbar.h | 44 - libs/gtkutil/widget.cpp | 86 - libs/gtkutil/widget.h | 117 - libs/gtkutil/window.cpp | 253 - libs/gtkutil/window.h | 105 - libs/gtkutil/xorrectangle.cpp | 50 - libs/gtkutil/xorrectangle.h | 90 - libs/imagelib.h | 134 - libs/instancelib.h | 168 - libs/maplib.h | 238 - libs/math/Makefile | 20 - libs/math/_.cpp | 0 libs/math/aabb.h | 280 - libs/math/curve.h | 252 - libs/math/expression.cpp | 209 - libs/math/expression.h | 552 - libs/math/frustum.h | 607 - libs/math/line.h | 138 - libs/math/matrix.h | 1194 -- libs/math/matrix.h.uncrustify | 0 libs/math/pi.h | 43 - libs/math/plane.h | 136 - libs/math/quaternion.h | 301 - libs/math/vector.h | 709 - libs/md5lib/md5lib.c | 388 - libs/memory/Makefile | 20 - libs/memory/allocator.cpp | 76 - libs/memory/allocator.h | 291 - libs/moduleobservers.h | 59 - libs/modulesystem/Makefile | 20 - libs/modulesystem/moduleregistry.h | 62 - libs/modulesystem/modulesmap.h | 135 - libs/modulesystem/singletonmodule.cpp | 46 - libs/modulesystem/singletonmodule.h | 131 - libs/os/Makefile | 20 - libs/os/_.cpp | 0 libs/os/dir.h | 68 - libs/os/file.h | 139 - libs/os/path.h | 267 - libs/pivot.h | 284 - libs/profile/Makefile | 21 - libs/profile/file.cpp | 376 - libs/profile/file.h | 172 - libs/profile/profile.cpp | 292 - libs/profile/profile.h | 49 - libs/property.h | 173 - libs/render.h | 1209 -- libs/scenelib.h | 972 - libs/script/Makefile | 20 - libs/script/_.cpp | 0 libs/script/scripttokeniser.h | 343 - libs/script/scripttokenwriter.h | 77 - libs/selectionlib.h | 180 - libs/shaderlib.h | 84 - libs/signal/Makefile | 20 - libs/signal/isignal.h | 166 - libs/signal/signal.cpp | 96 - libs/signal/signal.h | 342 - libs/signal/signalfwd.h | 44 - libs/splines/Makefile | 34 - libs/splines/math_angles.cpp | 152 - libs/splines/math_angles.h | 196 - libs/splines/math_matrix.cpp | 134 - libs/splines/math_matrix.h | 215 - libs/splines/math_quaternion.cpp | 79 - libs/splines/math_quaternion.h | 190 - libs/splines/math_vector.cpp | 147 - libs/splines/math_vector.h | 581 - libs/splines/q_parse.cpp | 537 - libs/splines/q_shared.cpp | 1011 - libs/splines/q_shared.h | 803 - libs/splines/splines.cpp | 1449 -- libs/splines/splines.h | 1140 -- libs/splines/util_list.h | 347 - libs/splines/util_str.cpp | 577 - libs/splines/util_str.h | 724 - libs/str.h | 502 - libs/stream/Makefile | 20 - libs/stream/_.cpp | 0 libs/stream/filestream.h | 173 - libs/stream/memstream.h | 74 - libs/stream/stringstream.h | 148 - libs/stream/textfilestream.h | 80 - libs/stream/textstream.h | 475 - libs/string/Makefile | 20 - libs/string/pooledstring.cpp | 25 - libs/string/pooledstring.h | 93 - libs/string/string.h | 548 - libs/string/stringfwd.h | 35 - libs/stringio.h | 374 - libs/texturelib.h | 43 - libs/transformlib.h | 176 - libs/traverselib.h | 362 - libs/typesystem.h | 137 - libs/uilib/Makefile | 22 - libs/uilib/uilib.cpp | 506 - libs/uilib/uilib.h | 649 - libs/undolib.h | 142 - libs/uniquenames.h | 322 - libs/versionlib.h | 84 - libs/xml/Makefile | 23 - libs/xml/ixml.h | 60 - libs/xml/xmlelement.h | 99 - libs/xml/xmlparser.h | 220 - libs/xml/xmltextags.cpp | 592 - libs/xml/xmltextags.h | 104 - libs/xml/xmlwriter.h | 179 - plugins/Makefile | 32 - plugins/archivepak/Makefile | 24 - plugins/archivepak/archive.cpp | 208 - plugins/archivepak/archive.h | 23 - plugins/archivepak/pak.h | 39 - plugins/archivepak/plugin.cpp | 53 - plugins/archivewad/Makefile | 24 - plugins/archivewad/archive.cpp | 211 - plugins/archivewad/archive.h | 23 - plugins/archivewad/plugin.cpp | 53 - plugins/archivewad/wad.h | 76 - plugins/archivezip/Makefile | 26 - plugins/archivezip/archive.cpp | 343 - plugins/archivezip/archive.h | 22 - plugins/archivezip/pkzip.h | 258 - plugins/archivezip/plugin.cpp | 112 - plugins/archivezip/zlibstream.h | 71 - plugins/brushexport/Makefile | 30 - plugins/brushexport/callbacks.cpp | 148 - plugins/brushexport/callbacks.h | 16 - plugins/brushexport/export.cpp | 367 - plugins/brushexport/export.h | 16 - plugins/brushexport/interface.cpp | 219 - plugins/brushexport/plugin.cpp | 142 - plugins/brushexport/plugin.h | 25 - plugins/brushexport/support.cpp | 32 - plugins/brushexport/support.h | 22 - plugins/entity/Makefile | 46 - plugins/entity/angle.h | 98 - plugins/entity/angles.h | 126 - plugins/entity/colour.h | 126 - plugins/entity/curve.h | 452 - plugins/entity/doom3group.cpp | 854 - plugins/entity/doom3group.h | 36 - plugins/entity/eclassmodel.cpp | 543 - plugins/entity/eclassmodel.h | 34 - plugins/entity/entity.cpp | 400 - plugins/entity/entity.h | 48 - plugins/entity/filters.cpp | 71 - plugins/entity/filters.h | 82 - plugins/entity/generic.cpp | 532 - plugins/entity/generic.h | 27 - plugins/entity/group.cpp | 535 - plugins/entity/group.h | 27 - plugins/entity/keyobservers.h | 54 - plugins/entity/light.cpp | 1680 -- plugins/entity/light.h | 36 - plugins/entity/miscmodel.cpp | 513 - plugins/entity/miscmodel.h | 31 - plugins/entity/model.h | 126 - plugins/entity/modelskinkey.h | 115 - plugins/entity/namedentity.h | 111 - plugins/entity/namekeys.h | 156 - plugins/entity/origin.h | 167 - plugins/entity/plugin.cpp | 102 - plugins/entity/prop_dynamic.cpp | 507 - plugins/entity/prop_dynamic.h | 31 - plugins/entity/rotation.h | 192 - plugins/entity/scale.h | 124 - plugins/entity/skincache.cpp | 335 - plugins/entity/skincache.h | 29 - plugins/entity/targetable.cpp | 38 - plugins/entity/targetable.h | 451 - plugins/image/Makefile | 35 - plugins/image/bmp.cpp | 197 - plugins/image/bmp.h | 31 - plugins/image/dds.cpp | 55 - plugins/image/dds.h | 31 - plugins/image/image.cpp | 192 - plugins/image/jpeg.cpp | 403 - plugins/image/jpeg.h | 40 - plugins/image/ktx.cpp | 434 - plugins/image/ktx.h | 31 - plugins/image/pcx.cpp | 211 - plugins/image/pcx.h | 31 - plugins/image/tga.cpp | 433 - plugins/image/tga.h | 31 - plugins/imagehl/Makefile | 29 - plugins/imagehl/hlw.cpp | 153 - plugins/imagehl/hlw.h | 30 - plugins/imagehl/imagehl.cpp | 104 - plugins/imagehl/imagehl.txt | 30 - plugins/imagehl/mip.cpp | 203 - plugins/imagehl/mip.h | 30 - plugins/imagehl/sprite.cpp | 221 - plugins/imagehl/sprite.h | 30 - plugins/iqmmodel/Makefile | 27 - plugins/iqmmodel/iqm.cpp | 313 - plugins/iqmmodel/iqm.h | 31 - plugins/iqmmodel/plugin.cpp | 107 - plugins/iqmmodel/plugin.h | 25 - plugins/mapq3/Makefile | 28 - plugins/mapq3/parse.cpp | 139 - plugins/mapq3/parse.h | 48 - plugins/mapq3/plugin.cpp | 152 - plugins/mapq3/write.cpp | 125 - plugins/mapq3/write.h | 29 - plugins/matsys/Makefile | 27 - plugins/matsys/plugin.cpp | 92 - plugins/matsys/shaders.cpp | 1578 -- plugins/matsys/shaders.h | 43 - plugins/md3model/model.h | 634 - plugins/model/Makefile | 27 - plugins/model/bitmaps/model_reload_entity.bmp | Bin 308 -> 0 bytes plugins/model/bitmaps/picomodel.bmp | Bin 192660 -> 0 bytes plugins/model/model.cpp | 1025 - plugins/model/model.h | 32 - plugins/model/plugin.cpp | 193 - plugins/prtview/AboutDialog.cpp | 98 - plugins/prtview/AboutDialog.h | 25 - plugins/prtview/ConfigDialog.cpp | 481 - plugins/prtview/ConfigDialog.h | 25 - plugins/prtview/LICENSE | 1 - plugins/prtview/LoadPortalFileDialog.cpp | 169 - plugins/prtview/LoadPortalFileDialog.h | 25 - plugins/prtview/Makefile | 30 - plugins/prtview/PrtView.txt | 12 - plugins/prtview/portals.cpp | 639 - plugins/prtview/portals.h | 162 - plugins/prtview/prtview.cpp | 329 - plugins/prtview/prtview.h | 37 - plugins/shaders/Makefile | 27 - plugins/shaders/plugin.cpp | 143 - plugins/shaders/shaders.cpp | 1842 -- plugins/shaders/shaders.h | 55 - plugins/vfspk3/Makefile | 28 - plugins/vfspk3/archive.cpp | 169 - plugins/vfspk3/archive.h | 29 - plugins/vfspk3/vfs.cpp | 971 - plugins/vfspk3/vfs.h | 42 - plugins/vfspk3/vfspk3.cpp | 90 - resources/Makefile | 119 - resources/bitmaps/black.xpm | 16 - resources/bitmaps/brush_flipx.xpm | 45 - resources/bitmaps/brush_flipy.xpm | 48 - resources/bitmaps/brush_flipz.xpm | 42 - resources/bitmaps/brush_rotatex.xpm | 49 - resources/bitmaps/brush_rotatey.xpm | 51 - resources/bitmaps/brush_rotatez.xpm | 45 - resources/bitmaps/cap_bevel.xpm | 95 - resources/bitmaps/cap_curve.xpm | 44 - resources/bitmaps/cap_cylinder.xpm | 102 - resources/bitmaps/cap_endcap.xpm | 105 - resources/bitmaps/cap_ibevel.xpm | 93 - resources/bitmaps/cap_iendcap.xpm | 103 - resources/bitmaps/console.xpm | 61 - resources/bitmaps/copy.xpm | 64 - resources/bitmaps/cut.xpm | 48 - resources/bitmaps/dontselectcurve.xpm | 44 - resources/bitmaps/dontselectmodel.xpm | 44 - resources/bitmaps/ellipsis.xpm | 11 - resources/bitmaps/entities.xpm | 61 - resources/bitmaps/file_new.xpm | 46 - resources/bitmaps/file_open.xpm | 59 - resources/bitmaps/file_save.xpm | 83 - resources/bitmaps/icon.xpm | 271 - resources/bitmaps/lightinspector.xpm | 192 - resources/bitmaps/logo.xpm | 4295 ----- resources/bitmaps/modify_edges.xpm | 45 - resources/bitmaps/modify_faces.xpm | 47 - resources/bitmaps/modify_vertices.xpm | 47 - resources/bitmaps/noFalloff.xpm | 15 - resources/bitmaps/notex.tga | Bin 5036 -> 0 bytes resources/bitmaps/paste.xpm | 77 - resources/bitmaps/patch_bend.xpm | 56 - resources/bitmaps/patch_drilldown.xpm | 36 - resources/bitmaps/patch_insdel.xpm | 51 - resources/bitmaps/patch_showboundingbox.xpm | 67 - resources/bitmaps/patch_weld.xpm | 57 - resources/bitmaps/patch_wireframe.xpm | 46 - resources/bitmaps/popup_selection.xpm | 41 - resources/bitmaps/redo.xpm | 36 - resources/bitmaps/refresh_models.xpm | 91 - resources/bitmaps/scalelockx.xpm | 25 - resources/bitmaps/scalelocky.xpm | 25 - resources/bitmaps/scalelockz.xpm | 25 - resources/bitmaps/select_additive.xpm | 22 - resources/bitmaps/select_autoexpand.xpm | 22 - resources/bitmaps/select_mouseresize.xpm | 40 - resources/bitmaps/select_mouserotate.xpm | 42 - resources/bitmaps/select_mousescale.xpm | 41 - resources/bitmaps/select_mousetranslate.xpm | 31 - resources/bitmaps/selection_csgmerge.xpm | 63 - resources/bitmaps/selection_csgsubtract.xpm | 63 - resources/bitmaps/selection_makehollow.xpm | 58 - resources/bitmaps/selection_makeroom.xpm | 57 - .../bitmaps/selection_selectcompletetall.xpm | 46 - resources/bitmaps/selection_selectinside.xpm | 73 - .../bitmaps/selection_selectpartialtall.xpm | 32 - .../bitmaps/selection_selecttouching.xpm | 65 - resources/bitmaps/shadernotex.tga | Bin 4494 -> 0 bytes resources/bitmaps/show_entities.xpm | 24 - resources/bitmaps/side_brush.png | Bin 6457 -> 0 bytes resources/bitmaps/side_clipper.xpm | 45 - resources/bitmaps/side_cut.png | Bin 8924 -> 0 bytes resources/bitmaps/side_edges.xpm | 45 - resources/bitmaps/side_entities.png | Bin 7431 -> 0 bytes resources/bitmaps/side_entities.xpm | 45 - resources/bitmaps/side_entspec.png | Bin 8838 -> 0 bytes resources/bitmaps/side_faces.xpm | 58 - resources/bitmaps/side_find.xpm | 44 - resources/bitmaps/side_move.png | Bin 7217 -> 0 bytes resources/bitmaps/side_patch.png | Bin 7307 -> 0 bytes resources/bitmaps/side_patch.xpm | 157 - resources/bitmaps/side_patchspec.png | Bin 8332 -> 0 bytes resources/bitmaps/side_resize.png | Bin 1095 -> 0 bytes resources/bitmaps/side_resize.xpm | 43 - resources/bitmaps/side_rotate.png | Bin 7573 -> 0 bytes resources/bitmaps/side_rotate.xpm | 44 - resources/bitmaps/side_scale.png | Bin 7930 -> 0 bytes resources/bitmaps/side_scale.xpm | 44 - resources/bitmaps/side_select.png | Bin 6478 -> 0 bytes resources/bitmaps/side_selectface.png | Bin 1730 -> 0 bytes resources/bitmaps/side_selectwhole.png | Bin 1507 -> 0 bytes resources/bitmaps/side_surface.xpm | 48 - resources/bitmaps/side_surfspec.png | Bin 7631 -> 0 bytes resources/bitmaps/side_tex.png | Bin 7604 -> 0 bytes resources/bitmaps/side_textures.xpm | 148 - resources/bitmaps/side_transform.xpm | 44 - resources/bitmaps/side_vertices.xpm | 52 - resources/bitmaps/splash.xcf | Bin 455574 -> 0 bytes resources/bitmaps/splash.xpm | 15768 ---------------- resources/bitmaps/texture_browser.xpm | 83 - resources/bitmaps/texture_lock.xpm | 37 - resources/bitmaps/textures_popup.xpm | 66 - resources/bitmaps/undo.xpm | 34 - resources/bitmaps/view_cameratoggle.xpm | 66 - resources/bitmaps/view_cameraupdate.xpm | 61 - resources/bitmaps/view_change.xpm | 45 - resources/bitmaps/view_clipper.xpm | 49 - resources/bitmaps/view_cubicclipping.xpm | 39 - resources/bitmaps/view_entity.xpm | 65 - resources/bitmaps/white.xpm | 15 - resources/bitmaps/window1.xpm | 43 - resources/bitmaps/window2.xpm | 42 - resources/bitmaps/window3.xpm | 43 - resources/bitmaps/window4.xpm | 43 - resources/bitmaps/ws_icons.xcf | Bin 109114 -> 0 bytes resources/defaultkeys.ini | 269 - resources/games/goldsrc.game | 28 - resources/games/platform.game | 26 - resources/gl/lighting_DBS_XY_Z_arbfp1.cg | 92 - resources/gl/lighting_DBS_XY_Z_arbvp1.cg | 78 - resources/gl/lighting_DBS_omni_fp.glp | 86 - resources/gl/lighting_DBS_omni_fp.glsl | 73 - resources/gl/lighting_DBS_omni_vp.glp | 410 - resources/gl/lighting_DBS_omni_vp.glsl | 58 - resources/gl/utils.cg | 36 - resources/gl/zfill_arbfp1.cg | 47 - resources/gl/zfill_arbvp1.cg | 49 - resources/gl/zfill_fp.glp | 19 - resources/gl/zfill_fp.glsl | 29 - resources/gl/zfill_vp.glp | 384 - resources/gl/zfill_vp.glsl | 35 - resources/goldsrc.game/default_build_menu.xml | 26 - .../platform.game/default_build_menu.xml | 26 - src/Makefile | 324 +- src/autosave.cpp | 210 - src/autosave.h | 38 - {tools/vmap => src}/brush.c | 0 src/brush.cpp | 394 - src/brush.h | 4075 ---- {tools/vmap => src}/brush_primit.c | 0 src/brush_primit.cpp | 1484 -- src/brush_primit.h | 164 - src/brushmanip.cpp | 1388 -- src/brushmanip.h | 114 - src/brushmodule.cpp | 485 - src/brushmodule.h | 36 - src/brushnode.cpp | 22 - src/brushnode.h | 182 - src/brushtokens.cpp | 22 - src/brushtokens.h | 755 - src/brushxml.cpp | 22 - src/brushxml.h | 435 - {tools/vmap => src}/bsp.c | 0 {tools/vmap => src}/bsp_analyze.c | 0 {tools/vmap => src}/bsp_info.c | 0 {tools/vmap => src}/bsp_scale.c | 0 {tools/vmap => src}/bspfile_abstract.c | 0 {tools/vmap => src}/bspfile_ibsp.c | 0 {tools/vmap => src}/bspfile_rbsp.c | 0 src/build.cpp | 1104 -- src/build.h | 48 - src/camwindow.cpp | 2248 --- src/camwindow.h | 89 - src/commands.cpp | 648 - src/commands.h | 62 - src/console.cpp | 69 - src/console.h | 42 - {tools/vmap => src}/convert_ase.c | 0 {tools/vmap => src}/convert_bsp.c | 0 {tools/vmap => src}/convert_map.c | 0 {tools/vmap => src}/convert_obj.c | 0 src/csg.cpp | 653 - src/csg.h | 54 - {tools/vmap => src}/decals.c | 0 src/dialog.cpp | 717 - src/dialog.h | 196 - src/eclass.cpp | 399 - src/eclass.h | 25 - src/eclass_def.cpp | 378 - src/eclass_def.h | 25 - src/eclass_doom3.cpp | 827 - src/eclass_doom3.h | 25 - src/eclass_fgd.cpp | 697 - src/eclass_fgd.h | 25 - src/eclass_xml.cpp | 598 - src/eclass_xml.h | 25 - src/entity.cpp | 648 - src/entity.h | 47 - src/entityinspector.cpp | 1756 -- src/entityinspector.h | 35 - src/entitylist.cpp | 417 - src/entitylist.h | 37 - src/environment.cpp | 258 - src/environment.h | 34 - src/error.cpp | 136 - src/error.h | 27 - {tools/vmap => src}/exportents.c | 0 {tools/vmap => src}/facebsp.c | 0 src/feedback.cpp | 334 - src/feedback.h | 254 - src/filetypes.cpp | 153 - src/filetypes.h | 31 - src/filters.cpp | 307 - src/filters.h | 29 - src/findtexturedialog.cpp | 284 - src/findtexturedialog.h | 39 - {tools/vmap => src}/fixaas.c | 0 {tools/vmap => src}/fog.c | 0 {tools/vmap => src}/game__null.h | 0 {tools/vmap => src}/game_fte.h | 0 src/glwidget.cpp | 55 - src/glwidget.h | 25 - src/grid.cpp | 302 - src/grid.h | 46 - src/groupdialog.cpp | 233 - src/groupdialog.h | 59 - src/gtkdlgs.cpp | 1022 - src/gtkdlgs.h | 68 - src/gtkmisc.cpp | 163 - src/gtkmisc.h | 71 - {tools/vmap => src}/help.c | 0 src/help.cpp | 57 - src/help.h | 29 - {tools/vmap => src}/image.c | 0 src/image.cpp | 68 - src/image.h | 29 - {tools/vmap => src}/leakfile.c | 0 {tools/vmap => src}/light.c | 0 {tools/vmap => src}/light_bounce.c | 0 {tools/vmap => src}/light_shadows.c | 0 {tools/vmap => src}/light_trace.c | 0 {tools/vmap => src}/light_ydnar.c | 0 {tools/vmap => src}/lightmaps.c | 0 {tools/vmap => src}/lightmaps_ydnar.c | 0 {tools/vmap => src}/main.c | 0 src/main.cpp | 621 - src/main.h | 25 - src/mainframe.cpp | 3388 ---- src/mainframe.h | 317 - {tools/vmap => src}/map.c | 0 src/map.cpp | 2386 --- src/map.h | 191 - {tools/vmap => src}/mesh.c | 0 {tools/vmap => src}/model.c | 0 src/mru.cpp | 248 - src/mru.h | 35 - src/multimon.cpp | 104 - src/multimon.h | 57 - src/nullmodel.cpp | 219 - src/nullmodel.h | 39 - src/parse.cpp | 52 - src/parse.h | 25 - {tools/vmap => src}/patch.c | 0 src/patch.cpp | 2960 --- src/patch.h | 2129 --- src/patchdialog.cpp | 1239 -- src/patchdialog.h | 46 - src/patchmanip.cpp | 1137 -- src/patchmanip.h | 78 - src/patchmodule.cpp | 247 - src/patchmodule.h | 25 - {tools/vmap => src}/path_init.c | 0 src/plugin.cpp | 354 - src/plugin.h | 57 - src/pluginapi.cpp | 91 - src/pluginapi.h | 37 - src/pluginmanager.cpp | 253 - src/pluginmanager.h | 75 - src/pluginmenu.cpp | 181 - src/pluginmenu.h | 33 - src/plugintoolbar.cpp | 148 - src/plugintoolbar.h | 35 - src/points.cpp | 414 - src/points.h | 43 - {tools/vmap => src}/portals.c | 0 src/preferencedictionary.cpp | 22 - src/preferencedictionary.h | 280 - src/preferences.cpp | 1011 - src/preferences.h | 461 - {tools/vmap => src}/prtfile.c | 0 src/qe3.cpp | 354 - src/qe3.h | 67 - src/qgl.cpp | 1515 -- src/qgl.h | 35 - src/referencecache.cpp | 803 - src/referencecache.h | 46 - src/renderer.cpp | 22 - src/renderer.h | 188 - src/renderstate.cpp | 2522 --- src/renderstate.h | 29 - src/resource.h | 18 - src/scenegraph.cpp | 296 - src/scenegraph.h | 25 - src/select.cpp | 1421 -- src/select.h | 116 - src/selection.cpp | 4098 ---- src/selection.h | 55 - src/server.cpp | 282 - src/server.h | 35 - {tools/vmap => src}/shaders.c | 0 src/shaders.cpp | 71 - src/shaders.h | 27 - src/sockets.cpp | 47 - src/sockets.h | 14 - src/stacktrace.cpp | 305 - src/stacktrace.h | 29 - {tools/vmap => src}/surface.c | 0 {tools/vmap => src}/surface_extra.c | 0 {tools/vmap => src}/surface_foliage.c | 0 {tools/vmap => src}/surface_fur.c | 0 {tools/vmap => src}/surface_meta.c | 0 src/surfacedialog.cpp | 2506 --- src/surfacedialog.h | 65 - src/texmanip.cpp | 343 - src/texmanip.h | 42 - src/textureentry.cpp | 72 - src/textureentry.h | 95 - src/textures.cpp | 902 - src/textures.h | 35 - src/texwindow.cpp | 2975 --- src/texwindow.h | 68 - src/timer.cpp | 103 - src/timer.h | 101 - {tools/vmap => src}/tjunction.c | 0 {tools/vmap => src}/tree.c | 0 src/treemodel.cpp | 1488 -- src/treemodel.h | 39 - src/undo.cpp | 624 - src/undo.h | 25 - src/url.cpp | 67 - src/url.h | 27 - src/view.cpp | 58 - src/view.h | 223 - {tools/vmap => src}/vis.c | 0 {tools/vmap => src}/visflow.c | 0 {tools/vmap => src}/vmap.h | 0 src/watchbsp.cpp | 821 - src/watchbsp.h | 45 - src/winding.cpp | 329 - src/winding.h | 329 - src/windowobservers.cpp | 190 - src/windowobservers.h | 60 - src/worldspawn.ico | Bin 5430 -> 0 bytes {tools/vmap => src}/writebsp.c | 0 src/xmlstuff.cpp | 31 - src/xmlstuff.h | 96 - src/xywindow.cpp | 2998 --- src/xywindow.h | 366 - tools/Makefile | 157 - worldspawn.desktop | 8 - 694 files changed, 167 insertions(+), 162291 deletions(-) rename {tools/common => common}/aselib.c (100%) rename {tools/common => common}/aselib.h (100%) rename {tools/common => common}/bspfile.c (100%) rename {tools/common => common}/bspfile.h (100%) rename {tools/common => common}/cmdlib.c (100%) rename {tools/common => common}/cmdlib.h (100%) rename {tools/common => common}/imagelib.c (100%) rename {tools/common => common}/imagelib.h (100%) rename {tools/common => common}/inout.c (100%) rename {tools/common => common}/inout.h (100%) rename {tools/common => common}/jpeg.c (100%) rename {tools/common => common}/l3dslib.c (100%) rename {tools/common => common}/l3dslib.h (100%) rename {tools/common => common}/matlib.c (100%) rename {tools/common => common}/matlib.h (100%) rename {tools/common => common}/md4.c (100%) rename {tools/common => common}/md4.h (100%) rename {tools/common => common}/mutex.c (100%) rename {tools/common => common}/mutex.h (100%) rename {tools/common => common}/polylib.c (100%) rename {tools/common => common}/polylib.h (100%) rename {tools/common => common}/polyset.h (100%) rename {tools/common => common}/qfiles.h (100%) rename {tools/common => common}/qthreads.h (100%) rename {tools/common => common}/scriplib.c (100%) rename {tools/common => common}/scriplib.h (100%) rename {tools/common => common}/surfaceflags.h (100%) rename {tools/common => common}/threads.c (100%) rename {tools/common => common}/trilib.c (100%) rename {tools/common => common}/trilib.h (100%) rename {tools/common => common}/vfs.c (100%) rename {tools/common => common}/vfs.h (100%) delete mode 100644 icon.png delete mode 100644 libs/_.cpp delete mode 100644 libs/archivelib.h delete mode 100644 libs/bytestreamutils.h delete mode 100644 libs/character.h delete mode 100644 libs/cmdlib.h delete mode 100644 libs/cmdlib/Makefile delete mode 100644 libs/cmdlib/cmdlib.cpp delete mode 100644 libs/container/Makefile delete mode 100644 libs/container/array.cpp delete mode 100644 libs/container/array.h delete mode 100644 libs/container/cache.h delete mode 100644 libs/container/container.h delete mode 100644 libs/container/hashfunc.h delete mode 100644 libs/container/hashtable.cpp delete mode 100644 libs/container/hashtable.h delete mode 100644 libs/container/stack.h delete mode 100644 libs/convert.h delete mode 100644 libs/debugging/Makefile delete mode 100644 libs/debugging/debugging.cpp delete mode 100644 libs/debugging/debugging.h delete mode 100644 libs/dragplanes.h delete mode 100644 libs/eclasslib.h delete mode 100644 libs/entitylib.h delete mode 100644 libs/entityxml.h delete mode 100644 libs/fs_filesystem.h delete mode 100644 libs/fs_path.h delete mode 100644 libs/generic/Makefile delete mode 100644 libs/generic/arrayrange.h delete mode 100644 libs/generic/bitfield.h delete mode 100644 libs/generic/callback.cpp delete mode 100644 libs/generic/callback.h delete mode 100644 libs/generic/constant.cpp delete mode 100644 libs/generic/constant.h delete mode 100644 libs/generic/enumeration.h delete mode 100644 libs/generic/functional.h delete mode 100644 libs/generic/object.cpp delete mode 100644 libs/generic/object.h delete mode 100644 libs/generic/reference.h delete mode 100644 libs/generic/referencecounted.h delete mode 100644 libs/generic/static.cpp delete mode 100644 libs/generic/static.h delete mode 100644 libs/generic/vector.h delete mode 100644 libs/gtkutil/Makefile delete mode 100644 libs/gtkutil/accelerator.cpp delete mode 100644 libs/gtkutil/accelerator.h delete mode 100644 libs/gtkutil/button.cpp delete mode 100644 libs/gtkutil/button.h delete mode 100644 libs/gtkutil/clipboard.cpp delete mode 100644 libs/gtkutil/clipboard.h delete mode 100644 libs/gtkutil/closure.h delete mode 100644 libs/gtkutil/container.h delete mode 100644 libs/gtkutil/cursor.cpp delete mode 100644 libs/gtkutil/cursor.h delete mode 100644 libs/gtkutil/dialog.cpp delete mode 100644 libs/gtkutil/dialog.h delete mode 100644 libs/gtkutil/entry.cpp delete mode 100644 libs/gtkutil/entry.h delete mode 100644 libs/gtkutil/filechooser.cpp delete mode 100644 libs/gtkutil/filechooser.h delete mode 100644 libs/gtkutil/frame.cpp delete mode 100644 libs/gtkutil/frame.h delete mode 100644 libs/gtkutil/glfont.cpp delete mode 100644 libs/gtkutil/glfont.h delete mode 100644 libs/gtkutil/glwidget.cpp delete mode 100644 libs/gtkutil/glwidget.h delete mode 100644 libs/gtkutil/idledraw.h delete mode 100644 libs/gtkutil/image.cpp delete mode 100644 libs/gtkutil/image.h delete mode 100644 libs/gtkutil/menu.cpp delete mode 100644 libs/gtkutil/menu.h delete mode 100644 libs/gtkutil/messagebox.cpp delete mode 100644 libs/gtkutil/messagebox.h delete mode 100644 libs/gtkutil/nonmodal.cpp delete mode 100644 libs/gtkutil/nonmodal.h delete mode 100644 libs/gtkutil/paned.cpp delete mode 100644 libs/gtkutil/paned.h delete mode 100644 libs/gtkutil/pointer.h delete mode 100644 libs/gtkutil/toolbar.cpp delete mode 100644 libs/gtkutil/toolbar.h delete mode 100644 libs/gtkutil/widget.cpp delete mode 100644 libs/gtkutil/widget.h delete mode 100644 libs/gtkutil/window.cpp delete mode 100644 libs/gtkutil/window.h delete mode 100644 libs/gtkutil/xorrectangle.cpp delete mode 100644 libs/gtkutil/xorrectangle.h delete mode 100644 libs/imagelib.h delete mode 100644 libs/instancelib.h delete mode 100644 libs/maplib.h delete mode 100644 libs/math/Makefile delete mode 100644 libs/math/_.cpp delete mode 100644 libs/math/aabb.h delete mode 100644 libs/math/curve.h delete mode 100644 libs/math/expression.cpp delete mode 100644 libs/math/expression.h delete mode 100644 libs/math/frustum.h delete mode 100644 libs/math/line.h delete mode 100644 libs/math/matrix.h delete mode 100644 libs/math/matrix.h.uncrustify delete mode 100644 libs/math/pi.h delete mode 100644 libs/math/plane.h delete mode 100644 libs/math/quaternion.h delete mode 100644 libs/math/vector.h delete mode 100644 libs/md5lib/md5lib.c delete mode 100644 libs/memory/Makefile delete mode 100644 libs/memory/allocator.cpp delete mode 100644 libs/memory/allocator.h delete mode 100644 libs/moduleobservers.h delete mode 100644 libs/modulesystem/Makefile delete mode 100644 libs/modulesystem/moduleregistry.h delete mode 100644 libs/modulesystem/modulesmap.h delete mode 100644 libs/modulesystem/singletonmodule.cpp delete mode 100644 libs/modulesystem/singletonmodule.h delete mode 100644 libs/os/Makefile delete mode 100644 libs/os/_.cpp delete mode 100644 libs/os/dir.h delete mode 100644 libs/os/file.h delete mode 100644 libs/os/path.h delete mode 100644 libs/pivot.h delete mode 100644 libs/profile/Makefile delete mode 100644 libs/profile/file.cpp delete mode 100644 libs/profile/file.h delete mode 100644 libs/profile/profile.cpp delete mode 100644 libs/profile/profile.h delete mode 100644 libs/property.h delete mode 100644 libs/render.h delete mode 100644 libs/scenelib.h delete mode 100644 libs/script/Makefile delete mode 100644 libs/script/_.cpp delete mode 100644 libs/script/scripttokeniser.h delete mode 100644 libs/script/scripttokenwriter.h delete mode 100644 libs/selectionlib.h delete mode 100644 libs/shaderlib.h delete mode 100644 libs/signal/Makefile delete mode 100644 libs/signal/isignal.h delete mode 100644 libs/signal/signal.cpp delete mode 100644 libs/signal/signal.h delete mode 100644 libs/signal/signalfwd.h delete mode 100644 libs/splines/Makefile delete mode 100644 libs/splines/math_angles.cpp delete mode 100644 libs/splines/math_angles.h delete mode 100644 libs/splines/math_matrix.cpp delete mode 100644 libs/splines/math_matrix.h delete mode 100644 libs/splines/math_quaternion.cpp delete mode 100644 libs/splines/math_quaternion.h delete mode 100644 libs/splines/math_vector.cpp delete mode 100644 libs/splines/math_vector.h delete mode 100644 libs/splines/q_parse.cpp delete mode 100644 libs/splines/q_shared.cpp delete mode 100644 libs/splines/q_shared.h delete mode 100644 libs/splines/splines.cpp delete mode 100644 libs/splines/splines.h delete mode 100644 libs/splines/util_list.h delete mode 100644 libs/splines/util_str.cpp delete mode 100644 libs/splines/util_str.h delete mode 100644 libs/str.h delete mode 100644 libs/stream/Makefile delete mode 100644 libs/stream/_.cpp delete mode 100644 libs/stream/filestream.h delete mode 100644 libs/stream/memstream.h delete mode 100644 libs/stream/stringstream.h delete mode 100644 libs/stream/textfilestream.h delete mode 100644 libs/stream/textstream.h delete mode 100644 libs/string/Makefile delete mode 100644 libs/string/pooledstring.cpp delete mode 100644 libs/string/pooledstring.h delete mode 100644 libs/string/string.h delete mode 100644 libs/string/stringfwd.h delete mode 100644 libs/stringio.h delete mode 100644 libs/texturelib.h delete mode 100644 libs/transformlib.h delete mode 100644 libs/traverselib.h delete mode 100644 libs/typesystem.h delete mode 100644 libs/uilib/Makefile delete mode 100644 libs/uilib/uilib.cpp delete mode 100644 libs/uilib/uilib.h delete mode 100644 libs/undolib.h delete mode 100644 libs/uniquenames.h delete mode 100644 libs/versionlib.h delete mode 100644 libs/xml/Makefile delete mode 100644 libs/xml/ixml.h delete mode 100644 libs/xml/xmlelement.h delete mode 100644 libs/xml/xmlparser.h delete mode 100644 libs/xml/xmltextags.cpp delete mode 100644 libs/xml/xmltextags.h delete mode 100644 libs/xml/xmlwriter.h delete mode 100644 plugins/Makefile delete mode 100644 plugins/archivepak/Makefile delete mode 100644 plugins/archivepak/archive.cpp delete mode 100644 plugins/archivepak/archive.h delete mode 100644 plugins/archivepak/pak.h delete mode 100644 plugins/archivepak/plugin.cpp delete mode 100644 plugins/archivewad/Makefile delete mode 100644 plugins/archivewad/archive.cpp delete mode 100644 plugins/archivewad/archive.h delete mode 100644 plugins/archivewad/plugin.cpp delete mode 100644 plugins/archivewad/wad.h delete mode 100644 plugins/archivezip/Makefile delete mode 100644 plugins/archivezip/archive.cpp delete mode 100644 plugins/archivezip/archive.h delete mode 100644 plugins/archivezip/pkzip.h delete mode 100644 plugins/archivezip/plugin.cpp delete mode 100644 plugins/archivezip/zlibstream.h delete mode 100644 plugins/brushexport/Makefile delete mode 100644 plugins/brushexport/callbacks.cpp delete mode 100644 plugins/brushexport/callbacks.h delete mode 100644 plugins/brushexport/export.cpp delete mode 100644 plugins/brushexport/export.h delete mode 100644 plugins/brushexport/interface.cpp delete mode 100644 plugins/brushexport/plugin.cpp delete mode 100644 plugins/brushexport/plugin.h delete mode 100644 plugins/brushexport/support.cpp delete mode 100644 plugins/brushexport/support.h delete mode 100644 plugins/entity/Makefile delete mode 100644 plugins/entity/angle.h delete mode 100644 plugins/entity/angles.h delete mode 100644 plugins/entity/colour.h delete mode 100644 plugins/entity/curve.h delete mode 100644 plugins/entity/doom3group.cpp delete mode 100644 plugins/entity/doom3group.h delete mode 100644 plugins/entity/eclassmodel.cpp delete mode 100644 plugins/entity/eclassmodel.h delete mode 100644 plugins/entity/entity.cpp delete mode 100644 plugins/entity/entity.h delete mode 100644 plugins/entity/filters.cpp delete mode 100644 plugins/entity/filters.h delete mode 100644 plugins/entity/generic.cpp delete mode 100644 plugins/entity/generic.h delete mode 100644 plugins/entity/group.cpp delete mode 100644 plugins/entity/group.h delete mode 100644 plugins/entity/keyobservers.h delete mode 100644 plugins/entity/light.cpp delete mode 100644 plugins/entity/light.h delete mode 100644 plugins/entity/miscmodel.cpp delete mode 100644 plugins/entity/miscmodel.h delete mode 100644 plugins/entity/model.h delete mode 100644 plugins/entity/modelskinkey.h delete mode 100644 plugins/entity/namedentity.h delete mode 100644 plugins/entity/namekeys.h delete mode 100644 plugins/entity/origin.h delete mode 100644 plugins/entity/plugin.cpp delete mode 100644 plugins/entity/prop_dynamic.cpp delete mode 100644 plugins/entity/prop_dynamic.h delete mode 100644 plugins/entity/rotation.h delete mode 100644 plugins/entity/scale.h delete mode 100644 plugins/entity/skincache.cpp delete mode 100644 plugins/entity/skincache.h delete mode 100644 plugins/entity/targetable.cpp delete mode 100644 plugins/entity/targetable.h delete mode 100644 plugins/image/Makefile delete mode 100644 plugins/image/bmp.cpp delete mode 100644 plugins/image/bmp.h delete mode 100644 plugins/image/dds.cpp delete mode 100644 plugins/image/dds.h delete mode 100644 plugins/image/image.cpp delete mode 100644 plugins/image/jpeg.cpp delete mode 100644 plugins/image/jpeg.h delete mode 100644 plugins/image/ktx.cpp delete mode 100644 plugins/image/ktx.h delete mode 100644 plugins/image/pcx.cpp delete mode 100644 plugins/image/pcx.h delete mode 100644 plugins/image/tga.cpp delete mode 100644 plugins/image/tga.h delete mode 100644 plugins/imagehl/Makefile delete mode 100644 plugins/imagehl/hlw.cpp delete mode 100644 plugins/imagehl/hlw.h delete mode 100644 plugins/imagehl/imagehl.cpp delete mode 100644 plugins/imagehl/imagehl.txt delete mode 100644 plugins/imagehl/mip.cpp delete mode 100644 plugins/imagehl/mip.h delete mode 100644 plugins/imagehl/sprite.cpp delete mode 100644 plugins/imagehl/sprite.h delete mode 100644 plugins/iqmmodel/Makefile delete mode 100644 plugins/iqmmodel/iqm.cpp delete mode 100644 plugins/iqmmodel/iqm.h delete mode 100644 plugins/iqmmodel/plugin.cpp delete mode 100644 plugins/iqmmodel/plugin.h delete mode 100644 plugins/mapq3/Makefile delete mode 100644 plugins/mapq3/parse.cpp delete mode 100644 plugins/mapq3/parse.h delete mode 100644 plugins/mapq3/plugin.cpp delete mode 100644 plugins/mapq3/write.cpp delete mode 100644 plugins/mapq3/write.h delete mode 100644 plugins/matsys/Makefile delete mode 100644 plugins/matsys/plugin.cpp delete mode 100644 plugins/matsys/shaders.cpp delete mode 100644 plugins/matsys/shaders.h delete mode 100644 plugins/md3model/model.h delete mode 100644 plugins/model/Makefile delete mode 100644 plugins/model/bitmaps/model_reload_entity.bmp delete mode 100644 plugins/model/bitmaps/picomodel.bmp delete mode 100644 plugins/model/model.cpp delete mode 100644 plugins/model/model.h delete mode 100644 plugins/model/plugin.cpp delete mode 100644 plugins/prtview/AboutDialog.cpp delete mode 100644 plugins/prtview/AboutDialog.h delete mode 100644 plugins/prtview/ConfigDialog.cpp delete mode 100644 plugins/prtview/ConfigDialog.h delete mode 100644 plugins/prtview/LICENSE delete mode 100644 plugins/prtview/LoadPortalFileDialog.cpp delete mode 100644 plugins/prtview/LoadPortalFileDialog.h delete mode 100644 plugins/prtview/Makefile delete mode 100644 plugins/prtview/PrtView.txt delete mode 100644 plugins/prtview/portals.cpp delete mode 100644 plugins/prtview/portals.h delete mode 100644 plugins/prtview/prtview.cpp delete mode 100644 plugins/prtview/prtview.h delete mode 100644 plugins/shaders/Makefile delete mode 100644 plugins/shaders/plugin.cpp delete mode 100644 plugins/shaders/shaders.cpp delete mode 100644 plugins/shaders/shaders.h delete mode 100644 plugins/vfspk3/Makefile delete mode 100644 plugins/vfspk3/archive.cpp delete mode 100644 plugins/vfspk3/archive.h delete mode 100644 plugins/vfspk3/vfs.cpp delete mode 100644 plugins/vfspk3/vfs.h delete mode 100644 plugins/vfspk3/vfspk3.cpp delete mode 100644 resources/Makefile delete mode 100644 resources/bitmaps/black.xpm delete mode 100644 resources/bitmaps/brush_flipx.xpm delete mode 100644 resources/bitmaps/brush_flipy.xpm delete mode 100644 resources/bitmaps/brush_flipz.xpm delete mode 100644 resources/bitmaps/brush_rotatex.xpm delete mode 100644 resources/bitmaps/brush_rotatey.xpm delete mode 100644 resources/bitmaps/brush_rotatez.xpm delete mode 100644 resources/bitmaps/cap_bevel.xpm delete mode 100644 resources/bitmaps/cap_curve.xpm delete mode 100644 resources/bitmaps/cap_cylinder.xpm delete mode 100644 resources/bitmaps/cap_endcap.xpm delete mode 100644 resources/bitmaps/cap_ibevel.xpm delete mode 100644 resources/bitmaps/cap_iendcap.xpm delete mode 100644 resources/bitmaps/console.xpm delete mode 100644 resources/bitmaps/copy.xpm delete mode 100644 resources/bitmaps/cut.xpm delete mode 100644 resources/bitmaps/dontselectcurve.xpm delete mode 100644 resources/bitmaps/dontselectmodel.xpm delete mode 100644 resources/bitmaps/ellipsis.xpm delete mode 100644 resources/bitmaps/entities.xpm delete mode 100644 resources/bitmaps/file_new.xpm delete mode 100644 resources/bitmaps/file_open.xpm delete mode 100644 resources/bitmaps/file_save.xpm delete mode 100644 resources/bitmaps/icon.xpm delete mode 100644 resources/bitmaps/lightinspector.xpm delete mode 100644 resources/bitmaps/logo.xpm delete mode 100644 resources/bitmaps/modify_edges.xpm delete mode 100644 resources/bitmaps/modify_faces.xpm delete mode 100644 resources/bitmaps/modify_vertices.xpm delete mode 100644 resources/bitmaps/noFalloff.xpm delete mode 100644 resources/bitmaps/notex.tga delete mode 100644 resources/bitmaps/paste.xpm delete mode 100644 resources/bitmaps/patch_bend.xpm delete mode 100644 resources/bitmaps/patch_drilldown.xpm delete mode 100644 resources/bitmaps/patch_insdel.xpm delete mode 100644 resources/bitmaps/patch_showboundingbox.xpm delete mode 100644 resources/bitmaps/patch_weld.xpm delete mode 100644 resources/bitmaps/patch_wireframe.xpm delete mode 100644 resources/bitmaps/popup_selection.xpm delete mode 100644 resources/bitmaps/redo.xpm delete mode 100644 resources/bitmaps/refresh_models.xpm delete mode 100644 resources/bitmaps/scalelockx.xpm delete mode 100644 resources/bitmaps/scalelocky.xpm delete mode 100644 resources/bitmaps/scalelockz.xpm delete mode 100644 resources/bitmaps/select_additive.xpm delete mode 100644 resources/bitmaps/select_autoexpand.xpm delete mode 100644 resources/bitmaps/select_mouseresize.xpm delete mode 100644 resources/bitmaps/select_mouserotate.xpm delete mode 100644 resources/bitmaps/select_mousescale.xpm delete mode 100644 resources/bitmaps/select_mousetranslate.xpm delete mode 100644 resources/bitmaps/selection_csgmerge.xpm delete mode 100644 resources/bitmaps/selection_csgsubtract.xpm delete mode 100644 resources/bitmaps/selection_makehollow.xpm delete mode 100644 resources/bitmaps/selection_makeroom.xpm delete mode 100644 resources/bitmaps/selection_selectcompletetall.xpm delete mode 100644 resources/bitmaps/selection_selectinside.xpm delete mode 100644 resources/bitmaps/selection_selectpartialtall.xpm delete mode 100644 resources/bitmaps/selection_selecttouching.xpm delete mode 100644 resources/bitmaps/shadernotex.tga delete mode 100644 resources/bitmaps/show_entities.xpm delete mode 100644 resources/bitmaps/side_brush.png delete mode 100644 resources/bitmaps/side_clipper.xpm delete mode 100644 resources/bitmaps/side_cut.png delete mode 100644 resources/bitmaps/side_edges.xpm delete mode 100644 resources/bitmaps/side_entities.png delete mode 100644 resources/bitmaps/side_entities.xpm delete mode 100644 resources/bitmaps/side_entspec.png delete mode 100644 resources/bitmaps/side_faces.xpm delete mode 100644 resources/bitmaps/side_find.xpm delete mode 100644 resources/bitmaps/side_move.png delete mode 100644 resources/bitmaps/side_patch.png delete mode 100644 resources/bitmaps/side_patch.xpm delete mode 100644 resources/bitmaps/side_patchspec.png delete mode 100644 resources/bitmaps/side_resize.png delete mode 100644 resources/bitmaps/side_resize.xpm delete mode 100644 resources/bitmaps/side_rotate.png delete mode 100644 resources/bitmaps/side_rotate.xpm delete mode 100644 resources/bitmaps/side_scale.png delete mode 100644 resources/bitmaps/side_scale.xpm delete mode 100644 resources/bitmaps/side_select.png delete mode 100644 resources/bitmaps/side_selectface.png delete mode 100644 resources/bitmaps/side_selectwhole.png delete mode 100644 resources/bitmaps/side_surface.xpm delete mode 100644 resources/bitmaps/side_surfspec.png delete mode 100644 resources/bitmaps/side_tex.png delete mode 100644 resources/bitmaps/side_textures.xpm delete mode 100644 resources/bitmaps/side_transform.xpm delete mode 100644 resources/bitmaps/side_vertices.xpm delete mode 100644 resources/bitmaps/splash.xcf delete mode 100644 resources/bitmaps/splash.xpm delete mode 100644 resources/bitmaps/texture_browser.xpm delete mode 100644 resources/bitmaps/texture_lock.xpm delete mode 100644 resources/bitmaps/textures_popup.xpm delete mode 100644 resources/bitmaps/undo.xpm delete mode 100644 resources/bitmaps/view_cameratoggle.xpm delete mode 100644 resources/bitmaps/view_cameraupdate.xpm delete mode 100644 resources/bitmaps/view_change.xpm delete mode 100644 resources/bitmaps/view_clipper.xpm delete mode 100644 resources/bitmaps/view_cubicclipping.xpm delete mode 100644 resources/bitmaps/view_entity.xpm delete mode 100644 resources/bitmaps/white.xpm delete mode 100644 resources/bitmaps/window1.xpm delete mode 100644 resources/bitmaps/window2.xpm delete mode 100644 resources/bitmaps/window3.xpm delete mode 100644 resources/bitmaps/window4.xpm delete mode 100644 resources/bitmaps/ws_icons.xcf delete mode 100644 resources/defaultkeys.ini delete mode 100644 resources/games/goldsrc.game delete mode 100644 resources/games/platform.game delete mode 100644 resources/gl/lighting_DBS_XY_Z_arbfp1.cg delete mode 100644 resources/gl/lighting_DBS_XY_Z_arbvp1.cg delete mode 100644 resources/gl/lighting_DBS_omni_fp.glp delete mode 100644 resources/gl/lighting_DBS_omni_fp.glsl delete mode 100644 resources/gl/lighting_DBS_omni_vp.glp delete mode 100644 resources/gl/lighting_DBS_omni_vp.glsl delete mode 100644 resources/gl/utils.cg delete mode 100644 resources/gl/zfill_arbfp1.cg delete mode 100644 resources/gl/zfill_arbvp1.cg delete mode 100644 resources/gl/zfill_fp.glp delete mode 100644 resources/gl/zfill_fp.glsl delete mode 100644 resources/gl/zfill_vp.glp delete mode 100644 resources/gl/zfill_vp.glsl delete mode 100644 resources/goldsrc.game/default_build_menu.xml delete mode 100644 resources/platform.game/default_build_menu.xml delete mode 100644 src/autosave.cpp delete mode 100644 src/autosave.h rename {tools/vmap => src}/brush.c (100%) delete mode 100644 src/brush.cpp delete mode 100644 src/brush.h rename {tools/vmap => src}/brush_primit.c (100%) delete mode 100644 src/brush_primit.cpp delete mode 100644 src/brush_primit.h delete mode 100644 src/brushmanip.cpp delete mode 100644 src/brushmanip.h delete mode 100644 src/brushmodule.cpp delete mode 100644 src/brushmodule.h delete mode 100644 src/brushnode.cpp delete mode 100644 src/brushnode.h delete mode 100644 src/brushtokens.cpp delete mode 100644 src/brushtokens.h delete mode 100644 src/brushxml.cpp delete mode 100644 src/brushxml.h rename {tools/vmap => src}/bsp.c (100%) rename {tools/vmap => src}/bsp_analyze.c (100%) rename {tools/vmap => src}/bsp_info.c (100%) rename {tools/vmap => src}/bsp_scale.c (100%) rename {tools/vmap => src}/bspfile_abstract.c (100%) rename {tools/vmap => src}/bspfile_ibsp.c (100%) rename {tools/vmap => src}/bspfile_rbsp.c (100%) delete mode 100644 src/build.cpp delete mode 100644 src/build.h delete mode 100644 src/camwindow.cpp delete mode 100644 src/camwindow.h delete mode 100644 src/commands.cpp delete mode 100644 src/commands.h delete mode 100644 src/console.cpp delete mode 100644 src/console.h rename {tools/vmap => src}/convert_ase.c (100%) rename {tools/vmap => src}/convert_bsp.c (100%) rename {tools/vmap => src}/convert_map.c (100%) rename {tools/vmap => src}/convert_obj.c (100%) delete mode 100644 src/csg.cpp delete mode 100644 src/csg.h rename {tools/vmap => src}/decals.c (100%) delete mode 100644 src/dialog.cpp delete mode 100644 src/dialog.h delete mode 100644 src/eclass.cpp delete mode 100644 src/eclass.h delete mode 100644 src/eclass_def.cpp delete mode 100644 src/eclass_def.h delete mode 100644 src/eclass_doom3.cpp delete mode 100644 src/eclass_doom3.h delete mode 100644 src/eclass_fgd.cpp delete mode 100644 src/eclass_fgd.h delete mode 100644 src/eclass_xml.cpp delete mode 100644 src/eclass_xml.h delete mode 100644 src/entity.cpp delete mode 100644 src/entity.h delete mode 100644 src/entityinspector.cpp delete mode 100644 src/entityinspector.h delete mode 100644 src/entitylist.cpp delete mode 100644 src/entitylist.h delete mode 100644 src/environment.cpp delete mode 100644 src/environment.h delete mode 100644 src/error.cpp delete mode 100644 src/error.h rename {tools/vmap => src}/exportents.c (100%) rename {tools/vmap => src}/facebsp.c (100%) delete mode 100644 src/feedback.cpp delete mode 100644 src/feedback.h delete mode 100644 src/filetypes.cpp delete mode 100644 src/filetypes.h delete mode 100644 src/filters.cpp delete mode 100644 src/filters.h delete mode 100644 src/findtexturedialog.cpp delete mode 100644 src/findtexturedialog.h rename {tools/vmap => src}/fixaas.c (100%) rename {tools/vmap => src}/fog.c (100%) rename {tools/vmap => src}/game__null.h (100%) rename {tools/vmap => src}/game_fte.h (100%) delete mode 100644 src/glwidget.cpp delete mode 100644 src/glwidget.h delete mode 100644 src/grid.cpp delete mode 100644 src/grid.h delete mode 100644 src/groupdialog.cpp delete mode 100644 src/groupdialog.h delete mode 100644 src/gtkdlgs.cpp delete mode 100644 src/gtkdlgs.h delete mode 100644 src/gtkmisc.cpp delete mode 100644 src/gtkmisc.h rename {tools/vmap => src}/help.c (100%) delete mode 100644 src/help.cpp delete mode 100644 src/help.h rename {tools/vmap => src}/image.c (100%) delete mode 100644 src/image.cpp delete mode 100644 src/image.h rename {tools/vmap => src}/leakfile.c (100%) rename {tools/vmap => src}/light.c (100%) rename {tools/vmap => src}/light_bounce.c (100%) rename {tools/vmap => src}/light_shadows.c (100%) rename {tools/vmap => src}/light_trace.c (100%) rename {tools/vmap => src}/light_ydnar.c (100%) rename {tools/vmap => src}/lightmaps.c (100%) rename {tools/vmap => src}/lightmaps_ydnar.c (100%) rename {tools/vmap => src}/main.c (100%) delete mode 100644 src/main.cpp delete mode 100644 src/main.h delete mode 100644 src/mainframe.cpp delete mode 100644 src/mainframe.h rename {tools/vmap => src}/map.c (100%) delete mode 100644 src/map.cpp delete mode 100644 src/map.h rename {tools/vmap => src}/mesh.c (100%) rename {tools/vmap => src}/model.c (100%) delete mode 100644 src/mru.cpp delete mode 100644 src/mru.h delete mode 100644 src/multimon.cpp delete mode 100644 src/multimon.h delete mode 100644 src/nullmodel.cpp delete mode 100644 src/nullmodel.h delete mode 100644 src/parse.cpp delete mode 100644 src/parse.h rename {tools/vmap => src}/patch.c (100%) delete mode 100644 src/patch.cpp delete mode 100644 src/patch.h delete mode 100644 src/patchdialog.cpp delete mode 100644 src/patchdialog.h delete mode 100644 src/patchmanip.cpp delete mode 100644 src/patchmanip.h delete mode 100644 src/patchmodule.cpp delete mode 100644 src/patchmodule.h rename {tools/vmap => src}/path_init.c (100%) delete mode 100644 src/plugin.cpp delete mode 100644 src/plugin.h delete mode 100644 src/pluginapi.cpp delete mode 100644 src/pluginapi.h delete mode 100644 src/pluginmanager.cpp delete mode 100644 src/pluginmanager.h delete mode 100644 src/pluginmenu.cpp delete mode 100644 src/pluginmenu.h delete mode 100644 src/plugintoolbar.cpp delete mode 100644 src/plugintoolbar.h delete mode 100644 src/points.cpp delete mode 100644 src/points.h rename {tools/vmap => src}/portals.c (100%) delete mode 100644 src/preferencedictionary.cpp delete mode 100644 src/preferencedictionary.h delete mode 100644 src/preferences.cpp delete mode 100644 src/preferences.h rename {tools/vmap => src}/prtfile.c (100%) delete mode 100644 src/qe3.cpp delete mode 100644 src/qe3.h delete mode 100644 src/qgl.cpp delete mode 100644 src/qgl.h delete mode 100644 src/referencecache.cpp delete mode 100644 src/referencecache.h delete mode 100644 src/renderer.cpp delete mode 100644 src/renderer.h delete mode 100644 src/renderstate.cpp delete mode 100644 src/renderstate.h delete mode 100644 src/resource.h delete mode 100644 src/scenegraph.cpp delete mode 100644 src/scenegraph.h delete mode 100644 src/select.cpp delete mode 100644 src/select.h delete mode 100644 src/selection.cpp delete mode 100644 src/selection.h delete mode 100644 src/server.cpp delete mode 100644 src/server.h rename {tools/vmap => src}/shaders.c (100%) delete mode 100644 src/shaders.cpp delete mode 100644 src/shaders.h delete mode 100644 src/sockets.cpp delete mode 100644 src/sockets.h delete mode 100644 src/stacktrace.cpp delete mode 100644 src/stacktrace.h rename {tools/vmap => src}/surface.c (100%) rename {tools/vmap => src}/surface_extra.c (100%) rename {tools/vmap => src}/surface_foliage.c (100%) rename {tools/vmap => src}/surface_fur.c (100%) rename {tools/vmap => src}/surface_meta.c (100%) delete mode 100644 src/surfacedialog.cpp delete mode 100644 src/surfacedialog.h delete mode 100644 src/texmanip.cpp delete mode 100644 src/texmanip.h delete mode 100644 src/textureentry.cpp delete mode 100644 src/textureentry.h delete mode 100644 src/textures.cpp delete mode 100644 src/textures.h delete mode 100644 src/texwindow.cpp delete mode 100644 src/texwindow.h delete mode 100644 src/timer.cpp delete mode 100644 src/timer.h rename {tools/vmap => src}/tjunction.c (100%) rename {tools/vmap => src}/tree.c (100%) delete mode 100644 src/treemodel.cpp delete mode 100644 src/treemodel.h delete mode 100644 src/undo.cpp delete mode 100644 src/undo.h delete mode 100644 src/url.cpp delete mode 100644 src/url.h delete mode 100644 src/view.cpp delete mode 100644 src/view.h rename {tools/vmap => src}/vis.c (100%) rename {tools/vmap => src}/visflow.c (100%) rename {tools/vmap => src}/vmap.h (100%) delete mode 100644 src/watchbsp.cpp delete mode 100644 src/watchbsp.h delete mode 100644 src/winding.cpp delete mode 100644 src/winding.h delete mode 100644 src/windowobservers.cpp delete mode 100644 src/windowobservers.h delete mode 100644 src/worldspawn.ico rename {tools/vmap => src}/writebsp.c (100%) delete mode 100644 src/xmlstuff.cpp delete mode 100644 src/xmlstuff.h delete mode 100644 src/xywindow.cpp delete mode 100644 src/xywindow.h delete mode 100644 tools/Makefile delete mode 100755 worldspawn.desktop diff --git a/Makefile b/Makefile index 6e5c33f..a180946 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,7 @@ all: - mkdir -p ./build cd libs && $(MAKE) cd src && $(MAKE) - cd plugins && $(MAKE) - cd tools && $(MAKE) - cd resources && $(MAKE) clean: cd libs && $(MAKE) clean cd src && $(MAKE) clean - cd plugins && $(MAKE) clean - cd tools && $(MAKE) clean diff --git a/README.md b/README.md index 59ea4cf..b876396 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,64 @@ -# ![WorldSpawn Logo](icon.png) WorldSpawn -The worlds most opinionated fork of Radiant. +# vmap -The editor we use at Vera Visions to create BSP levels. -It was forked from NetRadiant in June of 2018 and was a result of necessity. +A fork of q3map2, now available as a stand-alone compiler targetting [FTEQW](https://www.fteqw.org/) -We wanted to move away from a proprietary toolchain that had technical issues the developer would not ever get back to us about, so we ended up here. -Use it if you actually want to use the features listed below - note that they require a modified engine as our BSP format is different from standard idTech 3 BSP. -You will not be able to make levels compatible with other games and engines. - -There's plenty of other editors for the first-party id Tech games. -**Please use those instead if you want to use a level editor with actual support, submission for feature requests, etc. - we are only sharing this because that's the best way of preserving software.** - -**Please respect this notice, thank you.** - -![Screenshot](docs/screen.jpg) - -## Editor Changes -- Valve 220 format is used **top to bottom**, **imported & exported**, with texture coords handled internally the same way, including the compiler -- Integration with our **own material format** (no more giant .shader files) -- Support for vertex-color/alpha editing of patches using our new **fixed patch format**, allowing technologies such as **4-way texture blending** and whatever your designers can imagine -- Gracefully deals with duplicate entity attribute key/value pairs, to support features like Source Engine style **Input/Output system** for triggers -- Support for **VVM** (based on IQM) model format in the BSP compiler as well as the editor -- Support for **internal** and external **High-Dynamic-Range lightmaps** in the BSP compiler -- Support for **cubemap aware surfaces** in the BSP compiler -- Support for our patchDef2WS and patchDef3WS curved surfaces in the BSP compiler -- *More bug-fixes than you could possibly imagine* - -## Why -Back then there was no fork of Radiant supporting the 220 format like said program had exported. -We had to make that happen on our own, since then we've expanded and kept changing more to meet our own needs. -On top of that, there's other benefits from working in our own Radiant fork. - -Rapid experimentation and tech development doesn't fit into an editor like GtkRadiant, -which aims to be stable, reliable and support a specific set of games really, really well. - -We can afford to break compat here in order to achieve our goals. It will break, be unstable -and all that jazz at the cost of supporting the greatest and latest of we're working on. - -Some code in here (like the IQM support in the compiler) has made it into other Radiant forks -when we deem it to be mature. However not everything in here is going to be of interest -to other Radiant forks. - -A lot of the changes are specific to our BSP format & engine too. -So tech like per-surface picked and generated environment maps will never make it into other games. -Sorry! +## Compiler Changes +- Improved High-Dynamic-Range lightmaps +- Support for our patchDef2WS and patchDef3WS curved surfaces in the BSP compiler, allowing for 4-way texture blended patches. +- Reads individual material scripts (.mat) instead of large .shader files +- Surfaces are aware which env_cubemap ents they belong to +- light_surface entity support, so you don't have to write map specific materials to override texture light properties +- Handles Half-Life styled point lights, including zhlt_lightflags +- Handles Half-Life styled light_environment entities +- New material keys: vmap_lightLinear, vmap_lightLinearFade +- Support for target-less spotlights +- Explicit support for func_detail, func_detail_illusionary +- Support for misc_prefab (including other .map files) +- vmap_remapMaterial/q3map_remapShader can carry over surface flags now +- Support for entity key: _entsurfaceflags, so surfaces can override their surfaceflags +- Support for entity key: _entcontentflags, so brushes can override their contentflags ## Compiling To compile on a standard GNU/Linux system: -`LDFLAGS=-ldl make -j $(nproc)` +`make` -On BSD you should probably use GNU make right now. The Makefiles are simple enough however. -Clang should also be supported, pass `CC=clang and CXX=clang++` if you want to use it. +On BSD you should probably use GNU make right now. +Clang should also be supported, pass `CC=clang` if you want to use it. On NT you'll have to jump through a lot more hoops, here's the gist: 1. MSYS2: https://www.msys2.org/ -2. in the msys2 shell, enter `pacman -S --needed base-devel git unzip mingw-w64-$(uname -m)-{toolchain,make,gtk2,gtkglext,minizip-git}` +2. in the msys2 shell, enter `pacman -S --needed base-devel git unzip mingw-w64-$(uname -m)-{toolchain,make,minizip-git}` 3. boot into the Mingw64 shell, don't use the stock MSYS2 shell 4. run make and it should build everything, in theory **Please don't contact us about helping you build it on Windows. This is a development tool. This is provided AS-IS.** -It'll compile everything into a subdirectory 'build'. At the end it'll copy files from ./resources into it too. - -In the Nuclide SDK, build_editor.sh will call make with the appropriate flags for Linux/BSD automatically and -move it into Nuclide's ./bin directory. - ## Dependencies * GNU make * gcc-core * gcc-c++ -* gtk2-devel -* gtkglext-devel +* glib2-devel * libxml2-devel * libjpeg8-devel +* libpng-devel * minizip-devel ## Support **As mentioned before, if you need help with this: you're on your own.** -Please use [GtkRadiant](https://github.com/TTimo/GtkRadiant) if you want to make levels for existing games. +## Special Thanks + +The original q3map/2 developers: +- id Software +- Splash Damage +- ydnar +- GtkRadiant team and contributors +- NetRadiant team and contributors + +vmap developers: +- Vera Visions, L.L.C. +- Spike +- Joshua Ashton +- Slartibarty \ No newline at end of file diff --git a/tools/common/aselib.c b/common/aselib.c similarity index 100% rename from tools/common/aselib.c rename to common/aselib.c diff --git a/tools/common/aselib.h b/common/aselib.h similarity index 100% rename from tools/common/aselib.h rename to common/aselib.h diff --git a/tools/common/bspfile.c b/common/bspfile.c similarity index 100% rename from tools/common/bspfile.c rename to common/bspfile.c diff --git a/tools/common/bspfile.h b/common/bspfile.h similarity index 100% rename from tools/common/bspfile.h rename to common/bspfile.h diff --git a/tools/common/cmdlib.c b/common/cmdlib.c similarity index 100% rename from tools/common/cmdlib.c rename to common/cmdlib.c diff --git a/tools/common/cmdlib.h b/common/cmdlib.h similarity index 100% rename from tools/common/cmdlib.h rename to common/cmdlib.h diff --git a/tools/common/imagelib.c b/common/imagelib.c similarity index 100% rename from tools/common/imagelib.c rename to common/imagelib.c diff --git a/tools/common/imagelib.h b/common/imagelib.h similarity index 100% rename from tools/common/imagelib.h rename to common/imagelib.h diff --git a/tools/common/inout.c b/common/inout.c similarity index 100% rename from tools/common/inout.c rename to common/inout.c diff --git a/tools/common/inout.h b/common/inout.h similarity index 100% rename from tools/common/inout.h rename to common/inout.h diff --git a/tools/common/jpeg.c b/common/jpeg.c similarity index 100% rename from tools/common/jpeg.c rename to common/jpeg.c diff --git a/tools/common/l3dslib.c b/common/l3dslib.c similarity index 100% rename from tools/common/l3dslib.c rename to common/l3dslib.c diff --git a/tools/common/l3dslib.h b/common/l3dslib.h similarity index 100% rename from tools/common/l3dslib.h rename to common/l3dslib.h diff --git a/tools/common/matlib.c b/common/matlib.c similarity index 100% rename from tools/common/matlib.c rename to common/matlib.c diff --git a/tools/common/matlib.h b/common/matlib.h similarity index 100% rename from tools/common/matlib.h rename to common/matlib.h diff --git a/tools/common/md4.c b/common/md4.c similarity index 100% rename from tools/common/md4.c rename to common/md4.c diff --git a/tools/common/md4.h b/common/md4.h similarity index 100% rename from tools/common/md4.h rename to common/md4.h diff --git a/tools/common/mutex.c b/common/mutex.c similarity index 100% rename from tools/common/mutex.c rename to common/mutex.c diff --git a/tools/common/mutex.h b/common/mutex.h similarity index 100% rename from tools/common/mutex.h rename to common/mutex.h diff --git a/tools/common/polylib.c b/common/polylib.c similarity index 100% rename from tools/common/polylib.c rename to common/polylib.c diff --git a/tools/common/polylib.h b/common/polylib.h similarity index 100% rename from tools/common/polylib.h rename to common/polylib.h diff --git a/tools/common/polyset.h b/common/polyset.h similarity index 100% rename from tools/common/polyset.h rename to common/polyset.h diff --git a/tools/common/qfiles.h b/common/qfiles.h similarity index 100% rename from tools/common/qfiles.h rename to common/qfiles.h diff --git a/tools/common/qthreads.h b/common/qthreads.h similarity index 100% rename from tools/common/qthreads.h rename to common/qthreads.h diff --git a/tools/common/scriplib.c b/common/scriplib.c similarity index 100% rename from tools/common/scriplib.c rename to common/scriplib.c diff --git a/tools/common/scriplib.h b/common/scriplib.h similarity index 100% rename from tools/common/scriplib.h rename to common/scriplib.h diff --git a/tools/common/surfaceflags.h b/common/surfaceflags.h similarity index 100% rename from tools/common/surfaceflags.h rename to common/surfaceflags.h diff --git a/tools/common/threads.c b/common/threads.c similarity index 100% rename from tools/common/threads.c rename to common/threads.c diff --git a/tools/common/trilib.c b/common/trilib.c similarity index 100% rename from tools/common/trilib.c rename to common/trilib.c diff --git a/tools/common/trilib.h b/common/trilib.h similarity index 100% rename from tools/common/trilib.h rename to common/trilib.h diff --git a/tools/common/vfs.c b/common/vfs.c similarity index 100% rename from tools/common/vfs.c rename to common/vfs.c diff --git a/tools/common/vfs.h b/common/vfs.h similarity index 100% rename from tools/common/vfs.h rename to common/vfs.h diff --git a/icon.png b/icon.png deleted file mode 100644 index 1a2b03b32a536d0df3b4c493101fba0fa73929ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65969 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 -class SingleByteInputStream -{ -typedef typename InputStreamType::byte_type byte_type; - -InputStreamType& m_inputStream; -byte_type m_buffer[SIZE]; -byte_type* m_cur; -byte_type* m_end; - -public: - -SingleByteInputStream( InputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer + SIZE ), m_end( m_cur ){ -} -bool readByte( byte_type& b ){ - if ( m_cur == m_end ) { - if ( m_end != m_buffer + SIZE ) { - return false; - } - - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - - if ( m_end == m_buffer ) { - return false; - } - } - - b = *m_cur++; - - return true; -} -}; - -/// \brief A binary-to-text wrapper around an InputStream. -/// Converts CRLF or LFCR line-endings to LF line-endings. -template -class BinaryToTextInputStream : public TextInputStream -{ -SingleByteInputStream m_inputStream; -public: -BinaryToTextInputStream( BinaryInputStreamType& inputStream ) : m_inputStream( inputStream ){ -} -std::size_t read( char* buffer, std::size_t length ){ - char* p = buffer; - for (;; ) - { - if ( length != 0 && m_inputStream.readByte( *reinterpret_cast( p ) ) ) { - if ( *p != '\r' ) { - ++p; - --length; - } - } - else - { - return p - buffer; - } - } -} -}; - -/// \brief An ArchiveFile which is stored uncompressed as part of a larger archive file. -class StoredArchiveFile : public ArchiveFile -{ -CopiedString m_name; -FileInputStream m_filestream; -SubFileInputStream m_substream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -StoredArchiveFile( const char* name, const char* archiveName, position_type position, size_type stream_size, size_type file_size ) - : m_name( name ), m_filestream( archiveName ), m_substream( m_filestream, position, stream_size ), m_size( file_size ){ -} - -static StoredArchiveFile* create( const char* name, const char* archiveName, position_type position, size_type stream_size, size_type file_size ){ - return New().scalar( name, archiveName, position, stream_size, file_size ); -} - -void release(){ - Delete().scalar( this ); -} -size_type size() const { - return m_size; -} -const char* getName() const { - return m_name.c_str(); -} -InputStream& getInputStream(){ - return m_substream; -} -}; - -/// \brief An ArchiveTextFile which is stored uncompressed as part of a larger archive file. -class StoredArchiveTextFile : public ArchiveTextFile -{ -CopiedString m_name; -FileInputStream m_filestream; -SubFileInputStream m_substream; -BinaryToTextInputStream m_textStream; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -StoredArchiveTextFile( const char* name, const char* archiveName, position_type position, size_type stream_size ) - : m_name( name ), m_filestream( archiveName ), m_substream( m_filestream, position, stream_size ), m_textStream( m_substream ){ -} - -static StoredArchiveTextFile* create( const char* name, const char* archiveName, position_type position, size_type stream_size ){ - return New().scalar( name, archiveName, position, stream_size ); -} - -void release(){ - Delete().scalar( this ); -} -const char* getName() const { - return m_name.c_str(); -} -TextInputStream& getInputStream(){ - return m_textStream; -} -}; - -/// \brief An ArchiveFile which is stored as a single file on disk. -class DirectoryArchiveFile : public ArchiveFile -{ -CopiedString m_name; -FileInputStream m_istream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; - -DirectoryArchiveFile( const char* name, const char* filename ) - : m_name( name ), m_istream( filename ){ - if ( !failed() ) { - m_istream.seek( 0, FileInputStream::end ); - m_size = m_istream.tell(); - m_istream.seek( 0 ); - } - else - { - m_size = 0; - } -} -bool failed() const { - return m_istream.failed(); -} - -void release(){ - delete this; -} -size_type size() const { - return m_size; -} -const char* getName() const { - return m_name.c_str(); -} -InputStream& getInputStream(){ - return m_istream; -} -}; - -/// \brief An ArchiveTextFile which is stored as a single file on disk. -class DirectoryArchiveTextFile : public ArchiveTextFile -{ -CopiedString m_name; -TextFileInputStream m_inputStream; -public: - -DirectoryArchiveTextFile( const char* name, const char* filename ) - : m_name( name ), m_inputStream( filename ){ -} -bool failed() const { - return m_inputStream.failed(); -} - -void release(){ - delete this; -} -const char* getName() const { - return m_name.c_str(); -} -TextInputStream& getInputStream(){ - return m_inputStream; -} -}; - - -#endif diff --git a/libs/bytestreamutils.h b/libs/bytestreamutils.h deleted file mode 100644 index 8cfd582..0000000 --- a/libs/bytestreamutils.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BYTESTREAMUTILS_H ) -#define INCLUDED_BYTESTREAMUTILS_H - -#include "globaldefs.h" - -#if GDEF_COMPILER_GNU - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#include - -#endif - -#include - -// if C99 is unavailable, fall back to the types most likely to be the right sizes -#if !defined( int16_t ) -typedef signed short int16_t; -#endif -#if !defined( uint16_t ) -typedef unsigned short uint16_t; -#endif -#if !defined( int32_t ) -typedef signed int int32_t; -#endif -#if !defined( uint32_t ) -typedef unsigned int uint32_t; -#endif - - - - -template -inline void istream_read_little_endian( InputStreamType& istream, Type& value ){ - istream.read(reinterpret_cast( &value ), sizeof(Type)); - if (GDEF_ARCH_ENDIAN_BIG) { - std::reverse(reinterpret_cast( &value ), - reinterpret_cast( &value ) + sizeof(Type)); - } -} - -template -inline void istream_read_big_endian( InputStreamType& istream, Type& value ){ - istream.read(reinterpret_cast( &value ), sizeof(Type)); - if (!GDEF_ARCH_ENDIAN_BIG) { - std::reverse(reinterpret_cast( &value ), - reinterpret_cast( &value ) + sizeof(Type)); - } -} - -template -inline void istream_read_byte( InputStreamType& istream, typename InputStreamType::byte_type& b ){ - istream.read( &b, 1 ); -} - - -template -inline int16_t istream_read_int16_le( InputStreamType& istream ){ - int16_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline int16_t istream_read_int16_be( InputStreamType& istream ){ - int16_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline uint16_t istream_read_uint16_le( InputStreamType& istream ){ - uint16_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline uint16_t istream_read_uint16_be( InputStreamType& istream ){ - uint16_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline int32_t istream_read_int32_le( InputStreamType& istream ){ - int32_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline int32_t istream_read_int32_be( InputStreamType& istream ){ - int32_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline uint32_t istream_read_uint32_le( InputStreamType& istream ){ - uint32_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline uint32_t istream_read_uint32_be( InputStreamType& istream ){ - uint32_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline float istream_read_float32_le( InputStreamType& istream ){ - float value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline float istream_read_float32_be( InputStreamType& istream ){ - float value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline typename InputStreamType::byte_type istream_read_byte( InputStreamType& istream ){ - typename InputStreamType::byte_type b; - istream.read( &b, sizeof( typename InputStreamType::byte_type ) ); - return b; -} - -#endif diff --git a/libs/character.h b/libs/character.h deleted file mode 100644 index bc35d3f..0000000 --- a/libs/character.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CHARACTER_H ) -#define INCLUDED_CHARACTER_H - -/// \file -/// \brief Character encoding. - -/// \brief Returns true if \p c is an ASCII character that can be represented with 7 bits. -inline bool char_is_ascii( char c ){ - return ( c & 0x80 ) == 0; -} - -/// \brief Returns true if \p string consists entirely of ASCII characters. -inline bool string_is_ascii( const char* string ){ - while ( *string != '\0' ) - { - if ( !char_is_ascii( *string++ ) ) { - return false; - } - } - return true; -} - -#endif diff --git a/libs/cmdlib.h b/libs/cmdlib.h deleted file mode 100644 index abdc15a..0000000 --- a/libs/cmdlib.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// start of shared cmdlib stuff -// - -#ifndef __CMDLIB__ -#define __CMDLIB__ - -#include "globaldefs.h" -#include - - -// TTimo started adding portability code: -// return true if spawning was successful, false otherwise -// on win32 we have a bCreateConsole flag to create a new console or run inside the current one -//boolean Q_Exec(const char* pCmd, boolean bCreateConsole); -// execute a system command: -// cmd: the command to run -// cmdline: the command line -// NOTE TTimo following are win32 specific: -// execdir: the directory to execute in -// bCreateConsole: spawn a new console or not -// return values; -// if the spawn was fine -// TODO TTimo add functionality to track the process until it dies - -bool Q_Exec( const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor ); - -// some easy portability crap - - -#define access_owner_read 0400 -#define access_owner_write 0200 -#define access_owner_execute 0100 -#define access_owner_rw_ 0600 -#define access_owner_r_x 0500 -#define access_owner__wx 0300 -#define access_owner_rwx 0700 - -#define access_group_read 0040 -#define access_group_write 0020 -#define access_group_execute 0010 -#define access_group_rw_ 0060 -#define access_group_r_x 0050 -#define access_group__wx 0030 -#define access_group_rwx 0070 - -#define access_others_read 0004 -#define access_others_write 0002 -#define access_others_execute 0001 -#define access_others_rw_ 0006 -#define access_others_r_x 0005 -#define access_others__wx 0003 -#define access_others_rwx 0007 - - -#define access_rwxrwxr_x ( access_owner_rwx | access_group_rwx | access_others_r_x ) -#define access_rwxrwxrwx ( access_owner_rwx | access_group_rwx | access_others_rwx ) - -// Q_mkdir -// returns true if succeeded in creating directory -#if GDEF_OS_WINDOWS -#include -inline bool Q_mkdir( const char* name ){ - return _mkdir( name ) != -1; -} -#else -#include -inline bool Q_mkdir( const char* name ){ - return mkdir( name, access_rwxrwxr_x ) != -1; -} -#endif - - -inline double Sys_DoubleTime( void ){ - return clock() / 1000.0; -} - - - -#endif diff --git a/libs/cmdlib/Makefile b/libs/cmdlib/Makefile deleted file mode 100644 index 235d1e3..0000000 --- a/libs/cmdlib/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - cmdlib.o - -# binary target -../libcmdlib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -cmdlib.o: cmdlib.cpp - -clean: - -rm -f *.o ../libcmdlib.a diff --git a/libs/cmdlib/cmdlib.cpp b/libs/cmdlib/cmdlib.cpp deleted file mode 100644 index a53a343..0000000 --- a/libs/cmdlib/cmdlib.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// start of shared cmdlib stuff -// - -#include "cmdlib.h" -#include "globaldefs.h" - -#include -#include - -#include "string/string.h" -#include "os/path.h" -#include "container/array.h" - - -#if GDEF_OS_POSIX - -#include -#include -#include - -bool Q_Exec( const char *cmd, char *cmdline, const char *, bool, bool waitfor ){ - char fullcmd[2048]; - char *pCmd; - pid_t pid; -#if GDEF_DEBUG - printf( "Q_Exec damnit\n" ); -#endif - switch ( ( pid = fork() ) ) - { - default: - if ( waitfor ) { - waitpid( pid, NULL, 0 ); - } - break; - case -1: - return true; - break; - case 0: - // always concat the command on linux - if ( cmd ) { - strcpy( fullcmd, cmd ); - } - else{ - fullcmd[0] = '\0'; - } - if ( cmdline ) { - strcat( fullcmd, " " ); - strcat( fullcmd, cmdline ); - } - pCmd = fullcmd; - while ( *pCmd == ' ' ) - pCmd++; -#if GDEF_DEBUG - printf( "Running system...\n" ); - printf( "Command: %s\n", pCmd ); -#endif - system( pCmd ); -#if GDEF_DEBUG - printf( "system() returned\n" ); -#endif - _exit( 0 ); - break; - } - return true; -} - -#elif GDEF_OS_WINDOWS - -#include - -// NOTE TTimo windows is VERY nitpicky about the syntax in CreateProcess -bool Q_Exec( const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor ){ - PROCESS_INFORMATION ProcessInformation; - STARTUPINFO startupinfo = {0}; - DWORD dwCreationFlags; - GetStartupInfo( &startupinfo ); - if ( bCreateConsole ) { - dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS; - } - else{ - dwCreationFlags = DETACHED_PROCESS | NORMAL_PRIORITY_CLASS; - } - const char *pCmd; - char *pCmdline; - pCmd = cmd; - if ( pCmd ) { - while ( *pCmd == ' ' ) - pCmd++; - } - pCmdline = cmdline; - if ( pCmdline ) { - while ( *pCmdline == ' ' ) - pCmdline++; - } - - if ( CreateProcess( - pCmd, - pCmdline, - NULL, - NULL, - FALSE, - dwCreationFlags, - NULL, - execdir, - &startupinfo, - &ProcessInformation - ) ) { - if ( waitfor ) { - WaitForSingleObject( ProcessInformation.hProcess, INFINITE ); - } - return true; - } - return false; -} - -#endif diff --git a/libs/container/Makefile b/libs/container/Makefile deleted file mode 100644 index 269e838..0000000 --- a/libs/container/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - array.o hashtable.o - -# binary target -../libcontainer.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -array.o: array.cpp array.h cache.h container.h hashfunc.h -hashtable.o: hashtable.cpp hashtable.h stack.h - -clean: - -rm -f *.o ../libcontainer.a diff --git a/libs/container/array.cpp b/libs/container/array.cpp deleted file mode 100644 index 8ce77f5..0000000 --- a/libs/container/array.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "array.h" - -namespace -{ -class Bleh -{ -Array m_array; -public: -Bleh() : m_array( 16 ){ -} -}; - -void testAutoArray(){ - Array array( 32 ); -} -} \ No newline at end of file diff --git a/libs/container/array.h b/libs/container/array.h deleted file mode 100644 index 5de4fe8..0000000 --- a/libs/container/array.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_ARRAY_H ) -#define INCLUDED_CONTAINER_ARRAY_H - -#include "globaldefs.h" -#include -#include - -#include "memory/allocator.h" - -/// \brief An array whose size is variable at run-time. -/// -/// - Resizing the array destroys all the existing elements and invalidates all iterators. -/// - Default-Constructible, Copyable, Assignable. -/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ -/// -/// \param Element The type to be stored in the array. Must provide a default-constructor and a copy-constructor. -/// \param Allocator A custom memory-allocator, conforming to the std::allocator interface. -template > -class Array : public Allocator -{ -std::size_t m_size; -Element* m_data; - -Element* construct( std::size_t size ){ -#if 1 - return New( *this ).vector( size ); -#else - return new Element[size]; -#endif -} -template -Element* construct( std::size_t size, const T1& value ){ - return New( *this ).vector( size, value ); -} -void destroy( Element* data, std::size_t size ){ -#if 1 - Delete( *this ).vector( data, size ); -#else - delete[] data; -#endif -} - -public: -typedef Element value_type; -typedef value_type* iterator; -typedef const value_type* const_iterator; - -Array() - : m_size( 0 ), m_data( 0 ){ -} -Array( std::size_t size ) - : m_size( size ), m_data( construct( size ) ){ -} -template -Array( std::size_t size, const T1& value ) - : m_size( size ), m_data( construct( size, value ) ){ -} -Array( const Array& other ) - : Allocator( other ), m_size( other.size() ), m_data( construct( m_size ) ){ - std::copy( other.begin(), other.end(), begin() ); -} -template -Array( Iterator start, Iterator finish ) - : m_size( std::distance( start, finish ) ), m_data( construct( m_size ) ){ - std::copy( start, finish, begin() ); -} -~Array(){ - destroy( m_data, m_size ); -} - -Array& operator=( const Array& other ){ - if ( other.size() == size() ) { - std::copy( other.begin(), other.end(), begin() ); - } - else - { - Array temp( other ); - temp.swap( *this ); - } - return *this; -} - -void swap( Array& other ){ - std::swap( m_size, other.m_size ); - std::swap( m_data, other.m_data ); -} - -iterator begin(){ - return m_data; -} -const_iterator begin() const { - return m_data; -} -iterator end(){ - return m_data + m_size; -} -const_iterator end() const { - return m_data + m_size; -} - -value_type& operator[]( std::size_t index ){ -#if GDEF_DEBUG - ASSERT_MESSAGE( index < size(), "array index out of bounds" ); -#endif - return m_data[index]; -} -const value_type& operator[]( std::size_t index ) const { -#if GDEF_DEBUG - ASSERT_MESSAGE( index < size(), "array index out of bounds" ); -#endif - return m_data[index]; -} -value_type* data(){ - return m_data; -} -const value_type* data() const { - return m_data; -} -std::size_t size() const { - return m_size; -} -bool empty() const { - return m_size == 0; -} - -void resize( std::size_t count ){ - if ( count != size() ) { - Array temp( count ); - temp.swap( *this ); - } -} -void resize( std::size_t count, const value_type& value ){ - if ( count != size() ) { - Array temp( count, value ); - temp.swap( *this ); - } -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( Array& self, Array& other ){ - self.swap( other ); -} -} -#endif diff --git a/libs/container/cache.h b/libs/container/cache.h deleted file mode 100644 index 880a7a7..0000000 --- a/libs/container/cache.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_CACHE_H ) -#define INCLUDED_CONTAINER_CACHE_H - -#include -#include "container/hashtable.h" -#include "memory/allocator.h" - -template -class DefaultCreationPolicy -{ -public: -Type* construct( const Parameter& parameter ){ - return New().scalar( parameter ); -} -void destroy( Type* p ){ - Delete().scalar( p ); -} -}; - -template -class SharedValue -{ -typedef Type value_type; -typedef value_type* pointer; -typedef value_type& reference; - -std::size_t m_count; -pointer m_value; - -public: -SharedValue() - : m_count( 0 ), m_value( 0 ){ -} -~SharedValue(){ - ASSERT_MESSAGE( m_count == 0, "destroying a referenced object\n" ); -} -void set( pointer value ){ - m_value = value; -} -pointer get(){ - return m_value; -} -std::size_t increment(){ - return ++m_count; -} -std::size_t decrement(){ - ASSERT_MESSAGE( !empty(), "destroying a non-existent object\n" ); - return --m_count; -} -std::size_t count(){ - return m_count; -} -bool empty(){ - return m_count == 0; -} -reference operator*() const { - ASSERT_NOTNULL( m_value ); - return *m_value; -} -pointer operator->() const { - return &( operator*() ); -} -}; - - - -/// \brief Caches values that are uniquely identified by a key. -/// -/// - Automatically removes objects that are no longer referenced. -/// -/// \param Key Uniquely identifies each element. -/// \param Cached The type to be cached. Must define a constructor that accepts \c Key. -/// \param CreationPolicy Must define 'Cached* construct(const Key&)' and 'void destroy(Cached*)'. The lifetime of the \c Key passed to 'construct' is guaranteed to be longer than the subsequent matched call to 'destroy'. -template, typename CreationPolicy = DefaultCreationPolicy > -class HashedCache : public CreationPolicy -{ -typedef SharedValue Element; -typedef HashTable map_type; - -map_type m_map; - -public: -explicit HashedCache( const CreationPolicy& creation = CreationPolicy() ) - : CreationPolicy( creation ), m_map( 256 ){ -} -~HashedCache(){ - ASSERT_MESSAGE( empty(), "HashedCache::~HashedCache: not empty" ); -} - -typedef typename map_type::iterator iterator; -typedef typename map_type::value_type value_type; - -iterator begin(){ - return m_map.begin(); -} -iterator end(){ - return m_map.end(); -} - -bool empty() const { - return m_map.empty(); -} - -iterator find( const Key& key ){ - return m_map.find( key ); -} - -void capture( iterator i ){ - ( *i ).value.increment(); -} -void release( iterator i ){ - if ( ( *i ).value.decrement() == 0 ) { - CreationPolicy::destroy( ( *i ).value.get() ); - m_map.erase( i ); - } -} - -#if 1 -Element& capture( const Key& key ){ -#if 0 - Element& elem = m_map[key]; - if ( elem.increment() == 1 ) { - elem.set( CreationPolicy::construct( key ) ); - } - return elem; -#else - iterator i = m_map.insert( key, Element() ); - if ( ( *i ).value.increment() == 1 ) { - ( *i ).value.set( CreationPolicy::construct( ( *i ).key ) ); - } - return ( *i ).value; -#endif -} -#else -value_type& capture( const Key& key ){ - iterator i = m_map.find( key ); - if ( i == m_map.end() ) { - i = m_map.insert( key, Element() ); - ( *i ).value.set( CreationPolicy::construct( ( *i ).key ) ); - } - ( *i ).value.increment(); - return ( *i ); -} -#endif -void release( const Key& key ){ - iterator i = m_map.find( key ); - ASSERT_MESSAGE( i != m_map.end(), "releasing a non-existent object\n" ); - release( i ); -} - -void clear(){ - m_map.clear(); -} -}; - - -#endif diff --git a/libs/container/container.h b/libs/container/container.h deleted file mode 100644 index a2d1fec..0000000 --- a/libs/container/container.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_CONTAINER_H ) -#define INCLUDED_CONTAINER_CONTAINER_H - -#include -#include -#include - -#include "generic/static.h" - -/// \brief A single-value container, which can either be empty or full. -template -class Single -{ -Type* m_value; -public: -Single() : m_value( 0 ){ -} -bool empty(){ - return m_value == 0; -} -Type* insert( const Type& other ){ - m_value = new Type( other ); - return m_value; -} -void clear(){ - delete m_value; - m_value = 0; -} -Type& get(){ - //ASSERT_MESSAGE(!empty(), "Single: must be initialised before being accessed"); - return *m_value; -} -const Type& get() const { - //ASSERT_MESSAGE(!empty(), "Single: must be initialised before being accessed"); - return *m_value; -} -}; - - -/// \brief An adaptor to make std::list into a Unique Sequence - which cannot contain the same value more than once. -/// \param Value Uniquely identifies itself. Must provide a copy-constructor and an equality operator. -template -class UnsortedSet -{ -typedef typename std::list Values; -Values m_values; -public: -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; -typedef typename Values::reverse_iterator reverse_iterator; -typedef typename Values::const_reverse_iterator const_reverse_iterator; - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} -reverse_iterator rbegin(){ - return m_values.rbegin(); -} -const_reverse_iterator rbegin() const { - return m_values.rbegin(); -} -reverse_iterator rend(){ - return m_values.rend(); -} -const_reverse_iterator rend() const { - return m_values.rend(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -void swap( UnsortedSet& other ){ - std::swap( m_values, other.m_values ); -} -iterator insert( const Value& value ){ - ASSERT_MESSAGE( find( value ) == end(), "UnsortedSet::insert: already added" ); - m_values.push_back( value ); - return --end(); -} -void erase( const Value& value ){ - iterator i = find( value ); - ASSERT_MESSAGE( i != end(), "UnsortedSet::erase: not found" ); - m_values.erase( i ); -} -iterator find( const Value& value ){ - return std::find( begin(), end(), value ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( UnsortedSet& self, UnsortedSet& other ){ - self.swap( other ); -} -} - -/// An adaptor to make std::list into a Unique Associative Sequence - which cannot contain the same value more than once. -/// Key: Uniquely identifies a value. Must provide a copy-constructor and an equality operator. -/// Value: Must provide a copy-constructor. -template -class UnsortedMap -{ -typedef typename std::list< std::pair > Values; -Values m_values; -public: -typedef typename Values::value_type value_type; -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -iterator insert( const value_type& value ){ - ASSERT_MESSAGE( find( value.first ) == end(), "UnsortedMap::insert: already added" ); - m_values.push_back( value ); - return --m_values.end(); -} -void erase( const Key& key ){ - iterator i = find( key ); - ASSERT_MESSAGE( i != end(), "UnsortedMap::erase: not found" ); - erase( i ); -} -void erase( iterator i ){ - m_values.erase( i ); -} -iterator find( const Key& key ){ - for ( iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - if ( ( *i ).first == key ) { - return i; - } - } - return m_values.end(); -} -const_iterator find( const Key& key ) const { - for ( const_iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - if ( ( *i ).first == key ) { - return i; - } - } - return m_values.end(); -} - -Value& operator[]( const Key& key ){ - iterator i = find( key ); - if ( i != end() ) { - return ( *i ).second; - } - - m_values.push_back( Values::value_type( key, Value() ) ); - return m_values.back().second; -} -}; - -/// An adaptor to assert when duplicate values are added, or non-existent values removed from a std::set. -template -class UniqueSet -{ -typedef std::set Values; -Values m_values; -public: -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; -typedef typename Values::reverse_iterator reverse_iterator; -typedef typename Values::const_reverse_iterator const_reverse_iterator; - - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} -reverse_iterator rbegin(){ - return m_values.rbegin(); -} -const_reverse_iterator rbegin() const { - return m_values.rbegin(); -} -reverse_iterator rend(){ - return m_values.rend(); -} -const_reverse_iterator rend() const { - return m_values.rend(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -void swap( UniqueSet& other ){ - std::swap( m_values, other.m_values ); -} -iterator insert( const Value& value ){ - std::pair result = m_values.insert( value ); - ASSERT_MESSAGE( result.second, "UniqueSet::insert: already added" ); - return result.first; -} -void erase( const Value& value ){ - iterator i = find( value ); - ASSERT_MESSAGE( i != end(), "UniqueSet::erase: not found" ); - m_values.erase( i ); -} -iterator find( const Value& value ){ - return std::find( begin(), end(), value ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( UniqueSet& self, UniqueSet& other ){ - self.swap( other ); -} -} - -template -class ReferencePair -{ -Type* m_first; -Type* m_second; -public: -ReferencePair() : m_first( 0 ), m_second( 0 ){ -} -void attach( Type& t ){ - ASSERT_MESSAGE( m_first == 0 || m_second == 0, "ReferencePair::insert: pointer already exists" ); - if ( m_first == 0 ) { - m_first = &t; - } - else if ( m_second == 0 ) { - m_second = &t; - } -} -void detach( Type& t ){ - ASSERT_MESSAGE( m_first == &t || m_second == &t, "ReferencePair::erase: pointer not found" ); - if ( m_first == &t ) { - m_first = 0; - } - else if ( m_second == &t ) { - m_second = 0; - } -} -template -void forEach( const Functor& functor ){ - if ( m_second != 0 ) { - functor( *m_second ); - } - if ( m_first != 0 ) { - functor( *m_first ); - } -} -}; - - -#endif diff --git a/libs/container/hashfunc.h b/libs/container/hashfunc.h deleted file mode 100644 index 1a027f9..0000000 --- a/libs/container/hashfunc.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_HASHFUNC_H ) -#define INCLUDED_CONTAINER_HASHFUNC_H - -#include -#include "string/string.h" -#include "container/array.h" -typedef unsigned long int ub4; /* unsigned 4-byte quantities */ -typedef unsigned char ub1; - -inline ub1 ub1_as_ub1_nocase( ub1 byte ){ - return std::tolower( byte ); -} - -inline ub4 ub1x4_as_ub4_nocase( const ub1 bytes[4] ){ - ub4 result; - reinterpret_cast( &result )[0] = ub1_as_ub1_nocase( bytes[0] ); - reinterpret_cast( &result )[1] = ub1_as_ub1_nocase( bytes[1] ); - reinterpret_cast( &result )[2] = ub1_as_ub1_nocase( bytes[2] ); - reinterpret_cast( &result )[3] = ub1_as_ub1_nocase( bytes[3] ); - return result; -} - -class ub1_default_traits -{ -public: -static ub1 as_ub1( ub1 byte ){ - return byte; -} -}; - -class ub1_nocase_traits -{ -public: -static ub1 as_ub1( ub1 byte ){ - return ub1_as_ub1_nocase( byte ); -} -}; - -class ub1x4_default_traits -{ -public: -static ub4 as_ub4( const ub1 bytes[4] ){ - return *reinterpret_cast( bytes ); -} -}; - -class ub1x4_nocase_traits -{ -public: -static ub4 as_ub4( const ub1 bytes[4] ){ - return ub1x4_as_ub4_nocase( bytes ); -} -}; - -class ub4_default_traits -{ -public: -static ub4 as_ub4( ub4 i ){ - return i; -} -}; - -class ub4_nocase_traits -{ -public: -static ub4 as_ub4( ub4 i ){ - return ub1x4_as_ub4_nocase( reinterpret_cast( &i ) ); -} -}; - -// lookup2.c -// By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this -// code any way you wish, private, educational, or commercial. It's free. - -#define hashsize( n ) ( (ub4)1 << ( n ) ) -#define hashmask( n ) ( hashsize( n ) - 1 ) - -/* - -------------------------------------------------------------------- - mix -- mix 3 32-bit values reversibly. - For every delta with one or two bit set, and the deltas of all three - high bits or all three low bits, whether the original value of a,b,c - is almost all zero or is uniformly distributed, - * If mix() is run forward or backward, at least 32 bits in a,b,c - have at least 1/4 probability of changing. - * If mix() is run forward, every bit of c will change between 1/3 and - 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) - mix() was built out of 36 single-cycle latency instructions in a - structure that could supported 2x parallelism, like so: - a -= b; - a -= c; x = (c>>13); - b -= c; a ^= x; - b -= a; x = (a<<8); - c -= a; b ^= x; - c -= b; x = (b>>13); - ... - Unfortunately, superscalar Pentiums and Sparcs can't take advantage - of that parallelism. They've also turned some of those single-cycle - latency instructions into multi-cycle latency instructions. Still, - this is the fastest good hash I could find. There were about 2^^68 - to choose from. I only looked at a billion or so. - -------------------------------------------------------------------- - */ -#define mix( a,b,c ) \ - { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ - } - -/* same, but slower, works on systems that might have 8 byte ub4's */ -#define mix2( a,b,c ) \ - { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( ( b & 0xffffffff ) >> 13 ); \ - a -= b; a -= c; a ^= ( ( c & 0xffffffff ) >> 12 ); \ - b -= c; b -= a; b = ( b ^ ( a << 16 ) ) & 0xffffffff; \ - c -= a; c -= b; c = ( c ^ ( b >> 5 ) ) & 0xffffffff; \ - a -= b; a -= c; a = ( a ^ ( c >> 3 ) ) & 0xffffffff; \ - b -= c; b -= a; b = ( b ^ ( a << 10 ) ) & 0xffffffff; \ - c -= a; c -= b; c = ( c ^ ( b >> 15 ) ) & 0xffffffff; \ - } - -/* - -------------------------------------------------------------------- - hash() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - len : the length of the key, counting by bytes - level : can be any 4-byte value - Returns a 32-bit value. Every bit of the key affects every bit of - the return value. Every 1-bit and 2-bit delta achieves avalanche. - About 36+6len instructions. - - The best hash table sizes are powers of 2. There is no need to do - mod a prime (mod is sooo slow!). If you need less than 32 bits, - use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); - In which case, the hash table should have hashsize(10) elements. - - If you are hashing n strings (ub1 **)k, do it like this: - for (i=0, h=0; i -inline ub4 hash( - const ub1 *k, /* the key */ - ub4 length, /* the length of the key */ - ub4 initval, /* the previous hash, or an arbitrary value */ - const UB1Traits& ub1traits, - const UB4x1Traits& ub4x1traits - ){ - register ub4 a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while ( len >= 12 ) - { - a += ( k[0] + ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 ) ); - b += ( k[4] + ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 ) ); - c += ( k[8] + ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[11] ) << 24 ) ); - mix( a,b,c ); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch ( len ) /* all the case statements fall through */ - { - case 11: c += ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 24 ); - case 10: c += ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 16 ); - case 9: c += ( ( ub4 ) UB1Traits::as_ub1( k[8] ) << 8 ); - /* the first byte of c is reserved for the length */ - case 8: b += ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 ); - case 7: b += ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 ); - case 6: b += ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 ); - case 5: b += UB1Traits::as_ub1( k[4] ); - case 4: a += ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 ); - case 3: a += ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 ); - case 2: a += ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 ); - case 1: a += UB1Traits::as_ub1( k[0] ); - /* case 0: nothing left to add */ - } - mix( a,b,c ); - /*-------------------------------------------- report the result */ - return c; -} - -/* - -------------------------------------------------------------------- - This works on all machines. hash2() is identical to hash() on - little-endian machines, except that the length has to be measured - in ub4s instead of bytes. It is much faster than hash(). It - requires - -- that the key be an array of ub4's, and - -- that all your machines have the same endianness, and - -- that the length be the number of ub4's in the key - -------------------------------------------------------------------- - */ -template -inline ub4 hash2( - const ub4 *k, /* the key */ - ub4 length, /* the length of the key, in ub4s */ - ub4 initval, /* the previous hash, or an arbitrary value */ - const UB4Traits& ub4traits - ){ - register ub4 a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while ( len >= 3 ) - { - a += UB4Traits::as_ub4( k[0] ); - b += UB4Traits::as_ub4( k[1] ); - c += UB4Traits::as_ub4( k[2] ); - mix( a,b,c ); - k += 3; len -= 3; - } - - /*-------------------------------------- handle the last 2 ub4's */ - c += length; - switch ( len ) /* all the case statements fall through */ - { - /* c is reserved for the length */ - case 2: b += UB4Traits::as_ub4( k[1] ); - case 1: a += UB4Traits::as_ub4( k[0] ); - /* case 0: nothing left to add */ - } - mix( a,b,c ); - /*-------------------------------------------- report the result */ - return c; -} - -typedef ub4 hash_t; - -inline hash_t hash_ub1( const ub1* key, std::size_t len, hash_t previous = 0 ){ - return hash( key, ub4( len ), previous, ub1_default_traits(), ub1x4_default_traits() ); -} - -inline hash_t hash_ub1_nocase( const ub1* key, std::size_t len, hash_t previous = 0 ){ - return hash( key, ub4( len ), previous, ub1_nocase_traits(), ub1x4_nocase_traits() ); -} - -template -inline hash_t hash_ub4( const ub4* key, std::size_t len, const UB4Traits& traits, hash_t previous = 0 ){ - return hash2( key,ub4( len ), previous, traits ); -} - -inline ub4 hash_combine( ub4 left, ub4 right ){ - return hash_ub1( reinterpret_cast( &left ), 4, right ); -} - -template -inline hash_t pod_hash( const POD& pod ){ - return hash_ub1( reinterpret_cast( &pod ), sizeof( POD ) ); -} - -inline hash_t string_hash( const char* string, hash_t previous = 0 ){ - return hash_ub1( reinterpret_cast( string ), string_length( string ), previous ); -} - -inline hash_t string_hash_nocase( const char* string, hash_t previous = 0 ){ - return hash_ub1_nocase( reinterpret_cast( string ), string_length( string ), previous ); -} - -struct RawStringHash -{ - typedef hash_t hash_type; - hash_type operator()( const char* string ) const { - return string_hash( string ); - } -}; - -struct HashString -{ - typedef hash_t hash_type; - hash_type operator()( const CopiedString& string ) const { - return string_hash( string.c_str() ); - } -}; - -struct HashStringNoCase -{ - typedef hash_t hash_type; - hash_type operator()( const CopiedString& string ) const { - return string_hash_nocase( string.c_str() ); - } -}; - -/// \brief Length of a string in ub4. -/// "wibble" (6) gives 2, -/// "and" (3) gives 1, -/// "bleh" (4) gives 2 -inline std::size_t string_length_ub4( const char* string ){ - return ( ( string_length( string ) >> 2 ) + 1 ) << 2; -} - -/// \brief Hashable key type that stores a string as an array of ub4 - making hashing faster. -/// Also caches the 32-bit result of the hash to speed up comparison of keys. -template -class HashKey -{ -Array m_key; -hash_t m_hash; - -void copy( const HashKey& other ){ - std::copy( other.m_key.begin(), other.m_key.end(), m_key.begin() ); - m_hash = other.m_hash; -} -void copy( const char* string ){ - strncpy( reinterpret_cast( m_key.data() ), string, m_key.size() ); - for ( Array::iterator i = m_key.begin(); i != m_key.end(); ++i ) - { - *i = UB4Traits::as_ub4( *i ); - } - m_hash = hash_ub4( m_key.data(), m_key.size(), ub4_default_traits() ); -} -bool equal( const HashKey& other ) const { - return m_hash == other.m_hash && m_key.size() == other.m_key.size() - && std::equal( m_key.begin(), m_key.end(), other.m_key.begin() ); -} - -public: -HashKey( const HashKey& other ) : m_key( other.m_key.size() ){ - copy( other ); -} -HashKey( const char* string ) : m_key( string_length_ub4( string ) ){ - copy( string ); -} -HashKey& operator=( const char* string ){ - m_key.resize( string_length_ub4( string ) ); - copy( string ); - return *this; -} -bool operator==( const HashKey& other ) const { - return equal( other ); -} -bool operator!=( const HashKey& other ) const { - return !equal( other ); -} -hash_t hash() const { - return m_hash; -} -#if 0 -const char* c_str() const { - return reinterpret_cast( m_key.data() ); -} -#endif -}; - -/// \brief Hash function to use with HashKey. -struct HashKeyHasher -{ - typedef hash_t hash_type; - hash_type operator()( const HashKey& key ) const { - return key.hash(); - } -}; - - - -#endif diff --git a/libs/container/hashtable.cpp b/libs/container/hashtable.cpp deleted file mode 100644 index f2e6602..0000000 --- a/libs/container/hashtable.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hashtable.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -#include "hashfunc.h" - -namespace ExampleHashTable -{ -void testStuff(){ - // HashTable example - typedef HashTable MyHashTable; - MyHashTable hashtable; - hashtable["bleh"] = 5; - hashtable.insert( "blah", 17 ); - hashtable["foo"] = 99; - hashtable.insert( "bar", 23 ); - - int bleh = ( *hashtable.find( "bleh" ) ).value; // 5 - int blah = hashtable["blah"]; // 17 - hashtable.erase( "foo" ); - MyHashTable::iterator barIter = hashtable.find( "bar" ); - hashtable.erase( barIter ); - - for ( MyHashTable::iterator i = hashtable.begin(); i != hashtable.end(); ++i ) - { - if ( ( *i ).key != "bleh" ) { - ++hashtable["count"]; // insertion does not invalidate iterators - } - } - // end example -} - -struct Always -{ - Always(){ - testStuff(); - } -} always; -} - -#endif diff --git a/libs/container/hashtable.h b/libs/container/hashtable.h deleted file mode 100644 index 7fa7907..0000000 --- a/libs/container/hashtable.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_HASHTABLE_H ) -#define INCLUDED_CONTAINER_HASHTABLE_H - -#include -#include -#include -#include -#include "debugging/debugging.h" - -namespace HashTableDetail -{ -inline std::size_t next_power_of_two( std::size_t size ){ - std::size_t result = 1; - while ( result < size ) - { - result <<= 1; - } - return result; -} - -struct BucketNodeBase -{ - BucketNodeBase* next; - BucketNodeBase* prev; -}; - -inline void list_initialise( BucketNodeBase& self ){ - self.next = self.prev = &self; -} - -inline void list_swap( BucketNodeBase& self, BucketNodeBase& other ){ - BucketNodeBase tmp( self ); - if ( other.next == &other ) { - list_initialise( self ); - } - else - { - self = other; - self.next->prev = self.prev->next = &self; - } - if ( tmp.next == &self ) { - list_initialise( other ); - } - else - { - other = tmp; - other.next->prev = other.prev->next = &other; - } -} - -inline void node_link( BucketNodeBase* node, BucketNodeBase* next ){ - node->next = next; - node->prev = next->prev; - next->prev = node; - node->prev->next = node; -} -inline void node_unlink( BucketNodeBase* node ){ - node->prev->next = node->next; - node->next->prev = node->prev; -} - -template -struct KeyValue -{ - const Key key; - Value value; - - KeyValue( const Key& key_, const Value& value_ ) - : key( key_ ), value( value_ ){ - } -}; - -template -struct BucketNode : public BucketNodeBase -{ - Hash m_hash; - KeyValue m_value; - - BucketNode( Hash hash, const Key& key, const Value& value ) - : m_hash( hash ), m_value( key, value ){ - } - BucketNode* getNext() const { - return static_cast( next ); - } - BucketNode* getPrev() const { - return static_cast( prev ); - } -}; - -template -class BucketIterator -{ -typedef BucketNode Node; -Node* m_node; - -void increment(){ - m_node = m_node->getNext(); -} - -public: -typedef std::forward_iterator_tag iterator_category; -typedef std::ptrdiff_t difference_type; -typedef difference_type distance_type; -typedef KeyValue value_type; -typedef value_type* pointer; -typedef value_type& reference; - -BucketIterator( Node* node ) : m_node( node ){ -} - -Node* node(){ - return m_node; -} - -bool operator==( const BucketIterator& other ) const { - return m_node == other.m_node; -} -bool operator!=( const BucketIterator& other ) const { - return !operator==( other ); -} -BucketIterator& operator++(){ - increment(); - return *this; -} -BucketIterator operator++( int ){ - BucketIterator tmp = *this; - increment(); - return tmp; -} -value_type& operator*() const { - return m_node->m_value; -} -value_type* operator->() const { - return &( operator*() ); -} -}; -} - - -/// A hash-table container which maps keys to values. -/// -/// - Inserting or removing elements does not invalidate iterators. -/// - Inserting or retrieving an element for a given key takes O(1) time on average. -/// - Elements are stored in no particular order. -/// -/// \param Key Uniquely identifies a value. Must provide a copy-constructor. -/// \param Value The value to be stored . Must provide a default-constructor and a copy-constructor. -/// \param Hasher Must provide 'std::size_t operator()(const Key&) const' which always returns the same result if the same argument is given. -/// \param KeyEqual Must provide 'bool operator==(const Key&, const Key&) const' which returns true only if both arguments are equal. -/// -/// \dontinclude container/hashtable.cpp -/// \skipline HashTable example -/// \until end example -template > -class HashTable : private KeyEqual, private Hasher -{ -typedef typename Hasher::hash_type hash_type; -typedef HashTableDetail::KeyValue KeyValue; -typedef HashTableDetail::BucketNode BucketNode; - -inline BucketNode* node_create( hash_type hash, const Key& key, const Value& value ){ - return new BucketNode( hash, key, value ); -} -inline void node_destroy( BucketNode* node ){ - delete node; -} - -typedef BucketNode* Bucket; - -static Bucket* buckets_new( std::size_t count ){ - Bucket* buckets = new Bucket[count]; - std::uninitialized_fill( buckets, buckets + count, Bucket( 0 ) ); - return buckets; -} -static void buckets_delete( Bucket* buckets ){ - delete[] buckets; -} - -std::size_t m_bucketCount; -Bucket* m_buckets; -std::size_t m_size; -HashTableDetail::BucketNodeBase m_list; - -BucketNode* getFirst(){ - return static_cast( m_list.next ); -} -BucketNode* getLast(){ - return static_cast( &m_list ); -} - -public: - -typedef KeyValue value_type; -typedef HashTableDetail::BucketIterator iterator; - -private: - -void initialise(){ - list_initialise( m_list ); -} -hash_type hashKey( const Key& key ){ - return Hasher::operator()( key ); -} - -std::size_t getBucketId( hash_type hash ) const { - return hash & ( m_bucketCount - 1 ); -} -Bucket& getBucket( hash_type hash ){ - return m_buckets[getBucketId( hash )]; -} -BucketNode* bucket_find( Bucket bucket, hash_type hash, const Key& key ){ - std::size_t bucketId = getBucketId( hash ); - for ( iterator i( bucket ); i != end(); ++i ) - { - hash_type nodeHash = i.node()->m_hash; - - if ( getBucketId( nodeHash ) != bucketId ) { - return 0; - } - - if ( nodeHash == hash && KeyEqual::operator()( ( *i ).key, key ) ) { - return i.node(); - } - } - return 0; -} -BucketNode* bucket_insert( Bucket& bucket, BucketNode* node ){ - // link node into list - node_link( node, bucket_next( bucket ) ); - bucket = node; - return node; -} -BucketNode* bucket_next( Bucket& bucket ){ - Bucket* end = m_buckets + m_bucketCount; - for ( Bucket* i = &bucket; i != end; ++i ) - { - if ( *i != 0 ) { - return *i; - } - } - return getLast(); -} - -void buckets_resize( std::size_t count ){ - BucketNode* first = getFirst(); - BucketNode* last = getLast(); - - buckets_delete( m_buckets ); - - m_bucketCount = count; - - m_buckets = buckets_new( m_bucketCount ); - initialise(); - - for ( BucketNode* i = first; i != last; ) - { - BucketNode* node = i; - i = i->getNext(); - bucket_insert( getBucket( ( *node ).m_hash ), node ); - } -} -void size_increment(){ - if ( m_size == m_bucketCount ) { - buckets_resize( m_bucketCount == 0 ? 8 : m_bucketCount << 1 ); - } - ++m_size; -} -void size_decrement(){ - --m_size; -} - -HashTable( const HashTable& other ); -HashTable& operator=( const HashTable& other ); -public: -HashTable() : m_bucketCount( 0 ), m_buckets( 0 ), m_size( 0 ){ - initialise(); -} -HashTable( std::size_t bucketCount ) : m_bucketCount( HashTableDetail::next_power_of_two( bucketCount ) ), m_buckets( buckets_new( m_bucketCount ) ), m_size( 0 ){ - initialise(); -} -~HashTable(){ - for ( BucketNode* i = getFirst(); i != getLast(); ) - { - BucketNode* node = i; - i = i->getNext(); - node_destroy( node ); - } - buckets_delete( m_buckets ); -} - -iterator begin(){ - return iterator( getFirst() ); -} -iterator end(){ - return iterator( getLast() ); -} - -bool empty() const { - return m_size == 0; -} -std::size_t size() const { - return m_size; -} - -/// \brief Returns an iterator pointing to the value associated with \p key if it is contained by the hash-table, else \c end(). -iterator find( const Key& key ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return iterator( node ); - } - } - } - - return end(); -} -/// \brief Adds \p value to the hash-table associated with \p key if it does not exist. -iterator insert( const Key& key, const Value& value ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket& bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return iterator( node ); - } - } - } - - size_increment(); - return iterator( bucket_insert( getBucket( hash ), node_create( hash, key, value ) ) ); -} - -/// \brief Removes the value pointed to by \p i from the hash-table. -/// -/// \p i must be a deferenceable iterator into the hash-table. -void erase( iterator i ){ - Bucket& bucket = getBucket( i.node()->m_hash ); - BucketNode* node = i.node(); - - // if this was the last node in the bucket - if ( bucket == node ) { - bucket = ( node->getNext() == getLast() || &getBucket( node->getNext()->m_hash ) != &bucket ) ? 0 : node->getNext(); - } - - node_unlink( node ); - ASSERT_MESSAGE( node != 0, "tried to erase a non-existent key/value" ); - node_destroy( node ); - - size_decrement(); -} - -/// \brief Returns the value identified by \p key if it is contained by the hash-table, else inserts and returns a new default-constructed value associated with \p key. -Value& operator[]( const Key& key ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket& bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return node->m_value.value; - } - } - } - size_increment(); - return bucket_insert( getBucket( hash ), node_create( hash, key, Value() ) )->m_value.value; -} -/// \brief Removes the value associated with \p key from the hash-table. -void erase( const Key& key ){ - erase( find( key ) ); -} -/// \brief Swaps the contents of the hash-table with \p other. -void swap( HashTable& other ){ - std::swap( m_buckets, other.m_buckets ); - std::swap( m_bucketCount, other.m_bucketCount ); - std::swap( m_size, other.m_size ); - HashTableDetail::list_swap( m_list, other.m_list ); -} -/// \brief Removes all values from the hash-table. -void clear(){ - HashTable tmp; - tmp.swap( *this ); -} -}; - -#endif diff --git a/libs/container/stack.h b/libs/container/stack.h deleted file mode 100644 index 10040a7..0000000 --- a/libs/container/stack.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_STACK_H ) -#define INCLUDED_CONTAINER_STACK_H - -#include "memory/allocator.h" -#include - -/// \brief A stack whose storage capacity is variable at run-time. Similar to std::vector. -/// -/// - Pushing or popping elements is a constant-time operation (on average). -/// - The storage capacity of the stack will grow when a new element is added beyond the current capacity. Iterators are invalidated when the storage capacity grows. -/// - DefaultConstructible, Copyable, Assignable. -/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ -/// -/// \param Type: The type to be stored in the stack. Must provide a copy-constructor. -template -class Stack : public DefaultAllocator -{ -typedef DefaultAllocator Allocator; - -enum -{ - DEFAULT_CAPACITY = 4, -}; - -typedef Type* pointer; -typedef const Type* const_pointer; - -public: -typedef const_pointer const_iterator; -private: - -pointer m_data; -pointer m_end; -std::size_t m_capacity; - - -void insert( const Type& value ){ - Allocator::construct( m_end++, value ); -} -void insert_overflow( const Type& value ){ - const std::size_t new_capacity = ( m_capacity ) ? m_capacity + m_capacity : std::size_t( DEFAULT_CAPACITY ); - const pointer new_data = Allocator::allocate( new_capacity ); - const pointer new_end = std::copy( m_data, m_end, new_data ); - - destroy(); - Allocator::deallocate( m_data, m_capacity ); - - m_capacity = new_capacity; - m_data = new_data; - m_end = new_end; - insert( value ); -} -void destroy(){ - for ( pointer p = m_data; p != m_end; ++p ) - { - Allocator::destroy( p ); - } -} -void construct( const Stack& other ){ - pointer p = m_data; - for ( const_iterator i = other.begin(); i != other.end(); ++i ) - { - Allocator::construct( p++, *i ); - } -} - -public: - -Stack() : - m_data( 0 ), - m_end( 0 ), - m_capacity( 0 ){ -} -Stack( const Type& value ) : - m_data( 0 ), - m_end( 0 ), - m_capacity( 0 ){ - push( value ); -} -Stack( const Stack& other ) : - DefaultAllocator( other ){ - m_capacity = other.m_capacity; - m_data = Allocator::allocate( m_capacity ); - construct( other ); - m_end = m_data + other.size(); -} -~Stack(){ - destroy(); - Allocator::deallocate( m_data, m_capacity ); -} - -const_iterator begin() const { - return m_data; -} -const_iterator end() const { - return m_end; -} - -bool empty() const { - return end() == begin(); -} -void clear(){ - destroy(); - m_end = m_data; -} - -std::size_t size() const { - return m_end - m_data; -} -Type operator[]( const std::size_t i ) const { - return m_data[i]; -} -/// \brief Pushes \p value onto the stack at the top element. If reserved storage is insufficient for the new element, this will invalidate all iterators. -void push( const Type& value ){ - if ( size() == m_capacity ) { - insert_overflow( value ); - } - else - { - insert( value ); - } -} -/// \brief Removes the top element of the stack. -void pop(){ - Allocator::destroy( --m_end ); -} -/// \brief Returns the top element of the mutable stack. -Type& top(){ - return *( m_end - 1 ); -} -/// \brief Returns the top element of the non-mutable stack. -const Type& top() const { - return *( m_end - 1 ); -} -/// \brief Returns the element below the top element of the mutable stack. -Type& parent(){ - return *( m_end - 2 ); -} -/// \brief Returns the element below the top element of the non-mutable stack. -const Type& parent() const { - return *( m_end - 2 ); -} -/// \brief Swaps the values of this stack and \p other. -void swap( Stack& other ){ - std::swap( m_data, other.m_data ); - std::swap( m_end, other.m_end ); - std::swap( m_capacity, other.m_capacity ); -} -#if 1 // use copy-swap technique -Stack& operator=( const Stack& other ){ - Stack temp( other ); - temp.swap( *this ); - return *this; -} -#else // avoids memory allocation if capacity is already sufficient. -Stack& operator=( const Stack& other ){ - if ( &other != this ) { - destroy(); - - if ( other.size() > m_capacity ) { - Allocator::deallocate( m_data, m_capacity ); - m_capacity = other.m_capacity; - m_data = Allocator::allocate( m_capacity ); - } - m_end = m_data + other.size(); - - construct( other ); - } - return *this; -} -#endif -}; - -/// \brief Returns true if \p self is lexicographically less than \p other. -template -inline bool operator<( const Stack& self, const Stack& other ){ - return std::lexicographical_compare( self.begin(), self.end(), other.begin(), other.end() ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( Stack& self, Stack& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/convert.h b/libs/convert.h deleted file mode 100644 index 322e902..0000000 --- a/libs/convert.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONVERT_H ) -#define INCLUDED_CONVERT_H - -/// \file -/// \brief Character encoding conversion. - -#include "debugging/debugging.h" -#include -#include - -#include "character.h" - -/// \brief Returns the number of bytes required to represent \p character in UTF-8 encoding. -inline std::size_t utf8_character_length( const char* character ){ - if ( ( *character & 0xE0 ) == 0xC0 ) { // 110xxxxx - return 2; - } - else if ( ( *character & 0xF0 ) == 0xE0 ) { // 1110xxxx - return 3; - } - else if ( ( *character & 0xF8 ) == 0xF0 ) { // 11110xxx - return 4; - } - else if ( ( *character & 0xFC ) == 0xF8 ) { // 111110xx - return 5; - } - else if ( ( *character & 0xFE ) == 0xFC ) { // 1111110x - return 6; - } - ERROR_MESSAGE( "" ); - return 0; -} - -struct UTF8Character -{ - const char* buffer; - std::size_t length; - UTF8Character() : buffer( 0 ), length( 0 ){ - } - UTF8Character( const char* bytes ) : buffer( bytes ), length( utf8_character_length( bytes ) ){ - } -}; - -inline bool operator<( const UTF8Character& self, const UTF8Character& other ){ - return std::lexicographical_compare( self.buffer, self.buffer + self.length, other.buffer, other.buffer + other.length ); -} - -/// \brief Writes \p c to \p ostream in Hex form. Useful for debugging. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const UTF8Character& c ){ - for ( const char* p = c.buffer; p != c.buffer + c.length; ++p ) - { - ostream << HexChar( *p ); - } - return ostream; -} - - - -/// \brief The character-set encoding for the current C locale. -/// -/// Obtain the global instance with globalCharacterSet(). -class CharacterSet -{ -const char* m_charSet; -public: -CharacterSet(){ - if ( g_get_charset( &m_charSet ) != FALSE ) { - m_charSet = 0; - } -} -bool isUTF8() const { - return m_charSet == 0; -} -const char* get() const { - return m_charSet; -} -}; - -typedef LazyStatic GlobalCharacterSet; - -/// \brief Returns the global instance of CharacterSet. -inline CharacterSet& globalCharacterSet(){ - return GlobalCharacterSet::instance(); -} - - -class UTF8CharacterToExtendedASCII -{ -public: -UTF8Character m_utf8; -char m_c; -UTF8CharacterToExtendedASCII() : m_c( '\0' ){ -} -UTF8CharacterToExtendedASCII( const UTF8Character& utf8, char c ) : m_utf8( utf8 ), m_c( c ){ -} -}; - -inline bool operator<( const UTF8CharacterToExtendedASCII& self, const UTF8CharacterToExtendedASCII& other ){ - return self.m_utf8 < other.m_utf8; -} - -inline std::size_t extended_ascii_to_index( char c ){ - return static_cast( c & 0x7F ); -} - -inline char extended_ascii_for_index( std::size_t i ){ - return static_cast( i | 0x80 ); -} - -/// \brief The active extended-ascii character set encoding. -/// Performs UTF-8 encoding and decoding of extended-ascii characters. -/// -/// Obtain the global instance with globalExtendedASCIICharacterSet(). -class ExtendedASCIICharacterSet -{ -typedef char UTF8CharBuffer[6]; -UTF8CharBuffer m_converted[128]; -UTF8Character m_decodeMap[128]; -UTF8CharacterToExtendedASCII m_encodeMap[128]; -public: -ExtendedASCIICharacterSet(){ - if ( !globalCharacterSet().isUTF8() ) { - GIConv descriptor = g_iconv_open( "UTF-8", globalCharacterSet().get() ); - for ( std::size_t i = 1; i < 128; ++i ) - { - char c = extended_ascii_for_index( i ); - char* inbuf = &c; - gsize inbytesleft = 1; - char* outbuf = m_converted[i]; - gsize outbytesleft = 6; - if ( g_iconv( descriptor, &inbuf, &inbytesleft, &outbuf, &outbytesleft ) != (size_t)( -1 ) ) { - UTF8Character utf8( m_converted[i] ); - m_decodeMap[i] = utf8; - m_encodeMap[i] = UTF8CharacterToExtendedASCII( utf8, c ); - } - } - g_iconv_close( descriptor ); - std::sort( m_encodeMap, m_encodeMap + 128 ); - } -} -/// \brief Prints the (up to) 128 characters in the current extended-ascii character set. -/// Useful for debugging. -void print() const { - globalOutputStream() << "UTF-8 conversion required from charset: " << globalCharacterSet().get() << "\n"; - for ( std::size_t i = 1; i < 128; ++i ) - { - if ( m_decodeMap[i].buffer != 0 ) { - globalOutputStream() << extended_ascii_for_index( i ) << " = " << m_decodeMap[i] << "\n"; - } - } -} -/// \brief Returns \p c decoded from extended-ascii to UTF-8. -/// \p c must be an extended-ascii character. -const UTF8Character& decode( char c ) const { - ASSERT_MESSAGE( !globalCharacterSet().isUTF8(), "locale is utf8, no conversion required" ); - ASSERT_MESSAGE( !char_is_ascii( c ), "decode: ascii character" ); - ASSERT_MESSAGE( m_decodeMap[extended_ascii_to_index( c )].buffer != 0, "decode: invalid character: " << HexChar( c ) ); - return m_decodeMap[extended_ascii_to_index( c )]; -} -/// \brief Returns \p c encoded to extended-ascii from UTF-8. -/// \p c must map to an extended-ascii character. -char encode( const UTF8Character& c ) const { - ASSERT_MESSAGE( !globalCharacterSet().isUTF8(), "locale is utf8, no conversion required" ); - ASSERT_MESSAGE( !char_is_ascii( *c.buffer ), "encode: ascii character" ); - std::pair range - = std::equal_range( m_encodeMap, m_encodeMap + 128, UTF8CharacterToExtendedASCII( c, 0 ) ); - ASSERT_MESSAGE( range.first != range.second, "encode: invalid character: " << c ); - return ( *range.first ).m_c; -} -}; - -typedef LazyStatic GlobalExtendedASCIICharacterSet; - -/// \brief Returns the global instance of ExtendedASCIICharacterSet. -inline ExtendedASCIICharacterSet& globalExtendedASCIICharacterSet(){ - return GlobalExtendedASCIICharacterSet::instance(); -} - -class ConvertUTF8ToLocale -{ -public: -StringRange m_range; -ConvertUTF8ToLocale( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){ -} -ConvertUTF8ToLocale( const StringRange& range ) : m_range( range ){ -} -}; - -/// \brief Writes \p convert to \p ostream after encoding each character to extended-ascii from UTF-8. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConvertUTF8ToLocale& convert ){ - if ( globalCharacterSet().isUTF8() ) { - return ostream << convert.m_range; - } - - for ( const char* p = convert.m_range.first; p != convert.m_range.last; ) - { - if ( !char_is_ascii( *p ) ) { - UTF8Character c( p ); - ostream << globalExtendedASCIICharacterSet().encode( c ); - p += c.length; - } - else - { - ostream << *p++; - } - } - return ostream; -} - - -class ConvertLocaleToUTF8 -{ -public: -StringRange m_range; -ConvertLocaleToUTF8( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){ -} -ConvertLocaleToUTF8( const StringRange& range ) : m_range( range ){ -} -}; - -/// \brief Writes \p convert to \p ostream after decoding each character from extended-ascii to UTF-8. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConvertLocaleToUTF8& convert ){ - if ( globalCharacterSet().isUTF8() ) { - return ostream << convert.m_range; - } - - for ( const char* p = convert.m_range.first; p != convert.m_range.last; ++p ) - { - if ( !char_is_ascii( *p ) ) { - UTF8Character c( globalExtendedASCIICharacterSet().decode( *p ) ); - ostream.write( c.buffer, c.length ); - } - else - { - ostream << *p; - } - } - return ostream; -} - - -#endif diff --git a/libs/debugging/Makefile b/libs/debugging/Makefile deleted file mode 100644 index cf3e127..0000000 --- a/libs/debugging/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - debugging.o - -# binary target -../libdebugging.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -debugging.o: debugging.cpp debugging.h - -clean: - -rm -f *.o ../libdebugging.a diff --git a/libs/debugging/debugging.cpp b/libs/debugging/debugging.cpp deleted file mode 100644 index b292840..0000000 --- a/libs/debugging/debugging.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging.h" - -void TEST_ASSERT(){ - ERROR_MESSAGE( "test" ); - ASSERT_NOTNULL( 0 ); -} diff --git a/libs/debugging/debugging.h b/libs/debugging/debugging.h deleted file mode 100644 index 405131d..0000000 --- a/libs/debugging/debugging.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DEBUGGING_DEBUGGING_H ) -#define INCLUDED_DEBUGGING_DEBUGGING_H - -/// \file -/// \brief Debugging macros for fatal error/assert messages. - -#include "globaldefs.h" -#include "stream/textstream.h" -#include "warnings.h" -#include "generic/static.h" - -#if GDEF_COMPILER_MSVC && ( defined( _M_IX86 ) || defined( _M_AMD64 ) ) -#define DEBUGGER_BREAKPOINT() __asm { int 3 } -#elif GDEF_COMPILER_GNU && __GNUC__ >= 2 && ( defined ( __i386__ ) || defined ( __x86_64__ ) ) -#define DEBUGGER_BREAKPOINT() __asm__ __volatile__ ( "int $03" ) -#else -#include - -#define DEBUGGER_BREAKPOINT() raise( SIGTRAP ); -#endif - -#define STR( x ) #x -#define STR2( x ) STR( x ) -#define FILE_LINE __FILE__ ":" STR2( __LINE__ ) - -#define DEBUG_ASSERTS - -class DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream() = 0; -virtual bool handleMessage() = 0; -}; - -class NullDebugMessageHandler : public NullOutputStream, public DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream(){ - return *this; -} -virtual bool handleMessage(){ - return false; -} -}; - -class DefaultDebugMessageHandler : public DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream(){ - return globalErrorStream(); -} -virtual bool handleMessage(){ -#if GDEF_DEBUG - return false; // send debug-break -#else - return true; -#endif -} -}; - -class DebugMessageHandlerRef : public DefaultDebugMessageHandler -{ -DebugMessageHandler* m_handler; -public: -DebugMessageHandlerRef() - : m_handler( this ){ -} -void setHandler( DebugMessageHandler& handler ){ - m_handler = &handler; -} -DebugMessageHandler& getHandler(){ - return *m_handler; -} -}; - -typedef Static GlobalDebugMessageHandler; - -inline DebugMessageHandler& globalDebugMessageHandler(){ - return GlobalDebugMessageHandler::instance().getHandler(); -} - -#if defined( DEBUG_ASSERTS ) - -/// \brief Sends a \p message to the current debug-message-handler text-output-stream if \p condition evaluates to false. -#define ASSERT_MESSAGE( condition, message ) do { \ - if ( !( condition ) ) \ - { \ - globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nassertion failure: " << message << "\n"; \ - if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); } \ - }} while ( 0 ) - -/// \brief Sends a \p message to the current debug-message-handler text-output-stream. -#define ERROR_MESSAGE( message ) do { \ - globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nruntime error: " << message << "\n"; \ - if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); }} while ( 0 ) - -#define ASSERT_NOTNULL( ptr ) ASSERT_MESSAGE( ptr != 0, "pointer \"" #ptr "\" is null" ) -#define ASSERT_TRUE( flag ) ASSERT_MESSAGE( !!(flag) == true, "condition \"" #flag "\" is false" ) - -#else - -#define ASSERT_MESSAGE( condition, message ) -#define ERROR_MESSAGE( message ) -#define ASSERT_NOTNULL( ptr ) - -#endif - -#endif diff --git a/libs/dragplanes.h b/libs/dragplanes.h deleted file mode 100644 index 0988b31..0000000 --- a/libs/dragplanes.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DRAGPLANES_H ) -#define INCLUDED_DRAGPLANES_H - -#include "selectable.h" -#include "selectionlib.h" -#include "math/aabb.h" -#include "math/line.h" - -// local must be a pure rotation -inline Vector3 translation_to_local( const Vector3& translation, const Matrix4& local ){ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3( matrix4_transposed( local ), translation ), - local - ) - ); -} - -// local must be a pure rotation -inline Vector3 translation_from_local( const Vector3& translation, const Matrix4& local ){ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3( local, translation ), - matrix4_transposed( local ) - ) - ); -} - -class DragPlanes -{ -public: -ObservedSelectable m_selectable_right; // +x -ObservedSelectable m_selectable_left; // -x -ObservedSelectable m_selectable_front; // +y -ObservedSelectable m_selectable_back; // -y -ObservedSelectable m_selectable_top; // +z -ObservedSelectable m_selectable_bottom; // -z -AABB m_bounds; - -DragPlanes( const SelectionChangeCallback& onchanged ) : - m_selectable_right( onchanged ), - m_selectable_left( onchanged ), - m_selectable_front( onchanged ), - m_selectable_back( onchanged ), - m_selectable_top( onchanged ), - m_selectable_bottom( onchanged ){ -} -bool isSelected() const { - return m_selectable_right.isSelected() - || m_selectable_left.isSelected() - || m_selectable_front.isSelected() - || m_selectable_back.isSelected() - || m_selectable_top.isSelected() - || m_selectable_bottom.isSelected(); -} -void setSelected( bool selected ){ - m_selectable_right.setSelected( selected ); - m_selectable_left.setSelected( selected ); - m_selectable_front.setSelected( selected ); - m_selectable_back.setSelected( selected ); - m_selectable_top.setSelected( selected ); - m_selectable_bottom.setSelected( selected ); -} -void selectPlanes( const AABB& aabb, Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback, const Matrix4& rotation = g_matrix4_identity ){ - Line line( test.getNear(), test.getFar() ); - Vector3 corners[8]; - aabb_corners_oriented( aabb, rotation, corners ); - - Plane3 planes[6]; - aabb_planes_oriented( aabb, rotation, planes ); - - for ( Vector3* i = corners; i != corners + 8; ++i ) - { - *i = vector3_subtracted( line_closest_point( line, *i ), *i ); - } - - if ( vector3_dot( planes[0].normal(), corners[1] ) > 0 - && vector3_dot( planes[0].normal(), corners[2] ) > 0 - && vector3_dot( planes[0].normal(), corners[5] ) > 0 - && vector3_dot( planes[0].normal(), corners[6] ) > 0 ) { - Selector_add( selector, m_selectable_right ); - selectedPlaneCallback( planes[0] ); - //globalOutputStream() << "right\n"; - } - if ( vector3_dot( planes[1].normal(), corners[0] ) > 0 - && vector3_dot( planes[1].normal(), corners[3] ) > 0 - && vector3_dot( planes[1].normal(), corners[4] ) > 0 - && vector3_dot( planes[1].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_left ); - selectedPlaneCallback( planes[1] ); - //globalOutputStream() << "left\n"; - } - if ( vector3_dot( planes[2].normal(), corners[0] ) > 0 - && vector3_dot( planes[2].normal(), corners[1] ) > 0 - && vector3_dot( planes[2].normal(), corners[4] ) > 0 - && vector3_dot( planes[2].normal(), corners[5] ) > 0 ) { - Selector_add( selector, m_selectable_front ); - selectedPlaneCallback( planes[2] ); - //globalOutputStream() << "front\n"; - } - if ( vector3_dot( planes[3].normal(), corners[2] ) > 0 - && vector3_dot( planes[3].normal(), corners[3] ) > 0 - && vector3_dot( planes[3].normal(), corners[6] ) > 0 - && vector3_dot( planes[3].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_back ); - selectedPlaneCallback( planes[3] ); - //globalOutputStream() << "back\n"; - } - if ( vector3_dot( planes[4].normal(), corners[0] ) > 0 - && vector3_dot( planes[4].normal(), corners[1] ) > 0 - && vector3_dot( planes[4].normal(), corners[2] ) > 0 - && vector3_dot( planes[4].normal(), corners[3] ) > 0 ) { - Selector_add( selector, m_selectable_top ); - selectedPlaneCallback( planes[4] ); - //globalOutputStream() << "top\n"; - } - if ( vector3_dot( planes[5].normal(), corners[4] ) > 0 - && vector3_dot( planes[5].normal(), corners[5] ) > 0 - && vector3_dot( planes[5].normal(), corners[6] ) > 0 - && vector3_dot( planes[5].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_bottom ); - selectedPlaneCallback( planes[5] ); - //globalOutputStream() << "bottom\n"; - } - - m_bounds = aabb; -} -void selectReversedPlanes( const AABB& aabb, Selector& selector, const SelectedPlanes& selectedPlanes, const Matrix4& rotation = g_matrix4_identity ){ - Plane3 planes[6]; - aabb_planes_oriented( aabb, rotation, planes ); - - if ( selectedPlanes.contains( plane3_flipped( planes[0] ) ) ) { - Selector_add( selector, m_selectable_right ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[1] ) ) ) { - Selector_add( selector, m_selectable_left ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[2] ) ) ) { - Selector_add( selector, m_selectable_front ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[3] ) ) ) { - Selector_add( selector, m_selectable_back ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[4] ) ) ) { - Selector_add( selector, m_selectable_top ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[5] ) ) ) { - Selector_add( selector, m_selectable_bottom ); - } -} -AABB evaluateResize( const Vector3& translation ) const { - Vector3 min = m_bounds.origin - m_bounds.extents; - Vector3 max = m_bounds.origin + m_bounds.extents; - if ( m_bounds.extents[0] != 0 ) { - if ( m_selectable_right.isSelected() ) { - max[0] += translation[0]; - //globalOutputStream() << "moving right\n"; - } - if ( m_selectable_left.isSelected() ) { - min[0] += translation[0]; - //globalOutputStream() << "moving left\n"; - } - } - if ( m_bounds.extents[1] != 0 ) { - if ( m_selectable_front.isSelected() ) { - max[1] += translation[1]; - //globalOutputStream() << "moving front\n"; - } - if ( m_selectable_back.isSelected() ) { - min[1] += translation[1]; - //globalOutputStream() << "moving back\n"; - } - } - if ( m_bounds.extents[2] != 0 ) { - if ( m_selectable_top.isSelected() ) { - max[2] += translation[2]; - //globalOutputStream() << "moving top\n"; - } - if ( m_selectable_bottom.isSelected() ) { - min[2] += translation[2]; - //globalOutputStream() << "moving bottom\n"; - } - } - - return AABB( vector3_mid( min, max ), vector3_scaled( vector3_subtracted( max, min ), 0.5 ) ); -} -AABB evaluateResize( const Vector3& translation, const Matrix4& rotation ) const { - AABB aabb( evaluateResize( translation_to_local( translation, rotation ) ) ); - aabb.origin = m_bounds.origin + translation_from_local( aabb.origin - m_bounds.origin, rotation ); - return aabb; -} -Matrix4 evaluateTransform( const Vector3& translation ) const { - AABB aabb( evaluateResize( translation ) ); - Vector3 scale( - m_bounds.extents[0] != 0 ? aabb.extents[0] / m_bounds.extents[0] : 1, - m_bounds.extents[1] != 0 ? aabb.extents[1] / m_bounds.extents[1] : 1, - m_bounds.extents[2] != 0 ? aabb.extents[2] / m_bounds.extents[2] : 1 - ); - - Matrix4 matrix( matrix4_translation_for_vec3( aabb.origin - m_bounds.origin ) ); - matrix4_pivoted_scale_by_vec3( matrix, scale, m_bounds.origin ); - - return matrix; -} -}; - -#endif diff --git a/libs/eclasslib.h b/libs/eclasslib.h deleted file mode 100644 index 2a92fcd..0000000 --- a/libs/eclasslib.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_ECLASSLIB_H ) -#define INCLUDED_ECLASSLIB_H - -#include -#include -#include -#include -#include - -#include "ieclass.h" -#include "irender.h" - -#include "math/vector.h" -#include "string/string.h" - -typedef Vector3 Colour3; - -class ListAttributeType -{ -using ListItem = std::pair; -using ListItems = std::vector; -ListItems m_items; -public: - -typedef ListItems::const_iterator const_iterator; -const_iterator begin() const { - return m_items.begin(); -} -const_iterator end() const { - return m_items.end(); -} - -const ListItem& operator[]( std::size_t i ) const { - return m_items[i]; -} -const_iterator findValue( const char* value ) const { - for ( ListItems::const_iterator i = m_items.begin(); i != m_items.end(); ++i ) - { - if ( string_equal( value, ( *i ).second.c_str() ) ) { - return i; - } - } - return m_items.end(); -} - -void push_back( const char* name, const char* value ){ - m_items.push_back( ListItems::value_type( name, value ) ); -} -}; - -class EntityClassAttribute -{ -public: -CopiedString m_type; -CopiedString m_name; -CopiedString m_value; -CopiedString m_description; -EntityClassAttribute(){ -} -EntityClassAttribute( const char* type, const char* name, const char* value = "", const char* description = "" ) : m_type( type ), m_name( name ), m_value( value ), m_description( description ){ -} -}; - -typedef std::pair EntityClassAttributePair; -typedef std::list EntityClassAttributes; -typedef std::list StringList; - -inline const char* EntityClassAttributePair_getName( const EntityClassAttributePair& attributePair ){ - if ( !string_empty( attributePair.second.m_name.c_str() ) ) { - return attributePair.second.m_name.c_str(); - } - return attributePair.first.c_str(); -} - -inline const char* EntityClassAttributePair_getDescription( const EntityClassAttributePair& attributePair ){ - if ( !string_empty( attributePair.second.m_description.c_str() ) ) { - return attributePair.second.m_description.c_str(); - } - return EntityClassAttributePair_getName( attributePair ); -} - -class EntityClass -{ -public: -CopiedString m_name; -StringList m_parent; -bool fixedsize; -bool unknown; // wasn't found in source -Vector3 mins; -Vector3 maxs; - -Colour3 color; -Shader* m_state_fill; -Shader* m_state_wire; -Shader* m_state_blend; - -CopiedString m_comments; -char flagnames[MAX_FLAGS][32]; - -CopiedString m_modelpath; -CopiedString m_skin; - -void ( *free )( EntityClass* ); - -EntityClassAttributes m_attributes; - -bool inheritanceResolved; -bool sizeSpecified; -bool colorSpecified; - -const char* name() const { - return m_name.c_str(); -} -const char* comments() const { - return m_comments.c_str(); -} -const char* modelpath() const { - return m_modelpath.c_str(); -} -const char* skin() const { - return m_skin.c_str(); -} -}; - -inline const char* EntityClass_valueForKey( const EntityClass& entityClass, const char* key ){ - for ( EntityClassAttributes::const_iterator i = entityClass.m_attributes.begin(); i != entityClass.m_attributes.end(); ++i ) - { - if ( string_equal( key, ( *i ).first.c_str() ) ) { - return ( *i ).second.m_value.c_str(); - } - } - return ""; -} - -inline EntityClassAttributePair& EntityClass_insertAttribute( EntityClass& entityClass, const char* key, const EntityClassAttribute& attribute = EntityClassAttribute() ){ - entityClass.m_attributes.push_back( EntityClassAttributePair( key, attribute ) ); - return entityClass.m_attributes.back(); -} - - -inline void buffer_write_colour_fill( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "(%g %g %g)", colour[0], colour[1], colour[2] ); -} - -inline void buffer_write_colour_wire( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "<%g %g %g>", colour[0], colour[1], colour[2] ); -} - -inline void buffer_write_colour_blend( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "[%g %g %g]", colour[0], colour[1], colour[2] ); -} - -inline Shader* colour_capture_state_fill( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_fill( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_fill( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_fill( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline Shader* colour_capture_state_wire( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_wire( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_wire( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_wire( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline Shader* colour_capture_state_blend( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_blend( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_blend( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_blend( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline void eclass_capture_state( EntityClass* eclass ){ - eclass->m_state_fill = colour_capture_state_fill( eclass->color ); - eclass->m_state_wire = colour_capture_state_wire( eclass->color ); - eclass->m_state_blend = colour_capture_state_blend( eclass->color ); -} - -inline void eclass_release_state( EntityClass* eclass ){ - colour_release_state_fill( eclass->color ); - colour_release_state_wire( eclass->color ); - colour_release_state_blend( eclass->color ); -} - -// eclass constructor -inline EntityClass* Eclass_Alloc(){ - EntityClass* e = new EntityClass; - - e->fixedsize = false; - e->unknown = false; - memset( e->flagnames, 0, MAX_FLAGS * 32 ); - - e->maxs = Vector3( -1,-1,-1 ); - e->mins = Vector3( 1, 1, 1 ); - - e->free = 0; - - e->inheritanceResolved = true; - e->sizeSpecified = false; - e->colorSpecified = false; - - return e; -} - -// eclass destructor -inline void Eclass_Free( EntityClass* e ){ - eclass_release_state( e ); - - delete e; -} - -inline bool classname_equal( const char* classname, const char* other ){ - return string_equal( classname, other ); -} - -inline EntityClass* EClass_Create( const char* name, const Vector3& colour, const char* comments ){ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - e->m_name = name; - - e->color = colour; - eclass_capture_state( e ); - - if ( comments ) { - e->m_comments = comments; - } - - return e; -} - -inline EntityClass* EClass_Create_FixedSize( const char* name, const Vector3& colour, const Vector3& mins, const Vector3& maxs, const char* comments ){ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - e->m_name = name; - - e->color = colour; - eclass_capture_state( e ); - - e->fixedsize = true; - - e->mins = mins; - e->maxs = maxs; - - if ( comments ) { - e->m_comments = comments; - } - - return e; -} - -const Vector3 smallbox[2] = { - Vector3( -8,-8,-8 ), - Vector3( 8, 8, 8 ), -}; - -inline EntityClass *EntityClass_Create_Default( const char *name, bool has_brushes ){ - // create a new class for it - if ( has_brushes ) { - return EClass_Create( name, Vector3( 0.0f, 0.5f, 0.0f ), "Not found in source." ); - } - else - { - return EClass_Create_FixedSize( name, Vector3( 0.0f, 0.5f, 0.0f ), smallbox[0], smallbox[1], "Not found in source." ); - } -} - -#endif diff --git a/libs/entitylib.h b/libs/entitylib.h deleted file mode 100644 index 9371397..0000000 --- a/libs/entitylib.h +++ /dev/null @@ -1,718 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_ENTITYLIB_H ) -#define INCLUDED_ENTITYLIB_H - -#include "ireference.h" -#include "debugging/debugging.h" - -#include "ientity.h" -#include "irender.h" -#include "igl.h" -#include "selectable.h" - -#include "generic/callback.h" -#include "math/vector.h" -#include "math/aabb.h" -#include "undolib.h" -#include "string/pooledstring.h" -#include "generic/referencecounted.h" -#include "scenelib.h" -#include "container/container.h" -#include "eclasslib.h" - -#include -#include - -inline void arrow_draw( const Vector3& origin, const Vector3& direction_forward, const Vector3& direction_left, const Vector3& direction_up ){ - Vector3 endpoint( vector3_added( origin, vector3_scaled( direction_forward, 32.0 ) ) ); - - Vector3 tip1( vector3_added( vector3_added( endpoint, vector3_scaled( direction_forward, -8.0 ) ), vector3_scaled( direction_up, -4.0 ) ) ); - Vector3 tip2( vector3_added( tip1, vector3_scaled( direction_up, 8.0 ) ) ); - Vector3 tip3( vector3_added( vector3_added( endpoint, vector3_scaled( direction_forward, -8.0 ) ), vector3_scaled( direction_left, -4.0 ) ) ); - Vector3 tip4( vector3_added( tip3, vector3_scaled( direction_left, 8.0 ) ) ); - - glBegin( GL_LINES ); - - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip1 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip2 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip3 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip4 ) ); - - glVertex3fv( vector3_to_array( tip1 ) ); - glVertex3fv( vector3_to_array( tip3 ) ); - - glVertex3fv( vector3_to_array( tip3 ) ); - glVertex3fv( vector3_to_array( tip2 ) ); - - glVertex3fv( vector3_to_array( tip2 ) ); - glVertex3fv( vector3_to_array( tip4 ) ); - - glVertex3fv( vector3_to_array( tip4 ) ); - glVertex3fv( vector3_to_array( tip1 ) ); - - glEnd(); -} - -class SelectionIntersection; - -inline void aabb_testselect( const AABB& aabb, SelectionTest& test, SelectionIntersection& best ){ - const IndexPointer::index_type indices[24] = { - 2, 1, 5, 6, - 1, 0, 4, 5, - 0, 1, 2, 3, - 3, 7, 4, 0, - 3, 2, 6, 7, - 7, 6, 5, 4, - }; - - Vector3 points[8]; - aabb_corners( aabb, points ); - test.TestQuads( VertexPointer( reinterpret_cast( points ), sizeof( Vector3 ) ), IndexPointer( indices, 24 ), best ); -} - -inline void aabb_draw_wire( const Vector3 points[8] ){ - unsigned int indices[26] = { - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7, - // 0, 6, 1, 7, 2, 4, 3, 5 // X cross - 1, 7 // diagonal line (connect mins to maxs corner) - }; -#if 1 - glVertexPointer( 3, GL_FLOAT, 0, points ); - glDrawElements( GL_LINES, sizeof( indices ) / sizeof( indices[0] ), GL_UNSIGNED_INT, indices ); -#else - glBegin( GL_LINES ); - for ( std::size_t i = 0; i < sizeof( indices ) / sizeof( indices[0] ); ++i ) - { - glVertex3fv( points[indices[i]] ); - } - glEnd(); -#endif -} - -inline void aabb_draw_flatshade( const Vector3 points[8] ){ - glBegin( GL_QUADS ); - - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glEnd(); -} - -inline void aabb_draw_wire( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - aabb_draw_wire( points ); -} - -inline void aabb_draw_flatshade( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - aabb_draw_flatshade( points ); -} - -inline void aabb_draw_textured( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - - glBegin( GL_QUADS ); - - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[6] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[4] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[5] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[3] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[7] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glEnd(); -} - -inline void aabb_draw_solid( const AABB& aabb, RenderStateFlags state ){ - if ( state & RENDER_TEXTURE ) { - aabb_draw_textured( aabb ); - } - else - { - aabb_draw_flatshade( aabb ); - } -} - -inline void aabb_draw( const AABB& aabb, RenderStateFlags state ){ - if ( state & RENDER_FILL ) { - aabb_draw_solid( aabb, state ); - } - else - { - aabb_draw_wire( aabb ); - } -} - -class RenderableSolidAABB : public OpenGLRenderable -{ -const AABB& m_aabb; -public: -RenderableSolidAABB( const AABB& aabb ) : m_aabb( aabb ){ -} -void render( RenderStateFlags state ) const { - aabb_draw_solid( m_aabb, state ); -} -}; - -class RenderableWireframeAABB : public OpenGLRenderable -{ -const AABB& m_aabb; -public: -RenderableWireframeAABB( const AABB& aabb ) : m_aabb( aabb ){ -} -void render( RenderStateFlags state ) const { - aabb_draw_wire( m_aabb ); -} -}; - - -/// \brief A key/value pair of strings. -/// -/// - Notifies observers when value changes - value changes to "" on destruction. -/// - Provides undo support through the global undo system. -class KeyValue : public EntityKeyValue -{ -typedef UnsortedSet KeyObservers; - -std::size_t m_refcount; -KeyObservers m_observers; -CopiedString m_string; -const char* m_empty; -ObservedUndoableObject m_undo; -static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged; -public: - -KeyValue( const char* string, const char* empty ) - : m_refcount( 0 ), m_string( string ), m_empty( empty ), m_undo( m_string, UndoImportCaller( *this ) ){ - notify(); -} -~KeyValue(){ - ASSERT_MESSAGE( m_observers.empty(), "KeyValue::~KeyValue: observers still attached" ); -} - -static void setKeyValueChangedFunc( EntityCreator::KeyValueChangedFunc func ){ - m_entityKeyValueChanged = func; -} - -void IncRef(){ - ++m_refcount; -} -void DecRef(){ - if ( --m_refcount == 0 ) { - delete this; - } -} - -void instanceAttach( MapFile* map ){ - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - m_undo.instanceDetach( map ); -} - -void attach( const KeyObserver& observer ){ - ( *m_observers.insert ( observer ) )( c_str() ); -} -void detach( const KeyObserver& observer ){ - observer( m_empty ); - m_observers.erase( observer ); -} -const char* c_str() const { - if ( string_empty( m_string.c_str() ) ) { - return m_empty; - } - return m_string.c_str(); -} -void assign( const char* other ){ - if ( !string_equal( m_string.c_str(), other ) ) { - m_undo.save(); - m_string = other; - notify(); - } -} - -void notify(){ - m_entityKeyValueChanged(); - KeyObservers::reverse_iterator i = m_observers.rbegin(); - while ( i != m_observers.rend() ) - { - ( *i++ )( c_str() ); - } -} - -void importState( const CopiedString& string ){ - m_string = string; - - notify(); -} -typedef MemberCaller UndoImportCaller; -}; - -/// \brief An unsorted list of key/value pairs. -/// -/// - Notifies observers when a pair is inserted or removed. -/// - Provides undo support through the global undo system. -/// - New keys are appended to the end of the list. -#include "stream/stringstream.h" -class EntityKeyValues : public Entity -{ -public: -typedef KeyValue Value; - -static StringPool& getPool(){ - return Static::instance(); -} -private: -static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged; -static Counter* m_counter; - -EntityClass* m_eclass; - -class KeyContext {}; -typedef Static KeyPool; -typedef PooledString Key; -typedef SmartPointer KeyValuePtr; -typedef UnsortedMap KeyValues; -KeyValues m_keyValues; - -typedef UnsortedSet Observers; -Observers m_observers; - -ObservedUndoableObject m_undo; -bool m_instanced; - -bool m_observerMutex; - -void notifyInsert( const char* key, Value& value ){ - m_observerMutex = true; - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->insert( key, value ); - } - m_observerMutex = false; -} -void notifyErase( const char* key, Value& value ){ - m_observerMutex = true; - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->erase( key, value ); - } - m_observerMutex = false; -} -void forEachKeyValue_notifyInsert(){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - notifyInsert( ( *i ).first.c_str(), *( *i ).second ); - } -} -void forEachKeyValue_notifyErase(){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - notifyErase( ( *i ).first.c_str(), *( *i ).second ); - } -} - -void insert( const char* key, const KeyValuePtr& keyValue ){ - KeyValues::iterator i = m_keyValues.insert( KeyValues::value_type( key, keyValue ) ); - notifyInsert( key, *( *i ).second ); - - if ( m_instanced ) { - ( *i ).second->instanceAttach( m_undo.map() ); - } -} - -/* see if our key already exists in here */ -void insert( const char* key, const char* value ){ - int dupecheck = 1; - - if (!strncmp(key, "On", 2)) - dupecheck = 0; - - KeyValues::iterator i = m_keyValues.find( key ); - - /* does the key already exist */ - if (i != m_keyValues.end() ) { - /* re-assign only when we're a special field, else pick a new name */ - if (dupecheck) { - ( *i ).second->assign( value ); - printf("[ENTLIB]: dupe found, setting %s to %s\n", key, value); - } else { - bool b = true; - unsigned int num = 0; - StringOutputStream new_key(64); - - /* loop through and generate an enumerated variant */ - do { - /* keep incrementing num until we find a free slot */ - num++; - new_key.clear(); - new_key << key << "#" << Unsigned(num); - i = m_keyValues.find(new_key.c_str()); - - if (i == m_keyValues.end()) { - insert(new_key.c_str(), value); - b = false; - } - } while (b != false); - } - } - else - { - m_undo.save(); - insert( key, KeyValuePtr( new KeyValue( value, EntityClass_valueForKey( *m_eclass, key ) ) ) ); - printf("[ENTLIB]: inserting key %s = %s\n", key, value); - } -} - -void erase( KeyValues::iterator i ){ - if ( m_instanced ) { - ( *i ).second->instanceDetach( m_undo.map() ); - } - - Key key( ( *i ).first ); - KeyValuePtr value( ( *i ).second ); - m_keyValues.erase( i ); - notifyErase( key.c_str(), *value ); -} - -void erase( const char* key ){ - KeyValues::iterator i = m_keyValues.find( key ); - if ( i != m_keyValues.end() ) { - m_undo.save(); - erase( i ); - } -} - -public: -bool m_isContainer; - -EntityKeyValues( EntityClass* eclass ) : - m_eclass( eclass ), - m_undo( m_keyValues, UndoImportCaller( *this ) ), - m_instanced( false ), - m_observerMutex( false ), - m_isContainer( !eclass->fixedsize ){ -} -EntityKeyValues( const EntityKeyValues& other ) : - Entity( other ), - m_eclass( &other.getEntityClass() ), - m_undo( m_keyValues, UndoImportCaller( *this ) ), - m_instanced( false ), - m_observerMutex( false ), - m_isContainer( other.m_isContainer ){ - for ( KeyValues::const_iterator i = other.m_keyValues.begin(); i != other.m_keyValues.end(); ++i ) - { - insert( ( *i ).first.c_str(), ( *i ).second->c_str() ); - } -} -~EntityKeyValues(){ - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ) - { - // post-increment to allow current element to be removed safely - ( *i++ )->clear(); - } - ASSERT_MESSAGE( m_observers.empty(), "EntityKeyValues::~EntityKeyValues: observers still attached" ); -} - -static void setKeyValueChangedFunc( EntityCreator::KeyValueChangedFunc func ){ - m_entityKeyValueChanged = func; - KeyValue::setKeyValueChangedFunc( func ); -} -static void setCounter( Counter* counter ){ - m_counter = counter; -} - -void importState( const KeyValues& keyValues ){ - for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ) - { - erase( i++ ); - } - - for ( KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i ) - { - insert( ( *i ).first.c_str(), ( *i ).second ); - } - - m_entityKeyValueChanged(); -} -typedef MemberCaller UndoImportCaller; - -void attach( Observer& observer ){ - ASSERT_MESSAGE( !m_observerMutex, "observer cannot be attached during iteration" ); - m_observers.insert( &observer ); - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - observer.insert( ( *i ).first.c_str(), *( *i ).second ); - } -} -void detach( Observer& observer ){ - ASSERT_MESSAGE( !m_observerMutex, "observer cannot be detached during iteration" ); - m_observers.erase( &observer ); - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - observer.erase( ( *i ).first.c_str(), *( *i ).second ); - } -} - -void forEachKeyValue_instanceAttach( MapFile* map ){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - ( *i ).second->instanceAttach( map ); - } -} -void forEachKeyValue_instanceDetach( MapFile* map ){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - ( *i ).second->instanceDetach( map ); - } -} - -void instanceAttach( MapFile* map ){ - if ( m_counter != 0 ) { - m_counter->increment(); - } - - m_instanced = true; - forEachKeyValue_instanceAttach( map ); - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - if ( m_counter != 0 ) { - m_counter->decrement(); - } - - m_undo.instanceDetach( map ); - forEachKeyValue_instanceDetach( map ); - m_instanced = false; -} - -// entity -EntityClass& getEntityClass() const { - return *m_eclass; -} -void forEachKeyValue( Visitor& visitor ) const { - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - visitor.visit( ( *i ).first.c_str(), ( *i ).second->c_str() ); - } -} -void setKeyValue( const char* key, const char* value ){ - if ( value[0] == '\0' - /*|| string_equal(EntityClass_valueForKey(*m_eclass, key), value)*/ ) { // don't delete values equal to default - erase( key ); - } - else - { - insert( key, value ); - } - m_entityKeyValueChanged(); -} -const char* getKeyValue( const char* key ) const { - KeyValues::const_iterator i = m_keyValues.find( key ); - if ( i != m_keyValues.end() ) { - return ( *i ).second->c_str(); - } - - return EntityClass_valueForKey( *m_eclass, key ); -} -int getKeyEntries( void ) const { - int i = 0; - - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - i++; - } -} - -bool isContainer() const { - return m_isContainer; -} -}; - -/// \brief A Resource reference with a controlled lifetime. -/// \brief The resource is released when the ResourceReference is destroyed. -class ResourceReference -{ -CopiedString m_name; -Resource* m_resource; -public: -ResourceReference( const char* name ) - : m_name( name ){ - capture(); -} -ResourceReference( const ResourceReference& other ) - : m_name( other.m_name ){ - capture(); -} -ResourceReference& operator=( const ResourceReference& other ){ - ResourceReference tmp( other ); - tmp.swap( *this ); - return *this; -} -~ResourceReference(){ - release(); -} - -void capture(){ - m_resource = GlobalReferenceCache().capture( m_name.c_str() ); -} -void release(){ - GlobalReferenceCache().release( m_name.c_str() ); -} - -const char* getName() const { - return m_name.c_str(); -} -void setName( const char* name ){ - ResourceReference tmp( name ); - tmp.swap( *this ); -} - -void swap( ResourceReference& other ){ - std::swap( m_resource, other.m_resource ); - std::swap( m_name, other.m_name ); -} - -void attach( ModuleObserver& observer ){ - m_resource->attach( observer ); -} -void detach( ModuleObserver& observer ){ - m_resource->detach( observer ); -} - -Resource* get(){ - return m_resource; -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( ResourceReference& self, ResourceReference& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/entityxml.h b/libs/entityxml.h deleted file mode 100644 index 89a9406..0000000 --- a/libs/entityxml.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITYXML_H ) -#define INCLUDED_ENTITYXML_H - -#include "ientity.h" -#include "xml/ixml.h" -#include "xml/xmlelement.h" - -class entity_import : public XMLImporter -{ -Entity& m_entity; -public: -entity_import( Entity& entity ) - : m_entity( entity ){ -} -void pushElement( const XMLElement& element ){ - if ( strcmp( element.name(), "epair" ) == 0 ) { - m_entity.setKeyValue( element.attribute( "key" ), element.attribute( "value" ) ); - } -} -void popElement( const char* name ){ -} -std::size_t write( const char* data, std::size_t length ){ - return length; -} -}; - -class entity_export : public XMLExporter -{ -class ExportXMLVisitor : public Entity::Visitor -{ -XMLImporter& m_importer; -public: -ExportXMLVisitor( XMLImporter& importer ) : m_importer( importer ){ -} -void visit( const char* key, const char* value ){ - StaticElement element( "epair" ); - element.insertAttribute( "key", key ); - element.insertAttribute( "value", value ); - m_importer.pushElement( element ); - m_importer.popElement( element.name() ); -} -}; - -const Entity& m_entity; - -public: -entity_export( const Entity& entity ) : m_entity( entity ){ -} -void exportXML( XMLImporter& observer ){ - ExportXMLVisitor visitor( observer ); - - m_entity.forEachKeyValue( visitor ); -} -}; - -inline void entity_copy( Entity& entity, const Entity& other ){ - entity_export exporter( other ); - entity_import importer( entity ); - exporter.exportXML( importer ); -} - -template -class EntityConstruction -{ -public: -typedef EntityClass* type; -static type get( const EntityType& entity ){ - return &entity.getEntity().getEntityClass(); -} -static void copy( EntityType& entity, const EntityType& other ){ - entity_copy( entity.getEntity(), other.getEntity() ); -} -}; - - - -#endif diff --git a/libs/fs_filesystem.h b/libs/fs_filesystem.h deleted file mode 100644 index 5cd42a6..0000000 --- a/libs/fs_filesystem.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FS_FILESYSTEM_H ) -#define INCLUDED_FS_FILESYSTEM_H - -#include "string/string.h" -#include "os/path.h" - -#include - -inline unsigned int path_get_depth( const char* path ){ - unsigned int depth = 0; - while ( path != 0 && path[0] != '\0' ) - { - path = strchr( path, '/' ); - if ( path != 0 ) { - ++path; - } - ++depth; - } - return depth; -} - -/// \brief A generic unix-style file-system which maps paths to files and directories. -/// Provides average O(log n) find and insert methods. -/// \param file_type The data type which represents a file. -template -class GenericFileSystem -{ -class Path -{ -CopiedString m_path; -unsigned int m_depth; -public: -Path( const char* path ) - : m_path( path ), m_depth( path_get_depth( c_str() ) ){ -} -Path( StringRange range ) - : m_path( range ), m_depth( path_get_depth( c_str() ) ){ -} -bool operator<( const Path& other ) const { - return string_less_nocase( c_str(), other.c_str() ); -} -unsigned int depth() const { - return m_depth; -} -const char* c_str() const { - return m_path.c_str(); -} -}; - -class Entry -{ -file_type* m_file; -public: -Entry() : m_file( 0 ){ -} -Entry( file_type* file ) : m_file( file ){ -} -file_type* file() const { - return m_file; -} -bool is_directory() const { - return file() == 0; -} -}; - -typedef std::map Entries; -Entries m_entries; - -public: -typedef typename Entries::iterator iterator; -typedef typename Entries::value_type value_type; -typedef Entry entry_type; - -iterator begin(){ - return m_entries.begin(); -} -iterator end(){ - return m_entries.end(); -} - -/// \brief Returns the file at \p path. -/// Creates all directories below \p path if they do not exist. -/// O(log n) on average. -entry_type& operator[]( const Path& path ){ - { - const char* end = path_remove_directory( path.c_str() ); - while ( end[0] != '\0' ) - { - Path dir( StringRange( path.c_str(), end ) ); - m_entries.insert( value_type( dir, Entry( 0 ) ) ); - end = path_remove_directory( end ); - } - } - - return m_entries[path]; -} - -/// \brief Returns the file at \p path or end() if not found. -iterator find( const Path& path ){ - return m_entries.find( path ); -} - -iterator begin( const char* root ){ - if ( root[0] == '\0' ) { - return m_entries.begin(); - } - iterator i = m_entries.find( root ); - if ( i == m_entries.end() ) { - return i; - } - return ++i; -} - -/// \brief Performs a depth-first traversal of the file-system subtree rooted at \p root. -/// Traverses the entire tree if \p root is "". -/// Calls \p visitor.file() with the path to each file relative to the filesystem root. -/// Calls \p visitor.directory() with the path to each directory relative to the filesystem root. -template -void traverse( visitor_type visitor, const char* root ){ - unsigned int start_depth = path_get_depth( root ); - unsigned int skip_depth = 0; - for ( iterator i = begin( root ); i != end() && i->first.depth() > start_depth; ++i ) - { - if ( i->first.depth() == skip_depth ) { - skip_depth = 0; - } - if ( skip_depth == 0 ) { - if ( !i->second.is_directory() ) { - visitor.file( i->first.c_str() ); - } - else if ( visitor.directory( i->first.c_str(), i->first.depth() - start_depth ) ) { - skip_depth = i->first.depth(); - } - } - } -} -}; - -#endif diff --git a/libs/fs_path.h b/libs/fs_path.h deleted file mode 100644 index 2baf297..0000000 --- a/libs/fs_path.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FS_PATH_H ) -#define INCLUDED_FS_PATH_H - -#include "stream/stringstream.h" - -/// \brief A unix-style path string which can be modified at runtime. -/// -/// - Maintains a path ending in a path-separator. -/// - Provides a limited STL-style interface to push and pop file or directory names at the end of the path. -class UnixPath -{ -StringBuffer m_string; - -void check_separator(){ - if ( !empty() && m_string.back() != '/' ) { - m_string.push_back( '/' ); - } -} - -public: -/// \brief Constructs with the directory \p root. -UnixPath( const char* root ) - : m_string( root ){ - check_separator(); -} - -bool empty() const { - return m_string.empty(); -} - -const char* c_str() const { - return m_string.c_str(); -} - -/// \brief Appends the directory \p name. -void push( const char* name ){ - m_string.push_string( name ); - check_separator(); -} -/// \brief Appends the directory [\p first, \p last). -void push( const char* first, const char* last ){ - m_string.push_range( first, last ); - check_separator(); -} -/// \brief Appends the filename \p name. -void push_filename( const char* name ){ - m_string.push_string( name ); -} -/// \brief Removes the last directory or filename appended. -void pop(){ - if ( m_string.back() == '/' ) { - m_string.pop_back(); - } - while ( !empty() && m_string.back() != '/' ) - { - m_string.pop_back(); - } -} -}; - -#endif diff --git a/libs/generic/Makefile b/libs/generic/Makefile deleted file mode 100644 index 45e95c6..0000000 --- a/libs/generic/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - callback.o constant.o object.o static.o - -# binary target -../libgeneric.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -callback.o: callback.cpp callback.h -constant.o: constant.cpp constant.h -object.o: object.cpp object.h -static.o: static.cpp static.h - -clean: - -rm -f *.o ../libgeneric.a diff --git a/libs/generic/arrayrange.h b/libs/generic/arrayrange.h deleted file mode 100644 index e036cf3..0000000 --- a/libs/generic/arrayrange.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_ARRAYRANGE_H ) -#define INCLUDED_GENERIC_ARRAYRANGE_H - -/// \file -/// \brief Macros for automatically converting a compile-time-sized array to a range. - -template -struct ArrayRange -{ - typedef Element* Iterator; - ArrayRange( Iterator first, Iterator last ) - : first( first ), last( last ){ - } - Iterator first; - Iterator last; -}; - -template -inline ArrayRange makeArrayRange( Element* first, Element* last ){ - return ArrayRange( first, last ); -} - -template -struct ArrayConstRange -{ - typedef const Element* Iterator; - ArrayConstRange( Iterator first, Iterator last ) - : first( first ), last( last ){ - } - Iterator first; - Iterator last; -}; - -template -inline ArrayConstRange makeArrayRange( const Element* first, const Element* last ){ - return ArrayConstRange( first, last ); -} - -#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( *array ) ) -#define ARRAY_END( array ) ( array + ARRAY_SIZE( array ) ) -#define ARRAY_RANGE( array ) ( makeArrayRange( array, ARRAY_END( array ) ) ) - - -typedef ArrayConstRange StringArrayRange; -#define STRING_ARRAY_RANGE( array ) ( StringArrayRange( array, ARRAY_END( array ) ) ) - -typedef ArrayRange StringRange; - -#endif diff --git a/libs/generic/bitfield.h b/libs/generic/bitfield.h deleted file mode 100644 index f9427aa..0000000 --- a/libs/generic/bitfield.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_BITFIELD_H ) -#define INCLUDED_GENERIC_BITFIELD_H - -/// \file -/// \brief Type safe bitfield. - -/// \brief A bit-field value. -/// -/// - Can be forward-declared when the definition of Enumeration is unknown. -/// - Can only be constructed from valid enumerated values. -/// - Can only be compared and combined with others of the same type. -/// -/// \param Enumeration A type that contains an enum \c Value of the bits that can be set in this field. -template -class BitFieldValue : public Enumeration -{ -unsigned m_value; -protected: -explicit BitFieldValue( unsigned value ) : m_value( value ){ -} -public: -BitFieldValue() : m_value( 0 ){ -} -explicit BitFieldValue( typename Enumeration::Value value ) : m_value( 1 << value ){ -} -unsigned get() const { - return m_value; -} -}; - -template -class BitFieldValueUnsafe : public BitFieldValue -{ -public: -explicit BitFieldValueUnsafe( unsigned value ) : BitFieldValue( value ){ -} -}; - -template -inline bool operator==( BitFieldValue self, BitFieldValue other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( BitFieldValue self, BitFieldValue other ){ - return !operator==( self, other ); -} - -template -inline BitFieldValue operator|( BitFieldValue self, BitFieldValue other ){ - return BitFieldValueUnsafe( self.get() | other.get() ); -} -template -inline BitFieldValue& operator|=( BitFieldValue& self, BitFieldValue other ){ - return self = self | other; -} -template -inline BitFieldValue operator&( BitFieldValue self, BitFieldValue other ){ - return BitFieldValueUnsafe( self.get() & other.get() ); -} -template -inline BitFieldValue& operator&=( BitFieldValue& self, BitFieldValue other ){ - return self = self & other; -} -template -inline BitFieldValue operator~( BitFieldValue self ){ - return BitFieldValueUnsafe( ~self.get() ); -} - - - -inline unsigned int bitfield_enable( unsigned int bitfield, unsigned int mask ){ - return bitfield | mask; -} -inline unsigned int bitfield_disable( unsigned int bitfield, unsigned int mask ){ - return bitfield & ~mask; -} -inline bool bitfield_enabled( unsigned int bitfield, unsigned int mask ){ - return ( bitfield & mask ) != 0; -} - -template -inline BitFieldValue bitfield_enable( BitFieldValue bitfield, BitFieldValue mask ){ - return bitfield | mask; -} -template -inline BitFieldValue bitfield_disable( BitFieldValue bitfield, BitFieldValue mask ){ - return bitfield & ~mask; -} -template -inline bool bitfield_enabled( BitFieldValue bitfield, BitFieldValue mask ){ - return ( bitfield & mask ).get() != 0; -} - -#endif diff --git a/libs/generic/callback.cpp b/libs/generic/callback.cpp deleted file mode 100644 index c6dfeee..0000000 --- a/libs/generic/callback.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "callback.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleMemberCaller -{ -// MemberCaller example -class Integer -{ -public: -int value; - -void printValue() const { - // print this->value here; -} - -void setValue(){ - value = 3; -} -// a typedef to make things more readable -typedef MemberCaller SetValueCaller; -}; - -void example(){ - Integer foo = { 0 }; - - { - Callback bar = ConstMemberCaller( foo ); - - // invoke the callback - bar(); // foo.printValue() - } - - - { - // use the typedef to improve readability - Callback bar = Integer::SetValueCaller( foo ); - - // invoke the callback - bar(); // foo.setValue() - } -} -// end example -} - -namespace ExampleReferenceCaller -{ -// ReferenceCaller example -void Int_printValue( const int& value ){ - // print value here; -} - -void Int_setValue( int& value ){ - value = 3; -} - -// a typedef to make things more readable -typedef ReferenceCaller IntSetValueCaller; - -void example(){ - int foo = 0; - - { - Callback bar = ConstReferenceCaller( foo ); - - // invoke the callback - bar(); // Int_printValue(foo) - } - - - { - // use the typedef to improve readability - Callback bar = IntSetValueCaller( foo ); - - // invoke the callback - bar(); // Int_setValue(foo) - } -} -// end example -} - -#endif - -namespace -{ -class A1 -{ -}; -class A2 -{ -}; -class A3 -{ -}; -class A4 -{ -}; - -class Test -{ -public: -void test0(){ -} -typedef Member Test0; -typedef MemberCaller Test0Caller; -void test0const() const { -} -typedef ConstMember Test0Const; -typedef ConstMemberCaller Test0ConstCaller; -void test1( A1 ){ -} -typedef Member Test1; -typedef MemberCaller Test1Caller; -void test1const( A1 ) const { -} -typedef ConstMember Test1Const; -typedef ConstMemberCaller Test1ConstCaller; -void test2( A1, A2 ){ -} -typedef Member Test2; -void test2const( A1, A2 ) const { -} -typedef ConstMember Test2Const; -void test3( A1, A2, A3 ){ -} -typedef Member Test3; -void test3const( A1, A2, A3 ) const { -} -typedef ConstMember Test3Const; -}; - -void test0free(){ -} -void test1free( A1 ){ -} -void test2free( A1, A2 ){ -} -typedef Function Test2Free; -void test3free( A1, A2, A3 ){ -} -typedef Function Test3Free; - - -void test0( Test& test ){ -} -typedef ReferenceCaller Test0Caller; - -void test0const( const Test& test ){ -} -typedef ConstReferenceCaller Test0ConstCaller; - -void test0p( Test* test ){ -} -typedef PointerCaller Test0PCaller; - -void test0constp( const Test* test ){ -} -typedef ConstPointerCaller Test0ConstPCaller; - -void test1( Test& test, A1 ){ -} -typedef ReferenceCaller Test1Caller; - -void test1const( const Test& test, A1 ){ -} -typedef ConstReferenceCaller Test1ConstCaller; - -void test1p( Test* test, A1 ){ -} -typedef PointerCaller Test1PCaller; - -void test1constp( const Test* test, A1 ){ -} -typedef ConstPointerCaller Test1ConstPCaller; - -void test2( Test& test, A1, A2 ){ -} -typedef Function Test2; - -void test3( Test& test, A1, A2, A3 ){ -} -typedef Function Test3; - -void instantiate(){ - Test test; - const Test& testconst = test; - { - Callback a = makeCallbackF(&test0free); - Callback b = Test::Test0Caller( test ); - b = makeCallback( Test::Test0(), test ); - Callback c = Test::Test0ConstCaller( testconst ); - c = makeCallback( Test::Test0Const(), test ); - Test0Caller{ test }; - Test0ConstCaller{ testconst }; - Test0PCaller{ &test }; - Test0ConstPCaller{ &testconst }; - a(); - bool u = a != b; - } - { - typedef Callback TestCallback1; - TestCallback1 a = makeCallbackF(&test1free); - TestCallback1 b = Test::Test1Caller( test ); - b = makeCallback( Test::Test1(), test ); - TestCallback1 c = Test::Test1ConstCaller( testconst ); - c = makeCallback( Test::Test1Const(), test ); - Test1Caller{ test }; - Test1ConstCaller{ testconst }; - Test1PCaller{ &test }; - Test1ConstPCaller{ &testconst }; - a( A1() ); - bool u = a != b; - } - { - typedef Callback TestCallback2; - TestCallback2 a = makeStatelessCallback( Test2Free() ); - TestCallback2 b = makeCallback( Test2(), test ); - makeCallback( Test::Test2(), test ); - makeCallback( Test::Test2Const(), test ); - a( A1(), A2() ); - bool u = a != b; - } - { - typedef Callback TestCallback3; - TestCallback3 a = makeStatelessCallback( Test3Free() ); - TestCallback3 b = makeCallback( Test3(), test ); - makeCallback( Test::Test3(), test ); - makeCallback( Test::Test3Const(), test ); - a( A1(), A2(), A3() ); - bool u = a != b; - } -} -} diff --git a/libs/generic/callback.h b/libs/generic/callback.h deleted file mode 100644 index 9c16e55..0000000 --- a/libs/generic/callback.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_CLOSURE_H ) -#define INCLUDED_GENERIC_CLOSURE_H - -/// \file -/// \brief Type-safe techniques for binding the first argument of an opaque callback. - -#include -#include "functional.h" - -namespace detail { - -template -class CallbackBase { -void *m_environment; -Thunk_ m_thunk; -public: -typedef Thunk_ Thunk; - -CallbackBase(void *environment, Thunk function) : m_environment(environment), m_thunk(function) { -} - -void *getEnvironment() const { - return m_environment; -} - -Thunk getThunk() const { - return m_thunk; -} -}; - -template -inline bool operator==(const CallbackBase &self, const CallbackBase &other) { - return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk(); -} - -template -inline bool operator!=(const CallbackBase &self, const CallbackBase &other) { - return !(self == other); -} - -template -inline bool operator<(const CallbackBase &self, const CallbackBase &other) { - return self.getEnvironment() < other.getEnvironment() || - (!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk()); -} - -} - -namespace detail { - -template -struct ConvertFromOpaque { -}; - -// reference - -template -inline const void *convertToOpaque(const T &t) { - return &t; -} - -template -struct ConvertFromOpaque { - static T const &apply(void *p) { - return *static_cast(p); - } -}; - -template -inline void *convertToOpaque(T &t) { - return &t; -} - -template -struct ConvertFromOpaque { - static T &apply(void *p) { - return *static_cast( p ); - } -}; - -// pointer - -template::value>::type> -inline const void *convertToOpaque(const T *t) { - return t; -} - -template -struct ConvertFromOpaque { - static const T *apply(void *p) { - return static_cast(p); - } -}; - -template::value>::type> -inline void *convertToOpaque(T *t) { - return t; -} - -template -struct ConvertFromOpaque { - static T *apply(void *p) { - return static_cast(p); - } -}; - -// function pointer - -template -inline const void *convertToOpaque(R(*const &t)(Ts ...)) { - return &t; -} - -template -struct ConvertFromOpaque { - using Type = R (*)(Ts...); - - static Type const &apply(void *p) { - return *static_cast(p); - } -}; - -template -inline void *convertToOpaque(R(*&t)(Ts ...)) { - return &t; -} - -template -struct ConvertFromOpaque { - using Type = R (*)(Ts...); - - static Type &apply(void *p) { - return *static_cast(p); - } -}; - -template -class BindFirstOpaqueN; - -template -class BindFirstOpaqueN { -FirstBound firstBound; -public: -explicit BindFirstOpaqueN(FirstBound firstBound) : firstBound(firstBound) { -} - -R operator()(Ts... args) const { - return Caller::call(firstBound, args ...); -} - -FirstBound getBound() const { - return firstBound; -} - -static R thunk(void *environment, Ts... args) { - return thunk_(detail::ConvertFromOpaque::apply(environment), args ...); -} - -static R thunk_(FirstBound environment, Ts... args) { - return Caller::call(environment, args ...); -} - -void *getEnvironment() const { - return const_cast(detail::convertToOpaque(firstBound)); -} -}; - -} - -template -using BindFirstOpaque = detail::BindFirstOpaqueN >; - -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer. -/// -/// Use with the callback constructors MemberCaller0, ConstMemberCaller0, ReferenceCaller0, ConstReferenceCaller0, PointerCaller0, ConstPointerCaller0 and FreeCaller0. -template -class Callback; - -template -class Callback : public detail::CallbackBase { -using Base = detail::CallbackBase; - -static R nullThunk(void *, Ts...) { -} - -public: -using func = R(Ts ...); - -Callback() : Base(0, nullThunk) { -} - -template -Callback(const BindFirstOpaque &caller) : Base(caller.getEnvironment(), BindFirstOpaque::thunk) { -} - -Callback(void *environment, typename Base::Thunk function) : Base(environment, function) { -} - -R operator()(Ts... args) const { - return Base::getThunk()(Base::getEnvironment(), args ...); -} -}; - -namespace detail { -template -struct Arglist; - -template -struct Arglist { - using type = R(Head, Ts ...); - - template - using unshift = Arglist; - - using shift = Arglist; -}; - -template -struct Arglist { - using type = R(Ts ...); - - template - using unshift = Arglist; -}; - -template -using ArgShift = typename detail::Arglist::shift::type; - -template -using ArgUnshift = typename detail::Arglist::template unshift::type; -} - -template -inline Callback > > makeCallback(const Caller &caller, get_argument callee) { - return BindFirstOpaque(callee); -} - -template -class CallerShiftFirst; - -template -class CallerShiftFirst { -public: -using func = R(FirstArgument, Ts ...); - -static R call(FirstArgument, Ts... args) { - return Caller::call(args ...); -} -}; - -template -inline Callback > makeStatelessCallback(const Caller &caller) { - return makeCallback(CallerShiftFirst, void *> >(), nullptr); -} - -/// \brief Forms a Callback from a non-const Environment reference and a non-const Environment member-function. -template member> -using MemberCaller = BindFirstOpaque >; - -/// \brief Constructs a Callback1 from a non-const \p functor -/// -/// \param Functor Must define \c first_argument_type and \c operator()(first_argument_type). -template -inline Callback > makeCallback(Functor &functor) { - return MemberCaller, &Functor::operator()>(functor); -} - -/// \brief Forms a Callback from a const Environment reference and a const Environment member-function. -template member> -using ConstMemberCaller = BindFirstOpaque >; - -/// \brief Constructs a Callback1 from a const \p functor -/// -/// \param Functor Must define \c first_argument_type and const \c operator()(first_argument_type). -template -inline Callback > makeCallback(const Functor &functor) { - return ConstMemberCaller, &Functor::operator()>(functor); -} - -/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference. -template *func> -using ReferenceCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference. -template *func> -using ConstReferenceCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer. -template *func> -using PointerCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer. -template *func> -using ConstPointerCaller = BindFirstOpaque, func> >; - -namespace detail { -template -class FreeCaller : public BindFirstOpaque > > { -public: -FreeCaller() : BindFirstOpaque > >(nullptr) { -} -}; - -template -struct FreeCallerWrapper; - -template -struct FreeCallerWrapper { - using func = R(void *, Ts ...); - - static R call(void *f, Ts... args) { - // ideally, we'd get the implementation of the function type directly. Instead, it's passed in - return reinterpret_cast(f)(args ...); - } -}; -} - -/// \brief Forms a Callback from a free function -template -using FreeCaller = detail::FreeCaller, F>; - -template -inline Callback makeCallbackF(R (*func)(Ts...)) { - void *pVoid = reinterpret_cast(func); - return BindFirstOpaque >(pVoid); -} - -#endif diff --git a/libs/generic/constant.cpp b/libs/generic/constant.cpp deleted file mode 100644 index bcf9b4e..0000000 --- a/libs/generic/constant.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "constant.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleConstant -{ -class Bleh -{ -public: - -STRING_CONSTANT( Name, "Bleh" ); -INTEGER_CONSTANT( Version, 1 ); -}; - -int version = Bleh::Version(); -const char* name = Bleh::Name(); -} - -#endif diff --git a/libs/generic/constant.h b/libs/generic/constant.h deleted file mode 100644 index ab64ec3..0000000 --- a/libs/generic/constant.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_CONSTANT_H ) -#define INCLUDED_GENERIC_CONSTANT_H - -/// \file -/// \brief Language extensions for constants that are guaranteed to be evaluated at compile-time. - -/// \brief A compile-time-constant as a type. -template -struct ConstantWrapper -{ - typedef typename Type::Value Value; - operator Value() const - { - return Type::evaluate(); - } -}; -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConstantWrapper& c ){ - return ostream_write( ostream, typename Type::Value( c ) ); -} - -#define TYPE_CONSTANT( name, value, type ) struct name ## _CONSTANT_ { typedef type Value; static Value evaluate() { return value; } }; typedef ConstantWrapper name -#define STRING_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, const char* ) -#define INTEGER_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, int ) -#define UINT_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, unsigned int ) - -STRING_CONSTANT( EmptyString, "" ); - -#endif diff --git a/libs/generic/enumeration.h b/libs/generic/enumeration.h deleted file mode 100644 index 8d6c75e..0000000 --- a/libs/generic/enumeration.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_ENUMERATION_H ) -#define INCLUDED_GENERIC_ENUMERATION_H - -/// \file -/// \brief Type safe enumeration. - -/// \brief An enumerated value. -/// -/// - Can be forward-declared when the definition of Enumeration is unknown. -/// - Can only be constructed from valid enumerated values. -/// - Can only be compared with others of the same type. -/// -/// \param Enumeration A type that contains an enum \c Value of the allowed values of the enumeration. -template -class EnumeratedValue : public Enumeration -{ -typename Enumeration::Value m_value; -public: -explicit EnumeratedValue( typename Enumeration::Value value ) : m_value( value ){ -} -typename Enumeration::Value get() const { - return m_value; -} -}; - -template -inline bool operator==( EnumeratedValue self, EnumeratedValue other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( EnumeratedValue self, EnumeratedValue other ){ - return !operator==( self, other ); -} - -#endif diff --git a/libs/generic/functional.h b/libs/generic/functional.h deleted file mode 100644 index cb618cf..0000000 --- a/libs/generic/functional.h +++ /dev/null @@ -1,214 +0,0 @@ -#if !defined( INCLUDED_FUNCTIONAL_H ) -#define INCLUDED_FUNCTIONAL_H - -#include -#include - -namespace detail { - -template -struct rank : rank { -}; - -template<> -struct rank<0> { -}; - -struct get_func { - - template - struct wrapper { - using type = T; - }; - - template - using func_member = wrapper; - - template - static wrapper > test(rank<2>) { - return {}; - } - - template - struct func_lambda { - using type = typename func_lambda::type; - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template > - static wrapper > test(rank<1>) { - return {}; - } -}; - -template -struct Fn; - -template -struct Fn { - using result_type = R; - - template - using get = typename std::tuple_element >::type; -}; -} - -template -using get_func = typename decltype(detail::get_func::test(detail::rank<2>{}))::type::type; - -template -using get_result_type = typename detail::Fn >::result_type; - -template -using get_argument = typename detail::Fn >::template get; - -namespace detail { - -template -class FunctionN; - -template -class FunctionN { -public: -template -class instance { -public: -using func = R(Ts ...); - -static R call(Ts... args) { - return (f)(args ...); -} -}; -}; - -} - -template -using Function = typename detail::FunctionN::template instance; - -namespace detail { -template -struct MemberFunction; - -template -struct MemberFunction { - using type = R (Object::*)(Ts...); - using type_const = R (Object::*)(Ts...) const; -}; -} - -namespace detail { -template -class MemberN; - -template -class MemberN { -public: -template -class instance { -public: -using func = R(Object &, Ts ...); - -static R call(Object &object, Ts... args) { - return (object.*f)(args ...); -} -}; -}; -} - -template -using MemberFunction = typename detail::MemberFunction::type; - -template func> -using Member = typename detail::MemberN::template instance; - -namespace detail { -template -class ConstMemberN; - -template -class ConstMemberN { -public: -template -class instance { -public: -using func = R(const Object &, Ts ...); - -static R call(const Object &object, Ts... args) { - return (object.*f)(args ...); -} -}; -}; -} - -template -using ConstMemberFunction = typename detail::MemberFunction::type_const; - -template func> -using ConstMember = typename detail::ConstMemberN::template instance; - -// misc - -namespace detail { -template -struct seq { -}; - -template -struct gens : gens { -}; - -template -struct gens<0, S...> { - using type = seq; -}; - -template -using seq_new = typename gens::type; - -template -class FunctorNInvoke; - -template -class FunctorNInvoke { -std::tuple args; - -template -struct caller; - -template -struct caller > { - static inline R call(FunctorNInvoke *self, Functor functor) { - (void) self; - return functor(std::get(self->args)...); - } -}; - -public: -FunctorNInvoke(Ts... args) : args(args ...) { -} - -inline R operator()(Functor functor) { - return caller >::call(this, functor); -} -}; -} - -template -using FunctorInvoke = detail::FunctorNInvoke >; - -#endif diff --git a/libs/generic/object.cpp b/libs/generic/object.cpp deleted file mode 100644 index bbb5610..0000000 --- a/libs/generic/object.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "object.h" - -namespace -{ -class Blah -{ -int i; -public: -Blah(){ - i = 3; -} -}; - -void Test(){ - char storage[sizeof( Blah )]; - constructor( *reinterpret_cast( storage ) ); -} -} \ No newline at end of file diff --git a/libs/generic/object.h b/libs/generic/object.h deleted file mode 100644 index 084f760..0000000 --- a/libs/generic/object.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_OBJECT_H ) -#define INCLUDED_GENERIC_OBJECT_H - -#include "globaldefs.h" - -/// \file -/// \brief Convenience functions (syntactic sugar) to wrap explicit constructor (aka in-place 'new') and destructor calls. -/// -/// Use makeReference() to wrap non-const-reference constructor parameters. - -#if GDEF_COMPILER_MSVC && _MSC_VER > 1000 -#pragma warning(disable:4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized -#endif - -#include - -template -inline void constructor( Type& object ){ - new( &object )Type(); -} - -template -inline void constructor( Type& object, const T1& t1 ){ - new( &object )Type( t1 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2 ){ - new( &object )Type( t1, t2 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3 ){ - new( &object )Type( t1, t2, t3 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4 ){ - new( &object )Type( t1, t2, t3, t4 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5 ){ - new( &object )Type( t1, t2, t3, t4, t5 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6, t7 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6, t7, t8 ); -} - -template -inline void destructor( Type& object ){ - object.~Type(); -} - - - -#endif diff --git a/libs/generic/reference.h b/libs/generic/reference.h deleted file mode 100644 index df5a05a..0000000 --- a/libs/generic/reference.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_REFERENCE_H ) -#define INCLUDED_GENERIC_REFERENCE_H - -/// \file -/// \brief Wrappers to allow storing objects in templated containers using 'reference' semantics. - -/// \brief A reference to a mutable object. -/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'. -/// \param Type The type of the referenced object. -template -class Reference -{ -Type* m_contained; -public: -explicit Reference( Type& contained ) : m_contained( &contained ){ -} -operator Type&() const -{ - return *m_contained; -} -Type& get() const { - return *m_contained; -} -Type* get_pointer() const { - return m_contained; -} -}; - -template -bool operator<( const Reference& self, const Reference& other ){ - return self.get() < other.get(); -} -template -bool operator==( const Reference& self, const Reference& other ){ - return self.get() == other.get(); -} - -/// \brief construct a reference to a mutable object. -template -inline Reference makeReference( Type& value ){ - return Reference( value ); -} - -/// \brief A reference to a non-mutable object. -/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'. -/// \param Type The type of the referenced object. -template -class ConstReference -{ -const Type* m_contained; -public: -explicit ConstReference( const Type& contained ) : m_contained( &contained ){ -} -operator const Type&() const -{ - return *m_contained; -} -const Type& get() const { - return *m_contained; -} -const Type* get_pointer() const { - return m_contained; -} -}; - -template -bool operator<( const ConstReference& self, const ConstReference& other ){ - return self.get() < other.get(); -} -template -bool operator==( const ConstReference& self, const ConstReference& other ){ - return self.get() == other.get(); -} - -/// \brief construct a reference to a non-mutable object. -template -inline ConstReference makeReference( const Type& value ){ - return ConstReference( value ); -} - - -#endif diff --git a/libs/generic/referencecounted.h b/libs/generic/referencecounted.h deleted file mode 100644 index 37abd91..0000000 --- a/libs/generic/referencecounted.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_REFERENCECOUNTED_H ) -#define INCLUDED_GENERIC_REFERENCECOUNTED_H - -/// \file -/// \brief 'smart' pointers and references. - -#include - -template -class IncRefDecRefCounter -{ -public: -void increment( Type& value ){ - value.IncRef(); -} -void decrement( Type& value ){ - value.DecRef(); -} -}; - -/// \brief A smart-pointer that uses a counter stored in the object pointed-to. -template > -class SmartPointer : public Counter -{ -Type* m_value; -public: - -SmartPointer( const SmartPointer& other ) - : m_value( other.m_value ){ - Counter::increment( *m_value ); -} -explicit SmartPointer( Type* value ) - : m_value( value ){ - Counter::increment( *m_value ); -} -~SmartPointer(){ - Counter::decrement( *m_value ); -} -SmartPointer& operator=( const SmartPointer& other ){ - SmartPointer temp( other ); - temp.swap( *this ); - return *this; -} -SmartPointer& operator=( Type* value ){ - SmartPointer temp( value ); - temp.swap( *this ); - return *this; -} -void swap( SmartPointer& other ){ - std::swap( m_value, other.m_value ); -} - -operator Type*() const -{ - return m_value; -} -Type& operator*() const { - return *m_value; -} -Type* operator->() const { - return m_value; -} -Type* get() const { - return m_value; -} -}; - -template -inline bool operator<( const SmartPointer& self, const SmartPointer& other ){ - return self.get() < other.get(); -} -template -inline bool operator==( const SmartPointer& self, const SmartPointer& other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( const SmartPointer& self, const SmartPointer& other ){ - return !::operator==( self, other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( SmartPointer& self, SmartPointer& other ){ - self.swap( other ); -} -} - - -/// \brief A smart-reference that uses a counter stored in the object pointed-to. -template > -class SmartReference : public Counter -{ -Type* m_value; -public: - -SmartReference( const SmartReference& other ) - : m_value( other.m_value ){ - Counter::increment( *m_value ); -} -explicit SmartReference( Type& value ) - : m_value( &value ){ - Counter::increment( *m_value ); -} -~SmartReference(){ - Counter::decrement( *m_value ); -} -SmartReference& operator=( const SmartReference& other ){ - SmartReference temp( other ); - temp.swap( *this ); - return *this; -} -SmartReference& operator=( Type& value ){ - SmartReference temp( value ); - temp.swap( *this ); - return *this; -} -void swap( SmartReference& other ){ - std::swap( m_value, other.m_value ); -} - -operator Type&() const -{ - return *m_value; -} -Type& get() const { - return *m_value; -} -Type* get_pointer() const { - return m_value; -} -}; - -template -inline bool operator<( const SmartReference& self, const SmartReference& other ){ - return self.get() < other.get(); -} -template -inline bool operator==( const SmartReference& self, const SmartReference& other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( const SmartReference& self, const SmartReference& other ){ - return !::operator==( self, other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( SmartReference& self, SmartReference& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/generic/static.cpp b/libs/generic/static.cpp deleted file mode 100644 index a92246b..0000000 --- a/libs/generic/static.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "static.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleStatic -{ -// Static example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -}; - -typedef Static StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - // StaticMyClass::instance() may be invalid here because construction order is undefined -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = StaticMyClass::instance().value; -} -// end example -} - -namespace ExampleLazyStatic -{ -// LazyStatic example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -// destructor will never be called -}; - -typedef LazyStatic StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - int bar = StaticMyClass::instance().value; -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = StaticMyClass::instance().value; -} -// end example -} - -namespace ExampleSmartStatic -{ -// SmartStatic example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -}; - -typedef CountedStatic StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - // StaticMyClass::instance() is invalid before the ref is constructed - SmartStatic ref; - int bar = ref.instance().value; - - SmartStatic ref2; // any number of instances are allowed. -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = SmartStatic().instance().value; // an instance can be a temporary -} -// end example -} - -#endif diff --git a/libs/generic/static.h b/libs/generic/static.h deleted file mode 100644 index ad501fc..0000000 --- a/libs/generic/static.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_STATIC_H ) -#define INCLUDED_GENERIC_STATIC_H - -/// \file -/// \brief Template techniques for instantiating singletons. - -#include - -class Null -{ -}; - -/// \brief A singleton which is statically initialised. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline Static example -/// \until end example -template -class Static -{ -static Type m_instance; -public: -static Type& instance(){ - return m_instance; -} -}; - -template -Type Static::m_instance; - - -/// \brief A singleton which is lazily initialised. -/// The instance is constructed the first time it is referenced, and is never destroyed. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline LazyStatic example -/// \until end example -template -class LazyStatic -{ -static Type* m_instance; // this will be initialised to 0 by the CRT, according to the c++ standard -public: -static Type& instance(){ - if ( m_instance == 0 ) { - m_instance = new Type; // allocate using 'new' to get the correct alignment - } - return *m_instance; -} -}; - -template -Type * LazyStatic::m_instance; - - -/// \brief A singleton which keeps a count of the number of times it is referenced. -/// -/// The instance is constructed when its reference count changes from 0 to 1 and destroyed when its reference count changes from 1 to 0. -/// Use with SmartStatic. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -template -class CountedStatic -{ -static std::size_t m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard -static Type* m_instance; -public: -static Type& instance(){ - return *m_instance; -} -static void capture(){ - if ( ++m_refcount == 1 ) { - m_instance = new Type; // allocate using 'new' to get the correct alignment - } -} -static void release(){ - if ( --m_refcount == 0 ) { - delete m_instance; - } -} -}; - -template -std::size_t CountedStatic::m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard -template -Type * CountedStatic::m_instance; - -/// \brief A reference to a CountedStatic. -/// Guarantees that CountedStatic will be constructed for the lifetime of this object. -/// -/// \param Type The type parameter of the CountedStatic to reference. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline SmartStatic example -/// \until end example -template -class SmartStatic -{ -public: -SmartStatic(){ - CountedStatic::capture(); -} -~SmartStatic(){ - CountedStatic::release(); -} -Type& instance(){ - return CountedStatic::instance(); -} -}; - - -#endif diff --git a/libs/generic/vector.h b/libs/generic/vector.h deleted file mode 100644 index ea1e3bd..0000000 --- a/libs/generic/vector.h +++ /dev/null @@ -1,212 +0,0 @@ - -#if !defined( INCLUDED_VECTOR_H ) -#define INCLUDED_VECTOR_H - -#include - -template -class BasicVector2 -{ -Element m_elements[2]; -public: -BasicVector2(){ -} -BasicVector2( const Element& x_, const Element& y_ ){ - x() = x_; - y() = y_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} - -const Element& operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -/// \brief A 3-element vector. -template -class BasicVector3 -{ -Element m_elements[3]; -public: - -BasicVector3(){ -} -template -BasicVector3( const BasicVector3& other ){ - x() = static_cast( other.x() ); - y() = static_cast( other.y() ); - z() = static_cast( other.z() ); -} -BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){ - x() = x_; - y() = y_; - z() = z_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} -Element& z(){ - return m_elements[2]; -} -const Element& z() const { - return m_elements[2]; -} - -const Element& operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -/// \brief A 4-element vector. -template -class BasicVector4 -{ -Element m_elements[4]; -public: - -BasicVector4(){ -} -BasicVector4( Element x_, Element y_, Element z_, Element w_ ){ - x() = x_; - y() = y_; - z() = z_; - w() = w_; -} -BasicVector4( const BasicVector3& self, Element w_ ){ - x() = self.x(); - y() = self.y(); - z() = self.z(); - w() = w_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} -Element& z(){ - return m_elements[2]; -} -const Element& z() const { - return m_elements[2]; -} -Element& w(){ - return m_elements[3]; -} -const Element& w() const { - return m_elements[3]; -} - -Element index( std::size_t i ) const { - return m_elements[i]; -} -Element& index( std::size_t i ){ - return m_elements[i]; -} -Element operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -template -inline BasicVector3 vector3_from_array( const Element* array ){ - return BasicVector3( array[0], array[1], array[2] ); -} - -template -inline Element* vector3_to_array( BasicVector3& self ){ - return self.data(); -} -template -inline const Element* vector3_to_array( const BasicVector3& self ){ - return self.data(); -} - -template -inline Element* vector4_to_array( BasicVector4& self ){ - return self.data(); -} -template -inline const Element* vector4_to_array( const BasicVector4& self ){ - return self.data(); -} - -template -inline BasicVector3& vector4_to_vector3( BasicVector4& self ){ - return *reinterpret_cast*>( vector4_to_array( self ) ); -} -template -inline const BasicVector3& vector4_to_vector3( const BasicVector4& self ){ - return *reinterpret_cast*>( vector4_to_array( self ) ); -} - -/// \brief A 2-element vector stored in single-precision floating-point. -typedef BasicVector2 Vector2; - -/// \brief A 3-element vector stored in single-precision floating-point. -typedef BasicVector3 Vector3; - -/// \brief A 4-element vector stored in single-precision floating-point. -typedef BasicVector4 Vector4; - - -#endif diff --git a/libs/gtkutil/Makefile b/libs/gtkutil/Makefile deleted file mode 100644 index 49015f8..0000000 --- a/libs/gtkutil/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GLEXT_CFLAGS=$(shell pkg-config --cflags gtkglext-1.0) -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) - -LIB_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS) $(GLEXT_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -accelerator.o \ -button.o \ -clipboard.o \ -cursor.o \ -dialog.o \ -entry.o \ -filechooser.o \ -frame.o \ -glfont.o \ -glwidget.o \ -image.o \ -menu.o \ -messagebox.o \ -nonmodal.o \ -paned.o \ -toolbar.o \ -widget.o \ -window.o \ -xorrectangle.o - -# binary target -../libgtkutil.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -accelerator.o: accelerator.cpp accelerator.h -button.o: button.cpp button.h -clipboard.o: clipboard.cpp clipboard.h -cursor.o: cursor.cpp cursor.h -dialog.o: dialog.cpp dialog.h -entry.o: entry.cpp entry.h -filechooser.o: filechooser.cpp filechooser.h -frame.o: frame.cpp frame.h -glfont.o: glfont.cpp glfont.h -glwidget.o: glwidget.cpp glwidget.h -image.o: image.cpp image.h -menu.o: menu.cpp menu.h -messagebox.o: messagebox.cpp messagebox.h -nonmodal.o: nonmodal.cpp nonmodal.h -paned.o: paned.cpp paned.h -toolbar.o: toolbar.cpp toolbar.h -widget.o: widget.cpp widget.h -window.o: window.cpp window.h -xorrectangle.o: xorrectangle.cpp xorrectangle.h - -clean: - -rm -f *.o ../libgtkutil.a diff --git a/libs/gtkutil/accelerator.cpp b/libs/gtkutil/accelerator.cpp deleted file mode 100644 index 8bcdb03..0000000 --- a/libs/gtkutil/accelerator.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "accelerator.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "generic/callback.h" -#include "generic/bitfield.h" -#include "string/string.h" - -#include "pointer.h" -#include "closure.h" - -#include - - -const char *global_keys_find(unsigned int key) -{ - const char *s; - if (key == 0) { - return ""; - } - s = gdk_keyval_name(key); - if (!s) { - return ""; - } - return s; -} - -unsigned int global_keys_find(const char *name) -{ - guint k; - if (!name || !*name) { - return 0; - } - k = gdk_keyval_from_name(name); - if (k == GDK_KEY_VoidSymbol) { - return 0; - } - return k; -} - -void accelerator_write(const Accelerator &accelerator, TextOutputStream &ostream) -{ -#if 0 - if ( accelerator.modifiers & GDK_SHIFT_MASK ) { - ostream << "Shift + "; - } - if ( accelerator.modifiers & GDK_MOD1_MASK ) { - ostream << "Alt + "; - } - if ( accelerator.modifiers & GDK_CONTROL_MASK ) { - ostream << "Control + "; - } - - const char* keyName = global_keys_find( accelerator.key ); - if ( !string_empty( keyName ) ) { - ostream << keyName; - } - else - { - ostream << static_cast( accelerator.key ); - } -#endif - ostream << gtk_accelerator_get_label(accelerator.key, accelerator.modifiers); -} - -typedef std::map > AcceleratorMap; -typedef std::set AcceleratorSet; - -bool accelerator_map_insert(AcceleratorMap &acceleratorMap, Accelerator accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - return acceleratorMap.insert(AcceleratorMap::value_type(accelerator, callback)).second; - } - return true; -} - -bool accelerator_map_erase(AcceleratorMap &acceleratorMap, Accelerator accelerator) -{ - if (accelerator.key != 0) { - AcceleratorMap::iterator i = acceleratorMap.find(accelerator); - if (i == acceleratorMap.end()) { - return false; - } - acceleratorMap.erase(i); - } - return true; -} - -Accelerator accelerator_for_event_key(guint keyval, guint state) -{ - keyval = gdk_keyval_to_upper(keyval); - if (keyval == GDK_KEY_ISO_Left_Tab) { - keyval = GDK_KEY_Tab; - } - return Accelerator(keyval, (GdkModifierType) (state & gtk_accelerator_get_default_mod_mask())); -} - -bool AcceleratorMap_activate(const AcceleratorMap &acceleratorMap, const Accelerator &accelerator) -{ - AcceleratorMap::const_iterator i = acceleratorMap.find(accelerator); - if (i != acceleratorMap.end()) { - (*i).second(); - return true; - } - - return false; -} - -static gboolean accelerator_key_event(ui::Window window, GdkEventKey *event, AcceleratorMap *acceleratorMap) -{ - return AcceleratorMap_activate(*acceleratorMap, accelerator_for_event_key(event->keyval, event->state)); -} - - -AcceleratorMap g_special_accelerators; - - -namespace MouseButton { -enum { - Left = 1 << 0, - Right = 1 << 1, - Middle = 1 << 2, -}; -} - -typedef unsigned int ButtonMask; - -void print_buttons(ButtonMask mask) -{ - globalOutputStream() << "button state: "; - if ((mask & MouseButton::Left) != 0) { - globalOutputStream() << "Left "; - } - if ((mask & MouseButton::Right) != 0) { - globalOutputStream() << "Right "; - } - if ((mask & MouseButton::Middle) != 0) { - globalOutputStream() << "Middle "; - } - globalOutputStream() << "\n"; -} - -ButtonMask ButtonMask_for_event_button(guint button) -{ - switch (button) { - case 1: - return MouseButton::Left; - case 2: - return MouseButton::Middle; - case 3: - return MouseButton::Right; - } - return 0; -} - -bool window_has_accel(ui::Window toplevel) -{ - return g_slist_length(gtk_accel_groups_from_object(G_OBJECT(toplevel))) != 0; -} - -namespace { -bool g_accel_enabled = true; -} - -bool global_accel_enabled() -{ - return g_accel_enabled; -} - - -GClosure *accel_group_add_accelerator(ui::AccelGroup group, Accelerator accelerator, const Callback &callback); - -void accel_group_remove_accelerator(ui::AccelGroup group, Accelerator accelerator); - -AcceleratorMap g_queuedAcceleratorsAdd; -AcceleratorSet g_queuedAcceleratorsRemove; - -void globalQueuedAccelerators_add(Accelerator accelerator, const Callback &callback) -{ - if (!g_queuedAcceleratorsAdd.insert(AcceleratorMap::value_type(accelerator, callback)).second) { - globalErrorStream() << "globalQueuedAccelerators_add: accelerator already queued: " << accelerator << "\n"; - } -} - -void globalQueuedAccelerators_remove(Accelerator accelerator) -{ - if (g_queuedAcceleratorsAdd.erase(accelerator) == 0) { - if (!g_queuedAcceleratorsRemove.insert(accelerator).second) { - globalErrorStream() << "globalQueuedAccelerators_remove: accelerator already queued: " << accelerator - << "\n"; - } - } -} - -void globalQueuedAccelerators_commit() -{ - for (AcceleratorSet::const_iterator i = g_queuedAcceleratorsRemove.begin(); - i != g_queuedAcceleratorsRemove.end(); ++i) { - //globalOutputStream() << "removing: " << (*i).first << "\n"; - accel_group_remove_accelerator(global_accel, *i); - } - g_queuedAcceleratorsRemove.clear(); - for (AcceleratorMap::const_iterator i = g_queuedAcceleratorsAdd.begin(); i != g_queuedAcceleratorsAdd.end(); ++i) { - //globalOutputStream() << "adding: " << (*i).first << "\n"; - accel_group_add_accelerator(global_accel, (*i).first, (*i).second); - } - g_queuedAcceleratorsAdd.clear(); -} - -typedef std::set WindowSet; -WindowSet g_accel_windows; - -bool Buttons_press(ButtonMask &buttons, guint button, guint state) -{ - if (buttons == 0 && bitfield_enable(buttons, ButtonMask_for_event_button(button)) != 0) { - ASSERT_MESSAGE(g_accel_enabled, "Buttons_press: accelerators not enabled"); - g_accel_enabled = false; - for (WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i) { - ui::Window toplevel = *i; - ASSERT_MESSAGE(window_has_accel(toplevel), "ERROR"); - ASSERT_MESSAGE(gtk_widget_is_toplevel(toplevel), "disabling accel for non-toplevel window"); - gtk_window_remove_accel_group(toplevel, global_accel); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": disabled global accelerators\n"; -#endif - } - } - buttons = bitfield_enable(buttons, ButtonMask_for_event_button(button)); -#if 0 - globalOutputStream() << "Buttons_press: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_release(ButtonMask &buttons, guint button, guint state) -{ - if (buttons != 0 && bitfield_disable(buttons, ButtonMask_for_event_button(button)) == 0) { - ASSERT_MESSAGE(!g_accel_enabled, "Buttons_release: accelerators are enabled"); - g_accel_enabled = true; - for (WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i) { - ui::Window toplevel = *i; - ASSERT_MESSAGE(!window_has_accel(toplevel), "ERROR"); - ASSERT_MESSAGE(gtk_widget_is_toplevel(toplevel), "enabling accel for non-toplevel window"); - toplevel.add_accel_group(global_accel); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": enabled global accelerators\n"; -#endif - } - globalQueuedAccelerators_commit(); - } - buttons = bitfield_disable(buttons, ButtonMask_for_event_button(button)); -#if 0 - globalOutputStream() << "Buttons_release: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_releaseAll(ButtonMask &buttons) -{ - Buttons_release(buttons, MouseButton::Left | MouseButton::Middle | MouseButton::Right, 0); - return false; -} - -struct PressedButtons { - ButtonMask buttons; - - PressedButtons() : buttons(0) - { - } -}; - -gboolean PressedButtons_button_press(ui::Widget widget, GdkEventButton *event, PressedButtons *pressed) -{ - if (event->type == GDK_BUTTON_PRESS) { - return Buttons_press(pressed->buttons, event->button, event->state); - } - return FALSE; -} - -gboolean PressedButtons_button_release(ui::Widget widget, GdkEventButton *event, PressedButtons *pressed) -{ - if (event->type == GDK_BUTTON_RELEASE) { - return Buttons_release(pressed->buttons, event->button, event->state); - } - return FALSE; -} - -gboolean PressedButtons_focus_out(ui::Widget widget, GdkEventFocus *event, PressedButtons *pressed) -{ - Buttons_releaseAll(pressed->buttons); - return FALSE; -} - -void PressedButtons_connect(PressedButtons &pressedButtons, ui::Widget widget) -{ - widget.connect("button_press_event", G_CALLBACK(PressedButtons_button_press), &pressedButtons); - widget.connect("button_release_event", G_CALLBACK(PressedButtons_button_release), &pressedButtons); - widget.connect("focus_out_event", G_CALLBACK(PressedButtons_focus_out), &pressedButtons); -} - -PressedButtons g_pressedButtons; - - -#include -#include - -struct PressedKeys { - typedef std::set Keys; - Keys keys; - std::size_t refcount; - - PressedKeys() : refcount(0) - { - } -}; - -AcceleratorMap g_keydown_accelerators; -AcceleratorMap g_keyup_accelerators; - -bool Keys_press(PressedKeys::Keys &keys, guint keyval) -{ - if (keys.insert(keyval).second) { - return AcceleratorMap_activate(g_keydown_accelerators, accelerator_for_event_key(keyval, 0)); - } - return g_keydown_accelerators.find(accelerator_for_event_key(keyval, 0)) != g_keydown_accelerators.end(); -} - -bool Keys_release(PressedKeys::Keys &keys, guint keyval) -{ - if (keys.erase(keyval) != 0) { - return AcceleratorMap_activate(g_keyup_accelerators, accelerator_for_event_key(keyval, 0)); - } - return g_keyup_accelerators.find(accelerator_for_event_key(keyval, 0)) != g_keyup_accelerators.end(); -} - -void Keys_releaseAll(PressedKeys::Keys &keys, guint state) -{ - for (PressedKeys::Keys::iterator i = keys.begin(); i != keys.end(); ++i) { - AcceleratorMap_activate(g_keyup_accelerators, accelerator_for_event_key(*i, state)); - } - keys.clear(); -} - -gboolean PressedKeys_key_press(ui::Widget widget, GdkEventKey *event, PressedKeys *pressedKeys) -{ - //globalOutputStream() << "pressed: " << event->keyval << "\n"; - return event->state == 0 && Keys_press(pressedKeys->keys, event->keyval); -} - -gboolean PressedKeys_key_release(ui::Widget widget, GdkEventKey *event, PressedKeys *pressedKeys) -{ - //globalOutputStream() << "released: " << event->keyval << "\n"; - return Keys_release(pressedKeys->keys, event->keyval); -} - -gboolean PressedKeys_focus_in(ui::Widget widget, GdkEventFocus *event, PressedKeys *pressedKeys) -{ - ++pressedKeys->refcount; - return FALSE; -} - -gboolean PressedKeys_focus_out(ui::Widget widget, GdkEventFocus *event, PressedKeys *pressedKeys) -{ - if (--pressedKeys->refcount == 0) { - Keys_releaseAll(pressedKeys->keys, 0); - } - return FALSE; -} - -PressedKeys g_pressedKeys; - -void GlobalPressedKeys_releaseAll() -{ - Keys_releaseAll(g_pressedKeys.keys, 0); -} - -void GlobalPressedKeys_connect(ui::Window window) -{ - unsigned int key_press_handler = window.connect("key_press_event", G_CALLBACK(PressedKeys_key_press), - &g_pressedKeys); - unsigned int key_release_handler = window.connect("key_release_event", G_CALLBACK(PressedKeys_key_release), - &g_pressedKeys); - g_object_set_data(G_OBJECT(window), "key_press_handler", gint_to_pointer(key_press_handler)); - g_object_set_data(G_OBJECT(window), "key_release_handler", gint_to_pointer(key_release_handler)); - unsigned int focus_in_handler = window.connect("focus_in_event", G_CALLBACK(PressedKeys_focus_in), &g_pressedKeys); - unsigned int focus_out_handler = window.connect("focus_out_event", G_CALLBACK(PressedKeys_focus_out), - &g_pressedKeys); - g_object_set_data(G_OBJECT(window), "focus_in_handler", gint_to_pointer(focus_in_handler)); - g_object_set_data(G_OBJECT(window), "focus_out_handler", gint_to_pointer(focus_out_handler)); -} - -void GlobalPressedKeys_disconnect(ui::Window window) -{ - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "key_press_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "key_release_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "focus_in_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "focus_out_handler"))); -} - - -void special_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "special_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_special_accelerators, accelerator, callback)) { - globalErrorStream() << "special_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void special_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "special_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_special_accelerators, accelerator)) { - globalErrorStream() << "special_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - -void keydown_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "keydown_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_keydown_accelerators, accelerator, callback)) { - globalErrorStream() << "keydown_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void keydown_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "keydown_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_keydown_accelerators, accelerator)) { - globalErrorStream() << "keydown_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - -void keyup_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "keyup_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_keyup_accelerators, accelerator, callback)) { - globalErrorStream() << "keyup_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void keyup_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "keyup_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_keyup_accelerators, accelerator)) { - globalErrorStream() << "keyup_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - - -gboolean -accel_closure_callback(ui::AccelGroup group, ui::Widget widget, guint key, GdkModifierType modifiers, gpointer data) -{ - (*reinterpret_cast *>( data ))(); - return TRUE; -} - -GClosure *accel_group_add_accelerator(ui::AccelGroup group, Accelerator accelerator, const Callback &callback) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - //globalOutputStream() << "global_accel_connect: " << makeQuoted(accelerator) << "\n"; - GClosure *closure = create_cclosure(G_CALLBACK(accel_closure_callback), callback); - gtk_accel_group_connect(group, accelerator.key, accelerator.modifiers, GTK_ACCEL_VISIBLE, closure); - return closure; - } else { - special_accelerators_add(accelerator, callback); - return 0; - } -} - -void accel_group_remove_accelerator(ui::AccelGroup group, Accelerator accelerator) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - //globalOutputStream() << "global_accel_disconnect: " << makeQuoted(accelerator) << "\n"; - gtk_accel_group_disconnect_key(group, accelerator.key, accelerator.modifiers); - } else { - special_accelerators_remove(accelerator); - } -} - -ui::AccelGroup global_accel{ui::New}; - -GClosure *global_accel_group_add_accelerator(Accelerator accelerator, const Callback &callback) -{ - if (!global_accel_enabled()) { - // workaround: cannot add to GtkAccelGroup while it is disabled - //globalOutputStream() << "queued for add: " << accelerator << "\n"; - globalQueuedAccelerators_add(accelerator, callback); - return 0; - } - return accel_group_add_accelerator(global_accel, accelerator, callback); -} - -void global_accel_group_remove_accelerator(Accelerator accelerator) -{ - if (!global_accel_enabled()) { - //globalOutputStream() << "queued for remove: " << accelerator << "\n"; - globalQueuedAccelerators_remove(accelerator); - return; - } - accel_group_remove_accelerator(global_accel, accelerator); -} - -/// \brief Propagates key events to the focus-widget, overriding global accelerators. -static gboolean override_global_accelerators(ui::Window window, GdkEventKey *event, gpointer data) -{ - gboolean b = gtk_window_propagate_key_event(window, event); - return b; -} - -void global_accel_connect_window(ui::Window window) -{ -#if 1 - unsigned int override_handler = window.connect("key_press_event", G_CALLBACK(override_global_accelerators), 0); - g_object_set_data(G_OBJECT(window), "override_handler", gint_to_pointer(override_handler)); - - unsigned int special_key_press_handler = window.connect("key_press_event", G_CALLBACK(accelerator_key_event), - &g_special_accelerators); - g_object_set_data(G_OBJECT(window), "special_key_press_handler", gint_to_pointer(special_key_press_handler)); - - GlobalPressedKeys_connect(window); -#else - unsigned int key_press_handler = window.connect( "key_press_event", G_CALLBACK( accelerator_key_event ), &g_keydown_accelerators ); - unsigned int key_release_handler = window.connect( "key_release_event", G_CALLBACK( accelerator_key_event ), &g_keyup_accelerators ); - g_object_set_data( G_OBJECT( window ), "key_press_handler", gint_to_pointer( key_press_handler ) ); - g_object_set_data( G_OBJECT( window ), "key_release_handler", gint_to_pointer( key_release_handler ) ); -#endif - g_accel_windows.insert(window); - window.add_accel_group(global_accel); -} - -void global_accel_disconnect_window(ui::Window window) -{ -#if 1 - GlobalPressedKeys_disconnect(window); - - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "override_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "special_key_press_handler"))); -#else - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_press_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_release_handler" ) ) ); -#endif - gtk_window_remove_accel_group(window, global_accel); - std::size_t count = g_accel_windows.erase(window); - ASSERT_MESSAGE(count == 1, "failed to remove accel group\n"); -} - - -GClosure *global_accel_group_find(Accelerator accelerator) -{ - guint numEntries = 0; - GtkAccelGroupEntry *entry = gtk_accel_group_query(global_accel, accelerator.key, accelerator.modifiers, - &numEntries); - if (numEntries != 0) { - if (numEntries != 1) { - char *name = gtk_accelerator_name(accelerator.key, accelerator.modifiers); - globalErrorStream() << "accelerator already in-use: " << name << "\n"; - g_free(name); - } - return entry->closure; - } - return 0; -} - -void global_accel_group_connect(const Accelerator &accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - global_accel_group_add_accelerator(accelerator, callback); - } -} - -void global_accel_group_disconnect(const Accelerator &accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - global_accel_group_remove_accelerator(accelerator); - } -} diff --git a/libs/gtkutil/accelerator.h b/libs/gtkutil/accelerator.h deleted file mode 100644 index 2bde656..0000000 --- a/libs/gtkutil/accelerator.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_ACCELERATOR_H ) -#define INCLUDED_GTKUTIL_ACCELERATOR_H - -#include -#include - -#include "generic/callback.h" -#include "property.h" - -// ignore numlock -#define ALLOWED_MODIFIERS ( ~( GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK ) ) - -struct Accelerator { - Accelerator(guint _key) - : key(gdk_keyval_to_upper(_key)), modifiers((GdkModifierType) 0) - { - } - - Accelerator(guint _key, GdkModifierType _modifiers) - : key(gdk_keyval_to_upper(_key)), modifiers((GdkModifierType) (_modifiers & ALLOWED_MODIFIERS)) - { - } - - Accelerator(const Accelerator &src) - : key(gdk_keyval_to_upper(src.key)), modifiers((GdkModifierType) (src.modifiers & ALLOWED_MODIFIERS)) - { - } - - bool operator<(const Accelerator &other) const - { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers & ALLOWED_MODIFIERS; - int mod2 = other.modifiers & ALLOWED_MODIFIERS; - return k1 < k2 || (!(k2 < k1) && mod1 < mod2); - } - - bool operator==(const Accelerator &other) const - { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers & ALLOWED_MODIFIERS; - int mod2 = other.modifiers & ALLOWED_MODIFIERS; - return k1 == k2 && mod1 == mod2; - } - - Accelerator &operator=(const Accelerator &other) - { - key = other.key; - modifiers = (GdkModifierType) (other.modifiers & ALLOWED_MODIFIERS); - return *this; - } - - guint key; - GdkModifierType modifiers; -}; - -inline Accelerator accelerator_null() -{ - return Accelerator(0, (GdkModifierType) 0); -} - -const char *global_keys_find(unsigned int key); - -unsigned int global_keys_find(const char *name); - -class TextOutputStream; - -void accelerator_write(const Accelerator &accelerator, TextOutputStream &ostream); - -template -TextOutputStreamType &ostream_write(TextOutputStreamType &ostream, const Accelerator &accelerator) -{ - accelerator_write(accelerator, ostream); - return ostream; -} - -void keydown_accelerators_add(Accelerator accelerator, const Callback &callback); - -void keydown_accelerators_remove(Accelerator accelerator); - -void keyup_accelerators_add(Accelerator accelerator, const Callback &callback); - -void keyup_accelerators_remove(Accelerator accelerator); - -void global_accel_connect_window(ui::Window window); - -void global_accel_disconnect_window(ui::Window window); - -void GlobalPressedKeys_releaseAll(); - -extern ui::AccelGroup global_accel; - -GClosure *global_accel_group_find(Accelerator accelerator); - -void global_accel_group_connect(const Accelerator &accelerator, const Callback &callback); - -void global_accel_group_disconnect(const Accelerator &accelerator, const Callback &callback); - - -class Command { -public: -Callback m_callback; -const Accelerator &m_accelerator; - -Command(const Callback &callback, const Accelerator &accelerator) : m_callback(callback), - m_accelerator(accelerator) -{ -} -}; - -class Toggle { -public: -Command m_command; -Callback &)> m_exportCallback; - -Toggle(const Callback &callback, const Accelerator &accelerator, - const Callback &)> &exportCallback) : m_command(callback, accelerator), - m_exportCallback(exportCallback) -{ -} -}; - -class KeyEvent { -public: -const Accelerator &m_accelerator; -Callback m_keyDown; -Callback m_keyUp; - -KeyEvent(const Accelerator &accelerator, const Callback &keyDown, const Callback &keyUp) - : m_accelerator(accelerator), m_keyDown(keyDown), m_keyUp(keyUp) -{ -} -}; - - -struct PressedButtons; - -void PressedButtons_connect(PressedButtons &pressedButtons, ui::Widget widget); - -extern PressedButtons g_pressedButtons; - -#endif diff --git a/libs/gtkutil/button.cpp b/libs/gtkutil/button.cpp deleted file mode 100644 index cc0c59b..0000000 --- a/libs/gtkutil/button.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "button.h" - -#include - -#include "stream/textstream.h" -#include "stream/stringstream.h" -#include "generic/callback.h" - -#include "image.h" -#include "pointer.h" - -void clicked_closure_callback(ui::Widget widget, gpointer data) -{ - (*reinterpret_cast *>( data ))(); -} - -void button_connect_callback(ui::Button button, const Callback &callback) -{ -#if 1 - g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(callback.getThunk()), callback.getEnvironment()); -#else - g_signal_connect_closure( G_OBJECT( button ), "clicked", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), FALSE ); -#endif -} - -void button_connect_callback(ui::ToolButton button, const Callback &callback) -{ -#if 1 - g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(callback.getThunk()), callback.getEnvironment()); -#else - g_signal_connect_closure( G_OBJECT( button ), "clicked", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), FALSE ); -#endif -} - -guint toggle_button_connect_callback(ui::ToggleButton button, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( button ), "toggled", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(button), "handler", gint_to_pointer(handler)); - return handler; -} - -guint toggle_button_connect_callback(ui::ToggleToolButton button, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( button ), "toggled", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(button), "handler", gint_to_pointer(handler)); - return handler; -} - -void button_set_icon(ui::Button button, const char *icon) -{ - ui::Image image = ui::Image(new_local_image(icon)); - image.show(); - button.add(image); -} - -void toggle_button_set_active_no_signal(ui::ToggleButton button, gboolean active) -{ - //globalOutputStream() << "set active: " << active << "\n"; - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(button), "handler")); - //guint signal_id = g_signal_lookup("toggled", G_OBJECT_TYPE (button)); - //globalOutputStream() << "signal_id: " << signal_id << "\n"; - //guint found = g_signal_handler_find(G_OBJECT(button), G_SIGNAL_MATCH_ID, signal_id, 0, 0, 0, 0); - //globalOutputStream() << " handler found: " << found << "\n"; - g_signal_handler_block(G_OBJECT(button), handler_id); - gtk_toggle_button_set_active(button, active); - g_signal_handler_unblock(G_OBJECT(button), handler_id); -} - -void toggle_button_set_active_no_signal(ui::ToggleToolButton button, gboolean active) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(button), "handler")); - g_signal_handler_block(G_OBJECT(button), handler_id); - gtk_toggle_tool_button_set_active(button, active); - g_signal_handler_unblock(G_OBJECT(button), handler_id); -} - - -void radio_button_print_state(ui::RadioButton button) -{ - globalOutputStream() << "toggle button: "; - for (GSList *radio = gtk_radio_button_get_group(button); radio != 0; radio = g_slist_next(radio)) { - globalOutputStream() << gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio->data)); - } - globalOutputStream() << "\n"; -} - -ui::ToggleButton radio_button_get_nth(ui::RadioButton radio, int index) -{ - GSList *group = gtk_radio_button_get_group(radio); - return ui::ToggleButton::from(g_slist_nth_data(group, g_slist_length(group) - index - 1)); -} - -void radio_button_set_active(ui::RadioButton radio, int index) -{ - //radio_button_print_state(radio); - gtk_toggle_button_set_active(radio_button_get_nth(radio, index), TRUE); - //radio_button_print_state(radio); -} - -void radio_button_set_active_no_signal(ui::RadioButton radio, int index) -{ - { - for (GSList *l = gtk_radio_button_get_group(radio); l != 0; l = g_slist_next(l)) { - g_signal_handler_block(G_OBJECT(l->data), gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } - radio_button_set_active(radio, index); - { - for (GSList *l = gtk_radio_button_get_group(radio); l != 0; l = g_slist_next(l)) { - g_signal_handler_unblock(G_OBJECT(l->data), - gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } -} - -int radio_button_get_active(ui::RadioButton radio) -{ - //radio_button_print_state(radio); - GSList *group = gtk_radio_button_get_group(radio); - int index = g_slist_length(group) - 1; - for (; group != 0; group = g_slist_next(group)) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group->data))) { - break; - } else { - index--; - } - } - return index; -} diff --git a/libs/gtkutil/button.h b/libs/gtkutil/button.h deleted file mode 100644 index 908f6a0..0000000 --- a/libs/gtkutil/button.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_BUTTON_H ) -#define INCLUDED_GTKUTIL_BUTTON_H - -#include -#include "generic/callback.h" - -typedef int gint; -typedef gint gboolean; -typedef unsigned int guint; - -void button_connect_callback(ui::Button button, const Callback &callback); - -void button_connect_callback(ui::ToolButton button, const Callback &callback); - -guint toggle_button_connect_callback(ui::ToggleButton button, const Callback &callback); - -guint toggle_button_connect_callback(ui::ToggleToolButton button, const Callback &callback); - -void button_set_icon(ui::Button button, const char *icon); - -void toggle_button_set_active_no_signal(ui::ToggleButton item, gboolean active); - -void toggle_button_set_active_no_signal(ui::ToggleToolButton item, gboolean active); - -void radio_button_set_active(ui::RadioButton radio, int index); - -void radio_button_set_active_no_signal(ui::RadioButton radio, int index); - -int radio_button_get_active(ui::RadioButton radio); - -#endif diff --git a/libs/gtkutil/clipboard.cpp b/libs/gtkutil/clipboard.cpp deleted file mode 100644 index daab030..0000000 --- a/libs/gtkutil/clipboard.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "clipboard.h" - -#include "globaldefs.h" -#include "stream/memstream.h" -#include "stream/textstream.h" - - -/// \file -/// \brief Platform-independent GTK clipboard support. -/// \todo Using GDK_SELECTION_CLIPBOARD fails on win32, so we use the win32 API directly for now. -#if GDEF_OS_WINDOWS - -const char* c_clipboard_format = "RadiantClippings"; - -#include - -void clipboard_copy( ClipboardCopyFunc copy ){ - BufferOutputStream ostream; - copy( ostream ); - - bool bClipped = false; - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 ) { - if ( ::OpenClipboard( 0 ) ) { - EmptyClipboard(); - std::size_t length = ostream.size(); - HANDLE h = ::GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, length + sizeof( std::size_t ) ); - if ( h != 0 ) { - char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - *reinterpret_cast( buffer ) = length; - buffer += sizeof( std::size_t ); - memcpy( buffer, ostream.data(), length ); - ::GlobalUnlock( h ); - ::SetClipboardData( nClipboard, h ); - ::CloseClipboard(); - bClipped = true; - } - } - } - - if ( !bClipped ) { - globalOutputStream() << "Unable to register Windows clipboard formats, copy/paste between editors will not be possible\n"; - } -} - -void clipboard_paste( ClipboardPasteFunc paste ){ - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 && ::OpenClipboard( 0 ) ) { - if ( IsClipboardFormatAvailable( nClipboard ) ) { - HANDLE h = ::GetClipboardData( nClipboard ); - if ( h ) { - const char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - std::size_t length = *reinterpret_cast( buffer ); - buffer += sizeof( std::size_t ); - BufferInputStream istream( buffer, length ); - paste( istream ); - ::GlobalUnlock( h ); - } - } - ::CloseClipboard(); - } -} - -#else - -#include - -enum { - RADIANT_CLIPPINGS = 23, -}; - -static char RADIANT_CLIPPINGS_STR[] = "RADIANT_CLIPPINGS"; - -static const GtkTargetEntry clipboard_targets[] = { - {RADIANT_CLIPPINGS_STR, 0, RADIANT_CLIPPINGS,}, -}; - -static void clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer data) -{ - std::size_t len = *reinterpret_cast( data ); - const char *buffer = (len != 0) ? reinterpret_cast( data ) + sizeof(std::size_t) : 0; - - GdkAtom type = GDK_NONE; - if (info == clipboard_targets[0].info) { - type = gdk_atom_intern(clipboard_targets[0].target, FALSE); - } - - gtk_selection_data_set(selection_data, type, 8, reinterpret_cast( buffer ), - static_cast( len )); -} - -static void clipboard_clear(GtkClipboard *clipboard, gpointer data) -{ - delete[] reinterpret_cast( data ); -} - -static void clipboard_received(GtkClipboard *clipboard, GtkSelectionData *data, gpointer user_data) -{ - if (gtk_selection_data_get_length(data) < 0) { - globalErrorStream() << "Error retrieving selection\n"; - } else if (strcmp(gdk_atom_name(gtk_selection_data_get_data_type(data)), clipboard_targets[0].target) == 0) { - BufferInputStream istream(reinterpret_cast( gtk_selection_data_get_data(data)), - gtk_selection_data_get_length(data)); - (*reinterpret_cast( user_data ))(istream); - } -} - -void clipboard_copy(ClipboardCopyFunc copy) -{ - GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - - BufferOutputStream ostream; - copy(ostream); - std::size_t length = ostream.size(); - char *data = new char[length + sizeof(std::size_t)]; - *reinterpret_cast( data ) = length; - memcpy(data + sizeof(std::size_t), ostream.data(), length); - - gtk_clipboard_set_with_data(clipboard, clipboard_targets, 1, clipboard_get, clipboard_clear, data); -} - -ClipboardPasteFunc g_clipboardPasteFunc = 0; - -void clipboard_paste(ClipboardPasteFunc paste) -{ - GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - - g_clipboardPasteFunc = paste; - gtk_clipboard_request_contents(clipboard, gdk_atom_intern(clipboard_targets[0].target, FALSE), clipboard_received, - &g_clipboardPasteFunc); -} - - -#endif diff --git a/libs/gtkutil/clipboard.h b/libs/gtkutil/clipboard.h deleted file mode 100644 index ab8d48c..0000000 --- a/libs/gtkutil/clipboard.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CLIPBOARD_H ) -#define INCLUDED_GTKUTIL_CLIPBOARD_H - -class TextOutputStream; - -typedef void ( *ClipboardCopyFunc )(TextOutputStream &); - -void clipboard_copy(ClipboardCopyFunc copy); - -class TextInputStream; - -typedef void ( *ClipboardPasteFunc )(TextInputStream &); - -void clipboard_paste(ClipboardPasteFunc paste); - -#endif diff --git a/libs/gtkutil/closure.h b/libs/gtkutil/closure.h deleted file mode 100644 index f5d7802..0000000 --- a/libs/gtkutil/closure.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CLOSURE_H ) -#define INCLUDED_GTKUTIL_CLOSURE_H - -#include -#include "generic/callback.h" - -inline void closure_destroy(gpointer data, GClosure *closure) -{ - delete reinterpret_cast *>( data ); -} - -inline GClosure *create_cclosure(GCallback func, const Callback &callback) -{ - return g_cclosure_new(func, new Callback(callback), closure_destroy); -} - -inline GValue GValue_default() -{ - GValue value; - value.g_type = 0; - return value; -} - -inline gint object_get_int_property(GObject *object, const char *property) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_INT); - g_object_get_property(object, property, &gvalue); - return g_value_get_int(&gvalue); -} - -inline void object_set_int_property(GObject *object, const char *property, gint value) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_INT); - g_value_set_int(&gvalue, value); - g_object_set_property(object, property, &gvalue); -} - -inline gboolean object_get_boolean_property(GObject *object, const char *property) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_BOOLEAN); - g_object_get_property(object, property, &gvalue); - return g_value_get_boolean(&gvalue); -} - -inline void object_set_boolean_property(GObject *object, const char *property, gboolean value) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_BOOLEAN); - g_value_set_boolean(&gvalue, value); - g_object_set_property(object, property, &gvalue); -} - -#endif diff --git a/libs/gtkutil/container.h b/libs/gtkutil/container.h deleted file mode 100644 index a814bfb..0000000 --- a/libs/gtkutil/container.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CONTAINER_H ) -#define INCLUDED_GTKUTIL_CONTAINER_H - -inline void container_remove_all(ui::Container container) -{ - container.foreach([=](ui::Widget it) mutable { - container.remove(it); - }); -} - -#endif diff --git a/libs/gtkutil/cursor.cpp b/libs/gtkutil/cursor.cpp deleted file mode 100644 index 862df9c..0000000 --- a/libs/gtkutil/cursor.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cursor.h" - -#include "stream/textstream.h" - -#include -#include -#include - - -GdkCursor *create_blank_cursor() -{ - return gdk_cursor_new(GDK_BLANK_CURSOR); -} - -void blank_cursor(ui::Widget widget) -{ - GdkCursor *cursor = create_blank_cursor(); - gdk_window_set_cursor(gtk_widget_get_window(widget), cursor); - gdk_cursor_unref(cursor); -} - -void default_cursor(ui::Widget widget) -{ - gdk_window_set_cursor(gtk_widget_get_window(widget), 0); -} - - -void Sys_GetCursorPos(ui::Window window, int *x, int *y) -{ - gdk_display_get_pointer(gdk_display_get_default(), 0, x, y, 0); -} - -void Sys_SetCursorPos(ui::Window window, int x, int y) -{ - GdkScreen *screen; - gdk_display_get_pointer(gdk_display_get_default(), &screen, 0, 0, 0); - gdk_display_warp_pointer(gdk_display_get_default(), screen, x, y); -} - -gboolean DeferredMotion::gtk_motion(ui::Widget widget, GdkEventMotion *event, DeferredMotion *self) -{ - self->motion(event->x, event->y, event->state); - return FALSE; -} - -gboolean FreezePointer::motion_delta(ui::Window widget, GdkEventMotion *event, FreezePointer *self) -{ - int current_x, current_y; - Sys_GetCursorPos(widget, ¤t_x, ¤t_y); - int dx = current_x - self->last_x; - int dy = current_y - self->last_y; - int ddx = current_x - self->recorded_x; - int ddy = current_y - self->recorded_y; - self->last_x = current_x; - self->last_y = current_y; - if (dx != 0 || dy != 0) { - //globalOutputStream() << "motion x: " << dx << ", y: " << dy << "\n"; - if (ddx < -32 || ddx > 32 || ddy < -32 || ddy > 32) { - Sys_SetCursorPos(widget, self->recorded_x, self->recorded_y); - self->last_x = self->recorded_x; - self->last_y = self->recorded_y; - } - self->m_function(dx, dy, event->state, self->m_data); - } - return FALSE; -} - -void FreezePointer::freeze_pointer(ui::Window window, FreezePointer::MotionDeltaFunction function, void *data) -{ - ASSERT_MESSAGE(m_function == 0, "can't freeze pointer"); - - const GdkEventMask mask = static_cast( GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON_MOTION_MASK - | GDK_BUTTON1_MOTION_MASK - | GDK_BUTTON2_MOTION_MASK - | GDK_BUTTON3_MOTION_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_VISIBILITY_NOTIFY_MASK ); - - GdkCursor *cursor = create_blank_cursor(); - //GdkGrabStatus status = - gdk_pointer_grab(gtk_widget_get_window(window), TRUE, mask, 0, cursor, GDK_CURRENT_TIME); - gdk_cursor_unref(cursor); - - Sys_GetCursorPos(window, &recorded_x, &recorded_y); - - Sys_SetCursorPos(window, recorded_x, recorded_y); - - last_x = recorded_x; - last_y = recorded_y; - - m_function = function; - m_data = data; - - handle_motion = window.connect("motion_notify_event", G_CALLBACK(motion_delta), this); -} - -void FreezePointer::unfreeze_pointer(ui::Window window) -{ - g_signal_handler_disconnect(G_OBJECT(window), handle_motion); - - m_function = 0; - m_data = 0; - - Sys_SetCursorPos(window, recorded_x, recorded_y); - - gdk_pointer_ungrab(GDK_CURRENT_TIME); -} diff --git a/libs/gtkutil/cursor.h b/libs/gtkutil/cursor.h deleted file mode 100644 index 045494d..0000000 --- a/libs/gtkutil/cursor.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CURSOR_H ) -#define INCLUDED_GTKUTIL_CURSOR_H - -#include - -#include "debugging/debugging.h" - -typedef struct _GdkCursor GdkCursor; -typedef struct _GdkEventMotion GdkEventMotion; - -GdkCursor *create_blank_cursor(); - -void blank_cursor(ui::Widget widget); - -void default_cursor(ui::Widget widget); - -void Sys_GetCursorPos(ui::Window window, int *x, int *y); - -void Sys_SetCursorPos(ui::Window window, int x, int y); - - -class DeferredMotion { -guint m_handler; - -typedef void ( *MotionFunction )(gdouble x, gdouble y, guint state, void *data); - -MotionFunction m_function; -void *m_data; -gdouble m_x; -gdouble m_y; -guint m_state; - -static gboolean deferred(DeferredMotion *self) -{ - self->m_handler = 0; - self->m_function(self->m_x, self->m_y, self->m_state, self->m_data); - return FALSE; -} - -public: -DeferredMotion(MotionFunction function, void *data) : m_handler(0), m_function(function), m_data(data) -{ -} - -void motion(gdouble x, gdouble y, guint state) -{ - m_x = x; - m_y = y; - m_state = state; - if (m_handler == 0) { - m_handler = g_idle_add((GSourceFunc) deferred, this); - } -} - -static gboolean gtk_motion(ui::Widget widget, GdkEventMotion *event, DeferredMotion *self); -}; - -class DeferredMotionDelta { -int m_delta_x; -int m_delta_y; -guint m_motion_handler; - -typedef void ( *MotionDeltaFunction )(int x, int y, void *data); - -MotionDeltaFunction m_function; -void *m_data; - -static gboolean deferred_motion(gpointer data) -{ - reinterpret_cast( data )->m_function( - reinterpret_cast( data )->m_delta_x, - reinterpret_cast( data )->m_delta_y, - reinterpret_cast( data )->m_data - ); - reinterpret_cast( data )->m_motion_handler = 0; - reinterpret_cast( data )->m_delta_x = 0; - reinterpret_cast( data )->m_delta_y = 0; - return FALSE; -} - -public: -DeferredMotionDelta(MotionDeltaFunction function, void *data) : m_delta_x(0), m_delta_y(0), m_motion_handler(0), - m_function(function), m_data(data) -{ -} - -void flush() -{ - if (m_motion_handler != 0) { - g_source_remove(m_motion_handler); - deferred_motion(this); - } -} - -void motion_delta(int x, int y, unsigned int state) -{ - m_delta_x += x; - m_delta_y += y; - if (m_motion_handler == 0) { - m_motion_handler = g_idle_add(deferred_motion, this); - } -} -}; - -class FreezePointer { -unsigned int handle_motion; -int recorded_x, recorded_y, last_x, last_y; - -typedef void ( *MotionDeltaFunction )(int x, int y, unsigned int state, void *data); - -MotionDeltaFunction m_function; -void *m_data; -public: -FreezePointer() : handle_motion(0), m_function(0), m_data(0) -{ -} - -static gboolean motion_delta(ui::Window widget, GdkEventMotion *event, FreezePointer *self); - -void freeze_pointer(ui::Window window, MotionDeltaFunction function, void *data); - -void unfreeze_pointer(ui::Window window); -}; - -#endif diff --git a/libs/gtkutil/dialog.cpp b/libs/gtkutil/dialog.cpp deleted file mode 100644 index 786af87..0000000 --- a/libs/gtkutil/dialog.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dialog.h" - -#include - -#include "button.h" -#include "window.h" - -ui::VBox create_dialog_vbox(int spacing, int border) -{ - auto vbox = ui::VBox(FALSE, spacing); - vbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(vbox), border); - return vbox; -} - -ui::HBox create_dialog_hbox(int spacing, int border) -{ - auto hbox = ui::HBox(FALSE, spacing); - hbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(hbox), border); - return hbox; -} - -ui::Frame create_dialog_frame(const char *label, ui::Shadow shadow) -{ - auto frame = ui::Frame(label); - frame.show(); - gtk_frame_set_shadow_type(frame, (GtkShadowType) shadow); - return frame; -} - -ui::Table -create_dialog_table(unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, - int border) -{ - auto table = ui::Table(rows, columns, FALSE); - table.show(); - gtk_table_set_row_spacings(table, row_spacing); - gtk_table_set_col_spacings(table, col_spacing); - gtk_container_set_border_width(GTK_CONTAINER(table), border); - return table; -} - -ui::Button create_dialog_button(const char *label, GCallback func, gpointer data) -{ - auto button = ui::Button(label); - button.dimensions(64, -1); - button.show(); - button.connect("clicked", func, data); - return button; -} - -ui::Window -create_dialog_window(ui::Window parent, const char *title, GCallback func, gpointer data, int default_w, int default_h) -{ - ui::Window window = create_floating_window(title, parent); - gtk_window_set_default_size(window, default_w, default_h); - gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); - window.connect("delete_event", func, data); - - return window; -} - -gboolean modal_dialog_button_clicked(ui::Widget widget, ModalDialogButton *button) -{ - button->m_dialog.loop = false; - button->m_dialog.ret = button->m_value; - return TRUE; -} - -gboolean modal_dialog_delete(ui::Widget widget, GdkEvent *event, ModalDialog *dialog) -{ - dialog->loop = 0; - dialog->ret = eIDCANCEL; - return TRUE; -} - -EMessageBoxReturn modal_dialog_show(ui::Window window, ModalDialog &dialog) -{ - gtk_grab_add(window); - window.show(); - - dialog.loop = true; - while (dialog.loop) { - gtk_main_iteration(); - } - - window.hide(); - gtk_grab_remove(window); - - return dialog.ret; -} - -ui::Button create_modal_dialog_button(const char *label, ModalDialogButton &button) -{ - return create_dialog_button(label, G_CALLBACK(modal_dialog_button_clicked), &button); -} - -ui::Window -create_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int default_w, int default_h) -{ - return create_dialog_window(parent, title, G_CALLBACK(modal_dialog_delete), &dialog, default_w, default_h); -} - -ui::Window -create_fixedsize_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int width, int height) -{ - auto window = create_modal_dialog_window(parent, title, dialog, width, height); - - gtk_window_set_resizable(window, FALSE); - gtk_window_set_modal(window, TRUE); - gtk_window_set_position(window, GTK_WIN_POS_CENTER); - - window_remove_minmax(window); - - //window.dimensions(width, height); - //gtk_window_set_default_size(window, width, height); - //gtk_window_resize(window, width, height); - //GdkGeometry geometry = { width, height, -1, -1, width, height, -1, -1, -1, -1, GDK_GRAVITY_STATIC, }; - //gtk_window_set_geometry_hints(window, window, &geometry, (GdkWindowHints)(GDK_HINT_POS|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE)); - - return window; -} - -gboolean dialog_button_ok(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDOK; - return TRUE; -} - -gboolean dialog_button_cancel(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDCANCEL; - return TRUE; -} - -gboolean dialog_button_yes(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDYES; - return TRUE; -} - -gboolean dialog_button_no(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDNO; - return TRUE; -} - -gboolean dialog_delete_callback(ui::Widget widget, GdkEventAny *event, ModalDialog *data) -{ - widget.hide(); - data->loop = false; - return TRUE; -} - -ui::Window create_simple_modal_dialog_window(const char *title, ModalDialog &dialog, ui::Widget contents) -{ - ui::Window window = create_fixedsize_modal_dialog_window(ui::Window{ui::null}, title, dialog); - - auto vbox1 = create_dialog_vbox(8, 4); - window.add(vbox1); - - vbox1.add(contents); - - ui::Alignment alignment = ui::Alignment(0.5, 0.0, 0.0, 0.0); - alignment.show(); - vbox1.pack_start(alignment, FALSE, FALSE, 0); - - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - alignment.add(button); - - return window; -} - -RadioHBox RadioHBox_new(StringArrayRange names) -{ - auto hbox = ui::HBox(TRUE, 4); - hbox.show(); - - GSList *group = 0; - auto radio = ui::RadioButton(ui::null); - for (StringArrayRange::Iterator i = names.first; i != names.last; ++i) { - radio = ui::RadioButton::from(gtk_radio_button_new_with_label(group, *i)); - radio.show(); - hbox.pack_start(radio, FALSE, FALSE, 0); - - group = gtk_radio_button_get_group(radio); - } - - return RadioHBox(hbox, radio); -} - - -PathEntry PathEntry_new() -{ - auto frame = ui::Frame(); - frame.show(); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - - // path entry - auto hbox = ui::HBox(FALSE, 0); - hbox.show(); - - auto entry = ui::Entry(ui::New); - gtk_entry_set_has_frame(entry, FALSE); - entry.show(); - hbox.pack_start(entry, TRUE, TRUE, 0); - - // browse button - auto button = ui::Button(ui::New); - button_set_icon(button, "ellipsis.bmp"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - - frame.add(hbox); - - return PathEntry(frame, entry, button); -} - -void PathEntry_setPath(PathEntry &self, const char *path) -{ - gtk_entry_set_text(self.m_entry, path); -} - -typedef ReferenceCaller PathEntrySetPathCaller; - -void BrowsedPathEntry_clicked(ui::Widget widget, BrowsedPathEntry *self) -{ - self->m_browse(PathEntrySetPathCaller(self->m_entry)); -} - -BrowsedPathEntry::BrowsedPathEntry(const BrowseCallback &browse) : - m_entry(PathEntry_new()), - m_browse(browse) -{ - m_entry.m_button.connect("clicked", G_CALLBACK(BrowsedPathEntry_clicked), this); -} - - -ui::Label DialogLabel_new(const char *name) -{ - auto label = ui::Label(name); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - - return label; -} - -ui::Table DialogRow_new(const char *name, ui::Widget widget) -{ - auto table = ui::Table(1, 3, TRUE); - table.show(); - - gtk_table_set_col_spacings(table, 4); - gtk_table_set_row_spacings(table, 0); - - table.attach(DialogLabel_new(name), {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - table.attach(widget, {1, 3, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - return table; -} - -void DialogVBox_packRow(ui::Box vbox, ui::Widget row) -{ - vbox.pack_start(row, FALSE, FALSE, 0); -} diff --git a/libs/gtkutil/dialog.h b/libs/gtkutil/dialog.h deleted file mode 100644 index 5c246c5..0000000 --- a/libs/gtkutil/dialog.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_DIALOG_H ) -#define INCLUDED_GTKUTIL_DIALOG_H - -#include "generic/callback.h" -#include "generic/arrayrange.h" -#include "qerplugin.h" - -typedef int gint; -typedef gint gboolean; -typedef struct _GdkEventAny GdkEventAny; - - -struct ModalDialog { - ModalDialog() - : loop(true), ret(eIDCANCEL) - { - } - - bool loop; - EMessageBoxReturn ret; -}; - -struct ModalDialogButton { - ModalDialogButton(ModalDialog &dialog, EMessageBoxReturn value) - : m_dialog(dialog), m_value(value) - { - } - - ModalDialog &m_dialog; - EMessageBoxReturn m_value; -}; - -typedef void ( *GCallback )(void); - -typedef void *gpointer; - -ui::Window create_fixedsize_modal_window(ui::Window parent, const char *title, int width, int height); - -ui::Window create_dialog_window(ui::Window parent, const char *title, GCallback func, gpointer data, int default_w = -1, - int default_h = -1); - -ui::Table -create_dialog_table(unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, - int border = 0); - -ui::Button create_dialog_button(const char *label, GCallback func, gpointer data); - -ui::VBox create_dialog_vbox(int spacing, int border = 0); - -ui::HBox create_dialog_hbox(int spacing, int border = 0); - -ui::Frame create_dialog_frame(const char *label, ui::Shadow shadow = ui::Shadow::ETCHED_IN); - -ui::Button create_modal_dialog_button(const char *label, ModalDialogButton &button); - -ui::Window create_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int default_w = -1, - int default_h = -1); - -ui::Window -create_fixedsize_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int width = -1, - int height = -1); - -EMessageBoxReturn modal_dialog_show(ui::Window window, ModalDialog &dialog); - - -gboolean dialog_button_ok(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_cancel(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_yes(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_no(ui::Widget widget, ModalDialog *data); - -gboolean dialog_delete_callback(ui::Widget widget, GdkEventAny *event, ModalDialog *data); - -ui::Window create_simple_modal_dialog_window(const char *title, ModalDialog &dialog, ui::Widget contents); - -class RadioHBox { -public: -ui::HBox m_hbox; -ui::RadioButton m_radio; - -RadioHBox(ui::HBox hbox, ui::RadioButton radio) : - m_hbox(hbox), - m_radio(radio) -{ -} -}; - -RadioHBox RadioHBox_new(StringArrayRange names); - - -class PathEntry { -public: -ui::Frame m_frame; -ui::Entry m_entry; -ui::Button m_button; - -PathEntry(ui::Frame frame, ui::Entry entry, ui::Button button) : - m_frame(frame), - m_entry(entry), - m_button(button) -{ -} -}; - -PathEntry PathEntry_new(); - -class BrowsedPathEntry { -public: -typedef Callback SetPathCallback; -typedef Callback BrowseCallback; - -PathEntry m_entry; -BrowseCallback m_browse; - -BrowsedPathEntry(const BrowseCallback &browse); -}; - -ui::Label DialogLabel_new(const char *name); - -ui::Table DialogRow_new(const char *name, ui::Widget widget); - -void DialogVBox_packRow(ui::Box vbox, ui::Widget row); - - -#endif diff --git a/libs/gtkutil/entry.cpp b/libs/gtkutil/entry.cpp deleted file mode 100644 index 7d2554c..0000000 --- a/libs/gtkutil/entry.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "entry.h" - -#include - -void entry_set_string(ui::Entry entry, const char *string) -{ - gtk_entry_set_text(entry, string); -} - -void entry_set_int(ui::Entry entry, int i) -{ - char buf[32]; - sprintf(buf, "%d", i); - entry_set_string(entry, buf); -} - -void entry_set_float(ui::Entry entry, float f) -{ - char buf[32]; - sprintf(buf, "%g", f); - entry_set_string(entry, buf); -} - -const char *entry_get_string(ui::Entry entry) -{ - return gtk_entry_get_text(entry); -} - -int entry_get_int(ui::Entry entry) -{ - return atoi(entry_get_string(entry)); -} - -double entry_get_float(ui::Entry entry) -{ - return atof(entry_get_string(entry)); -} diff --git a/libs/gtkutil/entry.h b/libs/gtkutil/entry.h deleted file mode 100644 index 067157a..0000000 --- a/libs/gtkutil/entry.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_ENTRY_H ) -#define INCLUDED_GTKUTIL_ENTRY_H - -void entry_set_string(ui::Entry entry, const char *string); - -void entry_set_int(ui::Entry entry, int i); - -void entry_set_float(ui::Entry entry, float f); - -const char *entry_get_string(ui::Entry entry); - -int entry_get_int(ui::Entry entry); - -double entry_get_float(ui::Entry entry); - -#endif diff --git a/libs/gtkutil/filechooser.cpp b/libs/gtkutil/filechooser.cpp deleted file mode 100644 index 5b0898a..0000000 --- a/libs/gtkutil/filechooser.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filechooser.h" - -#include "ifiletypes.h" - -#include -#include -#include -#include - -#include "string/string.h" -#include "stream/stringstream.h" -#include "container/array.h" -#include "os/path.h" -#include "os/file.h" - -#include "messagebox.h" - - -struct filetype_pair_t { - filetype_pair_t() - : m_moduleName("") - { - } - - filetype_pair_t(const char *moduleName, filetype_t type) - : m_moduleName(moduleName), m_type(type) - { - } - - const char *m_moduleName; - filetype_t m_type; -}; - -class FileTypeList : public IFileTypeList { -struct filetype_copy_t { - filetype_copy_t(const filetype_pair_t &other) - : m_moduleName(other.m_moduleName), m_name(other.m_type.name), m_pattern(other.m_type.pattern) - { - } - - CopiedString m_moduleName; - CopiedString m_name; - CopiedString m_pattern; -}; - -typedef std::list Types; -Types m_types; -public: - -typedef Types::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_types.begin(); -} - -const_iterator end() const -{ - return m_types.end(); -} - -std::size_t size() const -{ - return m_types.size(); -} - -void addType(const char *moduleName, filetype_t type) -{ - m_types.push_back(filetype_pair_t(moduleName, type)); -} -}; - - -class GTKMasks { -const FileTypeList &m_types; -public: -std::vector m_filters; -std::vector m_masks; - -GTKMasks(const FileTypeList &types) : m_types(types) -{ - m_masks.reserve(m_types.size()); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i) { - std::size_t len = strlen((*i).m_name.c_str()) + strlen((*i).m_pattern.c_str()) + 3; - StringOutputStream buffer(len + 1); // length + null char - - buffer << (*i).m_name.c_str() << " <" << (*i).m_pattern.c_str() << ">"; - - m_masks.push_back(buffer.c_str()); - } - - m_filters.reserve(m_types.size()); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i) { - m_filters.push_back((*i).m_pattern); - } -} - -filetype_pair_t GetTypeForGTKMask(const char *mask) const -{ - std::vector::const_iterator j = m_masks.begin(); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i, ++j) { - if (string_equal((*j).c_str(), mask)) { - return filetype_pair_t((*i).m_moduleName.c_str(), - filetype_t((*i).m_name.c_str(), (*i).m_pattern.c_str())); - } - } - return filetype_pair_t(); -} - -}; - -static char g_file_dialog_file[1024]; - -const char * -file_dialog_show(ui::Window parent, bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - filetype_t type; - - if (pattern == 0) { - pattern = "*"; - } - - FileTypeList typelist; - GlobalFiletypes().getTypeList(pattern, &typelist, want_load, want_import, want_save); - - GTKMasks masks(typelist); - - if (title == 0) { - title = open ? "Open File" : "Save File"; - } - - ui::Dialog dialog{ui::null}; - if (open) { - dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL)); - } else { - dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL)); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "unnamed"); - } - - gtk_window_set_modal(dialog, TRUE); - gtk_window_set_position(dialog, GTK_WIN_POS_CENTER_ON_PARENT); - - // we expect an actual path below, if the path is 0 we might crash - if (path != 0 && !string_empty(path)) { - ASSERT_MESSAGE(path_is_absolute(path), "file_dialog_show: path not absolute: " << makeQuoted(path)); - - Array new_path(strlen(path) + 1); - - // copy path, replacing dir separators as appropriate - Array::iterator w = new_path.begin(); - for (const char *r = path; *r != '\0'; ++r) { - *w++ = (*r == '/') ? G_DIR_SEPARATOR : *r; - } - // remove separator from end of path if required - if (*(w - 1) == G_DIR_SEPARATOR) { - --w; - } - // terminate string - *w = '\0'; - - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), new_path.data()); - } - - // we should add all important paths as shortcut folder... - // gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), "/tmp/", NULL); - - - for (std::size_t i = 0; i < masks.m_filters.size(); ++i) { - GtkFileFilter *filter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(filter, masks.m_filters[i].c_str()); - gtk_file_filter_set_name(filter, masks.m_masks[i].c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - } - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - strcpy(g_file_dialog_file, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); - - if (!string_equal(pattern, "*")) { - GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); - if (filter != - 0) { // no filter set? some file-chooser implementations may allow the user to set no filter, which we treat as 'all files' - type = masks.GetTypeForGTKMask(gtk_file_filter_get_name(filter)).m_type; - // last ext separator - const char *extension = path_get_extension(g_file_dialog_file); - // no extension - if (string_empty(extension)) { - strcat(g_file_dialog_file, type.pattern + 1); - } else { - strcpy(g_file_dialog_file + (extension - g_file_dialog_file), type.pattern + 2); - } - } - } - - // convert back to unix format - for (char *w = g_file_dialog_file; *w != '\0'; w++) { - if (*w == '\\') { - *w = '/'; - } - } - } else { - g_file_dialog_file[0] = '\0'; - } - - ui::Widget(dialog).destroy(); - - // don't return an empty filename - if (g_file_dialog_file[0] == '\0') { - return NULL; - } - - return g_file_dialog_file; -} - -char *dir_dialog(ui::Window parent, const char *title, const char *path) -{ - auto dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL)); - - gtk_window_set_modal(dialog, TRUE); - gtk_window_set_position(dialog, GTK_WIN_POS_CENTER_ON_PARENT); - - if (!string_empty(path)) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - } - - char *filename = 0; - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - } - - dialog.destroy(); - - return filename; -} - -const char * -file_dialog(ui::Window parent, bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - for (;;) { - const char *file = file_dialog_show(parent, open, title, path, pattern, want_load, want_import, want_save); - - if (open - || !file - || !file_exists(file) - || ui::alert(parent, "The file specified already exists.\nDo you want to replace it?", title, - ui::alert_type::NOYES, ui::alert_icon::Question) == ui::alert_response::YES) { - return file; - } - } -} diff --git a/libs/gtkutil/filechooser.h b/libs/gtkutil/filechooser.h deleted file mode 100644 index e2b2b25..0000000 --- a/libs/gtkutil/filechooser.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_FILECHOOSER_H ) -#define INCLUDED_GTKUTIL_FILECHOOSER_H - -/// \file -/// GTK+ file-chooser dialogs. - -const char *file_dialog(ui::Window parent, bool open, const char *title, const char *path = 0, const char *pattern = 0, - bool want_load = false, bool want_import = false, bool want_save = false); - - -/// \brief Prompts the user to browse for a directory. -/// The prompt window will be transient to \p parent. -/// The directory will initially default to \p path, which must be an absolute path. -/// The returned string is allocated with \c g_malloc and must be freed with \c g_free. -char *dir_dialog(ui::Window parent, const char *title = "Choose Directory", const char *path = ""); - -#endif diff --git a/libs/gtkutil/frame.cpp b/libs/gtkutil/frame.cpp deleted file mode 100644 index 1f289d2..0000000 --- a/libs/gtkutil/frame.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "frame.h" - -#include -#include - -ui::Frame create_framed_widget(ui::Widget widget) -{ - auto frame = ui::Frame(); - frame.show(); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - frame.add(widget); - widget.show(); - return frame; -} diff --git a/libs/gtkutil/frame.h b/libs/gtkutil/frame.h deleted file mode 100644 index f35f9dc..0000000 --- a/libs/gtkutil/frame.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_FRAME_H ) -#define INCLUDED_GTKUTIL_FRAME_H - -ui::Frame create_framed_widget(ui::Widget widget); - -#endif diff --git a/libs/gtkutil/glfont.cpp b/libs/gtkutil/glfont.cpp deleted file mode 100644 index da0cd4f..0000000 --- a/libs/gtkutil/glfont.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "glfont.h" -#include "globaldefs.h" -#include "igl.h" - -// generic string printing with call lists -class GLFontCallList : public GLFont { -GLuint m_displayList; -int m_pixelHeight; -int m_pixelAscent; -int m_pixelDescent; -public: -GLFontCallList(GLuint displayList, int asc, int desc, int pixelHeight) : m_displayList(displayList), - m_pixelHeight(pixelHeight), - m_pixelAscent(asc), m_pixelDescent(desc) -{ -} - -virtual ~GLFontCallList() -{ - glDeleteLists(m_displayList, 256); -} - -void printString(const char *s) -{ - GlobalOpenGL().m_glListBase(m_displayList); - GlobalOpenGL().m_glCallLists(GLsizei(strlen(s)), GL_UNSIGNED_BYTE, reinterpret_cast( s )); -} - -virtual int getPixelAscent() const -{ - return m_pixelAscent; -} - -virtual int getPixelDescent() const -{ - return m_pixelDescent; -} - -virtual int getPixelHeight() const -{ - return m_pixelHeight; -} -}; - -#if GDEF_OS_WINDOWS -#include -#endif - -#include "debugging/debugging.h" - -// LordHavoc: this is code for direct Xlib bitmap character fetching, as an -// alternative to requiring gtkglarea, it was created due to a lack of this -// package on SuSE 9.x but this package is now commonly shipping in Linux -// distributions so this code may be unnecessary, feel free however to enable -// it when building packages for distros that do not ship with that package, -// or if you just prefer less dependencies... -#if 0 - -#include -#include -#include - -GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base; - XFontStruct *fontInfo; - Display *dpy = GDK_DISPLAY(); - unsigned int i, first, last, firstrow, lastrow; - int maxchars; - int firstbitmap; - - fontInfo = XLoadQueryFont( dpy, "-*-fixed-*-*-*-*-8-*-*-*-*-*-*-*" ); - if ( fontInfo == NULL ) { - // try to load other fonts - fontInfo = XLoadQueryFont( dpy, "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*" ); - - // any font will do ! - if ( fontInfo == NULL ) { - fontInfo = XLoadQueryFont( dpy, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" ); - } - - if ( fontInfo == NULL ) { - ERROR_MESSAGE( "couldn't create font" ); - } - } - - first = (int)fontInfo->min_char_or_byte2; - last = (int)fontInfo->max_char_or_byte2; - firstrow = (int)fontInfo->min_byte1; - lastrow = (int)fontInfo->max_byte1; - /* - * How many chars in the charset - */ - maxchars = 256 * lastrow + last; - font_list_base = glGenLists( maxchars + 1 ); - if ( font_list_base == 0 ) { - ERROR_MESSAGE( "couldn't create font" ); - } - - /* - * Get offset to first char in the charset - */ - firstbitmap = 256 * firstrow + first; - /* - * for each row of chars, call glXUseXFont to build the bitmaps. - */ - - for ( i = firstrow; i <= lastrow; i++ ) - { - glXUseXFont( fontInfo->fid, firstbitmap, last - first + 1, font_list_base + firstbitmap ); - firstbitmap += 256; - } - -/* *height = fontInfo->ascent + fontInfo->descent; - * width = fontInfo->max_bounds.width; */ - return new GLFontCallList( font_list_base, fontInfo->ascent, fontInfo->descent, fontInfo->ascent + fontInfo->descent ); -} - -#elif 0 - -#include - -GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base = glGenLists( 256 ); - gint font_height = 0, font_ascent = 0, font_descent = 0; - - PangoFontDescription* font_desc = pango_font_description_from_string( font_string ); - - PangoFont* font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - - if ( font == 0 ) { - pango_font_description_free( font_desc ); - font_desc = pango_font_description_from_string( "fixed 8" ); - font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - } - - if ( font == 0 ) { - pango_font_description_free( font_desc ); - font_desc = pango_font_description_from_string( "courier new 8" ); - font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - } - - if ( font != 0 ) { - PangoFontMetrics* font_metrics = pango_font_get_metrics( font, 0 ); - - font_ascent = pango_font_metrics_get_ascent( font_metrics ); - font_descent = pango_font_metrics_get_descent( font_metrics ); - font_height = font_ascent + font_descent; - - font_ascent = PANGO_PIXELS( font_ascent ); - font_descent = PANGO_PIXELS( font_descent ); - font_height = PANGO_PIXELS( font_height ); - - pango_font_metrics_unref( font_metrics ); - } - - pango_font_description_free( font_desc ); - - // fix for pango/gtkglext metrix bug - if ( font_height > 256 ) { - font_height = 16; - } - - return new GLFontCallList( font_list_base, font_ascent, font_descent, font_height ); -} -#else - -// new font code ripped from ZeroRadiant - -#include -#include -#include - -class GLFontInternal : public GLFont { -const char *font_string; -int font_height; -int font_ascent; -int font_descent; -int y_offset_bitmap_render_pango_units; -PangoContext *ft2_context; -PangoFontMap *fontmap; - -public: -GLFontInternal(const char *_font_string) : font_string(_font_string) -{ - PangoFontDescription *font_desc; - PangoLayout *layout; - PangoRectangle log_rect; - int font_ascent_pango_units; - int font_descent_pango_units; - -#if !PANGO_VERSION_CHECK(1, 22, 0) - ft2_context = pango_ft2_get_context( 72, 72 ); -#else - fontmap = pango_ft2_font_map_new(); - pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontmap), 72, 72); - ft2_context = pango_font_map_create_context(fontmap); -#endif - - font_desc = pango_font_description_from_string( "Liberation Mono 12" ); - //pango_font_description_set_size(font_desc, 10 * PANGO_SCALE); - pango_context_set_font_description(ft2_context, font_desc); - pango_font_description_free(font_desc); - // TODO fallback to fixed 8, courier new 8 - - layout = pango_layout_new(ft2_context); - -#ifdef FONT_SIZE_WORKAROUND - pango_layout_set_width( layout, -1 ); // -1 no wrapping. All text on one line. - pango_layout_set_text( layout, "The quick brown fox jumped over the lazy sleeping dog's back then sat on a tack.", -1 ); // -1 null-terminated string. -#endif - -#if !PANGO_VERSION_CHECK(1, 22, 0) - PangoLayoutIter *iter; - iter = pango_layout_get_iter( layout ); - font_ascent_pango_units = pango_layout_iter_get_baseline( iter ); - pango_layout_iter_free( iter ); -#else - font_ascent_pango_units = pango_layout_get_baseline(layout); -#endif - pango_layout_get_extents(layout, NULL, &log_rect); - g_object_unref(G_OBJECT(layout)); - font_descent_pango_units = log_rect.height - font_ascent_pango_units; - - font_ascent = PANGO_PIXELS_CEIL(font_ascent_pango_units); - font_descent = PANGO_PIXELS_CEIL(font_descent_pango_units); - font_height = font_ascent + font_descent; - y_offset_bitmap_render_pango_units = (font_ascent * PANGO_SCALE) - font_ascent_pango_units; -} - -virtual ~GLFontInternal() -{ - g_object_unref(G_OBJECT(ft2_context)); - g_object_unref(G_OBJECT(fontmap)); -} - -// Renders the input text at the current location with the current color. -// The X position of the current location is used to place the left edge of the text image, -// where the text image bounds are defined as the logical extents of the line of text. -// The Y position of the current location is used to place the bottom of the text image. -// You should offset the Y position by the amount returned by gtk_glwidget_font_descent() -// if you want to place the baseline of the text image at the current Y position. -// Note: A problem with this function is that if the lower left corner of the text falls -// just a hair outside of the viewport (meaning the current raster position is invalid), -// then no text will be rendered. The solution to this is a very hacky one. You can search -// Google for "glDrawPixels clipping". -virtual void printString(const char *s) -{ - // The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt. - - PangoLayout *layout; - PangoRectangle log_rect; - FT_Bitmap bitmap; - unsigned char *begin_bitmap_buffer; - GLfloat color[4]; - GLint previous_unpack_alignment; - GLboolean previous_blend_enabled; - GLint previous_blend_func_src; - GLint previous_blend_func_dst; - GLfloat previous_red_bias; - GLfloat previous_green_bias; - GLfloat previous_blue_bias; - GLfloat previous_alpha_scale; - - layout = pango_layout_new(ft2_context); - pango_layout_set_width(layout, -1); // -1 no wrapping. All text on one line. - pango_layout_set_text(layout, s, -1); // -1 null-terminated string. - pango_layout_get_extents(layout, NULL, &log_rect); - - if (log_rect.width > 0 && log_rect.height > 0) { - bitmap.rows = font_ascent + font_descent; - bitmap.width = PANGO_PIXELS_CEIL(log_rect.width); - bitmap.pitch = -bitmap.width; // Rendering it "upside down" for OpenGL. - begin_bitmap_buffer = (unsigned char *) g_malloc(bitmap.rows * bitmap.width); - memset(begin_bitmap_buffer, 0, bitmap.rows * bitmap.width); - bitmap.buffer = begin_bitmap_buffer + (bitmap.rows - 1) * bitmap.width; // See pitch above. - bitmap.num_grays = 0xff; - bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; - pango_ft2_render_layout_subpixel(&bitmap, layout, -log_rect.x, - y_offset_bitmap_render_pango_units); - GlobalOpenGL().m_glGetFloatv(GL_CURRENT_COLOR, color); - - // Save state. I didn't see any OpenGL push/pop operations for these. - // Question: Is saving/restoring this state necessary? Being safe. - GlobalOpenGL().m_glGetIntegerv(GL_UNPACK_ALIGNMENT, &previous_unpack_alignment); - previous_blend_enabled = GlobalOpenGL().m_glIsEnabled(GL_BLEND); - GlobalOpenGL().m_glGetIntegerv(GL_BLEND_SRC, &previous_blend_func_src); - GlobalOpenGL().m_glGetIntegerv(GL_BLEND_DST, &previous_blend_func_dst); - GlobalOpenGL().m_glGetFloatv(GL_RED_BIAS, &previous_red_bias); - GlobalOpenGL().m_glGetFloatv(GL_GREEN_BIAS, &previous_green_bias); - GlobalOpenGL().m_glGetFloatv(GL_BLUE_BIAS, &previous_blue_bias); - GlobalOpenGL().m_glGetFloatv(GL_ALPHA_SCALE, &previous_alpha_scale); - - GlobalOpenGL().m_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GlobalOpenGL().m_glEnable(GL_BLEND); - GlobalOpenGL().m_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GlobalOpenGL().m_glPixelTransferf(GL_RED_BIAS, color[0]); - GlobalOpenGL().m_glPixelTransferf(GL_GREEN_BIAS, color[1]); - GlobalOpenGL().m_glPixelTransferf(GL_BLUE_BIAS, color[2]); - GlobalOpenGL().m_glPixelTransferf(GL_ALPHA_SCALE, color[3]); - - GlobalOpenGL().m_glDrawPixels(bitmap.width, bitmap.rows, - GL_ALPHA, GL_UNSIGNED_BYTE, begin_bitmap_buffer); - g_free(begin_bitmap_buffer); - - // Restore state in reverse order of how we set it. - GlobalOpenGL().m_glPixelTransferf(GL_ALPHA_SCALE, previous_alpha_scale); - GlobalOpenGL().m_glPixelTransferf(GL_BLUE_BIAS, previous_blue_bias); - GlobalOpenGL().m_glPixelTransferf(GL_GREEN_BIAS, previous_green_bias); - GlobalOpenGL().m_glPixelTransferf(GL_RED_BIAS, previous_red_bias); - GlobalOpenGL().m_glBlendFunc(previous_blend_func_src, previous_blend_func_dst); - if (!previous_blend_enabled) { - GlobalOpenGL().m_glDisable(GL_BLEND); - } - GlobalOpenGL().m_glPixelStorei(GL_UNPACK_ALIGNMENT, previous_unpack_alignment); - } - - g_object_unref(G_OBJECT(layout)); -} - -virtual int getPixelAscent() const -{ - return font_ascent; -} - -virtual int getPixelDescent() const -{ - return font_descent; -} - -virtual int getPixelHeight() const -{ - return font_height; -} -}; - -GLFont *glfont_create(const char *font_string) -{ - return new GLFontInternal(font_string); -} - -#endif diff --git a/libs/gtkutil/glfont.h b/libs/gtkutil/glfont.h deleted file mode 100644 index e890791..0000000 --- a/libs/gtkutil/glfont.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_GLFONT_H ) -#define INCLUDED_GTKUTIL_GLFONT_H - -typedef unsigned int GLuint; - -class GLFont { -public: -virtual int getPixelHeight() const = 0; - -virtual int getPixelAscent() const = 0; - -virtual int getPixelDescent() const = 0; - -virtual void printString(const char *s) = 0; - -virtual ~GLFont() -{ -} -}; - -GLFont *glfont_create(const char *font_string); -// release with delete - -#endif diff --git a/libs/gtkutil/glwidget.cpp b/libs/gtkutil/glwidget.cpp deleted file mode 100644 index 335581f..0000000 --- a/libs/gtkutil/glwidget.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// OpenGL widget based on GtkGLExt - -#include "glwidget.h" - -#include "igl.h" - -void (*GLWidget_sharedContextCreated)() = 0; - -void (*GLWidget_sharedContextDestroyed)() = 0; - -unsigned int g_context_count = 0; - -ui::GLArea g_shared{ui::null}; - -void _glwidget_context_created(ui::GLArea self, void *data) -{ - if (++g_context_count == 1) { - g_shared = self; - g_object_ref(g_shared._handle); - - glwidget_make_current(g_shared); - GlobalOpenGL().contextValid = true; - - GLWidget_sharedContextCreated(); - } -} - -void _glwidget_context_destroyed(ui::GLArea self, void *data) -{ - if (--g_context_count == 0) { - GlobalOpenGL().contextValid = false; - - GLWidget_sharedContextDestroyed(); - - g_shared.unref(); - g_shared = ui::GLArea(ui::null); - } -} - -void glwidget_destroy_context(ui::GLArea self) -{ -} - -void glwidget_create_context(ui::GLArea self) -{ -} - -#if GTK_TARGET == 3 - -#include - -GdkGLContext *glwidget_context_created(ui::GLArea self) -{ - _glwidget_context_created(self, nullptr); - return gtk_gl_area_get_context(self); -} - -ui::GLArea glwidget_new(bool zbuffer) -{ - auto self = ui::GLArea(GTK_GL_AREA(gtk_gl_area_new())); - gtk_gl_area_set_has_depth_buffer(self, zbuffer); - gtk_gl_area_set_auto_render(self, false); - - self.connect("realize", G_CALLBACK(glwidget_context_created), nullptr); - return self; -} - -bool glwidget_make_current(ui::GLArea self) -{ -// if (!g_context_count) { -// glwidget_context_created(self); -// } - gtk_gl_area_make_current(self); - auto valid = GlobalOpenGL().contextValid; - return true; -} - -void glwidget_swap_buffers(ui::GLArea self) -{ - gtk_gl_area_queue_render(self); -} - -#endif - -#if GTK_TARGET == 2 - -#include -#include - -#include "pointer.h" - -struct config_t { - const char *name; - int *attribs; -}; -typedef const config_t *configs_iterator; - -int config_rgba32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs[] = { - { - "colour-buffer = 32bpp, depth-buffer = none", - config_rgba32, - }, - { - "colour-buffer = 16bpp, depth-buffer = none", - config_rgba, - } -}; - -GdkGLConfig *glconfig_new() -{ - for (configs_iterator i = configs, end = configs + 2; i != end; ++i) { - if (auto glconfig = gdk_gl_config_new(i->attribs)) { - globalOutputStream() << "OpenGL window configuration: " << i->name << "\n"; - return glconfig; - } - } - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = none\n"; - return gdk_gl_config_new_by_mode((GdkGLConfigMode) (GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE)); -} - -int config_rgba32_depth32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, - 24, - GDK_GL_DEPTH_SIZE, - 32, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth24[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs_with_depth[] = -{ - { - "colour-buffer = 32bpp, depth-buffer = 32bpp", - config_rgba32_depth32, - }, - { - "colour-buffer = 32bpp, depth-buffer = 24bpp", - config_rgba32_depth24, - }, - { - "colour-buffer = 32bpp, depth-buffer = 16bpp", - config_rgba32_depth16, - }, - { - "colour-buffer = 32bpp, depth-buffer = auto", - config_rgba32_depth, - }, - { - "colour-buffer = 16bpp, depth-buffer = 16bpp", - config_rgba_depth16, - }, - { - "colour-buffer = auto, depth-buffer = auto", - config_rgba_depth, - }, -}; - -GdkGLConfig *glconfig_new_with_depth() -{ - for (configs_iterator i = configs_with_depth, end = configs_with_depth + 6; i != end; ++i) { - if (auto glconfig = gdk_gl_config_new(i->attribs)) { - globalOutputStream() << "OpenGL window configuration: " << i->name << "\n"; - return glconfig; - } - } - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = auto (fallback)\n"; - return gdk_gl_config_new_by_mode((GdkGLConfigMode) (GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE | GDK_GL_MODE_DEPTH)); -} - -int glwidget_context_created(ui::GLArea self, void *data) -{ - _glwidget_context_created(self, data); - return false; -} - -int glwidget_context_destroyed(ui::GLArea self, void *data) -{ - _glwidget_context_destroyed(self, data); - return false; -} - -bool glwidget_enable_gl(ui::GLArea self, ui::Widget root, gpointer data) -{ - if (!root && !gtk_widget_is_gl_capable(self)) { - const auto zbuffer = g_object_get_data(G_OBJECT(self), "zbuffer"); - GdkGLConfig *glconfig = zbuffer ? glconfig_new_with_depth() : glconfig_new(); - ASSERT_MESSAGE(glconfig, "failed to create OpenGL config"); - - const auto share_list = g_shared ? gtk_widget_get_gl_context(g_shared) : nullptr; - gtk_widget_set_gl_capability(self, glconfig, share_list, true, GDK_GL_RGBA_TYPE); - - gtk_widget_realize(self); - if (!g_shared) { - g_shared = self; - } - // free glconfig? - } - return false; -} - -ui::GLArea glwidget_new(bool zbuffer) -{ - auto self = ui::GLArea::from(gtk_drawing_area_new()); - - g_object_set_data(G_OBJECT(self), "zbuffer", gint_to_pointer(zbuffer)); - - self.connect("hierarchy-changed", G_CALLBACK(glwidget_enable_gl), 0); - - self.connect("realize", G_CALLBACK(glwidget_context_created), 0); - self.connect("unrealize", G_CALLBACK(glwidget_context_destroyed), 0); - - return self; -} - -void glwidget_swap_buffers(ui::GLArea self) -{ - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(self); - gdk_gl_drawable_swap_buffers(gldrawable); -} - -bool glwidget_make_current(ui::GLArea self) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context(self); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(self); - return gdk_gl_drawable_gl_begin(gldrawable, glcontext); -} - -#endif diff --git a/libs/gtkutil/glwidget.h b/libs/gtkutil/glwidget.h deleted file mode 100644 index c0bbff4..0000000 --- a/libs/gtkutil/glwidget.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_GLWIDGET_H ) -#define INCLUDED_GTKUTIL_GLWIDGET_H - -extern void (*GLWidget_sharedContextCreated)(); - -extern void (*GLWidget_sharedContextDestroyed)(); - -ui::GLArea glwidget_new(bool zbuffer); - -void glwidget_create_context(ui::GLArea self); - -void glwidget_destroy_context(ui::GLArea self); - -bool glwidget_make_current(ui::GLArea self); - -void glwidget_swap_buffers(ui::GLArea self); - -#endif diff --git a/libs/gtkutil/idledraw.h b/libs/gtkutil/idledraw.h deleted file mode 100644 index d906f03..0000000 --- a/libs/gtkutil/idledraw.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_IDLEDRAW_H ) -#define INCLUDED_GTKUTIL_IDLEDRAW_H - -#include - -#include "generic/callback.h" - -class IdleDraw { -Callback m_draw; -unsigned int m_handler; - -static gboolean draw(gpointer data) -{ - reinterpret_cast( data )->m_draw(); - reinterpret_cast( data )->m_handler = 0; - return FALSE; -} - -public: -IdleDraw(const Callback &draw) : m_draw(draw), m_handler(0) -{ -} - -~IdleDraw() -{ - if (m_handler != 0) { - g_source_remove(m_handler); - } -} - -void queueDraw() -{ - if (m_handler == 0) { - m_handler = g_idle_add(&draw, this); - } -} - -typedef MemberCaller QueueDrawCaller; - -void flush() -{ - if (m_handler != 0) { - draw(this); - } -} -}; - - -#endif diff --git a/libs/gtkutil/image.cpp b/libs/gtkutil/image.cpp deleted file mode 100644 index 2ccc5f8..0000000 --- a/libs/gtkutil/image.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "image.h" - -#include - -#include "string/string.h" -#include "stream/stringstream.h" -#include "stream/textstream.h" - - -namespace { -CopiedString g_bitmapsPath; -} - -void BitmapsPath_set(const char *path) -{ - g_bitmapsPath = path; -} - -GdkPixbuf *pixbuf_new_from_file_with_mask(const char *filename) -{ - GdkPixbuf *rgb = gdk_pixbuf_new_from_file(filename, 0); - if (rgb == 0) { - return 0; - } else { - GdkPixbuf *rgba = gdk_pixbuf_add_alpha(rgb, FALSE, 255, 0, 255); - g_object_unref(rgb); - return rgba; - } -} - -ui::Image image_new_from_file_with_mask(const char *filename) -{ - GdkPixbuf *rgba = pixbuf_new_from_file_with_mask(filename); - if (rgba == 0) { - return ui::Image(ui::null); - } else { - auto image = ui::Image::from(gtk_image_new_from_pixbuf(rgba)); - g_object_unref(rgba); - return image; - } -} - -ui::Image image_new_missing() -{ - return ui::Image::from(gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_SMALL_TOOLBAR)); -} - -ui::Image new_image(const char *filename) -{ - if (auto image = image_new_from_file_with_mask(filename)) { - return image; - } - return image_new_missing(); -} - -ui::Image new_local_image(const char *filename) -{ - StringOutputStream fullPath(256); - fullPath << g_bitmapsPath.c_str() << filename; - return new_image(fullPath.c_str()); -} diff --git a/libs/gtkutil/image.h b/libs/gtkutil/image.h deleted file mode 100644 index 6604df2..0000000 --- a/libs/gtkutil/image.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_IMAGE_H ) -#define INCLUDED_GTKUTIL_IMAGE_H - -void BitmapsPath_set(const char *path); - -typedef struct _GdkPixbuf GdkPixbuf; - -GdkPixbuf *pixbuf_new_from_file_with_mask(const char *filename); - -ui::Image image_new_from_file_with_mask(const char *filename); - -ui::Image image_new_missing(); - -ui::Image new_image(const char *filename); // filename is full path to image file -ui::Image new_local_image(const char *filename); // filename is relative to local bitmaps path - -#endif diff --git a/libs/gtkutil/menu.cpp b/libs/gtkutil/menu.cpp deleted file mode 100644 index 33c906d..0000000 --- a/libs/gtkutil/menu.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "menu.h" - -#include -#include -#include -#include - -#include "generic/callback.h" - -#include "accelerator.h" -#include "closure.h" -#include "container.h" -#include "pointer.h" - -void menu_add_item(ui::Menu menu, ui::MenuItem item) -{ - menu.add(item); -} - -ui::MenuItem menu_separator(ui::Menu menu) -{ - auto menu_item = ui::MenuItem::from(gtk_menu_item_new()); - menu.add(menu_item); - gtk_widget_set_sensitive(menu_item, FALSE); - menu_item.show(); - return menu_item; -} - -ui::TearoffMenuItem menu_tearoff(ui::Menu menu) -{ - auto menu_item = ui::TearoffMenuItem::from(gtk_tearoff_menu_item_new()); - menu.add(menu_item); -// gtk_widget_set_sensitive(menu_item, FALSE); -- controls whether menu is detachable - menu_item.show(); - return menu_item; -} - -ui::MenuItem new_sub_menu_item_with_mnemonic(const char *mnemonic) -{ - auto item = ui::MenuItem(mnemonic, true); - item.show(); - - auto sub_menu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(item, sub_menu); - - return item; -} - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuShell parent, const char *mnemonic) -{ - auto item = new_sub_menu_item_with_mnemonic(mnemonic); - parent.add(item); - return ui::Menu::from(gtk_menu_item_get_submenu(item)); -} - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuBar bar, const char *mnemonic) -{ - return create_sub_menu_with_mnemonic(ui::MenuShell::from(bar._handle), mnemonic); -} - -ui::Menu create_sub_menu_with_mnemonic(ui::Menu parent, const char *mnemonic) -{ - return create_sub_menu_with_mnemonic(ui::MenuShell::from(parent._handle), mnemonic); -} - -void activate_closure_callback(ui::Widget widget, gpointer data) -{ - (*reinterpret_cast *>( data ))(); -} - -guint menu_item_connect_callback(ui::MenuItem item, const Callback &callback) -{ -#if 1 - return g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - return g_signal_connect_closure( G_OBJECT( item ), "activate", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), FALSE ); -#endif -} - -guint check_menu_item_connect_callback(ui::CheckMenuItem item, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( item ), "toggled", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(item), "handler", gint_to_pointer(handler)); - return handler; -} - -ui::MenuItem new_menu_item_with_mnemonic(const char *mnemonic, const Callback &callback) -{ - auto item = ui::MenuItem(mnemonic, true); - item.show(); - menu_item_connect_callback(item, callback); - return item; -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback) -{ - auto item = new_menu_item_with_mnemonic(mnemonic, callback); - menu.add(item); - return item; -} - -ui::CheckMenuItem new_check_menu_item_with_mnemonic(const char *mnemonic, const Callback &callback) -{ - auto item = ui::CheckMenuItem::from(gtk_check_menu_item_new_with_mnemonic(mnemonic)); - item.show(); - check_menu_item_connect_callback(item, callback); - return item; -} - -ui::CheckMenuItem -create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback) -{ - auto item = new_check_menu_item_with_mnemonic(mnemonic, callback); - menu.add(item); - return item; -} - -ui::RadioMenuItem -new_radio_menu_item_with_mnemonic(GSList **group, const char *mnemonic, const Callback &callback) -{ - auto item = ui::RadioMenuItem::from(gtk_radio_menu_item_new_with_mnemonic(*group, mnemonic)); - if (*group == 0) { - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); - } - *group = gtk_radio_menu_item_get_group(item); - item.show(); - check_menu_item_connect_callback(item, callback); - return item; -} - -ui::RadioMenuItem create_radio_menu_item_with_mnemonic(ui::Menu menu, GSList **group, const char *mnemonic, - const Callback &callback) -{ - auto item = new_radio_menu_item_with_mnemonic(group, mnemonic, callback); - menu.add(item); - return item; -} - -void check_menu_item_set_active_no_signal(ui::CheckMenuItem item, gboolean active) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(item), "handler")); - g_signal_handler_block(G_OBJECT(item), handler_id); - gtk_check_menu_item_set_active(item, active); - g_signal_handler_unblock(G_OBJECT(item), handler_id); -} - - -void radio_menu_item_set_active_no_signal(ui::RadioMenuItem item, gboolean active) -{ - { - for (GSList *l = gtk_radio_menu_item_get_group(item); l != 0; l = g_slist_next(l)) { - g_signal_handler_block(G_OBJECT(l->data), gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), active); - { - for (GSList *l = gtk_radio_menu_item_get_group(item); l != 0; l = g_slist_next(l)) { - g_signal_handler_unblock(G_OBJECT(l->data), - gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } -} - - -void menu_item_set_accelerator(ui::MenuItem item, GClosure *closure) -{ - GtkAccelLabel *accel_label = GTK_ACCEL_LABEL(gtk_bin_get_child(GTK_BIN(item))); - gtk_accel_label_set_accel_closure(accel_label, closure); -} - -void accelerator_name(const Accelerator &accelerator, GString *gstring) -{ - gboolean had_mod = FALSE; - if (accelerator.modifiers & GDK_SHIFT_MASK) { - g_string_append(gstring, "Shift"); - had_mod = TRUE; - } - if (accelerator.modifiers & GDK_CONTROL_MASK) { - if (had_mod) { - g_string_append(gstring, "+"); - } - g_string_append(gstring, "Ctrl"); - had_mod = TRUE; - } - if (accelerator.modifiers & GDK_MOD1_MASK) { - if (had_mod) { - g_string_append(gstring, "+"); - } - g_string_append(gstring, "Alt"); - had_mod = TRUE; - } - - if (had_mod) { - g_string_append(gstring, "+"); - } - if (accelerator.key < 0x80 || (accelerator.key > 0x80 && accelerator.key <= 0xff)) { - switch (accelerator.key) { - case ' ': - g_string_append(gstring, "Space"); - break; - case '\\': - g_string_append(gstring, "Backslash"); - break; - default: - g_string_append_c(gstring, gchar(toupper(accelerator.key))); - break; - } - } else { - gchar *tmp; - - tmp = gtk_accelerator_name(accelerator.key, (GdkModifierType) 0); - if (tmp[0] != 0 && tmp[1] == 0) { - tmp[0] = gchar(toupper(tmp[0])); - } - g_string_append(gstring, tmp); - g_free(tmp); - } -} - -void menu_item_add_accelerator(ui::MenuItem item, Accelerator accelerator) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - GClosure *closure = global_accel_group_find(accelerator); - ASSERT_NOTNULL(closure); - menu_item_set_accelerator(item, closure); - } -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Command &command) -{ - auto item = create_menu_item_with_mnemonic(menu, mnemonic, command.m_callback); - menu_item_add_accelerator(item, command.m_accelerator); - return item; -} - -void check_menu_item_set_active_callback(void *it, bool enabled) -{ - auto item = ui::CheckMenuItem::from(it); - check_menu_item_set_active_no_signal(item, enabled); -} - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Toggle &toggle) -{ - auto item = create_check_menu_item_with_mnemonic(menu, mnemonic, toggle.m_command.m_callback); - menu_item_add_accelerator(item, toggle.m_command.m_accelerator); - toggle.m_exportCallback(PointerCaller(item._handle)); - return item; -} diff --git a/libs/gtkutil/menu.h b/libs/gtkutil/menu.h deleted file mode 100644 index 08f8224..0000000 --- a/libs/gtkutil/menu.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_MENU_H ) -#define INCLUDED_GTKUTIL_MENU_H - -#include -#include "generic/callback.h" - -typedef int gint; -typedef gint gboolean; -typedef struct _GSList GSList; - -void menu_add_item(ui::Menu menu, ui::MenuItem item); - -ui::MenuItem menu_separator(ui::Menu menu); - -ui::TearoffMenuItem menu_tearoff(ui::Menu menu); - -ui::MenuItem new_sub_menu_item_with_mnemonic(const char *mnemonic); - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuBar bar, const char *mnemonic); - -ui::Menu create_sub_menu_with_mnemonic(ui::Menu parent, const char *mnemonic); - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback); - -ui::CheckMenuItem -create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback); - -ui::RadioMenuItem create_radio_menu_item_with_mnemonic(ui::Menu menu, GSList **group, const char *mnemonic, - const Callback &callback); - -class Command; - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Command &command); - -class Toggle; - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Toggle &toggle); - - -void check_menu_item_set_active_no_signal(ui::CheckMenuItem item, gboolean active); - -void radio_menu_item_set_active_no_signal(ui::RadioMenuItem item, gboolean active); - -#endif diff --git a/libs/gtkutil/messagebox.cpp b/libs/gtkutil/messagebox.cpp deleted file mode 100644 index ec64271..0000000 --- a/libs/gtkutil/messagebox.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "messagebox.h" - -#include -#include - -#include "dialog.h" -#include "widget.h" - -ui::Widget create_padding(int width, int height) -{ - ui::Alignment widget = ui::Alignment(0.0, 0.0, 0.0, 0.0); - widget.show(); - widget.dimensions(width, height); - return widget; -} - -const char *messagebox_stock_icon(EMessageBoxIcon type) -{ - switch (type) { - default: - case eMB_ICONDEFAULT: - return GTK_STOCK_DIALOG_INFO; - case eMB_ICONERROR: - return GTK_STOCK_DIALOG_ERROR; - case eMB_ICONWARNING: - return GTK_STOCK_DIALOG_WARNING; - case eMB_ICONQUESTION: - return GTK_STOCK_DIALOG_QUESTION; - case eMB_ICONASTERISK: - return GTK_STOCK_DIALOG_INFO; - } -} - -EMessageBoxReturn -gtk_MessageBox(ui::Window parentWindow, const char *text, const char *title, EMessageBoxType type, EMessageBoxIcon icon) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ModalDialogButton yes_button(dialog, eIDYES); - ModalDialogButton no_button(dialog, eIDNO); - - ui::Window window = create_fixedsize_modal_dialog_window(parentWindow, title, dialog, 400, 100); - - if (parentWindow) { - //window.connect( "delete_event", G_CALLBACK(floating_window_delete_present), parent); - gtk_window_deiconify(parentWindow); - } - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto vbox = create_dialog_vbox(8, 8); - window.add(vbox); - - - auto hboxDummy = create_dialog_hbox(0, 0); - vbox.pack_start(hboxDummy, FALSE, FALSE, 0); - - hboxDummy.pack_start(create_padding(0, 50), FALSE, FALSE, 0); // HACK to force minimum height - - auto iconBox = create_dialog_hbox(16, 0); - hboxDummy.pack_start(iconBox, FALSE, FALSE, 0); - - auto image = ui::Image::from(gtk_image_new_from_stock(messagebox_stock_icon(icon), GTK_ICON_SIZE_DIALOG)); - image.show(); - iconBox.pack_start(image, FALSE, FALSE, 0); - - auto label = ui::Label(text); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - gtk_label_set_line_wrap(label, TRUE); - iconBox.pack_start(label, TRUE, TRUE, 0); - - - auto vboxDummy = create_dialog_vbox(0, 0); - vbox.pack_start(vboxDummy, FALSE, FALSE, 0); - - auto alignment = ui::Alignment(0.5, 0.0, 0.0, 0.0); - alignment.show(); - vboxDummy.pack_start(alignment, FALSE, FALSE, 0); - - auto hbox = create_dialog_hbox(8, 0); - alignment.add(hbox); - - vboxDummy.pack_start(create_padding(400, 0), FALSE, FALSE, 0); // HACK to force minimum width - - - if (type == eMB_OK) { - auto button = create_modal_dialog_button("OK", ok_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, (GtkAccelFlags) 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, (GtkAccelFlags) 0); - widget_make_default(button); - button.show(); - - dialog.ret = eIDOK; - } else if (type == eMB_OKCANCEL) { - { - auto button = create_modal_dialog_button("OK", ok_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("OK", cancel_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - button.show(); - } - - dialog.ret = eIDCANCEL; - } else if (type == eMB_YESNOCANCEL) { - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - - dialog.ret = eIDCANCEL; - } else if (type == eMB_NOYES) { - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - - dialog.ret = eIDNO; - } else /* if (type == eMB_YESNO) */ - { - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - dialog.ret = eIDNO; - } - - modal_dialog_show(window, dialog); - - window.destroy(); - - return dialog.ret; -} diff --git a/libs/gtkutil/messagebox.h b/libs/gtkutil/messagebox.h deleted file mode 100644 index 0935b6e..0000000 --- a/libs/gtkutil/messagebox.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_MESSAGEBOX_H ) -#define INCLUDED_GTKUTIL_MESSAGEBOX_H - -#include "qerplugin.h" - -/// \brief Shows a modal message-box. -EMessageBoxReturn -gtk_MessageBox(ui::Window parent, const char *text, const char *title = "WorldSpawn", EMessageBoxType type = eMB_OK, - EMessageBoxIcon icon = eMB_ICONDEFAULT); - -#endif diff --git a/libs/gtkutil/nonmodal.cpp b/libs/gtkutil/nonmodal.cpp deleted file mode 100644 index 1402a90..0000000 --- a/libs/gtkutil/nonmodal.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "nonmodal.h" - -#include -#include - -gboolean escape_clear_focus_widget(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - if (event->keyval == GDK_KEY_Escape) { - gtk_window_set_focus(widget.window(), NULL); - return TRUE; - } - return FALSE; -} - -void widget_connect_escape_clear_focus_widget(ui::Widget widget) -{ - widget.connect("key_press_event", G_CALLBACK(escape_clear_focus_widget), 0); -} - -gboolean NonModalEntry::focus_in(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self) -{ - self->m_editing = false; - return FALSE; -} - -gboolean NonModalEntry::focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self) -{ - if (self->m_editing && gtk_widget_get_visible(entry)) { - self->m_apply(); - } - self->m_editing = false; - return FALSE; -} - -gboolean NonModalEntry::changed(ui::Entry entry, NonModalEntry *self) -{ - self->m_editing = true; - return FALSE; -} - -gboolean NonModalEntry::enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self) -{ - if (event->keyval == GDK_KEY_Return) { - self->m_apply(); - self->m_editing = false; - gtk_window_set_focus(entry.window(), NULL); - return TRUE; - } - return FALSE; -} - -gboolean NonModalEntry::escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self) -{ - if (event->keyval == GDK_KEY_Escape) { - self->m_cancel(); - self->m_editing = false; - gtk_window_set_focus(entry.window(), NULL); - return TRUE; - } - return FALSE; -} - -void NonModalEntry::connect(ui::Entry entry) -{ - entry.connect("focus_in_event", G_CALLBACK(focus_in), this); - entry.connect("focus_out_event", G_CALLBACK(focus_out), this); - entry.connect("key_press_event", G_CALLBACK(enter), this); - entry.connect("key_press_event", G_CALLBACK(escape), this); - entry.connect("changed", G_CALLBACK(changed), this); -} - -gboolean NonModalSpinner::changed(ui::SpinButton spin, NonModalSpinner *self) -{ - self->m_apply(); - return FALSE; -} - -gboolean NonModalSpinner::enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self) -{ - if (event->keyval == GDK_KEY_Return) { - gtk_window_set_focus(spin.window(), NULL); - return TRUE; - } - return FALSE; -} - -gboolean NonModalSpinner::escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self) -{ - if (event->keyval == GDK_KEY_Escape) { - self->m_cancel(); - gtk_window_set_focus(spin.window(), NULL); - return TRUE; - } - return FALSE; -} - -void NonModalSpinner::connect(ui::SpinButton spin) -{ - auto adj = ui::Adjustment::from(gtk_spin_button_get_adjustment(spin)); - guint handler = adj.connect("value_changed", G_CALLBACK(changed), this); - g_object_set_data(G_OBJECT(spin), "handler", gint_to_pointer(handler)); - spin.connect("key_press_event", G_CALLBACK(enter), this); - spin.connect("key_press_event", G_CALLBACK(escape), this); -} - -void NonModalRadio::connect(ui::RadioButton radio) -{ - GSList *group = gtk_radio_button_get_group(radio); - for (; group != 0; group = g_slist_next(group)) { - toggle_button_connect_callback(ui::ToggleButton::from(group->data), m_changed); - } -} diff --git a/libs/gtkutil/nonmodal.h b/libs/gtkutil/nonmodal.h deleted file mode 100644 index c09d750..0000000 --- a/libs/gtkutil/nonmodal.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_NONMODAL_H ) -#define INCLUDED_GTKUTIL_NONMODAL_H - -#include -#include "generic/callback.h" - -#include "pointer.h" -#include "button.h" - -gboolean escape_clear_focus_widget(ui::Widget widget, GdkEventKey *event, gpointer data); - -void widget_connect_escape_clear_focus_widget(ui::Widget widget); - -class NonModalEntry { -bool m_editing; -Callback m_apply; -Callback m_cancel; - -static gboolean focus_in(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self); - -static gboolean focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self); - -static gboolean changed(ui::Entry entry, NonModalEntry *self); - -static gboolean enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self); - -static gboolean escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self); - -public: -NonModalEntry(const Callback &apply, const Callback &cancel) : m_editing(false), m_apply(apply), - m_cancel(cancel) -{ -} - -void connect(ui::Entry entry); -}; - - -class NonModalSpinner { -Callback m_apply; -Callback m_cancel; - -static gboolean changed(ui::SpinButton spin, NonModalSpinner *self); - -static gboolean enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self); - -static gboolean escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self); - -public: -NonModalSpinner(const Callback &apply, const Callback &cancel) : m_apply(apply), m_cancel(cancel) -{ -} - -void connect(ui::SpinButton spin); -}; - - -class NonModalRadio { -Callback m_changed; - -public: -NonModalRadio(const Callback &changed) : m_changed(changed) -{ -} - -void connect(ui::RadioButton radio); -}; - - -#endif diff --git a/libs/gtkutil/paned.cpp b/libs/gtkutil/paned.cpp deleted file mode 100644 index 4e1b5c4..0000000 --- a/libs/gtkutil/paned.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "paned.h" - -#include -#include - -#include "frame.h" - - -class PanedState { -public: -float position; -int size; -}; - -gboolean hpaned_allocate(ui::Widget widget, GtkAllocation *allocation, PanedState *paned) -{ - if (paned->size != allocation->width) { - paned->size = allocation->width; - gtk_paned_set_position(GTK_PANED(widget), static_cast( paned->size * paned->position )); - } - return FALSE; -} - -gboolean vpaned_allocate(ui::Widget widget, GtkAllocation *allocation, PanedState *paned) -{ - if (paned->size != allocation->height) { - paned->size = allocation->height; - gtk_paned_set_position(GTK_PANED(widget), static_cast( paned->size * paned->position )); - } - return FALSE; -} - -gboolean paned_position(ui::Widget widget, gpointer dummy, PanedState *paned) -{ - if (paned->size != -1) { - paned->position = gtk_paned_get_position(GTK_PANED(widget)) / static_cast( paned->size ); - } - return FALSE; -} - -PanedState g_hpaned = {0.5f, -1,}; -PanedState g_vpaned1 = {0.5f, -1,}; -PanedState g_vpaned2 = {0.5f, -1,}; - -ui::HPaned create_split_views(ui::Widget topleft, ui::Widget topright, ui::Widget botleft, ui::Widget botright) -{ - auto hsplit = ui::HPaned(ui::New); - hsplit.show(); - - hsplit.connect("size_allocate", G_CALLBACK(hpaned_allocate), &g_hpaned); - hsplit.connect("notify::position", G_CALLBACK(paned_position), &g_hpaned); - - { - auto vsplit = ui::VPaned(ui::New); - gtk_paned_add1(GTK_PANED(hsplit), vsplit); - vsplit.show(); - - vsplit.connect("size_allocate", G_CALLBACK(vpaned_allocate), &g_vpaned1); - vsplit.connect("notify::position", G_CALLBACK(paned_position), &g_vpaned1); - - gtk_paned_add1(GTK_PANED(vsplit), create_framed_widget(topleft)); - gtk_paned_add2(GTK_PANED(vsplit), create_framed_widget(topright)); - } - { - auto vsplit = ui::VPaned(ui::New); - gtk_paned_add2(GTK_PANED(hsplit), vsplit); - vsplit.show(); - - vsplit.connect("size_allocate", G_CALLBACK(vpaned_allocate), &g_vpaned2); - vsplit.connect("notify::position", G_CALLBACK(paned_position), &g_vpaned2); - - gtk_paned_add1(GTK_PANED(vsplit), create_framed_widget(botleft)); - gtk_paned_add2(GTK_PANED(vsplit), create_framed_widget(botright)); - } - return hsplit; -} diff --git a/libs/gtkutil/paned.h b/libs/gtkutil/paned.h deleted file mode 100644 index 1c80ae6..0000000 --- a/libs/gtkutil/paned.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_PANED_H ) -#define INCLUDED_GTKUTIL_PANED_H - -ui::HPaned create_split_views(ui::Widget topleft, ui::Widget topright, ui::Widget botleft, ui::Widget botright); - -#endif diff --git a/libs/gtkutil/pointer.h b/libs/gtkutil/pointer.h deleted file mode 100644 index bfb996c..0000000 --- a/libs/gtkutil/pointer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_POINTER_H ) -#define INCLUDED_GTKUTIL_POINTER_H - -typedef int gint; -typedef void *gpointer; - -#include - -inline gint gpointer_to_int(gpointer p) -{ - return gint(std::size_t(p)); -} - -inline gpointer gint_to_pointer(gint i) -{ - return gpointer(std::size_t(i)); -} - -#endif diff --git a/libs/gtkutil/toolbar.cpp b/libs/gtkutil/toolbar.cpp deleted file mode 100644 index bf60733..0000000 --- a/libs/gtkutil/toolbar.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "toolbar.h" - -#include -#include - -#include "generic/callback.h" - -#include "accelerator.h" -#include "button.h" -#include "image.h" - - -void toolbar_append(ui::Toolbar toolbar, ui::ToolItem button, const char *description) -{ - gtk_widget_show_all(button); - gtk_widget_set_tooltip_text(button, description); - toolbar.add(button); -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Callback &callback) -{ - auto button = ui::ToolButton::from(gtk_tool_button_new(new_local_image(icon), nullptr)); - button_connect_callback(button, callback); - gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), description); - toolbar_append(toolbar, button, description); - return button; -} - -ui::ToggleToolButton toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, - const Callback &callback) -{ - auto button = ui::ToggleToolButton::from(gtk_toggle_tool_button_new()); - toggle_button_connect_callback(button, callback); - gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), new_local_image(icon)); - gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), description); - toolbar_append(toolbar, button, description); - return button; -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Command &command) -{ - return toolbar_append_button(toolbar, description, icon, command.m_callback); -} - -void toggle_button_set_active_callback(void *it, bool active) -{ - auto button = ui::ToggleToolButton::from(it); - toggle_button_set_active_no_signal(button, active); -} - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const Toggle &toggle) -{ - auto button = toolbar_append_toggle_button(toolbar, description, icon, toggle.m_command.m_callback); - toggle.m_exportCallback(PointerCaller(button._handle)); - return button; -} diff --git a/libs/gtkutil/toolbar.h b/libs/gtkutil/toolbar.h deleted file mode 100644 index b016ab2..0000000 --- a/libs/gtkutil/toolbar.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_TOOLBAR_H ) -#define INCLUDED_GTKUTIL_TOOLBAR_H - -#include -#include "generic/callback.h" - -class Command; - -class Toggle; - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Callback &callback); - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Command &command); - -ui::ToggleToolButton toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, - const Callback &callback); - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const Toggle &toggle); - -#endif diff --git a/libs/gtkutil/widget.cpp b/libs/gtkutil/widget.cpp deleted file mode 100644 index 805a8c5..0000000 --- a/libs/gtkutil/widget.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "widget.h" -#include - -void widget_queue_draw(ui::Widget &widget) -{ - gtk_widget_queue_draw(widget); -} - -void widget_make_default(ui::Widget widget) -{ - gtk_widget_set_can_default(widget, true); - gtk_widget_grab_default(widget); -} - -gboolean ToggleShown::notify_visible(ui::Widget widget, gpointer dummy, ToggleShown *self) -{ - self->update(); - return FALSE; -} - -gboolean ToggleShown::destroy(ui::Widget widget, ToggleShown *self) -{ - self->m_shownDeferred = gtk_widget_get_visible(self->m_widget) != FALSE; - self->m_widget = ui::Widget(ui::null); - return FALSE; -} - -void ToggleShown::update() -{ - m_item.update(); -} - -bool ToggleShown::active() const -{ - if (!m_widget) { - return m_shownDeferred; - } else { - return gtk_widget_get_visible(m_widget) != FALSE; - } -} - -void ToggleShown::exportActive(const Callback &importCallback) -{ - importCallback(active()); -} - -void ToggleShown::set(bool shown) -{ - if (!m_widget) { - m_shownDeferred = shown; - } else { - m_widget.visible(shown); - } -} - -void ToggleShown::toggle() -{ - m_widget.visible(!m_widget.visible()); -} - -void ToggleShown::connect(ui::Widget widget) -{ - m_widget = widget; - m_widget.visible(m_shownDeferred); - m_widget.connect("notify::visible", G_CALLBACK(notify_visible), this); - m_widget.connect("destroy", G_CALLBACK(destroy), this); - update(); -} - -gboolean WidgetFocusPrinter::focus_in(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self) -{ - globalOutputStream() << self->m_name << " takes focus\n"; - return FALSE; -} - -gboolean WidgetFocusPrinter::focus_out(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self) -{ - globalOutputStream() << self->m_name << " loses focus\n"; - return FALSE; -} - -void WidgetFocusPrinter::connect(ui::Widget widget) -{ - widget.connect("focus_in_event", G_CALLBACK(focus_in), this); - widget.connect("focus_out_event", G_CALLBACK(focus_out), this); -} diff --git a/libs/gtkutil/widget.h b/libs/gtkutil/widget.h deleted file mode 100644 index f693bc5..0000000 --- a/libs/gtkutil/widget.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_WIDGET_H ) -#define INCLUDED_GTKUTIL_WIDGET_H - -#include -#include -#include -#include "generic/callback.h" -#include "warnings.h" -#include "debugging/debugging.h" -#include "property.h" - -class ToggleItem { -Callback &)> m_exportCallback; -typedef std::list > ImportCallbacks; -ImportCallbacks m_importCallbacks; -public: -ToggleItem(const Callback &)> &exportCallback) : m_exportCallback(exportCallback) -{ -} - -void update() -{ - for (ImportCallbacks::iterator i = m_importCallbacks.begin(); i != m_importCallbacks.end(); ++i) { - m_exportCallback(*i); - } -} - -void addCallback(const Callback &callback) -{ - m_importCallbacks.push_back(callback); - m_exportCallback(callback); -} - -typedef MemberCaller &), &ToggleItem::addCallback> AddCallbackCaller; -}; - -class ToggleShown { -bool m_shownDeferred; - -ToggleShown(const ToggleShown &other); // NOT COPYABLE -ToggleShown &operator=(const ToggleShown &other); // NOT ASSIGNABLE - -static gboolean notify_visible(ui::Widget widget, gpointer dummy, ToggleShown *self); - -static gboolean destroy(ui::Widget widget, ToggleShown *self); - -public: -ui::Widget m_widget; -ToggleItem m_item; - -ToggleShown(bool shown) - : m_shownDeferred(shown), m_widget(ui::null), m_item(ActiveCaller(*this)) -{ -} - -void update(); - -bool active() const; - -void exportActive(const Callback &importCallback); - -typedef MemberCaller &), &ToggleShown::exportActive> ActiveCaller; - -void set(bool shown); - -void toggle(); - -typedef MemberCaller ToggleCaller; - -void connect(ui::Widget widget); -}; - - -void widget_queue_draw(ui::Widget &widget); - -typedef ReferenceCaller WidgetQueueDrawCaller; - - -void widget_make_default(ui::Widget widget); - -class WidgetFocusPrinter { -const char *m_name; - -static gboolean focus_in(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self); - -static gboolean focus_out(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self); - -public: -WidgetFocusPrinter(const char *name) : m_name(name) -{ -} - -void connect(ui::Widget widget); -}; - -#endif diff --git a/libs/gtkutil/window.cpp b/libs/gtkutil/window.cpp deleted file mode 100644 index 7084771..0000000 --- a/libs/gtkutil/window.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "window.h" - -#include - -#include "pointer.h" -#include "accelerator.h" - -inline void CHECK_RESTORE(ui::Widget w) -{ - if (gpointer_to_int(g_object_get_data(G_OBJECT(w), "was_mapped")) != 0) { - w.show(); - } -} - -inline void CHECK_MINIMIZE(ui::Widget w) -{ - g_object_set_data(G_OBJECT(w), "was_mapped", gint_to_pointer(gtk_widget_get_visible(w))); - w.hide(); -} - -static gboolean main_window_iconified(ui::Widget widget, GdkEventWindowState *event, gpointer data) -{ - if ((event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN)) != 0) { - if ((event->new_window_state & (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN)) != 0) { - CHECK_MINIMIZE(ui::Widget::from(data)); - } else { - CHECK_RESTORE(ui::Widget::from(data)); - } - } - return FALSE; -} - -unsigned int connect_floating(ui::Window main_window, ui::Window floating) -{ - return main_window.connect("window_state_event", G_CALLBACK(main_window_iconified), floating); -} - -gboolean destroy_disconnect_floating(ui::Window widget, gpointer data) -{ - g_signal_handler_disconnect(G_OBJECT(data), - gpointer_to_int(g_object_get_data(G_OBJECT(widget), "floating_handler"))); - return FALSE; -} - -gboolean floating_window_delete_present(ui::Window floating, GdkEventFocus *event, ui::Window main_window) -{ - if (gtk_window_is_active(floating) || gtk_window_is_active(main_window)) { - gtk_window_present(main_window); - } - return FALSE; -} - -guint connect_floating_window_delete_present(ui::Window floating, ui::Window main_window) -{ - return floating.connect("delete_event", G_CALLBACK(floating_window_delete_present), main_window); -} - -gboolean floating_window_destroy_present(ui::Window floating, ui::Window main_window) -{ - if (gtk_window_is_active(floating) || gtk_window_is_active(main_window)) { - gtk_window_present(main_window); - } - return FALSE; -} - -guint connect_floating_window_destroy_present(ui::Window floating, ui::Window main_window) -{ - return floating.connect("destroy", G_CALLBACK(floating_window_destroy_present), main_window); -} - -ui::Window create_floating_window(const char *title, ui::Window parent) -{ - ui::Window window = ui::Window(ui::window_type::TOP); - gtk_window_set_title(window, title); - - if (parent) { - gtk_window_set_transient_for(window, parent); - connect_floating_window_destroy_present(window, parent); - g_object_set_data(G_OBJECT(window), "floating_handler", gint_to_pointer(connect_floating(parent, window))); - window.connect("destroy", G_CALLBACK(destroy_disconnect_floating), parent); - } - - return window; -} - -void destroy_floating_window(ui::Window window) -{ - window.destroy(); -} - -gint window_realize_remove_sysmenu(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MENU)); - return FALSE; -} - -gboolean persistent_floating_window_delete(ui::Window floating, GdkEvent *event, ui::Window main_window) -{ - floating.hide(); - return TRUE; -} - -ui::Window create_persistent_floating_window(const char *title, ui::Window main_window) -{ - auto window = create_floating_window(title, main_window); - - gtk_widget_set_events(window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); - - connect_floating_window_delete_present(window, main_window); - window.connect("delete_event", G_CALLBACK(persistent_floating_window_delete), 0); - -#if 0 - if ( g_multimon_globals.m_bStartOnPrimMon && g_multimon_globals.m_bNoSysMenuPopups ) { - window.connect( "realize", G_CALLBACK( window_realize_remove_sysmenu ), 0 ); - } -#endif - - return window; -} - -gint window_realize_remove_minmax(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), - (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE)); - return FALSE; -} - -void window_remove_minmax(ui::Window window) -{ - window.connect("realize", G_CALLBACK(window_realize_remove_minmax), 0); -} - - -ui::ScrolledWindow create_scrolled_window(ui::Policy hscrollbar_policy, ui::Policy vscrollbar_policy, int border) -{ - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_scrolled_window_set_policy(scr, (GtkPolicyType) hscrollbar_policy, (GtkPolicyType) vscrollbar_policy); - gtk_scrolled_window_set_shadow_type(scr, GTK_SHADOW_IN); - gtk_container_set_border_width(GTK_CONTAINER(scr), border); - return scr; -} - -gboolean window_focus_in_clear_focus_widget(ui::Window widget, GdkEventKey *event, gpointer data) -{ - gtk_window_set_focus(widget, NULL); - return FALSE; -} - -guint window_connect_focus_in_clear_focus_widget(ui::Window window) -{ - return window.connect("focus_in_event", G_CALLBACK(window_focus_in_clear_focus_widget), NULL); -} - -void window_get_position(ui::Window window, WindowPosition &position) -{ - ASSERT_MESSAGE(window, "error saving window position"); - - gtk_window_get_position(window, &position.x, &position.y); - gtk_window_get_size(window, &position.w, &position.h); -} - -void window_set_position(ui::Window window, const WindowPosition &position) -{ - gtk_window_set_gravity(window, GDK_GRAVITY_STATIC); - - GdkScreen *screen = gdk_screen_get_default(); - if (position.x < 0 - || position.y < 0 - || position.x > gdk_screen_get_width(screen) - || position.y > gdk_screen_get_height(screen)) { - gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); - } else { - gtk_window_move(window, position.x, position.y); - } - - gtk_window_set_default_size(window, 800, 600); -} - -void WindowPosition_String::Import(WindowPosition &position, const char *value) -{ - if (sscanf(value, "%d %d %d %d", &position.x, &position.y, &position.w, &position.h) != 4) { - position = WindowPosition(c_default_window_pos); // ensure sane default value for window position - } -} - -void WindowPosition_String::Export(const WindowPosition &self, const Callback &returnz) -{ - char buffer[64]; - sprintf(buffer, "%d %d %d %d", self.x, self.y, self.w, self.h); - returnz(buffer); -} - -void WindowPositionTracker_String::Import(WindowPositionTracker &self, const char *value) -{ - WindowPosition position; - WindowPosition_String::Import(position, value); - self.setPosition(position); -} - -void -WindowPositionTracker_String::Export(const WindowPositionTracker &self, const Callback &returnz) -{ - WindowPosition_String::Export(self.getPosition(), returnz); -} - -gboolean WindowPositionTracker::configure(ui::Widget widget, GdkEventConfigure *event, WindowPositionTracker *self) -{ - self->m_position = WindowPosition(event->x, event->y, event->width, event->height); - return FALSE; -} - -void WindowPositionTracker::sync(ui::Window window) -{ - window_set_position(window, m_position); -} - -void WindowPositionTracker::connect(ui::Window window) -{ - sync(window); - window.connect("configure_event", G_CALLBACK(configure), this); -} - -const WindowPosition &WindowPositionTracker::getPosition() const -{ - return m_position; -} - -void WindowPositionTracker::setPosition(const WindowPosition &position) -{ - m_position = position; -} diff --git a/libs/gtkutil/window.h b/libs/gtkutil/window.h deleted file mode 100644 index 71efed4..0000000 --- a/libs/gtkutil/window.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_WINDOW_H ) -#define INCLUDED_GTKUTIL_WINDOW_H - -#include - -#include "debugging/debugging.h" -#include "generic/callback.h" -#include "widget.h" - -gboolean window_focus_in_clear_focus_widget(ui::Window widget, GdkEventKey *event, gpointer data); - -guint window_connect_focus_in_clear_focus_widget(ui::Window window); - -unsigned int connect_floating(ui::Window main_window, ui::Window floating); - -ui::Window create_floating_window(const char *title, ui::Window parent); - -void destroy_floating_window(ui::Window window); - -ui::Window create_persistent_floating_window(const char *title, ui::Window main_window); - -gboolean persistent_floating_window_delete(ui::Window floating, GdkEvent *event, ui::Window main_window); - -void window_remove_minmax(ui::Window window); - -ui::ScrolledWindow create_scrolled_window(ui::Policy hscrollbar_policy, ui::Policy vscrollbar_policy, int border = 0); - - -struct WindowPosition { - int x, y, w, h; - - WindowPosition() - { - } - - WindowPosition(int _x, int _y, int _w, int _h) - : x(_x), y(_y), w(_w), h(_h) - { - } -}; - -const WindowPosition c_default_window_pos(50, 25, 400, 300); - -void window_get_position(ui::Window window, WindowPosition &position); - -void window_set_position(ui::Window window, const WindowPosition &position); - -struct WindowPosition_String { - - static void Export(const WindowPosition &self, const Callback &returnz); - - static void Import(WindowPosition &self, const char *value); - -}; - -class WindowPositionTracker { -WindowPosition m_position; - -static gboolean configure(ui::Widget widget, GdkEventConfigure *event, WindowPositionTracker *self); - -public: -WindowPositionTracker() - : m_position(c_default_window_pos) -{ -} - -void sync(ui::Window window); - -void connect(ui::Window window); - -const WindowPosition &getPosition() const; - -//hack -void setPosition(const WindowPosition &position); -}; - - -struct WindowPositionTracker_String { - static void Export(const WindowPositionTracker &self, const Callback &returnz); - - static void Import(WindowPositionTracker &self, const char *value); -}; - -#endif diff --git a/libs/gtkutil/xorrectangle.cpp b/libs/gtkutil/xorrectangle.cpp deleted file mode 100644 index 3bb1510..0000000 --- a/libs/gtkutil/xorrectangle.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "xorrectangle.h" - -#include - -bool XORRectangle::initialised() const -{ - return !!cr; -} - -void XORRectangle::lazy_init() -{ - if (!initialised()) { - cr = gdk_cairo_create(gtk_widget_get_window(m_widget)); - } -} - -void XORRectangle::draw() const -{ - const int x = float_to_integer(m_rectangle.x); - const int y = float_to_integer(m_rectangle.y); - const int w = float_to_integer(m_rectangle.w); - const int h = float_to_integer(m_rectangle.h); - GtkAllocation allocation; - gtk_widget_get_allocation(m_widget, &allocation); - cairo_rectangle(cr, x, -(h) - (y - allocation.height), w, h); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); - cairo_stroke(cr); -} - -XORRectangle::XORRectangle(ui::GLArea widget) : m_widget(widget), cr(0) -{ -} - -XORRectangle::~XORRectangle() -{ - if (initialised()) { - cairo_destroy(cr); - } -} - -void XORRectangle::set(rectangle_t rectangle) -{ - if (gtk_widget_get_realized(m_widget)) { - lazy_init(); - draw(); - m_rectangle = rectangle; - draw(); - } -} diff --git a/libs/gtkutil/xorrectangle.h b/libs/gtkutil/xorrectangle.h deleted file mode 100644 index 8978ee2..0000000 --- a/libs/gtkutil/xorrectangle.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_XORRECTANGLE_H ) -#define INCLUDED_XORRECTANGLE_H - -#include -#include -#include "math/vector.h" - -class rectangle_t { -public: -rectangle_t() - : x(0), y(0), w(0), h(0) -{ -} - -rectangle_t(float _x, float _y, float _w, float _h) - : x(_x), y(_y), w(_w), h(_h) -{ -} - -float x; -float y; -float w; -float h; -}; - -struct Coord2D { - float x, y; - - Coord2D(float _x, float _y) - : x(_x), y(_y) - { - } -}; - -inline Coord2D coord2d_device2screen(const Coord2D &coord, unsigned int width, unsigned int height) -{ - return Coord2D(((coord.x + 1.0f) * 0.5f) * width, ((coord.y + 1.0f) * 0.5f) * height); -} - -inline rectangle_t rectangle_from_area(const float min[2], const float max[2], unsigned int width, unsigned int height) -{ - Coord2D botleft(coord2d_device2screen(Coord2D(min[0], min[1]), width, height)); - Coord2D topright(coord2d_device2screen(Coord2D(max[0], max[1]), width, height)); - return rectangle_t(botleft.x, botleft.y, topright.x - botleft.x, topright.y - botleft.y); -} - -class XORRectangle { - -rectangle_t m_rectangle; - -ui::GLArea m_widget; -cairo_t *cr; - -bool initialised() const; - -void lazy_init(); - -void draw() const; - -public: -XORRectangle(ui::GLArea widget); - -~XORRectangle(); - -void set(rectangle_t rectangle); -}; - - -#endif diff --git a/libs/imagelib.h b/libs/imagelib.h deleted file mode 100644 index c3e9c1c..0000000 --- a/libs/imagelib.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_IMAGELIB_H ) -#define INCLUDED_IMAGELIB_H - -#include "iimage.h" -#include "iarchive.h" -#include "idatastream.h" -#include - -struct RGBAPixel -{ - unsigned char red, green, blue, alpha; -}; - -class RGBAImage : public Image -{ -RGBAImage( const RGBAImage& other ); -RGBAImage& operator=( const RGBAImage& other ); -public: -RGBAPixel* pixels; -unsigned int width, height; - -RGBAImage( unsigned int _width, unsigned int _height ) - : pixels( new RGBAPixel[_width * _height] ), width( _width ), height( _height ){ -} -~RGBAImage(){ - delete[] pixels; -} - -void release(){ - delete this; -} -byte* getRGBAPixels() const { - return reinterpret_cast( pixels ); -} -unsigned int getWidth() const { - return width; -} -unsigned int getHeight() const { - return height; -} -}; - -class RGBAImageFlags : public RGBAImage -{ -public: -int m_surfaceFlags; -int m_contentFlags; -int m_value; -RGBAImageFlags( unsigned short _width, unsigned short _height, int surfaceFlags, int contentFlags, int value ) : - RGBAImage( _width, _height ), m_surfaceFlags( surfaceFlags ), m_contentFlags( contentFlags ), m_value( value ){ -} - -int getSurfaceFlags() const { - return m_surfaceFlags; -} -int getContentFlags() const { - return m_contentFlags; -} -int getValue() const { - return m_value; -} -}; - - -inline InputStream::byte_type* ArchiveFile_loadBuffer( ArchiveFile& file, std::size_t& length ){ - InputStream::byte_type* buffer = (InputStream::byte_type*)malloc( file.size() + 1 ); - length = file.getInputStream().read( buffer, file.size() ); - buffer[file.size()] = 0; - return buffer; -} - -inline void ArchiveFile_freeBuffer( InputStream::byte_type* buffer ){ - free( buffer ); -} - -class ScopedArchiveBuffer -{ -public: -std::size_t length; -InputStream::byte_type* buffer; - -ScopedArchiveBuffer( ArchiveFile& file ){ - buffer = ArchiveFile_loadBuffer( file, length ); -} -~ScopedArchiveBuffer(){ - ArchiveFile_freeBuffer( buffer ); -} -}; - -class PointerInputStream : public InputStream -{ -const byte* m_read; -public: -PointerInputStream( const byte* pointer ) - : m_read( pointer ){ -} -std::size_t read( byte* buffer, std::size_t length ){ - const byte* end = m_read + length; - while ( m_read != end ) - { - *buffer++ = *m_read++; - } - return length; -} -void seek( std::size_t offset ){ - m_read += offset; -} -const byte* get(){ - return m_read; -} -}; - -#endif diff --git a/libs/instancelib.h b/libs/instancelib.h deleted file mode 100644 index d07fc60..0000000 --- a/libs/instancelib.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_INSTANCELIB_H ) -#define INCLUDED_INSTANCELIB_H - -#include "debugging/debugging.h" - -#include "iscenegraph.h" - -#include "scenelib.h" -#include "generic/reference.h" -#include "generic/callback.h" -#include - -class InstanceSubgraphWalker : public scene::Traversable::Walker -{ -scene::Instantiable::Observer* m_observer; -mutable scene::Path m_path; -mutable Stack m_parent; -public: -InstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* parent ) - : m_observer( observer ), m_path( path ), m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - scene::Instance* instance = Node_getInstantiable( node )->create( m_path, m_parent.top() ); - m_observer->insert( instance ); - Node_getInstantiable( node )->insert( m_observer, m_path, instance ); - m_parent.push( instance ); - return true; -} -void post( scene::Node& node ) const { - m_path.pop(); - m_parent.pop(); -} -}; - -class UninstanceSubgraphWalker : public scene::Traversable::Walker -{ -scene::Instantiable::Observer* m_observer; -mutable scene::Path m_path; -public: -UninstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& parent ) - : m_observer( observer ), m_path( parent ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - return true; -} -void post( scene::Node& node ) const { - scene::Instance* instance = Node_getInstantiable( node )->erase( m_observer, m_path ); - m_observer->erase( instance ); - delete instance; - m_path.pop(); -} -}; - -class InstanceSet : public scene::Traversable::Observer -{ -typedef std::pair CachePath; - -typedef CachePath key_type; - -typedef std::map InstanceMap; -InstanceMap m_instances; -public: - -typedef InstanceMap::iterator iterator; - -iterator begin(){ - return m_instances.begin(); -} -iterator end(){ - return m_instances.end(); -} - -// traverse observer -void insert( scene::Node& child ){ - for ( iterator i = begin(); i != end(); ++i ) - { - Node_traverseSubgraph( child, InstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second, ( *i ).second ) ); - ( *i ).second->boundsChanged(); - } -} -void erase( scene::Node& child ){ - for ( iterator i = begin(); i != end(); ++i ) - { - Node_traverseSubgraph( child, UninstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second ) ); - ( *i ).second->boundsChanged(); - } -} - -// instance -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - for ( iterator i = begin(); i != end(); ++i ) - { - visitor.visit( *( *i ).second ); - } -} - -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( instance->path() ) ) ) == m_instances.end(), "InstanceSet::insert - element already exists" ); - m_instances.insert( InstanceMap::value_type( key_type( observer, PathConstReference( instance->path() ) ), instance ) ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( path ) ) ) != m_instances.end(), "InstanceSet::erase - failed to find element" ); - InstanceMap::iterator i = m_instances.find( key_type( observer, PathConstReference( path ) ) ); - scene::Instance* instance = i->second; - m_instances.erase( i ); - return instance; -} - -void transformChanged(){ - for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) - { - ( *i ).second->transformChanged(); - } -} -typedef MemberCaller TransformChangedCaller; -void boundsChanged(){ - for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) - { - ( *i ).second->boundsChanged(); - } -} -typedef MemberCaller BoundsChangedCaller; -}; - -template -inline void InstanceSet_forEach( InstanceSet& instances, const Functor& functor ){ - for ( InstanceSet::iterator i = instances.begin(), end = instances.end(); i != end; ++i ) - { - functor( *( *i ).second ); - } -} - -template -class InstanceSetEvaluateTransform -{ -public: -static void apply( InstanceSet& instances ){ - InstanceSet_forEach(instances, [&](scene::Instance &instance) { - InstanceTypeCast::cast(instance)->evaluateTransform(); - }); -} -typedef ReferenceCaller::apply> Caller; -}; - -#endif diff --git a/libs/maplib.h b/libs/maplib.h deleted file mode 100644 index 474ce4b..0000000 --- a/libs/maplib.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_MAPLIB_H ) -#define INCLUDED_MAPLIB_H - -#include "nameable.h" -#include "mapfile.h" - -#include "traverselib.h" -#include "transformlib.h" -#include "scenelib.h" -#include "string/string.h" -#include "instancelib.h" -#include "selectionlib.h" -#include "generic/callback.h" - - -class NameableString : public Nameable -{ -CopiedString m_name; -public: -NameableString( const char* name ) - : m_name( name ){ -} - -const char* name() const { - return m_name.c_str(); -} -void attach( const NameCallback& callback ){ -} -void detach( const NameCallback& callback ){ -} -}; - - -class UndoFileChangeTracker : public UndoTracker, public MapFile -{ -std::size_t m_size; -std::size_t m_saved; -typedef void ( UndoFileChangeTracker::*Pending )(); -Pending m_pending; -Callback m_changed; - -public: -UndoFileChangeTracker() : m_size( 0 ), m_saved( MAPFILE_MAX_CHANGES ), m_pending( 0 ){ -} -void print(){ - globalOutputStream() << "saved: " << Unsigned( m_saved ) << " size: " << Unsigned( m_size ) << "\n"; -} - -void push(){ - ++m_size; - m_changed(); - //print(); -} -void pop(){ - --m_size; - m_changed(); - //print(); -} -void pushOperation(){ - if ( m_size < m_saved ) { - // redo queue has been flushed.. it is now impossible to get back to the saved state via undo/redo - m_saved = MAPFILE_MAX_CHANGES; - } - push(); -} -void clear(){ - m_size = 0; - m_changed(); - //print(); -} -void begin(){ - m_pending = Pending( &UndoFileChangeTracker::pushOperation ); -} -void undo(){ - m_pending = Pending( &UndoFileChangeTracker::pop ); -} -void redo(){ - m_pending = Pending( &UndoFileChangeTracker::push ); -} - -void changed(){ - if ( m_pending != 0 ) { - ( ( *this ).*m_pending )(); - m_pending = 0; - } -} - -void save(){ - m_saved = m_size; - m_changed(); -} -bool saved() const { - return m_saved == m_size; -} - -void setChangedCallback( const Callback& changed ){ - m_changed = changed; - m_changed(); -} - -std::size_t changes() const { - return m_size; -} -}; - - -class MapRoot : public scene::Node::Symbiot, public scene::Instantiable, public scene::Traversable::Observer -{ -class TypeCasts -{ -NodeTypeCastTable m_casts; -public: -TypeCasts(){ - NodeStaticCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); -} -NodeTypeCastTable& get(){ - return m_casts; -} -}; - -scene::Node m_node; -IdentityTransform m_transform; -TraversableNodeSet m_traverse; -InstanceSet m_instances; -typedef SelectableInstance Instance; -NameableString m_name; -UndoFileChangeTracker m_changeTracker; -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable& get( NullType){ - return m_traverse; -} -TransformNode& get( NullType){ - return m_transform; -} -Nameable& get( NullType){ - return m_name; -} -MapFile& get( NullType){ - return m_changeTracker; -} - -MapRoot( const char* name ) : m_node( this, this, StaticTypeCasts::instance().get() ), m_name( name ){ - m_node.m_isRoot = true; - - m_traverse.attach( this ); - - GlobalUndoSystem().trackerAttach( m_changeTracker ); -} -~MapRoot(){ -} -void release(){ - GlobalUndoSystem().trackerDetach( m_changeTracker ); - - m_traverse.detach( this ); - delete this; -} -scene::Node& node(){ - return m_node; -} - -InstanceCounter m_instanceCounter; -void instanceAttach( const scene::Path& path ){ - if ( ++m_instanceCounter.m_count == 1 ) { - m_traverse.instanceAttach( path_find_mapfile( path.begin(), path.end() ) ); - } -} -void instanceDetach( const scene::Path& path ){ - if ( --m_instanceCounter.m_count == 0 ) { - m_traverse.instanceDetach( path_find_mapfile( path.begin(), path.end() ) ); - } -} - -void insert( scene::Node& child ){ - m_instances.insert( child ); -} -void erase( scene::Node& child ){ - m_instances.erase( child ); -} - -scene::Node& clone() const { - return ( new MapRoot( *this ) )->node(); -} - -scene::Instance* create( const scene::Path& path, scene::Instance* parent ){ - return new Instance( path, parent ); -} -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - m_instances.forEachInstance( visitor ); -} -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - m_instances.insert( observer, path, instance ); - instanceAttach( path ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - instanceDetach( path ); - return m_instances.erase( observer, path ); -} -}; - -inline void MapRoot_construct(){ -} - -inline void MapRoot_destroy(){ -} - -inline NodeSmartReference NewMapRoot( const char* name ){ - return NodeSmartReference( ( new MapRoot( name ) )->node() ); -} - - -#endif diff --git a/libs/math/Makefile b/libs/math/Makefile deleted file mode 100644 index d9c225b..0000000 --- a/libs/math/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libmath.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp aabb.h curve.h frustum.h line.h matrix.h pi.h plane.h quaternion.h vector.h - -clean: - -rm -f *.o ../libmath.a diff --git a/libs/math/_.cpp b/libs/math/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/math/aabb.h b/libs/math/aabb.h deleted file mode 100644 index 3cc174b..0000000 --- a/libs/math/aabb.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_AABB_H ) -#define INCLUDED_MATH_AABB_H - -/// \file -/// \brief Axis-aligned bounding-box data types and related operations. - -#include "math/matrix.h" -#include "math/plane.h" - -class AABB -{ -public: -Vector3 origin, extents; - -AABB() : origin( 0, 0, 0 ), extents( -1,-1,-1 ){ -} -AABB( const Vector3& origin_, const Vector3& extents_ ) : - origin( origin_ ), extents( extents_ ){ -} -}; - -const float c_aabb_max = FLT_MAX; - -inline bool extents_valid( float f ){ - return f >= 0.0f && f <= c_aabb_max; -} - -inline bool origin_valid( float f ){ - return f >= -c_aabb_max && f <= c_aabb_max; -} - -inline bool aabb_valid( const AABB& aabb ){ - return origin_valid( aabb.origin[0] ) - && origin_valid( aabb.origin[1] ) - && origin_valid( aabb.origin[2] ) - && extents_valid( aabb.extents[0] ) - && extents_valid( aabb.extents[1] ) - && extents_valid( aabb.extents[2] ); -} - -inline AABB aabb_for_minmax( const Vector3& min, const Vector3& max ){ - AABB aabb; - aabb.origin = vector3_mid( min, max ); - aabb.extents = vector3_subtracted( max, aabb.origin ); - return aabb; -} - -template -class AABBExtend -{ -public: -static void apply( AABB& aabb, const Vector3& point ){ - float displacement = point[Index::VALUE] - aabb.origin[Index::VALUE]; - float half_difference = static_cast( 0.5 * ( fabs( displacement ) - aabb.extents[Index::VALUE] ) ); - if ( half_difference > 0.0f ) { - aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference; - aabb.extents[Index::VALUE] += half_difference; - } -} -static void apply( AABB& aabb, const AABB& other ){ - float displacement = other.origin[Index::VALUE] - aabb.origin[Index::VALUE]; - float difference = other.extents[Index::VALUE] - aabb.extents[Index::VALUE]; - if ( fabs( displacement ) > fabs( difference ) ) { - float half_difference = static_cast( 0.5 * ( fabs( displacement ) + difference ) ); - if ( half_difference > 0.0f ) { - aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference; - aabb.extents[Index::VALUE] += half_difference; - } - } - else if ( difference > 0.0f ) { - aabb.origin[Index::VALUE] = other.origin[Index::VALUE]; - aabb.extents[Index::VALUE] = other.extents[Index::VALUE]; - } -} -}; - -inline void aabb_extend_by_point( AABB& aabb, const Vector3& point ){ - AABBExtend< IntegralConstant<0> >::apply( aabb, point ); - AABBExtend< IntegralConstant<1> >::apply( aabb, point ); - AABBExtend< IntegralConstant<2> >::apply( aabb, point ); -} - -inline void aabb_extend_by_point_safe( AABB& aabb, const Vector3& point ){ - if ( aabb_valid( aabb ) ) { - aabb_extend_by_point( aabb, point ); - } - else - { - aabb.origin = point; - aabb.extents = Vector3( 0, 0, 0 ); - } -} - -inline void aabb_extend_by_aabb( AABB& aabb, const AABB& other ){ - AABBExtend< IntegralConstant<0> >::apply( aabb, other ); - AABBExtend< IntegralConstant<1> >::apply( aabb, other ); - AABBExtend< IntegralConstant<2> >::apply( aabb, other ); -} - -inline void aabb_extend_by_aabb_safe( AABB& aabb, const AABB& other ){ - if ( aabb_valid( aabb ) && aabb_valid( other ) ) { - aabb_extend_by_aabb( aabb, other ); - } - else if ( aabb_valid( other ) ) { - aabb = other; - } -} - -inline void aabb_extend_by_vec3( AABB& aabb, const Vector3& extension ){ - vector3_add( aabb.extents, extension ); -} - - - - -template -inline bool aabb_intersects_point_dimension( const AABB& aabb, const Vector3& point ){ - return fabs( point[Index::VALUE] - aabb.origin[Index::VALUE] ) < aabb.extents[Index::VALUE]; -} - -inline bool aabb_intersects_point( const AABB& aabb, const Vector3& point ){ - return aabb_intersects_point_dimension< IntegralConstant<0> >( aabb, point ) - && aabb_intersects_point_dimension< IntegralConstant<1> >( aabb, point ) - && aabb_intersects_point_dimension< IntegralConstant<2> >( aabb, point ); -} - -template -inline bool aabb_intersects_aabb_dimension( const AABB& aabb, const AABB& other ){ - return fabs( other.origin[Index::VALUE] - aabb.origin[Index::VALUE] ) < ( aabb.extents[Index::VALUE] + other.extents[Index::VALUE] ); -} - -inline bool aabb_intersects_aabb( const AABB& aabb, const AABB& other ){ - return aabb_intersects_aabb_dimension< IntegralConstant<0> >( aabb, other ) - && aabb_intersects_aabb_dimension< IntegralConstant<1> >( aabb, other ) - && aabb_intersects_aabb_dimension< IntegralConstant<2> >( aabb, other ); -} - -inline unsigned int aabb_classify_plane( const AABB& aabb, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), aabb.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < ( fabs( plane.a * aabb.extents[0] ) - + fabs( plane.b * aabb.extents[1] ) - + fabs( plane.c * aabb.extents[2] ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - -inline unsigned int aabb_oriented_classify_plane( const AABB& aabb, const Matrix4& transform, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), aabb.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < ( fabs( aabb.extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( transform.x() ) ) ) - + fabs( aabb.extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( transform.y() ) ) ) - + fabs( aabb.extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( transform.z() ) ) ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - -inline void aabb_corners( const AABB& aabb, Vector3 corners[8] ){ - Vector3 min( vector3_subtracted( aabb.origin, aabb.extents ) ); - Vector3 max( vector3_added( aabb.origin, aabb.extents ) ); - corners[0] = Vector3( min[0], max[1], max[2] ); - corners[1] = Vector3( max[0], max[1], max[2] ); - corners[2] = Vector3( max[0], min[1], max[2] ); - corners[3] = Vector3( min[0], min[1], max[2] ); - corners[4] = Vector3( min[0], max[1], min[2] ); - corners[5] = Vector3( max[0], max[1], min[2] ); - corners[6] = Vector3( max[0], min[1], min[2] ); - corners[7] = Vector3( min[0], min[1], min[2] ); -} - -inline void aabb_corners_oriented( const AABB& aabb, const Matrix4& rotation, Vector3 corners[8] ){ - Vector3 x = vector4_to_vector3( rotation.x() ) * aabb.extents.x(); - Vector3 y = vector4_to_vector3( rotation.y() ) * aabb.extents.y(); - Vector3 z = vector4_to_vector3( rotation.z() ) * aabb.extents.z(); - - corners[0] = aabb.origin + -x + y + z; - corners[1] = aabb.origin + x + y + z; - corners[2] = aabb.origin + x + -y + z; - corners[3] = aabb.origin + -x + -y + z; - corners[4] = aabb.origin + -x + y + -z; - corners[5] = aabb.origin + x + y + -z; - corners[6] = aabb.origin + x + -y + -z; - corners[7] = aabb.origin + -x + -y + -z; -} - -inline void aabb_planes( const AABB& aabb, Plane3 planes[6] ){ - planes[0] = Plane3( g_vector3_axes[0], aabb.origin[0] + aabb.extents[0] ); - planes[1] = Plane3( vector3_negated( g_vector3_axes[0] ), -( aabb.origin[0] - aabb.extents[0] ) ); - planes[2] = Plane3( g_vector3_axes[1], aabb.origin[1] + aabb.extents[1] ); - planes[3] = Plane3( vector3_negated( g_vector3_axes[1] ), -( aabb.origin[1] - aabb.extents[1] ) ); - planes[4] = Plane3( g_vector3_axes[2], aabb.origin[2] + aabb.extents[2] ); - planes[5] = Plane3( vector3_negated( g_vector3_axes[2] ), -( aabb.origin[2] - aabb.extents[2] ) ); -} - -inline void aabb_planes_oriented( const AABB& aabb, const Matrix4& rotation, Plane3 planes[6] ){ - double x = vector3_dot( vector4_to_vector3( rotation.x() ), aabb.origin ); - double y = vector3_dot( vector4_to_vector3( rotation.y() ), aabb.origin ); - double z = vector3_dot( vector4_to_vector3( rotation.z() ), aabb.origin ); - - planes[0] = Plane3( vector4_to_vector3( rotation.x() ), x + aabb.extents[0] ); - planes[1] = Plane3( -vector4_to_vector3( rotation.x() ), -( x - aabb.extents[0] ) ); - planes[2] = Plane3( vector4_to_vector3( rotation.y() ), y + aabb.extents[1] ); - planes[3] = Plane3( -vector4_to_vector3( rotation.y() ), -( y - aabb.extents[1] ) ); - planes[4] = Plane3( vector4_to_vector3( rotation.z() ), z + aabb.extents[2] ); - planes[5] = Plane3( -vector4_to_vector3( rotation.z() ), -( z - aabb.extents[2] ) ); -} - -const Vector3 aabb_normals[6] = { - Vector3( 1, 0, 0 ), - Vector3( 0, 1, 0 ), - Vector3( 0, 0, 1 ), - Vector3( -1, 0, 0 ), - Vector3( 0,-1, 0 ), - Vector3( 0, 0,-1 ), -}; - -const float aabb_texcoord_topleft[2] = { 0, 0 }; -const float aabb_texcoord_topright[2] = { 1, 0 }; -const float aabb_texcoord_botleft[2] = { 0, 1 }; -const float aabb_texcoord_botright[2] = { 1, 1 }; - - -inline AABB aabb_for_oriented_aabb( const AABB& aabb, const Matrix4& transform ){ - return AABB( - matrix4_transformed_point( transform, aabb.origin ), - Vector3( - static_cast( fabs( transform[0] * aabb.extents[0] ) - + fabs( transform[4] * aabb.extents[1] ) - + fabs( transform[8] * aabb.extents[2] ) ), - static_cast( fabs( transform[1] * aabb.extents[0] ) - + fabs( transform[5] * aabb.extents[1] ) - + fabs( transform[9] * aabb.extents[2] ) ), - static_cast( fabs( transform[2] * aabb.extents[0] ) - + fabs( transform[6] * aabb.extents[1] ) - + fabs( transform[10] * aabb.extents[2] ) ) - ) - ); -} - -inline AABB aabb_for_oriented_aabb_safe( const AABB& aabb, const Matrix4& transform ){ - if ( aabb_valid( aabb ) ) { - return aabb_for_oriented_aabb( aabb, transform ); - } - return aabb; -} - -inline AABB aabb_infinite(){ - return AABB( Vector3( 0, 0, 0 ), Vector3( c_aabb_max, c_aabb_max, c_aabb_max ) ); -} - -#endif diff --git a/libs/math/curve.h b/libs/math/curve.h deleted file mode 100644 index b430bf0..0000000 --- a/libs/math/curve.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_CURVE_H ) -#define INCLUDED_MATH_CURVE_H - -/// \file -/// \brief Curve data types and related operations. - -#include "debugging/debugging.h" -#include "container/array.h" -#include - - -template -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1; // general case not implemented - } -}; - -typedef IntegralConstant<0> Zero; -typedef IntegralConstant<1> One; -typedef IntegralConstant<2> Two; -typedef IntegralConstant<3> Three; -typedef IntegralConstant<4> Four; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1 - t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return ( 1 - t ) * ( 1 - t ); - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 2 * ( 1 - t ) * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return ( 1 - t ) * ( 1 - t ) * ( 1 - t ); - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 3 * ( 1 - t ) * ( 1 - t ) * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 3 * ( 1 - t ) * t * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t * t * t; - } -}; - -typedef Array ControlPoints; - -inline Vector3 CubicBezier_evaluate( const Vector3* firstPoint, double t ){ - Vector3 result( 0, 0, 0 ); - double denominator = 0; - - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - - return result / denominator; -} - -inline Vector3 CubicBezier_evaluateMid( const Vector3* firstPoint ){ - return vector3_scaled( firstPoint[0], 0.125 ) - + vector3_scaled( firstPoint[1], 0.375 ) - + vector3_scaled( firstPoint[2], 0.375 ) - + vector3_scaled( firstPoint[3], 0.125 ); -} - -inline Vector3 CatmullRom_evaluate( const ControlPoints& controlPoints, double t ){ - // scale t to be segment-relative - t *= double(controlPoints.size() - 1); - - // subtract segment index; - std::size_t segment = 0; - for ( std::size_t i = 0; i < controlPoints.size() - 1; ++i ) - { - if ( t <= double(i + 1) ) { - segment = i; - break; - } - } - t -= segment; - - const double reciprocal_alpha = 1.0 / 3.0; - - Vector3 bezierPoints[4]; - bezierPoints[0] = controlPoints[segment]; - bezierPoints[1] = ( segment > 0 ) - ? controlPoints[segment] + vector3_scaled( controlPoints[segment + 1] - controlPoints[segment - 1], reciprocal_alpha * 0.5 ) - : controlPoints[segment] + vector3_scaled( controlPoints[segment + 1] - controlPoints[segment], reciprocal_alpha ); - bezierPoints[2] = ( segment < controlPoints.size() - 2 ) - ? controlPoints[segment + 1] + vector3_scaled( controlPoints[segment] - controlPoints[segment + 2], reciprocal_alpha * 0.5 ) - : controlPoints[segment + 1] + vector3_scaled( controlPoints[segment] - controlPoints[segment + 1], reciprocal_alpha ); - bezierPoints[3] = controlPoints[segment + 1]; - return CubicBezier_evaluate( bezierPoints, t ); -} - -typedef Array Knots; - -inline double BSpline_basis( const Knots& knots, std::size_t i, std::size_t degree, double t ){ - if ( degree == 0 ) { - if ( knots[i] <= t - && t < knots[i + 1] - && knots[i] < knots[i + 1] ) { - return 1; - } - return 0; - } - double leftDenom = knots[i + degree] - knots[i]; - double left = ( leftDenom == 0 ) ? 0 : ( ( t - knots[i] ) / leftDenom ) * BSpline_basis( knots, i, degree - 1, t ); - double rightDenom = knots[i + degree + 1] - knots[i + 1]; - double right = ( rightDenom == 0 ) ? 0 : ( ( knots[i + degree + 1] - t ) / rightDenom ) * BSpline_basis( knots, i + 1, degree - 1, t ); - return left + right; -} - -inline Vector3 BSpline_evaluate( const ControlPoints& controlPoints, const Knots& knots, std::size_t degree, double t ){ - Vector3 result( 0, 0, 0 ); - for ( std::size_t i = 0; i < controlPoints.size(); ++i ) - { - result += vector3_scaled( controlPoints[i], BSpline_basis( knots, i, degree, t ) ); - } - return result; -} - -typedef Array NURBSWeights; - -inline Vector3 NURBS_evaluate( const ControlPoints& controlPoints, const NURBSWeights& weights, const Knots& knots, std::size_t degree, double t ){ - Vector3 result( 0, 0, 0 ); - double denominator = 0; - for ( std::size_t i = 0; i < controlPoints.size(); ++i ) - { - double weight = weights[i] * BSpline_basis( knots, i, degree, t ); - result += vector3_scaled( controlPoints[i], weight ); - denominator += weight; - } - return result / denominator; -} - -inline void KnotVector_openUniform( Knots& knots, std::size_t count, std::size_t degree ){ - knots.resize( count + degree + 1 ); - - std::size_t equalKnots = 1; - - for ( std::size_t i = 0; i < equalKnots; ++i ) - { - knots[i] = 0; - knots[knots.size() - ( i + 1 )] = 1; - } - - std::size_t difference = knots.size() - 2 * ( equalKnots ); - for ( std::size_t i = 0; i < difference; ++i ) - { - knots[i + equalKnots] = Knots::value_type( double(i + 1) * 1.0 / double(difference + 1) ); - } -} - -#endif diff --git a/libs/math/expression.cpp b/libs/math/expression.cpp deleted file mode 100644 index 13f6bfe..0000000 --- a/libs/math/expression.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "expression.h" - -Vector3 testAdded1( const Vector3& a, const Vector3& b ){ - return vector3_added( a, vector3_added( a, b ) ); -} - -Vector3 testAdded2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_added( vector3_identity( a ), vector_added( vector3_identity( a ), vector3_identity( b ) ) ) ); -} - -Vector3 testMultiplied1( const Vector3& a, const Vector3& b ){ - return vector3_scaled( a, b ); -} - -Vector3 testMultiplied2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_multiplied( vector3_identity( a ), vector3_identity( b ) ) ); -} - -Vector3 testCross1( const Vector3& a, const Vector3& b ){ - return vector3_cross( a, b ); -} - -Vector3 testCross2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_cross( vector3_identity( a ), vector3_identity( b ) ) ); -} - -double testDot1( const Vector3& a, const Vector3& b ){ - return vector3_dot( a, b ); -} - -double testDot2( const Vector3& a, const Vector3& b ){ - return float_for_expression( vector_dot( vector3_identity( a ), vector3_identity( b ) ) ); -} - -double testLength1( const Vector3& a ){ - return vector3_length( a ); -} - -double testLength2( const Vector3& a ){ - return float_for_expression( vector_length( vector3_identity( a ) ) ); -} - -Vector3 testNormalised1( const Vector3& a ){ - return vector3_normalised( a ); -} - -Vector3 testNormalised2( const Vector3& a ){ - return vector3_for_expression( vector_normalised( vector3_identity( a ) ) ); -} - -Vector3 testNegated1( const Vector3& a ){ - return vector3_negated( a ); -} - -Vector3 testNegated2( const Vector3& a ){ - return vector3_for_expression( vector_negated( vector3_identity( a ) ) ); -} - -Vector3 testScaled1( const Vector3& a, const double& b ){ - return vector3_scaled( a, b ); -} - -Vector3 testScaled2( const Vector3& a, const double& b ){ - return vector3_for_expression( vector_scaled( vector3_identity( a ), float_literal( b ) ) ); -} - -Vector3 testMatrixMultiplied1( const Vector3& a, const Matrix4& b ){ - return matrix4_transformed_point( b, vector3_added( a, Vector3( 1, 0, 0 ) ) ); -} - -Vector3 testMatrixMultiplied2( const Vector3& a, const Matrix4& b ){ - return vector3_for_expression( - point_multiplied( - vector_added( - vector3_identity( a ), - vector3_literal( Vector3( 1, 0, 0 ) ) - ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4Multiplied1( const Matrix4& a, const Matrix4& b ){ - return matrix4_multiplied_by_matrix4( a, matrix4_multiplied_by_matrix4( a, b ) ); -} - -Matrix4 testMatrix4Multiplied2( const Matrix4& a, const Matrix4& b ){ - return matrix4_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4AffineMultiplied1( const Matrix4& a, const Matrix4& b ){ - return matrix4_affine_multiplied_by_matrix4( a, b ); -} - -Matrix4 testMatrix4AffineMultiplied2( const Matrix4& a, const Matrix4& b ){ - return matrix4_affine_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4MultipliedConstant1( const Matrix4& a ){ - return matrix4_multiplied_by_matrix4( a, g_matrix4_identity ); -} - -Matrix4 testMatrix4MultipliedConstant2( const Matrix4& a ){ - return matrix4_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( g_matrix4_identity ) - ) - ); -} -Matrix4 testMatrix4Transposed1( const Matrix4& a ){ - return matrix4_transposed( a ); -} - -Matrix4 testMatrix4Transposed2( const Matrix4& a ){ - return matrix4_for_expression( matrix_transposed( matrix4_identity( a ) ) ); -} - -Vector3 testMulti1( const Matrix4& a, const Vector3& b, const Vector3& c ){ - return vector3_added( matrix4_transformed_point( matrix4_transposed( a ), b ), c ); -} - -Vector3 testMulti2( const Matrix4& a, const Vector3& b, const Vector3& c ){ - return vector3_for_expression( - vector_added( - point_multiplied( - vector3_identity( b ), - matrix_transposed( matrix4_identity( a ) ) - ), - vector3_identity( c ) - ) - ); -} - -template -class TestBinaryFunction -{ -typedef Value ( *Function )( const First&, const Second& ); -Function m_function; -public: - -TestBinaryFunction( Function function ) : m_function( function ){ -} -Value run( const First& first, const Second& second ) const { - return m_function( first, second ); -} -}; - -template -class TestUnaryFunction -{ -typedef Value ( *Function )( const First& ); -Function m_function; -public: - -TestUnaryFunction( Function function ) : m_function( function ){ -} -Value run( const First& first ) const { - return m_function( first ); -} -}; - -class TestAll -{ -public: -TestAll(){ - Vector3 result1 = TestBinaryFunction( testAdded1 ).run( Vector3( 0, 0, 0 ), Vector3( 1, 1, 1 ) ); - Vector3 result2 = TestBinaryFunction( testAdded2 ).run( Vector3( 0, 0, 0 ), Vector3( 1, 1, 1 ) ); - Vector3 result3 = TestBinaryFunction( testMultiplied1 ).run( Vector3( 1, 2, 3 ), Vector3( 2, 1, 0.5f ) ); - Vector3 result4 = TestBinaryFunction( testMultiplied2 ).run( Vector3( 1, 2, 3 ), Vector3( 2, 1, 0.5f ) ); - Vector3 result5 = TestBinaryFunction( testScaled1 ).run( Vector3( 1, 2, 3 ), 2.0 ); - Vector3 result6 = TestBinaryFunction( testScaled2 ).run( Vector3( 1, 2, 3 ), 2.0 ); - Vector3 result7 = TestBinaryFunction( testMatrixMultiplied1 ).run( Vector3( 1, 2, 3 ), matrix4_rotation_for_x_degrees( 90 ) ); - Vector3 result8 = TestBinaryFunction( testMatrixMultiplied2 ).run( Vector3( 1, 2, 3 ), matrix4_rotation_for_x_degrees( 90 ) ); - Vector3 result9 = TestUnaryFunction( testNormalised1 ).run( Vector3( 1, 2, 3 ) ); - Vector3 result10 = TestUnaryFunction( testNormalised2 ).run( Vector3( 1, 2, 3 ) ); -} -} g_testAll; diff --git a/libs/math/expression.h b/libs/math/expression.h deleted file mode 100644 index 17eeace..0000000 --- a/libs/math/expression.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_EXPRESSION_H ) -#define INCLUDED_EXPRESSION_H - -#include - -template -class Literal -{ -Value m_value; -public: -typedef Value value_type; - -Literal( const Value& value ) - : m_value( value ){ -} -const value_type& eval() const { - return m_value; -} -}; - -template -inline Literal float_literal( const Value& value ){ - return Literal( value ); -} - -template -inline float float_for_expression( const Expression& expression ){ - return expression.eval(); -} - - -template -class ScalarDivided -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; - -ScalarDivided( const First& first_, const Second& second_ ) : first( first_ ), second( second_ ){ -} -value_type eval() const { - return static_cast( first.eval() / second.eval() ); -} -}; - -template -inline ScalarDivided float_divided( const First& first, const Second& second ){ - return ScalarDivided( first, second ); -} - -template -inline ScalarDivided, First> float_reciprocal( const First& first ){ - typedef typename First::value_type first_value_type; - return ScalarDivided, First>( float_literal( first_value_type( 1.0 ) ), first ); -} - -template -class SquareRoot -{ -First first; -public: -typedef typename First::value_type value_type; - -SquareRoot( const First& first_ ) : first( first_ ){ -} -value_type eval() const { - return static_cast( sqrt( first.eval() ) ); -} -}; - -template -inline SquareRoot float_square_root( const First& first ){ - return SquareRoot( first ); -} - - -template -class BasicVector3Literal -{ -const BasicVector3 m_value; -public: -typedef Element value_type; -typedef IntegralConstant<3> dimension; - -BasicVector3Literal( const BasicVector3& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int i ) const { - return m_value[i]; -} -}; - -template -inline BasicVector3Literal vector3_literal( const BasicVector3& value ){ - return BasicVector3Literal( value ); -} - -typedef BasicVector3Literal Vector3Literal; - -template -class BasicVector3Identity -{ -const BasicVector3& m_value; -public: -typedef Element value_type; -typedef IntegralConstant<3> dimension; - -BasicVector3Identity( const BasicVector3& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int i ) const { - return m_value[i]; -} -}; - -template -inline BasicVector3Identity vector3_identity( const BasicVector3& value ){ - return BasicVector3Identity( value ); -} - -typedef BasicVector3Identity Vector3Identity; - -template -inline BasicVector3 vector3_for_expression( const Expression& expression ){ - return Vector3( expression.eval( 0 ), expression.eval( 1 ), expression.eval( 2 ) ); -} - - -template -class VectorScalar -{ -First first; -Literal second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorScalar( const First& first_, const Second& second_ ) - : first( first_ ), second( second_.eval() ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ), second.eval() ); -} -}; - - - -template -class VectorVector -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorVector( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ), second.eval( i ) ); -} -}; - -template -class Added -{ -public: -typedef First value_type; - -static value_type apply( const First& first, const Second& second ){ - return static_cast( first + second ); -} -}; - -template -inline VectorVector, First, Second> -vector_added( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorVector, First, Second>( first, second ); -} - -template -class Multiplied -{ -public: -typedef First value_type; - -static value_type apply( const First& first, const Second& second ){ - return static_cast( first * second ); -} -}; - -template -inline VectorVector, First, Second> -vector_multiplied( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorVector, First, Second>( first, second ); -} - -template -inline VectorScalar, First, Second> -vector_scaled( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorScalar, First, Second>( first, second ); -} - -template -class Negated -{ -public: -typedef First value_type; - -static value_type apply( const First& first ){ - return -first; -} -}; - -template -class VectorUnary -{ -First first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorUnary( const First& first_ ) : first( first_ ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ) ); -} -}; - -template -inline VectorUnary > -vector_negated( const First& first ){ - typedef typename First::value_type first_value_type; - return VectorUnary >( first ); -} - -template -class VectorCross -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorCross( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return first.eval( ( i + 1 ) % 3 ) * second.eval( ( i + 2 ) % 3 ) - first.eval( ( i + 2 ) % 3 ) * second.eval( ( i + 1 ) % 3 ); -} -}; - -template -inline VectorCross -vector_cross( const First& first, const Second& second ){ - return VectorCross( first, second ); -} - - -template -class VectorDot -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorDot( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} - -template -struct eval_dot -{ - static value_type apply( const First& first, const Second& second ){ - return static_cast( - first.eval( Index::VALUE ) * second.eval( Index::VALUE ) - + eval_dot< IntegralConstant >::apply( first, second ) - ); - } -}; - -template<> -struct eval_dot< IntegralConstant<0> > -{ - static value_type apply( const First& first, const Second& second ){ - return first.eval( 0 ) * second.eval( 0 ); - } -}; - -value_type eval() const { - return eval_dot< IntegralConstant >::apply( first, second ); -} -}; - - -template -inline VectorDot vector_dot( const First& first, const Second& second ){ - return VectorDot( first, second ); -} - -template -class VectorLengthSquared -{ -First first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorLengthSquared( const First& first_ ) - : first( first_ ){ -} - -static value_type squared( const value_type& value ){ - return value * value; -} - -template -struct eval_squared -{ - static value_type apply( const First& first ){ - return static_cast( - squared( first.eval( Index::VALUE ) ) - + eval_squared< IntegralConstant >::apply( first ) - ); - } -}; - -template<> -struct eval_squared< IntegralConstant<0> > -{ - static value_type apply( const First& first ){ - return squared( first.eval( 0 ) ); - } -}; - -value_type eval() const { - return eval_squared< IntegralConstant >::apply( first ); -} -}; - -template -inline VectorLengthSquared vector_length_squared( const First& first ){ - return VectorLengthSquared( first ); -} - -template -inline SquareRoot< VectorLengthSquared > vector_length( const First& first ){ - return float_square_root( vector_length_squared( first ) ); -} - -#if 1 -template -inline VectorScalar< - Multiplied, - First, - // multiple evaulations of subexpression - ScalarDivided< - Literal, - SquareRoot< - VectorLengthSquared - > - > - > vector_normalised( const First& first ){ - typedef typename First::value_type first_value_type; - return vector_scaled( first, float_reciprocal( vector_length( first ) ) ); -} -#else -template -inline VectorScalar< - Multiplied, - First, - // single evaluation of subexpression - Literal - > -vector_normalised( const First& first ){ - typedef typename First::value_type first_value_type; - return vector_scaled( first, float_literal( static_cast( first_value_type( 1.0 ) / vector_length( first ).eval() ) ) ); -} -#endif - - -class Matrix4Literal -{ -const Matrix4 m_value; -public: -typedef float value_type; -typedef IntegralConstant<4> dimension0; -typedef IntegralConstant<4> dimension1; - -Matrix4Literal( const Matrix4& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int r, unsigned int c ) const { - return m_value[r * 4 + c]; -} -}; - -inline Matrix4Literal matrix4_literal( const Matrix4& value ){ - return Matrix4Literal( value ); -} - -class Matrix4Identity -{ -const Matrix4& m_value; -public: -typedef float value_type; -typedef IntegralConstant<4> dimension0; -typedef IntegralConstant<4> dimension1; - -Matrix4Identity( const Matrix4& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int r, unsigned int c ) const { - return m_value[r * 4 + c]; -} -}; - -inline Matrix4Identity matrix4_identity( const Matrix4& value ){ - return Matrix4Identity( value ); -} - -template -inline Matrix4 matrix4_for_expression( const Expression& expression ){ - return Matrix4( - expression.eval( 0, 0 ), expression.eval( 0, 1 ), expression.eval( 0, 2 ), expression.eval( 0, 3 ), - expression.eval( 1, 0 ), expression.eval( 1, 1 ), expression.eval( 1, 2 ), expression.eval( 1, 3 ), - expression.eval( 2, 0 ), expression.eval( 2, 1 ), expression.eval( 2, 2 ), expression.eval( 2, 3 ), - expression.eval( 3, 0 ), expression.eval( 3, 1 ), expression.eval( 3, 2 ), expression.eval( 3, 3 ) - ); -} - -template -inline Matrix4 matrix4_affine_for_expression( const Expression& expression ){ - return Matrix4( - expression.eval( 0, 0 ), expression.eval( 0, 1 ), expression.eval( 0, 2 ), 0, - expression.eval( 1, 0 ), expression.eval( 1, 1 ), expression.eval( 1, 2 ), 0, - expression.eval( 2, 0 ), expression.eval( 2, 1 ), expression.eval( 2, 2 ), 0, - expression.eval( 3, 0 ), expression.eval( 3, 1 ), expression.eval( 3, 2 ), 1 - ); -} - - -template -class PointMultiplied -{ -const First& first; -const Second& second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -PointMultiplied( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return static_cast( second.eval( 0, i ) * first.eval( 0 ) - + second.eval( 1, i ) * first.eval( 1 ) - + second.eval( 2, i ) * first.eval( 2 ) - + second.eval( 3, i ) ); -} -}; - -template -inline PointMultiplied point_multiplied( const First& point, const Second& matrix ){ - return PointMultiplied( point, matrix ); -} - -template -class Matrix4Multiplied -{ -const First& first; -const Second& second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension0 dimension0; -typedef typename First::dimension1 dimension1; - -Matrix4Multiplied( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} - -value_type eval( unsigned int r, unsigned int c ) const { - return static_cast( - second.eval( r, 0 ) * first.eval( 0, c ) - + second.eval( r, 1 ) * first.eval( 1, c ) - + second.eval( r, 2 ) * first.eval( 2, c ) - + second.eval( r, 3 ) * first.eval( 3, c ) - ); -} -}; - -template -inline Matrix4Multiplied matrix4_multiplied( const First& first, const Second& second ){ - return Matrix4Multiplied( first, second ); -} - -template -class MatrixTransposed -{ -const First& first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension0 dimension0; -typedef typename First::dimension1 dimension1; - -MatrixTransposed( const First& first_ ) - : first( first_ ){ -} - -value_type eval( unsigned int r, unsigned int c ) const { - return first.eval( c, r ); -} -}; - -template -inline MatrixTransposed matrix_transposed( const First& first ){ - return MatrixTransposed( first ); -} - -#endif diff --git a/libs/math/frustum.h b/libs/math/frustum.h deleted file mode 100644 index 32b0cdc..0000000 --- a/libs/math/frustum.h +++ /dev/null @@ -1,607 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_FRUSTUM_H ) -#define INCLUDED_MATH_FRUSTUM_H - -/// \file -/// \brief View-frustum data types and related operations. - -#include "generic/enumeration.h" -#include "math/matrix.h" -#include "math/plane.h" -#include "math/aabb.h" -#include "math/line.h" - -inline Matrix4 matrix4_frustum( float left, float right, float bottom, float top, float nearval, float farval ){ - return Matrix4( - static_cast( ( 2 * nearval ) / ( right - left ) ), - 0, - 0, - 0, - 0, - static_cast( ( 2 * nearval ) / ( top - bottom ) ), - 0, - 0, - static_cast( ( right + left ) / ( right - left ) ), - static_cast( ( top + bottom ) / ( top - bottom ) ), - static_cast( -( farval + nearval ) / ( farval - nearval ) ), - -1, - 0, - 0, - static_cast( -( 2 * farval * nearval ) / ( farval - nearval ) ), - 0 - ); -} - - - -typedef unsigned char ClipResult; -const ClipResult c_CLIP_PASS = 0x00; // 000000 -const ClipResult c_CLIP_LT_X = 0x01; // 000001 -const ClipResult c_CLIP_GT_X = 0x02; // 000010 -const ClipResult c_CLIP_LT_Y = 0x04; // 000100 -const ClipResult c_CLIP_GT_Y = 0x08; // 001000 -const ClipResult c_CLIP_LT_Z = 0x10; // 010000 -const ClipResult c_CLIP_GT_Z = 0x20; // 100000 -const ClipResult c_CLIP_FAIL = 0x3F; // 111111 - -template -class Vector4ClipLT -{ -public: -static bool compare( const Vector4& self ){ - return self[Index::VALUE] < self[3]; -} -static double scale( const Vector4& self, const Vector4& other ){ - return ( self[Index::VALUE] - self[3] ) / ( other[3] - other[Index::VALUE] ); -} -}; - -template -class Vector4ClipGT -{ -public: -static bool compare( const Vector4& self ){ - return self[Index::VALUE] > -self[3]; -} -static double scale( const Vector4& self, const Vector4& other ){ - return ( self[Index::VALUE] + self[3] ) / ( -other[3] - other[Index::VALUE] ); -} -}; - -template -class Vector4ClipPolygon -{ -public: -typedef Vector4* iterator; -typedef const Vector4* const_iterator; - -static std::size_t apply( const_iterator first, const_iterator last, iterator out ){ - const_iterator next = first, i = last - 1; - iterator tmp( out ); - bool b0 = ClipPlane::compare( *i ); - while ( next != last ) - { - bool b1 = ClipPlane::compare( *next ); - if ( b0 ^ b1 ) { - *out = vector4_subtracted( *next, *i ); - - double scale = ClipPlane::scale( *i, *out ); - - ( *out )[0] = static_cast( ( *i )[0] + scale * ( ( *out )[0] ) ); - ( *out )[1] = static_cast( ( *i )[1] + scale * ( ( *out )[1] ) ); - ( *out )[2] = static_cast( ( *i )[2] + scale * ( ( *out )[2] ) ); - ( *out )[3] = static_cast( ( *i )[3] + scale * ( ( *out )[3] ) ); - - ++out; - } - - if ( b1 ) { - *out = *next; - ++out; - } - - i = next; - ++next; - b0 = b1; - } - - return out - tmp; -} -}; - -#define CLIP_X_LT_W( p ) ( Vector4ClipLT< IntegralConstant<0> >::compare( p ) ) -#define CLIP_X_GT_W( p ) ( Vector4ClipGT< IntegralConstant<0> >::compare( p ) ) -#define CLIP_Y_LT_W( p ) ( Vector4ClipLT< IntegralConstant<1> >::compare( p ) ) -#define CLIP_Y_GT_W( p ) ( Vector4ClipGT< IntegralConstant<1> >::compare( p ) ) -#define CLIP_Z_LT_W( p ) ( Vector4ClipLT< IntegralConstant<2> >::compare( p ) ) -#define CLIP_Z_GT_W( p ) ( Vector4ClipGT< IntegralConstant<2> >::compare( p ) ) - -inline ClipResult homogenous_clip_point( const Vector4& clipped ){ - ClipResult result = c_CLIP_FAIL; - if ( CLIP_X_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_X; // X < W - } - if ( CLIP_X_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_X; // X > -W - } - if ( CLIP_Y_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_Y; // Y < W - } - if ( CLIP_Y_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_Y; // Y > -W - } - if ( CLIP_Z_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_Z; // Z < W - } - if ( CLIP_Z_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_Z; // Z > -W - } - return result; -} - -/// \brief Clips \p point by canonical matrix \p self. -/// Stores the result in \p clipped. -/// Returns a bitmask indicating which clip-planes the point was outside. -inline ClipResult matrix4_clip_point( const Matrix4& self, const Vector3& point, Vector4& clipped ){ - clipped[0] = point[0]; - clipped[1] = point[1]; - clipped[2] = point[2]; - clipped[3] = 1; - matrix4_transform_vector4( self, clipped ); - return homogenous_clip_point( clipped ); -} - - -inline std::size_t homogenous_clip_triangle( Vector4 clipped[9] ){ - Vector4 buffer[9]; - std::size_t count = 3; - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<0> > >::apply( clipped, clipped + count, buffer ); - count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<0> > >::apply( buffer, buffer + count, clipped ); - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<1> > >::apply( clipped, clipped + count, buffer ); - count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<1> > >::apply( buffer, buffer + count, clipped ); - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<2> > >::apply( clipped, clipped + count, buffer ); - return Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<2> > >::apply( buffer, buffer + count, clipped ); -} - -/// \brief Transforms and clips the triangle formed by \p p0, \p p1, \p p2 by the canonical matrix \p self. -/// Stores the resulting polygon in \p clipped. -/// Returns the number of points in the resulting polygon. -inline std::size_t matrix4_clip_triangle( const Matrix4& self, const Vector3& p0, const Vector3& p1, const Vector3& p2, Vector4 clipped[9] ){ - clipped[0][0] = p0[0]; - clipped[0][1] = p0[1]; - clipped[0][2] = p0[2]; - clipped[0][3] = 1; - clipped[1][0] = p1[0]; - clipped[1][1] = p1[1]; - clipped[1][2] = p1[2]; - clipped[1][3] = 1; - clipped[2][0] = p2[0]; - clipped[2][1] = p2[1]; - clipped[2][2] = p2[2]; - clipped[2][3] = 1; - - matrix4_transform_vector4( self, clipped[0] ); - matrix4_transform_vector4( self, clipped[1] ); - matrix4_transform_vector4( self, clipped[2] ); - - return homogenous_clip_triangle( clipped ); -} - -inline std::size_t homogenous_clip_line( Vector4 clipped[2] ){ - const Vector4& p0 = clipped[0]; - const Vector4& p1 = clipped[1]; - - // early out - { - ClipResult mask0 = homogenous_clip_point( clipped[0] ); - ClipResult mask1 = homogenous_clip_point( clipped[1] ); - - if ( ( mask0 | mask1 ) == c_CLIP_PASS ) { // both points passed all planes - return 2; - } - - if ( mask0 & mask1 ) { // both points failed any one plane - return 0; - } - } - - { - const bool index = CLIP_X_LT_W( p0 ); - if ( index ^ CLIP_X_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[0] - p0[3] ) / ( clip[3] - clip[0] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_X_GT_W( p0 ); - if ( index ^ CLIP_X_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[0] + p0[3] ) / ( -clip[3] - clip[0] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Y_LT_W( p0 ); - if ( index ^ CLIP_Y_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[1] - p0[3] ) / ( clip[3] - clip[1] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Y_GT_W( p0 ); - if ( index ^ CLIP_Y_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[1] + p0[3] ) / ( -clip[3] - clip[1] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Z_LT_W( p0 ); - if ( index ^ CLIP_Z_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[2] - p0[3] ) / ( clip[3] - clip[2] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Z_GT_W( p0 ); - if ( index ^ CLIP_Z_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[2] + p0[3] ) / ( -clip[3] - clip[2] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - return 2; -} - -/// \brief Transforms and clips the line formed by \p p0, \p p1 by the canonical matrix \p self. -/// Stores the resulting line in \p clipped. -/// Returns the number of points in the resulting line. -inline std::size_t matrix4_clip_line( const Matrix4& self, const Vector3& p0, const Vector3& p1, Vector4 clipped[2] ){ - clipped[0][0] = p0[0]; - clipped[0][1] = p0[1]; - clipped[0][2] = p0[2]; - clipped[0][3] = 1; - clipped[1][0] = p1[0]; - clipped[1][1] = p1[1]; - clipped[1][2] = p1[2]; - clipped[1][3] = 1; - - matrix4_transform_vector4( self, clipped[0] ); - matrix4_transform_vector4( self, clipped[1] ); - - return homogenous_clip_line( clipped ); -} - - - - -struct Frustum -{ - Plane3 right, left, bottom, top, back, front; - - Frustum(){ - } - Frustum( const Plane3& _right, - const Plane3& _left, - const Plane3& _bottom, - const Plane3& _top, - const Plane3& _back, - const Plane3& _front ) - : right( _right ), left( _left ), bottom( _bottom ), top( _top ), back( _back ), front( _front ){ - } -}; - -inline Frustum frustum_transformed( const Frustum& frustum, const Matrix4& transform ){ - return Frustum( - plane3_transformed( frustum.right, transform ), - plane3_transformed( frustum.left, transform ), - plane3_transformed( frustum.bottom, transform ), - plane3_transformed( frustum.top, transform ), - plane3_transformed( frustum.back, transform ), - plane3_transformed( frustum.front, transform ) - ); -} - -inline Frustum frustum_inverse_transformed( const Frustum& frustum, const Matrix4& transform ){ - return Frustum( - plane3_inverse_transformed( frustum.right, transform ), - plane3_inverse_transformed( frustum.left, transform ), - plane3_inverse_transformed( frustum.bottom, transform ), - plane3_inverse_transformed( frustum.top, transform ), - plane3_inverse_transformed( frustum.back, transform ), - plane3_inverse_transformed( frustum.front, transform ) - ); -} - -inline bool viewproj_test_point( const Matrix4& viewproj, const Vector3& point ){ - Vector4 hpoint( matrix4_transformed_vector4( viewproj, Vector4( point, 1.0f ) ) ); - if ( fabs( hpoint[0] ) < fabs( hpoint[3] ) - && fabs( hpoint[1] ) < fabs( hpoint[3] ) - && fabs( hpoint[2] ) < fabs( hpoint[3] ) ) { - return true; - } - return false; -} - -inline bool viewproj_test_transformed_point( const Matrix4& viewproj, const Vector3& point, const Matrix4& localToWorld ){ - return viewproj_test_point( viewproj, matrix4_transformed_point( localToWorld, point ) ); -} - -inline Frustum frustum_from_viewproj( const Matrix4& viewproj ){ - return Frustum - ( - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 0], viewproj[ 7] - viewproj[ 4], viewproj[11] - viewproj[ 8], viewproj[15] - viewproj[12] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 0], viewproj[ 7] + viewproj[ 4], viewproj[11] + viewproj[ 8], viewproj[15] + viewproj[12] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 1], viewproj[ 7] + viewproj[ 5], viewproj[11] + viewproj[ 9], viewproj[15] + viewproj[13] ) ), - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 1], viewproj[ 7] - viewproj[ 5], viewproj[11] - viewproj[ 9], viewproj[15] - viewproj[13] ) ), - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 2], viewproj[ 7] - viewproj[ 6], viewproj[11] - viewproj[10], viewproj[15] - viewproj[14] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 2], viewproj[ 7] + viewproj[ 6], viewproj[11] + viewproj[10], viewproj[15] + viewproj[14] ) ) - ); -} - -struct VolumeIntersection -{ - enum Value - { - OUTSIDE, - INSIDE, - PARTIAL - }; -}; - -typedef EnumeratedValue VolumeIntersectionValue; - -const VolumeIntersectionValue c_volumeOutside( VolumeIntersectionValue::OUTSIDE ); -const VolumeIntersectionValue c_volumeInside( VolumeIntersectionValue::INSIDE ); -const VolumeIntersectionValue c_volumePartial( VolumeIntersectionValue::PARTIAL ); - -inline VolumeIntersectionValue frustum_test_aabb( const Frustum& frustum, const AABB& aabb ){ - VolumeIntersectionValue result = c_volumeInside; - - switch ( aabb_classify_plane( aabb, frustum.right ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.left ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.bottom ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.top ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.back ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.front ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - return result; -} - -inline double plane_distance_to_point( const Plane3& plane, const Vector3& point ){ - return vector3_dot( plane.normal(), point ) + plane.d; -} - -inline double plane_distance_to_oriented_extents( const Plane3& plane, const Vector3& extents, const Matrix4& orientation ){ - return fabs( extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.x() ) ) ) - + fabs( extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.y() ) ) ) - + fabs( extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.z() ) ) ); -} - -/// \brief Return false if \p aabb with \p orientation is partially or completely outside \p plane. -inline bool plane_contains_oriented_aabb( const Plane3& plane, const AABB& aabb, const Matrix4& orientation ){ - double dot = plane_distance_to_point( plane, aabb.origin ); - return !( dot > 0 || -dot < plane_distance_to_oriented_extents( plane, aabb.extents, orientation ) ); -} - -inline VolumeIntersectionValue frustum_intersects_transformed_aabb( const Frustum& frustum, const AABB& aabb, const Matrix4& localToWorld ){ - AABB aabb_world( aabb ); - matrix4_transform_point( localToWorld, aabb_world.origin ); - - if ( plane_contains_oriented_aabb( frustum.right, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.left, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.bottom, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.top, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.back, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.front, aabb_world, localToWorld ) ) { - return c_volumeOutside; - } - return c_volumeInside; -} - -inline bool plane3_test_point( const Plane3& plane, const Vector3& point ){ - return vector3_dot( point, plane.normal() ) + plane.dist() <= 0; -} - -inline bool plane3_test_line( const Plane3& plane, const Segment& segment ){ - return segment_classify_plane( segment, plane ) == 2; -} - -inline bool frustum_test_point( const Frustum& frustum, const Vector3& point ){ - return !plane3_test_point( frustum.right, point ) - && !plane3_test_point( frustum.left, point ) - && !plane3_test_point( frustum.bottom, point ) - && !plane3_test_point( frustum.top, point ) - && !plane3_test_point( frustum.back, point ) - && !plane3_test_point( frustum.front, point ); -} - -inline bool frustum_test_line( const Frustum& frustum, const Segment& segment ){ - return !plane3_test_line( frustum.right, segment ) - && !plane3_test_line( frustum.left, segment ) - && !plane3_test_line( frustum.bottom, segment ) - && !plane3_test_line( frustum.top, segment ) - && !plane3_test_line( frustum.back, segment ) - && !plane3_test_line( frustum.front, segment ); -} - -inline bool viewer_test_plane( const Vector4& viewer, const Plane3& plane ){ - return ( ( plane.a * viewer[0] ) - + ( plane.b * viewer[1] ) - + ( plane.c * viewer[2] ) - + ( plane.d * viewer[3] ) ) > 0; -} - -inline Vector3 triangle_cross( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ - return vector3_cross( vector3_subtracted( p1, p0 ), vector3_subtracted( p1, p2 ) ); -} - -inline bool viewer_test_triangle( const Vector4& viewer, const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ - Vector3 cross( triangle_cross( p0, p1, p2 ) ); - return ( ( viewer[0] * cross[0] ) - + ( viewer[1] * cross[1] ) - + ( viewer[2] * cross[2] ) - + ( viewer[3] * 0 ) ) > 0; -} - -inline Vector4 viewer_from_transformed_viewer( const Vector4& viewer, const Matrix4& transform ){ - if ( viewer[3] == 0 ) { - return Vector4( matrix4_transformed_direction( transform, vector4_to_vector3( viewer ) ), 0 ); - } - else - { - return Vector4( matrix4_transformed_point( transform, vector4_to_vector3( viewer ) ), viewer[3] ); - } -} - -inline bool viewer_test_transformed_plane( const Vector4& viewer, const Plane3& plane, const Matrix4& localToWorld ){ -#if 0 - return viewer_test_plane( viewer_from_transformed_viewer( viewer, matrix4_affine_inverse( localToWorld ) ), plane ); -#else - return viewer_test_plane( viewer, plane3_transformed( plane, localToWorld ) ); -#endif -} - -inline Vector4 viewer_from_viewproj( const Matrix4& viewproj ){ - // get viewer pos in object coords - Vector4 viewer( matrix4_transformed_vector4( matrix4_full_inverse( viewproj ), Vector4( 0, 0, -1, 0 ) ) ); - if ( viewer[3] != 0 ) { // non-affine matrix - viewer[0] /= viewer[3]; - viewer[1] /= viewer[3]; - viewer[2] /= viewer[3]; - viewer[3] /= viewer[3]; - } - return viewer; -} - -#endif diff --git a/libs/math/line.h b/libs/math/line.h deleted file mode 100644 index 57d8525..0000000 --- a/libs/math/line.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_LINE_H ) -#define INCLUDED_MATH_LINE_H - -/// \file -/// \brief Line data types and related operations. - -#include "math/vector.h" -#include "math/plane.h" - -/// \brief A line segment defined by a start point and and end point. -class Line -{ -public: -Vector3 start, end; - -Line(){ -} -Line( const Vector3& start_, const Vector3& end_ ) : start( start_ ), end( end_ ){ -} -}; - -inline Vector3 line_closest_point( const Line& line, const Vector3& point ){ - Vector3 v = line.end - line.start; - Vector3 w = point - line.start; - - double c1 = vector3_dot( w,v ); - if ( c1 <= 0 ) { - return line.start; - } - - double c2 = vector3_dot( v,v ); - if ( c2 <= c1 ) { - return line.end; - } - - return Vector3( line.start + v * ( c1 / c2 ) ); -} - - -class Segment -{ -public: -Vector3 origin, extents; - -Segment(){ -} -Segment( const Vector3& origin_, const Vector3& extents_ ) : - origin( origin_ ), extents( extents_ ){ -} -}; - - -inline Segment segment_for_startend( const Vector3& start, const Vector3& end ){ - Segment segment; - segment.origin = vector3_mid( start, end ); - segment.extents = vector3_subtracted( end, segment.origin ); - return segment; -} - -inline unsigned int segment_classify_plane( const Segment& segment, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), segment.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < fabs( vector3_dot( plane.normal(), segment.extents ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - - -class Ray -{ -public: -Vector3 origin, direction; - -Ray(){ -} -Ray( const Vector3& origin_, const Vector3& direction_ ) : - origin( origin_ ), direction( direction_ ){ -} -}; - -inline Ray ray_for_points( const Vector3& origin, const Vector3& p2 ){ - return Ray( origin, vector3_normalised( vector3_subtracted( p2, origin ) ) ); -} - -inline void ray_transform( Ray& ray, const Matrix4& matrix ){ - matrix4_transform_point( matrix, ray.origin ); - matrix4_transform_direction( matrix, ray.direction ); -} - -// closest-point-on-line -inline double ray_squared_distance_to_point( const Ray& ray, const Vector3& point ){ - return vector3_length_squared( - vector3_subtracted( - point, - vector3_added( - ray.origin, - vector3_scaled( - ray.direction, - vector3_dot( - vector3_subtracted( point, ray.origin ), - ray.direction - ) - ) - ) - ) - ); -} - -inline double ray_distance_to_plane( const Ray& ray, const Plane3& plane ){ - return -( vector3_dot( plane.normal(), ray.origin ) - plane.dist() ) / vector3_dot( ray.direction, plane.normal() ); -} - -#endif diff --git a/libs/math/matrix.h b/libs/math/matrix.h deleted file mode 100644 index 95ecfac..0000000 --- a/libs/math/matrix.h +++ /dev/null @@ -1,1194 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_MATRIX_H ) -#define INCLUDED_MATH_MATRIX_H - -/// \file -/// \brief Matrix data types and related operations. - -#include "math/vector.h" - -/// \brief A 4x4 matrix stored in single-precision floating-point. -class Matrix4 -{ -float m_elements[16]; -public: - -Matrix4(){ -} -Matrix4( float xx_, float xy_, float xz_, float xw_, - float yx_, float yy_, float yz_, float yw_, - float zx_, float zy_, float zz_, float zw_, - float tx_, float ty_, float tz_, float tw_ ){ - xx() = xx_; - xy() = xy_; - xz() = xz_; - xw() = xw_; - yx() = yx_; - yy() = yy_; - yz() = yz_; - yw() = yw_; - zx() = zx_; - zy() = zy_; - zz() = zz_; - zw() = zw_; - tx() = tx_; - ty() = ty_; - tz() = tz_; - tw() = tw_; -} - -float& xx(){ - return m_elements[0]; -} -const float& xx() const { - return m_elements[0]; -} -float& xy(){ - return m_elements[1]; -} -const float& xy() const { - return m_elements[1]; -} -float& xz(){ - return m_elements[2]; -} -const float& xz() const { - return m_elements[2]; -} -float& xw(){ - return m_elements[3]; -} -const float& xw() const { - return m_elements[3]; -} -float& yx(){ - return m_elements[4]; -} -const float& yx() const { - return m_elements[4]; -} -float& yy(){ - return m_elements[5]; -} -const float& yy() const { - return m_elements[5]; -} -float& yz(){ - return m_elements[6]; -} -const float& yz() const { - return m_elements[6]; -} -float& yw(){ - return m_elements[7]; -} -const float& yw() const { - return m_elements[7]; -} -float& zx(){ - return m_elements[8]; -} -const float& zx() const { - return m_elements[8]; -} -float& zy(){ - return m_elements[9]; -} -const float& zy() const { - return m_elements[9]; -} -float& zz(){ - return m_elements[10]; -} -const float& zz() const { - return m_elements[10]; -} -float& zw(){ - return m_elements[11]; -} -const float& zw() const { - return m_elements[11]; -} -float& tx(){ - return m_elements[12]; -} -const float& tx() const { - return m_elements[12]; -} -float& ty(){ - return m_elements[13]; -} -const float& ty() const { - return m_elements[13]; -} -float& tz(){ - return m_elements[14]; -} -const float& tz() const { - return m_elements[14]; -} -float& tw(){ - return m_elements[15]; -} -const float& tw() const { - return m_elements[15]; -} - -Vector4& x(){ - return reinterpret_cast( xx() ); -} -const Vector4& x() const { - return reinterpret_cast( xx() ); -} -Vector4& y(){ - return reinterpret_cast( yx() ); -} -const Vector4& y() const { - return reinterpret_cast( yx() ); -} -Vector4& z(){ - return reinterpret_cast( zx() ); -} -const Vector4& z() const { - return reinterpret_cast( zx() ); -} -Vector4& t(){ - return reinterpret_cast( tx() ); -} -const Vector4& t() const { - return reinterpret_cast( tx() ); -} - -const float& index( std::size_t i ) const { - return m_elements[i]; -} -float& index( std::size_t i ){ - return m_elements[i]; -} -const float& operator[]( std::size_t i ) const { - return m_elements[i]; -} -float& operator[]( std::size_t i ){ - return m_elements[i]; -} -const float& index( std::size_t r, std::size_t c ) const { - return m_elements[( r << 2 ) + c]; -} -float& index( std::size_t r, std::size_t c ){ - return m_elements[( r << 2 ) + c]; -} -}; - -/// \brief The 4x4 identity matrix. -const Matrix4 g_matrix4_identity( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ); - - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -inline bool operator==( const Matrix4& self, const Matrix4& other ){ - return self.xx() == other.xx() && self.xy() == other.xy() && self.xz() == other.xz() && self.xw() == other.xw() - && self.yx() == other.yx() && self.yy() == other.yy() && self.yz() == other.yz() && self.yw() == other.yw() - && self.zx() == other.zx() && self.zy() == other.zy() && self.zz() == other.zz() && self.zw() == other.zw() - && self.tx() == other.tx() && self.ty() == other.ty() && self.tz() == other.tz() && self.tw() == other.tw(); -} - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -inline bool matrix4_equal( const Matrix4& self, const Matrix4& other ){ - return self == other; -} - -/// \brief Returns true if \p self and \p other are element-wise equal within \p epsilon. -inline bool matrix4_equal_epsilon( const Matrix4& self, const Matrix4& other, float epsilon ){ - return float_equal_epsilon( self.xx(), other.xx(), epsilon ) - && float_equal_epsilon( self.xy(), other.xy(), epsilon ) - && float_equal_epsilon( self.xz(), other.xz(), epsilon ) - && float_equal_epsilon( self.xw(), other.xw(), epsilon ) - && float_equal_epsilon( self.yx(), other.yx(), epsilon ) - && float_equal_epsilon( self.yy(), other.yy(), epsilon ) - && float_equal_epsilon( self.yz(), other.yz(), epsilon ) - && float_equal_epsilon( self.yw(), other.yw(), epsilon ) - && float_equal_epsilon( self.zx(), other.zx(), epsilon ) - && float_equal_epsilon( self.zy(), other.zy(), epsilon ) - && float_equal_epsilon( self.zz(), other.zz(), epsilon ) - && float_equal_epsilon( self.zw(), other.zw(), epsilon ) - && float_equal_epsilon( self.tx(), other.tx(), epsilon ) - && float_equal_epsilon( self.ty(), other.ty(), epsilon ) - && float_equal_epsilon( self.tz(), other.tz(), epsilon ) - && float_equal_epsilon( self.tw(), other.tw(), epsilon ); -} - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -/// \p self and \p other must be affine. -inline bool matrix4_affine_equal( const Matrix4& self, const Matrix4& other ){ - return self[0] == other[0] - && self[1] == other[1] - && self[2] == other[2] - && self[4] == other[4] - && self[5] == other[5] - && self[6] == other[6] - && self[8] == other[8] - && self[9] == other[9] - && self[10] == other[10] - && self[12] == other[12] - && self[13] == other[13] - && self[14] == other[14]; -} - -enum Matrix4Handedness -{ - MATRIX4_RIGHTHANDED = 0, - MATRIX4_LEFTHANDED = 1, -}; - -/// \brief Returns MATRIX4_RIGHTHANDED if \p self is right-handed, else returns MATRIX4_LEFTHANDED. -inline Matrix4Handedness matrix4_handedness( const Matrix4& self ){ - return ( - vector3_dot( - vector3_cross( vector4_to_vector3( self.x() ), vector4_to_vector3( self.y() ) ), - vector4_to_vector3( self.z() ) - ) - < 0.0 - ) ? MATRIX4_LEFTHANDED : MATRIX4_RIGHTHANDED; -} - - - - - -/// \brief Returns \p self post-multiplied by \p other. -inline Matrix4 matrix4_multiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ - return Matrix4( - other[0] * self[0] + other[1] * self[4] + other[2] * self[8] + other[3] * self[12], - other[0] * self[1] + other[1] * self[5] + other[2] * self[9] + other[3] * self[13], - other[0] * self[2] + other[1] * self[6] + other[2] * self[10] + other[3] * self[14], - other[0] * self[3] + other[1] * self[7] + other[2] * self[11] + other[3] * self[15], - other[4] * self[0] + other[5] * self[4] + other[6] * self[8] + other[7] * self[12], - other[4] * self[1] + other[5] * self[5] + other[6] * self[9] + other[7] * self[13], - other[4] * self[2] + other[5] * self[6] + other[6] * self[10] + other[7] * self[14], - other[4] * self[3] + other[5] * self[7] + other[6] * self[11] + other[7] * self[15], - other[8] * self[0] + other[9] * self[4] + other[10] * self[8] + other[11] * self[12], - other[8] * self[1] + other[9] * self[5] + other[10] * self[9] + other[11] * self[13], - other[8] * self[2] + other[9] * self[6] + other[10] * self[10] + other[11] * self[14], - other[8] * self[3] + other[9] * self[7] + other[10] * self[11] + other[11] * self[15], - other[12] * self[0] + other[13] * self[4] + other[14] * self[8] + other[15] * self[12], - other[12] * self[1] + other[13] * self[5] + other[14] * self[9] + other[15] * self[13], - other[12] * self[2] + other[13] * self[6] + other[14] * self[10] + other[15] * self[14], - other[12] * self[3] + other[13] * self[7] + other[14] * self[11] + other[15] * self[15] - ); -} - -/// \brief Post-multiplies \p self by \p other in-place. -inline void matrix4_multiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_multiplied_by_matrix4( self, other ); -} - - -/// \brief Returns \p self pre-multiplied by \p other. -inline Matrix4 matrix4_premultiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ -#if 1 - return matrix4_multiplied_by_matrix4( other, self ); -#else - return Matrix4( - self[0] * other[0] + self[1] * other[4] + self[2] * other[8] + self[3] * other[12], - self[0] * other[1] + self[1] * other[5] + self[2] * other[9] + self[3] * other[13], - self[0] * other[2] + self[1] * other[6] + self[2] * other[10] + self[3] * other[14], - self[0] * other[3] + self[1] * other[7] + self[2] * other[11] + self[3] * other[15], - self[4] * other[0] + self[5] * other[4] + self[6] * other[8] + self[7] * other[12], - self[4] * other[1] + self[5] * other[5] + self[6] * other[9] + self[7] * other[13], - self[4] * other[2] + self[5] * other[6] + self[6] * other[10] + self[7] * other[14], - self[4] * other[3] + self[5] * other[7] + self[6] * other[11] + self[7] * other[15], - self[8] * other[0] + self[9] * other[4] + self[10] * other[8] + self[11] * other[12], - self[8] * other[1] + self[9] * other[5] + self[10] * other[9] + self[11] * other[13], - self[8] * other[2] + self[9] * other[6] + self[10] * other[10] + self[11] * other[14], - self[8] * other[3] + self[9] * other[7] + self[10] * other[11] + self[11] * other[15], - self[12] * other[0] + self[13] * other[4] + self[14] * other[8] + self[15] * other[12], - self[12] * other[1] + self[13] * other[5] + self[14] * other[9] + self[15] * other[13], - self[12] * other[2] + self[13] * other[6] + self[14] * other[10] + self[15] * other[14], - self[12] * other[3] + self[13] * other[7] + self[14] * other[11] + self[15] * other[15] - ); -#endif -} - -/// \brief Pre-multiplies \p self by \p other in-place. -inline void matrix4_premultiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_premultiplied_by_matrix4( self, other ); -} - -/// \brief returns true if \p transform is affine. -inline bool matrix4_is_affine( const Matrix4& transform ){ - return transform[3] == 0 && transform[7] == 0 && transform[11] == 0 && transform[15] == 1; -} - -/// \brief Returns \p self post-multiplied by \p other. -/// \p self and \p other must be affine. -inline Matrix4 matrix4_affine_multiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ - return Matrix4( - other[0] * self[0] + other[1] * self[4] + other[2] * self[8], - other[0] * self[1] + other[1] * self[5] + other[2] * self[9], - other[0] * self[2] + other[1] * self[6] + other[2] * self[10], - 0, - other[4] * self[0] + other[5] * self[4] + other[6] * self[8], - other[4] * self[1] + other[5] * self[5] + other[6] * self[9], - other[4] * self[2] + other[5] * self[6] + other[6] * self[10], - 0, - other[8] * self[0] + other[9] * self[4] + other[10] * self[8], - other[8] * self[1] + other[9] * self[5] + other[10] * self[9], - other[8] * self[2] + other[9] * self[6] + other[10] * self[10], - 0, - other[12] * self[0] + other[13] * self[4] + other[14] * self[8] + self[12], - other[12] * self[1] + other[13] * self[5] + other[14] * self[9] + self[13], - other[12] * self[2] + other[13] * self[6] + other[14] * self[10] + self[14], - 1 - ); -} - -/// \brief Post-multiplies \p self by \p other in-place. -/// \p self and \p other must be affine. -inline void matrix4_affine_multiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_affine_multiplied_by_matrix4( self, other ); -} - -/// \brief Returns \p self pre-multiplied by \p other. -/// \p self and \p other must be affine. -inline Matrix4 matrix4_affine_premultiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ -#if 1 - return matrix4_affine_multiplied_by_matrix4( other, self ); -#else - return Matrix4( - self[0] * other[0] + self[1] * other[4] + self[2] * other[8], - self[0] * other[1] + self[1] * other[5] + self[2] * other[9], - self[0] * other[2] + self[1] * other[6] + self[2] * other[10], - 0, - self[4] * other[0] + self[5] * other[4] + self[6] * other[8], - self[4] * other[1] + self[5] * other[5] + self[6] * other[9], - self[4] * other[2] + self[5] * other[6] + self[6] * other[10], - 0, - self[8] * other[0] + self[9] * other[4] + self[10] * other[8], - self[8] * other[1] + self[9] * other[5] + self[10] * other[9], - self[8] * other[2] + self[9] * other[6] + self[10] * other[10], - 0, - self[12] * other[0] + self[13] * other[4] + self[14] * other[8] + other[12], - self[12] * other[1] + self[13] * other[5] + self[14] * other[9] + other[13], - self[12] * other[2] + self[13] * other[6] + self[14] * other[10] + other[14], - 1 - ) - ); -#endif -} - -/// \brief Pre-multiplies \p self by \p other in-place. -/// \p self and \p other must be affine. -inline void matrix4_affine_premultiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_affine_premultiplied_by_matrix4( self, other ); -} - -/// \brief Returns \p point transformed by \p self. -template -inline BasicVector3 matrix4_transformed_point( const Matrix4& self, const BasicVector3& point ){ - return BasicVector3( - static_cast( self[0] * point[0] + self[4] * point[1] + self[8] * point[2] + self[12] ), - static_cast( self[1] * point[0] + self[5] * point[1] + self[9] * point[2] + self[13] ), - static_cast( self[2] * point[0] + self[6] * point[1] + self[10] * point[2] + self[14] ) - ); -} - -/// \brief Transforms \p point by \p self in-place. -template -inline void matrix4_transform_point( const Matrix4& self, BasicVector3& point ){ - point = matrix4_transformed_point( self, point ); -} - -/// \brief Returns \p direction transformed by \p self. -template -inline BasicVector3 matrix4_transformed_direction( const Matrix4& self, const BasicVector3& direction ){ - return BasicVector3( - static_cast( self[0] * direction[0] + self[4] * direction[1] + self[8] * direction[2] ), - static_cast( self[1] * direction[0] + self[5] * direction[1] + self[9] * direction[2] ), - static_cast( self[2] * direction[0] + self[6] * direction[1] + self[10] * direction[2] ) - ); -} - -/// \brief Transforms \p direction by \p self in-place. -template -inline void matrix4_transform_direction( const Matrix4& self, BasicVector3& normal ){ - normal = matrix4_transformed_direction( self, normal ); -} - -/// \brief Returns \p vector4 transformed by \p self. -inline Vector4 matrix4_transformed_vector4( const Matrix4& self, const Vector4& vector4 ){ - return Vector4( - self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3], - self[1] * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3], - self[2] * vector4[0] + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3], - self[3] * vector4[0] + self[7] * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3] - ); -} - -/// \brief Transforms \p vector4 by \p self in-place. -inline void matrix4_transform_vector4( const Matrix4& self, Vector4& vector4 ){ - vector4 = matrix4_transformed_vector4( self, vector4 ); -} - - -/// \brief Transposes \p self in-place. -inline void matrix4_transpose( Matrix4& self ){ - std::swap( self.xy(), self.yx() ); - std::swap( self.xz(), self.zx() ); - std::swap( self.xw(), self.tx() ); - std::swap( self.yz(), self.zy() ); - std::swap( self.yw(), self.ty() ); - std::swap( self.zw(), self.tz() ); -} - -/// \brief Returns \p self transposed. -inline Matrix4 matrix4_transposed( const Matrix4& self ){ - return Matrix4( - self.xx(), - self.yx(), - self.zx(), - self.tx(), - self.xy(), - self.yy(), - self.zy(), - self.ty(), - self.xz(), - self.yz(), - self.zz(), - self.tz(), - self.xw(), - self.yw(), - self.zw(), - self.tw() - ); -} - - -/// \brief Inverts an affine transform in-place. -/// Adapted from Graphics Gems 2. -inline Matrix4 matrix4_affine_inverse( const Matrix4& self ){ - Matrix4 result; - - // determinant of rotation submatrix - double det - = self[0] * ( self[5] * self[10] - self[9] * self[6] ) - - self[1] * ( self[4] * self[10] - self[8] * self[6] ) - + self[2] * ( self[4] * self[9] - self[8] * self[5] ); - - // throw exception here if (det*det < 1e-25) - - // invert rotation submatrix - det = 1.0 / det; - - result[0] = static_cast( ( self[5] * self[10] - self[6] * self[9] ) * det ); - result[1] = static_cast( -( self[1] * self[10] - self[2] * self[9] ) * det ); - result[2] = static_cast( ( self[1] * self[6] - self[2] * self[5] ) * det ); - result[3] = 0; - result[4] = static_cast( -( self[4] * self[10] - self[6] * self[8] ) * det ); - result[5] = static_cast( ( self[0] * self[10] - self[2] * self[8] ) * det ); - result[6] = static_cast( -( self[0] * self[6] - self[2] * self[4] ) * det ); - result[7] = 0; - result[8] = static_cast( ( self[4] * self[9] - self[5] * self[8] ) * det ); - result[9] = static_cast( -( self[0] * self[9] - self[1] * self[8] ) * det ); - result[10] = static_cast( ( self[0] * self[5] - self[1] * self[4] ) * det ); - result[11] = 0; - - // multiply translation part by rotation - result[12] = -( self[12] * result[0] + - self[13] * result[4] + - self[14] * result[8] ); - result[13] = -( self[12] * result[1] + - self[13] * result[5] + - self[14] * result[9] ); - result[14] = -( self[12] * result[2] + - self[13] * result[6] + - self[14] * result[10] ); - result[15] = 1; - - return result; -} - -inline void matrix4_affine_invert( Matrix4& self ){ - self = matrix4_affine_inverse( self ); -} - -/// \brief A compile-time-constant integer. -template -struct IntegralConstant -{ - enum unnamed_ { VALUE = VALUE_ }; -}; - -/// \brief A compile-time-constant row/column index into a 4x4 matrix. -template -class Matrix4Index -{ -public: -typedef IntegralConstant r; -typedef IntegralConstant c; -typedef IntegralConstant<( r::VALUE * 4 ) + c::VALUE> i; -}; - -/// \brief A functor which returns the cofactor of a 3x3 submatrix obtained by ignoring a given row and column of a 4x4 matrix. -/// \param Row Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three rows to use. -/// \param Col Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three columns to use. -template -class Matrix4Cofactor -{ -public: -typedef typename Matrix4Index::i xx; -typedef typename Matrix4Index::i xy; -typedef typename Matrix4Index::i xz; -typedef typename Matrix4Index::i yx; -typedef typename Matrix4Index::i yy; -typedef typename Matrix4Index::i yz; -typedef typename Matrix4Index::i zx; -typedef typename Matrix4Index::i zy; -typedef typename Matrix4Index::i zz; -static double apply( const Matrix4& self ){ - return self[xx::VALUE] * ( self[yy::VALUE] * self[zz::VALUE] - self[zy::VALUE] * self[yz::VALUE] ) - - self[xy::VALUE] * ( self[yx::VALUE] * self[zz::VALUE] - self[zx::VALUE] * self[yz::VALUE] ) - + self[xz::VALUE] * ( self[yx::VALUE] * self[zy::VALUE] - self[zx::VALUE] * self[yy::VALUE] ); -} -}; - -/// \brief The cofactor element indices for a 4x4 matrix row or column. -/// \param Element The index of the element to ignore. -template -class Cofactor4 -{ -public: -typedef IntegralConstant<( Element <= 0 ) ? 1 : 0> x; -typedef IntegralConstant<( Element <= 1 ) ? 2 : 1> y; -typedef IntegralConstant<( Element <= 2 ) ? 3 : 2> z; -}; - -/// \brief Returns the determinant of \p self. -inline double matrix4_determinant( const Matrix4& self ){ - return self.xx() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply( self ) - - self.xy() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply( self ) - + self.xz() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply( self ) - - self.xw() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply( self ); -} - -/// \brief Returns the inverse of \p self using the Adjoint method. -/// \todo Throw an exception if the determinant is zero. -inline Matrix4 matrix4_full_inverse( const Matrix4& self ){ - double determinant = 1.0 / matrix4_determinant( self ); - - return Matrix4( - static_cast( Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<1>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<2>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<3>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<1>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<2>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<3>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<1>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<2>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<3>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<1>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<2>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<3>, Cofactor4<3> >::apply( self ) * determinant ) - ); -} - -/// \brief Inverts \p self in-place using the Adjoint method. -inline void matrix4_full_invert( Matrix4& self ){ - self = matrix4_full_inverse( self ); -} - - -/// \brief Constructs a pure-translation matrix from \p translation. -inline Matrix4 matrix4_translation_for_vec3( const Vector3& translation ){ - return Matrix4( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - translation[0], translation[1], translation[2], 1 - ); -} - -/// \brief Returns the translation part of \p self. -inline Vector3 matrix4_get_translation_vec3( const Matrix4& self ){ - return vector4_to_vector3( self.t() ); -} - -/// \brief Concatenates \p self with \p translation. -/// The concatenated \p translation occurs before \p self. -inline void matrix4_translate_by_vec3( Matrix4& self, const Vector3& translation ){ - matrix4_multiply_by_matrix4( self, matrix4_translation_for_vec3( translation ) ); -} - -/// \brief Returns \p self Concatenated with \p translation. -/// The concatenated translation occurs before \p self. -inline Matrix4 matrix4_translated_by_vec3( const Matrix4& self, const Vector3& translation ){ - return matrix4_multiplied_by_matrix4( self, matrix4_translation_for_vec3( translation ) ); -} - - -#include "math/pi.h" - -/// \brief Returns \p angle modulated by the range [0, 360). -/// \p angle must be in the range [-360, 360). -inline float angle_modulate_degrees_range( float angle ){ - return static_cast( float_mod_range( angle, 360.0 ) ); -} - -/// \brief Returns \p euler angles converted from radians to degrees. -inline Vector3 euler_radians_to_degrees( const Vector3& euler ){ - return Vector3( - static_cast( radians_to_degrees( euler.x() ) ), - static_cast( radians_to_degrees( euler.y() ) ), - static_cast( radians_to_degrees( euler.z() ) ) - ); -} - -/// \brief Returns \p euler angles converted from degrees to radians. -inline Vector3 euler_degrees_to_radians( const Vector3& euler ){ - return Vector3( - static_cast( degrees_to_radians( euler.x() ) ), - static_cast( degrees_to_radians( euler.y() ) ), - static_cast( degrees_to_radians( euler.z() ) ) - ); -} - - - -/// \brief Constructs a pure-rotation matrix about the x axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_x( float s, float c ){ - return Matrix4( - 1, 0, 0, 0, - 0, c, s, 0, - 0,-s, c, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the x axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_x( double x ){ - return matrix4_rotation_for_sincos_x( static_cast( sin( x ) ), static_cast( cos( x ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the x axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_x_degrees( float x ){ - return matrix4_rotation_for_x( degrees_to_radians( x ) ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_y( float s, float c ){ - return Matrix4( - c, 0,-s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_y( double y ){ - return matrix4_rotation_for_sincos_y( static_cast( sin( y ) ), static_cast( cos( y ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_y_degrees( float y ){ - return matrix4_rotation_for_y( degrees_to_radians( y ) ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_z( float s, float c ){ - return Matrix4( - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_z( double z ){ - return matrix4_rotation_for_sincos_z( static_cast( sin( z ) ), static_cast( cos( z ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_z_degrees( float z ){ - return matrix4_rotation_for_z( degrees_to_radians( z ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, y, z). -/*! \verbatim - clockwise rotation around X, Y, Z, facing along axis - 1 0 0 cy 0 -sy cz sz 0 - 0 cx sx 0 1 0 -sz cz 0 - 0 -sx cx sy 0 cy 0 0 1 - - rows of Z by cols of Y - cy*cz -sy*cz+sz -sy*sz+cz - -sz*cy -sz*sy+cz - - .. or something like that.. - - final rotation is Z * Y * X - cy*cz -sx*-sy*cz+cx*sz cx*-sy*sz+sx*cz - -cy*sz sx*sy*sz+cx*cz -cx*-sy*sz+sx*cz - sy -sx*cy cx*cy - - transposed - cy.cz + 0.sz + sy.0 cy.-sz + 0 .cz + sy.0 cy.0 + 0 .0 + sy.1 | - sx.sy.cz + cx.sz + -sx.cy.0 sx.sy.-sz + cx.cz + -sx.cy.0 sx.sy.0 + cx.0 + -sx.cy.1 | - -cx.sy.cz + sx.sz + cx.cy.0 -cx.sy.-sz + sx.cz + cx.cy.0 -cx.sy.0 + 0 .0 + cx.cy.1 | - \endverbatim */ -inline Matrix4 matrix4_rotation_for_euler_xyz( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz ), - static_cast( cy * sz ), - static_cast( -sy ), - 0, - static_cast( sx * sy * cz + cx * -sz ), - static_cast( sx * sy * sz + cx * cz ), - static_cast( sx * cy ), - 0, - static_cast( cx * sy * cz + sx * sz ), - static_cast( cx * sy * sz + -sx * cz ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_x( euler[0] ), - matrix4_rotation_for_y( euler[1] ) - ), - matrix4_rotation_for_z( euler[2] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, y, z). -inline Matrix4 matrix4_rotation_for_euler_xyz_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_xyz( euler_degrees_to_radians( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (x, y, z). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_xyz_degrees( Matrix4& self, const Vector3& euler ){ - matrix4_multiply_by_matrix4( self, matrix4_rotation_for_euler_xyz_degrees( euler ) ); -} - - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, z, x). -inline Matrix4 matrix4_rotation_for_euler_yzx( const Vector3& euler ){ - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_y( euler[1] ), - matrix4_rotation_for_z( euler[2] ) - ), - matrix4_rotation_for_x( euler[0] ) - ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, z, x). -inline Matrix4 matrix4_rotation_for_euler_yzx_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_yzx( euler_degrees_to_radians( euler ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, z, y). -inline Matrix4 matrix4_rotation_for_euler_xzy( const Vector3& euler ){ - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_x( euler[0] ), - matrix4_rotation_for_z( euler[2] ) - ), - matrix4_rotation_for_y( euler[1] ) - ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, z, y). -inline Matrix4 matrix4_rotation_for_euler_xzy_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_xzy( euler_degrees_to_radians( euler ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, x, z). -/*! \verbatim - | cy.cz + sx.sy.-sz + -cx.sy.0 0.cz + cx.-sz + sx.0 sy.cz + -sx.cy.-sz + cx.cy.0 | - | cy.sz + sx.sy.cz + -cx.sy.0 0.sz + cx.cz + sx.0 sy.sz + -sx.cy.cz + cx.cy.0 | - | cy.0 + sx.sy.0 + -cx.sy.1 0.0 + cx.0 + sx.1 sy.0 + -sx.cy.0 + cx.cy.1 | - \endverbatim */ -inline Matrix4 matrix4_rotation_for_euler_yxz( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz + sx * sy * -sz ), - static_cast( cy * sz + sx * sy * cz ), - static_cast( -cx * sy ), - 0, - static_cast( cx * -sz ), - static_cast( cx * cz ), - static_cast( sx ), - 0, - static_cast( sy * cz + -sx * cy * -sz ), - static_cast( sy * sz + -sx * cy * cz ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_y( euler[1] ), - matrix4_rotation_for_x( euler[0] ) - ), - matrix4_rotation_for_z( euler[2] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, x, z). -inline Matrix4 matrix4_rotation_for_euler_yxz_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_yxz( euler_degrees_to_radians( euler ) ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z). -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_euler_yxz_degrees( const Matrix4& self, const Vector3& euler ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_euler_yxz_degrees( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_yxz_degrees( Matrix4& self, const Vector3& euler ){ - self = matrix4_rotated_by_euler_yxz_degrees( self, euler ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, x, y). -inline Matrix4 matrix4_rotation_for_euler_zxy( const Vector3& euler ){ -#if 1 - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_z( euler[2] ), - matrix4_rotation_for_x( euler[0] ) - ), - matrix4_rotation_for_y( euler[1] ) - ); -#else - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cz * cy + sz * sx * sy ), - static_cast( sz * cx ), - static_cast( cz * -sy + sz * sx * cy ), - 0, - static_cast( -sz * cy + cz * sx * sy ), - static_cast( cz * cx ), - static_cast( -sz * -sy + cz * cx * cy ), - 0, - static_cast( cx * sy ), - static_cast( -sx ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degres=es) in the order (z, x, y). -inline Matrix4 matrix4_rotation_for_euler_zxy_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_zxy( euler_degrees_to_radians( euler ) ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y). -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_euler_zxy_degrees( const Matrix4& self, const Vector3& euler ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_euler_zxy_degrees( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_zxy_degrees( Matrix4& self, const Vector3& euler ){ - self = matrix4_rotated_by_euler_zxy_degrees( self, euler ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, y, x). -inline Matrix4 matrix4_rotation_for_euler_zyx( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz ), - static_cast( sx * sy * cz + cx * sz ), - static_cast( cx * -sy * cz + sx * sz ), - 0, - static_cast( cy * -sz ), - static_cast( sx * sy * -sz + cx * cz ), - static_cast( cx * -sy * -sz + sx * cz ), - 0, - static_cast( sy ), - static_cast( -sx * cy ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_z( euler[2] ), - matrix4_rotation_for_y( euler[1] ) - ), - matrix4_rotation_for_x( euler[0] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (z, y, x). -inline Matrix4 matrix4_rotation_for_euler_zyx_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_zyx( euler_degrees_to_radians( euler ) ); -} - - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (x, y, z). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_xyz( const Matrix4& self ){ - double a = asin( -self[2] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( atan2( self[6] / ca, self[10] / ca ) ), - static_cast( a ), - static_cast( atan2( self[1] / ca, self[0] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( atan2( -self[9], self[5] ) ), - static_cast( a ), - 0 - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_xyz(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_xyz_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_xyz( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (y, x, z). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_yxz( const Matrix4& self ){ - double a = asin( self[6] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( a ), - static_cast( atan2( -self[2] / ca, self[10] / ca ) ), - static_cast( atan2( -self[4] / ca, self[5] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( a ), - static_cast( atan2( self[8], self[0] ) ), - 0 - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_yxz(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_yxz_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_yxz( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, x, y). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_zxy( const Matrix4& self ){ - double a = asin( -self[9] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( a ), - static_cast( atan2( self[8] / ca, self[10] / ca ) ), - static_cast( atan2( self[1] / ca, self[5] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( a ), - 0, - static_cast( atan2( -self[4], self[0] ) ) - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_zxy(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_zxy_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_zxy( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, y, x). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_zyx( const Matrix4& self ){ - double a = asin( self[8] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( atan2( -self[9] / ca, self[10] / ca ) ), - static_cast( a ), - static_cast( atan2( -self[4] / ca, self[0] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - 0, - static_cast( a ), - static_cast( atan2( self[1], self[5] ) ) - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_zyx(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_zyx_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_zyx( self ) ); -} - - -/// \brief Rotate \p self by \p euler angles (degrees) applied in the order (x, y, z), using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_euler_xyz_degrees( Matrix4& self, const Vector3& euler, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -/// \brief Constructs a pure-scale matrix from \p scale. -inline Matrix4 matrix4_scale_for_vec3( const Vector3& scale ){ - return Matrix4( - scale[0], 0, 0, 0, - 0, scale[1], 0, 0, - 0, 0, scale[2], 0, - 0, 0, 0, 1 - ); -} - -/// \brief Calculates and returns the (x, y, z) scale values that produce the scale component of \p self. -/// \p self must be affine and orthogonal to produce a meaningful result. -inline Vector3 matrix4_get_scale_vec3( const Matrix4& self ){ - return Vector3( - static_cast( vector3_length( vector4_to_vector3( self.x() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.y() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.z() ) ) ) - ); -} - -/// \brief Scales \p self by \p scale. -inline void matrix4_scale_by_vec3( Matrix4& self, const Vector3& scale ){ - matrix4_multiply_by_matrix4( self, matrix4_scale_for_vec3( scale ) ); -} - -/// \brief Scales \p self by \p scale, using \p pivotpoint. -inline void matrix4_pivoted_scale_by_vec3( Matrix4& self, const Vector3& scale, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_scale_by_vec3( self, scale ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -/// \brief Transforms \p self by \p translation, \p euler and \p scale. -/// The transforms are combined in the order: scale, rotate-z, rotate-y, rotate-x, translate. -inline void matrix4_transform_by_euler_xyz_degrees( Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale ){ - matrix4_translate_by_vec3( self, translation ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_scale_by_vec3( self, scale ); -} - -/// \brief Transforms \p self by \p translation, \p euler and \p scale, using \p pivotpoint. -inline void matrix4_pivoted_transform_by_euler_xyz_degrees( Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint + translation ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_scale_by_vec3( self, scale ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -#endif diff --git a/libs/math/matrix.h.uncrustify b/libs/math/matrix.h.uncrustify deleted file mode 100644 index e69de29..0000000 diff --git a/libs/math/pi.h b/libs/math/pi.h deleted file mode 100644 index a9f368c..0000000 --- a/libs/math/pi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_PI_H ) -#define INCLUDED_MATH_PI_H - -/// \file -/// \brief Pi constants and degrees/radians conversion. - -const double c_pi = 3.1415926535897932384626433832795; -const double c_half_pi = c_pi / 2.0; -const double c_2pi = 2.0 * c_pi; -const double c_inv_2pi = 1.0 / c_2pi; - -const double c_DEG2RADMULT = c_pi / 180.0; -const double c_RAD2DEGMULT = 180.0 / c_pi; - -inline double radians_to_degrees( double radians ){ - return radians * c_RAD2DEGMULT; -} -inline double degrees_to_radians( double degrees ){ - return degrees * c_DEG2RADMULT; -} - -#endif diff --git a/libs/math/plane.h b/libs/math/plane.h deleted file mode 100644 index 4027164..0000000 --- a/libs/math/plane.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_PLANE_H ) -#define INCLUDED_MATH_PLANE_H - -/// \file -/// \brief Plane data types and related operations. - -#include "math/matrix.h" - -/// \brief A plane equation stored in double-precision floating-point. -class Plane3 -{ -public: -double a, b, c, d; - -Plane3(){ -} -Plane3( double _a, double _b, double _c, double _d ) - : a( _a ), b( _b ), c( _c ), d( _d ){ -} -template -Plane3( const BasicVector3& normal, double dist ) - : a( normal.x() ), b( normal.y() ), c( normal.z() ), d( dist ){ -} - -BasicVector3& normal(){ - return reinterpret_cast&>( *this ); -} -const BasicVector3& normal() const { - return reinterpret_cast&>( *this ); -} -double& dist(){ - return d; -} -const double& dist() const { - return d; -} -}; - -inline Plane3 plane3_normalised( const Plane3& plane ){ - double rmagnitude = 1.0 / sqrt( plane.a * plane.a + plane.b * plane.b + plane.c * plane.c ); - return Plane3( - plane.a * rmagnitude, - plane.b * rmagnitude, - plane.c * rmagnitude, - plane.d * rmagnitude - ); -} - -inline Plane3 plane3_translated( const Plane3& plane, const Vector3& translation ){ - Plane3 transformed; - transformed.a = plane.a; - transformed.b = plane.b; - transformed.c = plane.c; - transformed.d = -( ( -plane.d * transformed.a + translation.x() ) * transformed.a + - ( -plane.d * transformed.b + translation.y() ) * transformed.b + - ( -plane.d * transformed.c + translation.z() ) * transformed.c ); - return transformed; -} - -inline Plane3 plane3_transformed( const Plane3& plane, const Matrix4& transform ){ - Plane3 transformed; - transformed.a = transform[0] * plane.a + transform[4] * plane.b + transform[8] * plane.c; - transformed.b = transform[1] * plane.a + transform[5] * plane.b + transform[9] * plane.c; - transformed.c = transform[2] * plane.a + transform[6] * plane.b + transform[10] * plane.c; - transformed.d = -( ( -plane.d * transformed.a + transform[12] ) * transformed.a + - ( -plane.d * transformed.b + transform[13] ) * transformed.b + - ( -plane.d * transformed.c + transform[14] ) * transformed.c ); - return transformed; -} - -inline Plane3 plane3_inverse_transformed( const Plane3& plane, const Matrix4& transform ){ - return Plane3 - ( - transform[ 0] * plane.a + transform[ 1] * plane.b + transform[ 2] * plane.c + transform[ 3] * plane.d, - transform[ 4] * plane.a + transform[ 5] * plane.b + transform[ 6] * plane.c + transform[ 7] * plane.d, - transform[ 8] * plane.a + transform[ 9] * plane.b + transform[10] * plane.c + transform[11] * plane.d, - transform[12] * plane.a + transform[13] * plane.b + transform[14] * plane.c + transform[15] * plane.d - ); -} - -inline Plane3 plane3_flipped( const Plane3& plane ){ - return Plane3( vector3_negated( plane.normal() ), -plane.dist() ); -} - -const double c_PLANE_NORMAL_EPSILON = 0.0001f; -const double c_PLANE_DIST_EPSILON = 0.02; - -inline bool plane3_equal( const Plane3& self, const Plane3& other ){ - return vector3_equal_epsilon( self.normal(), other.normal(), c_PLANE_NORMAL_EPSILON ) - && float_equal_epsilon( self.dist(), other.dist(), c_PLANE_DIST_EPSILON ); -} - -inline bool plane3_opposing( const Plane3& self, const Plane3& other ){ - return plane3_equal( self, plane3_flipped( other ) ); -} - -inline bool plane3_valid( const Plane3& self ){ - return float_equal_epsilon( vector3_dot( self.normal(), self.normal() ), 1.0, 0.01 ); -} - -template -inline Plane3 plane3_for_points( const BasicVector3& p0, const BasicVector3& p1, const BasicVector3& p2 ){ - Plane3 self; - self.normal() = vector3_normalised( vector3_cross( vector3_subtracted( p1, p0 ), vector3_subtracted( p2, p0 ) ) ); - self.dist() = vector3_dot( p0, self.normal() ); - return self; -} - -template -inline Plane3 plane3_for_points( const BasicVector3 planepts[3] ){ - return plane3_for_points( planepts[2], planepts[1], planepts[0] ); -} - - -#endif diff --git a/libs/math/quaternion.h b/libs/math/quaternion.h deleted file mode 100644 index 24c6861..0000000 --- a/libs/math/quaternion.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_QUATERNION_H ) -#define INCLUDED_MATH_QUATERNION_H - -/// \file -/// \brief Quaternion data types and related operations. - -#include "math/matrix.h" - -/// \brief A quaternion stored in single-precision floating-point. -typedef Vector4 Quaternion; - -const Quaternion c_quaternion_identity( 0, 0, 0, 1 ); - -inline Quaternion quaternion_multiplied_by_quaternion( const Quaternion& quaternion, const Quaternion& other ){ - return Quaternion( - quaternion[3] * other[0] + quaternion[0] * other[3] + quaternion[1] * other[2] - quaternion[2] * other[1], - quaternion[3] * other[1] + quaternion[1] * other[3] + quaternion[2] * other[0] - quaternion[0] * other[2], - quaternion[3] * other[2] + quaternion[2] * other[3] + quaternion[0] * other[1] - quaternion[1] * other[0], - quaternion[3] * other[3] - quaternion[0] * other[0] - quaternion[1] * other[1] - quaternion[2] * other[2] - ); -} - -inline void quaternion_multiply_by_quaternion( Quaternion& quaternion, const Quaternion& other ){ - quaternion = quaternion_multiplied_by_quaternion( quaternion, other ); -} - -/// \brief Constructs a quaternion which rotates between two points on the unit-sphere, \p from and \p to. -inline Quaternion quaternion_for_unit_vectors( const Vector3& from, const Vector3& to ){ - return Quaternion( vector3_cross( from, to ), static_cast( vector3_dot( from, to ) ) ); -} - -inline Quaternion quaternion_for_axisangle( const Vector3& axis, double angle ){ - angle *= 0.5; - float sa = static_cast( sin( angle ) ); - return Quaternion( axis[0] * sa, axis[1] * sa, axis[2] * sa, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_x( double angle ){ - angle *= 0.5; - return Quaternion( static_cast( sin( angle ) ), 0, 0, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_y( double angle ){ - angle *= 0.5; - return Quaternion( 0, static_cast( sin( angle ) ), 0, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_z( double angle ){ - angle *= 0.5; - return Quaternion( 0, 0, static_cast( sin( angle ) ), static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_inverse( const Quaternion& quaternion ){ - return Quaternion( vector3_negated( vector4_to_vector3( quaternion ) ), quaternion[3] ); -} - -inline void quaternion_conjugate( Quaternion& quaternion ){ - quaternion = quaternion_inverse( quaternion ); -} - -inline Quaternion quaternion_normalised( const Quaternion& quaternion ){ - const double n = ( 1.0 / ( quaternion[0] * quaternion[0] + quaternion[1] * quaternion[1] + quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3] ) ); - return Quaternion( - static_cast( quaternion[0] * n ), - static_cast( quaternion[1] * n ), - static_cast( quaternion[2] * n ), - static_cast( quaternion[3] * n ) - ); -} - -inline void quaternion_normalise( Quaternion& quaternion ){ - quaternion = quaternion_normalised( quaternion ); -} - -/// \brief Constructs a pure-rotation matrix from \p quaternion. -inline Matrix4 matrix4_rotation_for_quaternion( const Quaternion& quaternion ){ -#if 0 - const double xx = quaternion[0] * quaternion[0]; - const double xy = quaternion[0] * quaternion[1]; - const double xz = quaternion[0] * quaternion[2]; - const double xw = quaternion[0] * quaternion[3]; - - const double yy = quaternion[1] * quaternion[1]; - const double yz = quaternion[1] * quaternion[2]; - const double yw = quaternion[1] * quaternion[3]; - - const double zz = quaternion[2] * quaternion[2]; - const double zw = quaternion[2] * quaternion[3]; - - return Matrix4( - static_cast( 1 - 2 * ( yy + zz ) ), - static_cast( 2 * ( xy + zw ) ), - static_cast( 2 * ( xz - yw ) ), - 0, - static_cast( 2 * ( xy - zw ) ), - static_cast( 1 - 2 * ( xx + zz ) ), - static_cast( 2 * ( yz + xw ) ), - 0, - static_cast( 2 * ( xz + yw ) ), - static_cast( 2 * ( yz - xw ) ), - static_cast( 1 - 2 * ( xx + yy ) ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - const double x2 = quaternion[0] + quaternion[0]; - const double y2 = quaternion[1] + quaternion[1]; - const double z2 = quaternion[2] + quaternion[2]; - const double xx = quaternion[0] * x2; - const double xy = quaternion[0] * y2; - const double xz = quaternion[0] * z2; - const double yy = quaternion[1] * y2; - const double yz = quaternion[1] * z2; - const double zz = quaternion[2] * z2; - const double wx = quaternion[3] * x2; - const double wy = quaternion[3] * y2; - const double wz = quaternion[3] * z2; - - return Matrix4( - static_cast( 1.0 - ( yy + zz ) ), - static_cast( xy + wz ), - static_cast( xz - wy ), - 0, - static_cast( xy - wz ), - static_cast( 1.0 - ( xx + zz ) ), - static_cast( yz + wx ), - 0, - static_cast( xz + wy ), - static_cast( yz - wx ), - static_cast( 1.0 - ( xx + yy ) ), - 0, - 0, - 0, - 0, - 1 - ); - -#endif -} - -const double c_half_sqrt2 = 0.70710678118654752440084436210485; -const float c_half_sqrt2f = static_cast( c_half_sqrt2 ); - -inline bool quaternion_component_is_90( float component ){ - return ( fabs( component ) - c_half_sqrt2 ) < 0.001; -} - -inline Matrix4 matrix4_rotation_for_quaternion_quantised( const Quaternion& quaternion ){ - if ( quaternion.y() == 0 - && quaternion.z() == 0 - && quaternion_component_is_90( quaternion.x() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_x( ( quaternion.x() > 0 ) ? 1.f : -1.f, 0 ); - } - - if ( quaternion.x() == 0 - && quaternion.z() == 0 - && quaternion_component_is_90( quaternion.y() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_y( ( quaternion.y() > 0 ) ? 1.f : -1.f, 0 ); - } - - if ( quaternion.x() == 0 - && quaternion.y() == 0 - && quaternion_component_is_90( quaternion.z() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_z( ( quaternion.z() > 0 ) ? 1.f : -1.f, 0 ); - } - - return matrix4_rotation_for_quaternion( quaternion ); -} - -inline Quaternion quaternion_for_matrix4_rotation( const Matrix4& matrix4 ){ - Quaternion out; - Matrix4 transposed = matrix4_transposed( matrix4 ); - - /* the monkeys added 1.0 to this for some reason. hint: it's WRONG - eukara */ - double trace = transposed[0] + transposed[5] + transposed[10] + 1.0f; - - if ( trace > 0.0 ) { - double S = 0.5 / sqrt( trace ); - return Quaternion( - static_cast( ( transposed[9] - transposed[6] ) * S ), - static_cast( ( transposed[2] - transposed[8] ) * S ), - static_cast( ( transposed[4] - transposed[1] ) * S ), - static_cast( 0.25 / S ) - ); - } - - if ( transposed[0] >= transposed[5] && transposed[0] >= transposed[10] ) { - double S = 2.0 * sqrt( 1.0 + transposed[0] - transposed[5] - transposed[10] ); - return Quaternion( - static_cast( 0.25 / S ), - static_cast( ( transposed[1] + transposed[4] ) / S ), - static_cast( ( transposed[2] + transposed[8] ) / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ) - ); - } - - if ( transposed[5] >= transposed[0] && transposed[5] >= transposed[10] ) { - double S = 2.0 * sqrt( 1.0 + transposed[5] - transposed[0] - transposed[10] ); - return Quaternion( - static_cast( ( transposed[1] + transposed[4] ) / S ), - static_cast( 0.25 / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ), - static_cast( ( transposed[2] + transposed[8] ) / S ) - ); - } - - double S = 2.0 * sqrt( 1.0 + transposed[10] - transposed[0] - transposed[5] ); - return Quaternion( - static_cast( ( transposed[2] + transposed[8] ) / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ), - static_cast( 0.25 / S ), - static_cast( ( transposed[1] + transposed[4] ) / S ) - ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p rotation. -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_quaternion( const Matrix4& self, const Quaternion& rotation ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_quaternion( rotation ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p rotation. -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_quaternion( Matrix4& self, const Quaternion& rotation ){ - self = matrix4_rotated_by_quaternion( self, rotation ); -} - -/// \brief Rotates \p self by \p rotation, using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_quaternion( Matrix4& self, const Quaternion& rotation, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_quaternion( self, rotation ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - -inline Vector3 quaternion_transformed_point( const Quaternion& quaternion, const Vector3& point ){ - double xx = quaternion.x() * quaternion.x(); - double yy = quaternion.y() * quaternion.y(); - double zz = quaternion.z() * quaternion.z(); - double ww = quaternion.w() * quaternion.w(); - - double xy2 = quaternion.x() * quaternion.y() * 2; - double xz2 = quaternion.x() * quaternion.z() * 2; - double xw2 = quaternion.x() * quaternion.w() * 2; - double yz2 = quaternion.y() * quaternion.z() * 2; - double yw2 = quaternion.y() * quaternion.w() * 2; - double zw2 = quaternion.z() * quaternion.w() * 2; - - return Vector3( - static_cast( ww * point.x() + yw2 * point.z() - zw2 * point.y() + xx * point.x() + xy2 * point.y() + xz2 * point.z() - zz * point.x() - yy * point.x() ), - static_cast( xy2 * point.x() + yy * point.y() + yz2 * point.z() + zw2 * point.x() - zz * point.y() + ww * point.y() - xw2 * point.z() - xx * point.y() ), - static_cast( xz2 * point.x() + yz2 * point.y() + zz * point.z() - yw2 * point.x() - yy * point.z() + xw2 * point.y() - xx * point.z() + ww * point.z() ) - ); -} - -/// \brief Constructs a pure-rotation transform from \p axis and \p angle (radians). -inline Matrix4 matrix4_rotation_for_axisangle( const Vector3& axis, double angle ){ - return matrix4_rotation_for_quaternion( quaternion_for_axisangle( axis, angle ) ); -} - -/// \brief Rotates \p self about \p axis by \p angle. -inline void matrix4_rotate_by_axisangle( Matrix4& self, const Vector3& axis, double angle ){ - matrix4_multiply_by_matrix4( self, matrix4_rotation_for_axisangle( axis, angle ) ); -} - -/// \brief Rotates \p self about \p axis by \p angle using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_axisangle( Matrix4& self, const Vector3& axis, double angle, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_axisangle( self, axis, angle ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -#endif diff --git a/libs/math/vector.h b/libs/math/vector.h deleted file mode 100644 index b4fd92c..0000000 --- a/libs/math/vector.h +++ /dev/null @@ -1,709 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_VECTOR_H ) -#define INCLUDED_MATH_VECTOR_H - -/// \file -/// \brief Vector data types and related operations. - -#include "generic/vector.h" -#include "globaldefs.h" - -#if GDEF_COMPILER_MSVC - -inline int lrint( double flt ){ - int i; - - _asm - { - fld flt - fistp i - }; - - return i; -} - -inline __int64 llrint( double f ){ - return static_cast<__int64>( f + 0.5 ); -} - -#elif GDEF_OS_BSD - -/*inline long lrint( double f ){ - return static_cast( f + 0.5 ); -}*/ - -/*inline long long llrint( double f ){ - return static_cast( f + 0.5 ); -}*/ - -#elif GDEF_COMPILER_GNU - -// lrint is part of ISO C99 -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#else -#error "unsupported platform" -#endif - -#include -#include -#include - - -//#include "debugging/debugging.h" - -/// \brief Returns true if \p self is equal to other \p other within \p epsilon. -template -inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){ - return fabs( other - self ) < epsilon; -} - -/// \brief Returns the value midway between \p self and \p other. -template -inline Element float_mid( const Element& self, const Element& other ){ - return Element( ( self + other ) * 0.5 ); -} - -/// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int. -template -inline int float_to_integer( const Element& f ){ - return lrint( f ); -} - -/// \brief Returns \p f rounded to the nearest multiple of \p snap. -template -inline Element float_snapped( const Element& f, const OtherElement& snap ){ - //return Element(float_to_integer(f / snap) * snap); - if ( snap == 0 ) { - return f; - } - return Element( llrint( f / snap ) * snap ); // llrint has more significant bits -} - -/// \brief Returns true if \p f has no decimal fraction part. -template -inline bool float_is_integer( const Element& f ){ - return f == Element( float_to_integer( f ) ); -} - -/// \brief Returns \p self modulated by the range [0, \p modulus) -/// \p self must be in the range [\p -modulus, \p modulus) -template -inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){ - return Element( ( self < 0.0 ) ? self + modulus : self ); -} - -/// \brief Returns \p self modulated by the range [0, \p modulus) -template -inline Element float_mod( const Element& self, const ModulusElement& modulus ){ - return float_mod_range( Element( fmod( static_cast( self ), static_cast( modulus ) ) ), modulus ); -} - - -template -inline BasicVector2 vector2_added( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() + other.x() ), - Element( self.y() + other.y() ) - ); -} -template -inline BasicVector2 operator+( const BasicVector2& self, const BasicVector2& other ){ - return vector2_added( self, other ); -} -template -inline void vector2_add( BasicVector2& self, const BasicVector2& other ){ - self.x() += Element( other.x() ); - self.y() += Element( other.y() ); -} -template -inline void operator+=( BasicVector2& self, const BasicVector2& other ){ - vector2_add( self, other ); -} - - -template -inline BasicVector2 vector2_subtracted( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() - other.x() ), - Element( self.y() - other.y() ) - ); -} -template -inline BasicVector2 operator-( const BasicVector2& self, const BasicVector2& other ){ - return vector2_subtracted( self, other ); -} -template -inline void vector2_subtract( BasicVector2& self, const BasicVector2& other ){ - self.x() -= Element( other.x() ); - self.y() -= lement( other.y() ); -} -template -inline void operator-=( BasicVector2& self, const BasicVector2& other ){ - vector2_subtract( self, other ); -} - - -template -inline BasicVector2 vector2_scaled( const BasicVector2& self, OtherElement other ){ - return BasicVector2( - Element( self.x() * other ), - Element( self.y() * other ) - ); -} -template -inline BasicVector2 operator*( const BasicVector2& self, OtherElement other ){ - return vector2_scaled( self, other ); -} -template -inline void vector2_scale( BasicVector2& self, OtherElement other ){ - self.x() *= Element( other ); - self.y() *= Element( other ); -} -template -inline void operator*=( BasicVector2& self, OtherElement other ){ - vector2_scale( self, other ); -} - - -template -inline BasicVector2 vector2_scaled( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() * other.x() ), - Element( self.y() * other.y() ) - ); -} -template -inline BasicVector2 operator*( const BasicVector2& self, const BasicVector2& other ){ - return vector2_scaled( self, other ); -} -template -inline void vector2_scale( BasicVector2& self, const BasicVector2& other ){ - self.x() *= Element( other.x() ); - self.y() *= Element( other.y() ); -} -template -inline void operator*=( BasicVector2& self, const BasicVector2& other ){ - vector2_scale( self, other ); -} - -template -inline BasicVector2 vector2_divided( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() / other.x() ), - Element( self.y() / other.y() ) - ); -} -template -inline BasicVector2 operator/( const BasicVector2& self, const BasicVector2& other ){ - return vector2_divided( self, other ); -} -template -inline void vector2_divide( BasicVector2& self, const BasicVector2& other ){ - self.x() /= Element( other.x() ); - self.y() /= Element( other.y() ); -} -template -inline void operator/=( BasicVector2& self, const BasicVector2& other ){ - vector2_divide( self, other ); -} - - -template -inline BasicVector2 vector2_divided( const BasicVector2& self, OtherElement other ){ - return BasicVector2( - Element( self.x() / other ), - Element( self.y() / other ) - ); -} -template -inline BasicVector2 operator/( const BasicVector2& self, OtherElement other ){ - return vector2_divided( self, other ); -} -template -inline void vector2_divide( BasicVector2& self, OtherElement other ){ - self.x() /= Element( other ); - self.y() /= Element( other ); -} -template -inline void operator/=( BasicVector2& self, OtherElement other ){ - vector2_divide( self, other ); -} - -template -inline double vector2_dot( const BasicVector2& self, const BasicVector2& other ){ - return self.x() * other.x() + self.y() * other.y(); -} - -template -inline double vector2_length_squared( const BasicVector2& self ){ - return vector2_dot( self, self ); -} - -template -inline double vector2_length( const BasicVector2& self ){ - return sqrt( vector2_length_squared( self ) ); -} - -template -inline double vector2_cross( const BasicVector2& self, const BasicVector2& other ){ - return self.x() * other.y() - self.y() * other.x(); -} - -const Vector3 g_vector3_identity( 0, 0, 0 ); -const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX ); -const Vector3 g_vector3_axis_x( 1, 0, 0 ); -const Vector3 g_vector3_axis_y( 0, 1, 0 ); -const Vector3 g_vector3_axis_z( 0, 0, 1 ); - -const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z }; - -template -inline void vector3_swap( BasicVector3& self, BasicVector3& other ){ - std::swap( self.x(), other.x() ); - std::swap( self.y(), other.y() ); - std::swap( self.z(), other.z() ); -} - -template -inline bool vector3_equal( const BasicVector3& self, const BasicVector3& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} -template -inline bool operator==( const BasicVector3& self, const BasicVector3& other ){ - return vector3_equal( self, other ); -} -template -inline bool operator!=( const BasicVector3& self, const BasicVector3& other ){ - return !vector3_equal( self, other ); -} - - -template -inline bool vector3_equal_epsilon( const BasicVector3& self, const BasicVector3& other, Epsilon epsilon ){ - return float_equal_epsilon( self.x(), other.x(), epsilon ) - && float_equal_epsilon( self.y(), other.y(), epsilon ) - && float_equal_epsilon( self.z(), other.z(), epsilon ); -} - - - -template -inline BasicVector3 vector3_added( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() + other.x() ), - Element( self.y() + other.y() ), - Element( self.z() + other.z() ) - ); -} -template -inline BasicVector3 operator+( const BasicVector3& self, const BasicVector3& other ){ - return vector3_added( self, other ); -} -template -inline void vector3_add( BasicVector3& self, const BasicVector3& other ){ - self.x() += static_cast( other.x() ); - self.y() += static_cast( other.y() ); - self.z() += static_cast( other.z() ); -} -template -inline void operator+=( BasicVector3& self, const BasicVector3& other ){ - vector3_add( self, other ); -} - -template -inline BasicVector3 vector3_subtracted( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() - other.x() ), - Element( self.y() - other.y() ), - Element( self.z() - other.z() ) - ); -} -template -inline BasicVector3 operator-( const BasicVector3& self, const BasicVector3& other ){ - return vector3_subtracted( self, other ); -} -template -inline void vector3_subtract( BasicVector3& self, const BasicVector3& other ){ - self.x() -= static_cast( other.x() ); - self.y() -= static_cast( other.y() ); - self.z() -= static_cast( other.z() ); -} -template -inline void operator-=( BasicVector3& self, const BasicVector3& other ){ - vector3_subtract( self, other ); -} - -template -inline BasicVector3 vector3_scaled( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() * other.x() ), - Element( self.y() * other.y() ), - Element( self.z() * other.z() ) - ); -} -template -inline BasicVector3 operator*( const BasicVector3& self, const BasicVector3& other ){ - return vector3_scaled( self, other ); -} -template -inline void vector3_scale( BasicVector3& self, const BasicVector3& other ){ - self.x() *= static_cast( other.x() ); - self.y() *= static_cast( other.y() ); - self.z() *= static_cast( other.z() ); -} -template -inline void operator*=( BasicVector3& self, const BasicVector3& other ){ - vector3_scale( self, other ); -} - -template -inline BasicVector3 vector3_scaled( const BasicVector3& self, const OtherElement& scale ){ - return BasicVector3( - Element( self.x() * scale ), - Element( self.y() * scale ), - Element( self.z() * scale ) - ); -} -template -inline BasicVector3 operator*( const BasicVector3& self, const OtherElement& scale ){ - return vector3_scaled( self, scale ); -} -template -inline void vector3_scale( BasicVector3& self, const OtherElement& scale ){ - self.x() *= static_cast( scale ); - self.y() *= static_cast( scale ); - self.z() *= static_cast( scale ); -} -template -inline void operator*=( BasicVector3& self, const OtherElement& scale ){ - vector3_scale( self, scale ); -} - -template -inline BasicVector3 vector3_divided( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() / other.x() ), - Element( self.y() / other.y() ), - Element( self.z() / other.z() ) - ); -} -template -inline BasicVector3 operator/( const BasicVector3& self, const BasicVector3& other ){ - return vector3_divided( self, other ); -} -template -inline void vector3_divide( BasicVector3& self, const BasicVector3& other ){ - self.x() /= static_cast( other.x() ); - self.y() /= static_cast( other.y() ); - self.z() /= static_cast( other.z() ); -} -template -inline void operator/=( BasicVector3& self, const BasicVector3& other ){ - vector3_divide( self, other ); -} - -template -inline BasicVector3 vector3_divided( const BasicVector3& self, const OtherElement& divisor ){ - return BasicVector3( - Element( self.x() / divisor ), - Element( self.y() / divisor ), - Element( self.z() / divisor ) - ); -} -template -inline BasicVector3 operator/( const BasicVector3& self, const OtherElement& divisor ){ - return vector3_divided( self, divisor ); -} -template -inline void vector3_divide( BasicVector3& self, const OtherElement& divisor ){ - self.x() /= static_cast( divisor ); - self.y() /= static_cast( divisor ); - self.z() /= static_cast( divisor ); -} -template -inline void operator/=( BasicVector3& self, const OtherElement& divisor ){ - vector3_divide( self, divisor ); -} - -template -inline double vector3_dot( const BasicVector3& self, const BasicVector3& other ){ - return self.x() * other.x() + self.y() * other.y() + self.z() * other.z(); -} - -template -inline BasicVector3 vector3_mid( const BasicVector3& begin, const BasicVector3& end ){ - return vector3_scaled( vector3_added( begin, end ), 0.5 ); -} - -template -inline BasicVector3 vector3_cross( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.y() * other.z() - self.z() * other.y() ), - Element( self.z() * other.x() - self.x() * other.z() ), - Element( self.x() * other.y() - self.y() * other.x() ) - ); -} - -template -inline BasicVector3 vector3_negated( const BasicVector3& self ){ - return BasicVector3( -self.x(), -self.y(), -self.z() ); -} -template -inline BasicVector3 operator-( const BasicVector3& self ){ - return vector3_negated( self ); -} - -template -inline void vector3_negate( BasicVector3& self ){ - self = vector3_negated( self ); -} - -template -inline double vector3_length_squared( const BasicVector3& self ){ - return vector3_dot( self, self ); -} - -template -inline double vector3_length( const BasicVector3& self ){ - return sqrt( vector3_length_squared( self ) ); -} - -template -inline Element float_divided( Element f, Element other ){ - //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor"); - return f / other; -} - -template -inline BasicVector3 vector3_normalised( const BasicVector3& self ){ - return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) ); -} - -template -inline void vector3_normalise( BasicVector3& self ){ - self = vector3_normalised( self ); -} - - -template -inline BasicVector3 vector3_snapped( const BasicVector3& self ){ - return BasicVector3( - Element( float_to_integer( self.x() ) ), - Element( float_to_integer( self.y() ) ), - Element( float_to_integer( self.z() ) ) - ); -} -template -inline void vector3_snap( BasicVector3& self ){ - self = vector3_snapped( self ); -} -template -inline BasicVector3 vector3_snapped( const BasicVector3& self, const OtherElement& snap ){ - return BasicVector3( - Element( float_snapped( self.x(), snap ) ), - Element( float_snapped( self.y(), snap ) ), - Element( float_snapped( self.z(), snap ) ) - ); -} -template -inline void vector3_snap( BasicVector3& self, const OtherElement& snap ){ - self = vector3_snapped( self, snap ); -} - -inline Vector3 vector3_for_spherical( double theta, double phi ){ - return Vector3( - static_cast( cos( theta ) * cos( phi ) ), - static_cast( sin( theta ) * cos( phi ) ), - static_cast( sin( phi ) ) - ); -} - - - - -template -inline bool vector4_equal( const BasicVector4& self, const BasicVector4& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w(); -} -template -inline bool operator==( const BasicVector4& self, const BasicVector4& other ){ - return vector4_equal( self, other ); -} -template -inline bool operator!=( const BasicVector4& self, const BasicVector4& other ){ - return !vector4_equal( self, other ); -} - -template -inline bool vector4_equal_epsilon( const BasicVector4& self, const BasicVector4& other, Element epsilon ){ - return float_equal_epsilon( self.x(), other.x(), epsilon ) - && float_equal_epsilon( self.y(), other.y(), epsilon ) - && float_equal_epsilon( self.z(), other.z(), epsilon ) - && float_equal_epsilon( self.w(), other.w(), epsilon ); -} -template -inline BasicVector4 vector4_mid( const BasicVector4& begin, const BasicVector4& end ){ - return vector4_scaled( vector4_added( begin, end ), 0.5 ); -} - -template -inline BasicVector4 vector4_added( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() + other.x() ), - float(self.y() + other.y() ), - float(self.z() + other.z() ), - float(self.w() + other.w() ) - ); -} -template -inline BasicVector4 operator+( const BasicVector4& self, const BasicVector4& other ){ - return vector4_added( self, other ); -} -template -inline void vector4_add( BasicVector4& self, const BasicVector4& other ){ - self.x() += static_cast( other.x() ); - self.y() += static_cast( other.y() ); - self.z() += static_cast( other.z() ); - self.w() += static_cast( other.w() ); -} -template -inline void operator+=( BasicVector4& self, const BasicVector4& other ){ - vector4_add( self, other ); -} - -template -inline BasicVector4 vector4_subtracted( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() - other.x() ), - float(self.y() - other.y() ), - float(self.z() - other.z() ), - float(self.w() - other.w() ) - ); -} -template -inline BasicVector4 operator-( const BasicVector4& self, const BasicVector4& other ){ - return vector4_subtracted( self, other ); -} -template -inline void vector4_subtract( BasicVector4& self, const BasicVector4& other ){ - self.x() -= static_cast( other.x() ); - self.y() -= static_cast( other.y() ); - self.z() -= static_cast( other.z() ); - self.w() -= static_cast( other.w() ); -} -template -inline void operator-=( BasicVector4& self, const BasicVector4& other ){ - vector4_subtract( self, other ); -} - -template -inline BasicVector4 vector4_scaled( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() * other.x() ), - float(self.y() * other.y() ), - float(self.z() * other.z() ), - float(self.w() * other.w() ) - ); -} -template -inline BasicVector4 operator*( const BasicVector4& self, const BasicVector4& other ){ - return vector4_scaled( self, other ); -} -template -inline void vector4_scale( BasicVector4& self, const BasicVector4& other ){ - self.x() *= static_cast( other.x() ); - self.y() *= static_cast( other.y() ); - self.z() *= static_cast( other.z() ); - self.w() *= static_cast( other.w() ); -} -template -inline void operator*=( BasicVector4& self, const BasicVector4& other ){ - vector4_scale( self, other ); -} - -template -inline BasicVector4 vector4_scaled( const BasicVector4& self, OtherElement scale ){ - return BasicVector4( - float(self.x() * scale), - float(self.y() * scale), - float(self.z() * scale), - float(self.w() * scale) - ); -} -template -inline BasicVector4 operator*( const BasicVector4& self, OtherElement scale ){ - return vector4_scaled( self, scale ); -} -template -inline void vector4_scale( BasicVector4& self, OtherElement scale ){ - self.x() *= static_cast( scale ); - self.y() *= static_cast( scale ); - self.z() *= static_cast( scale ); - self.w() *= static_cast( scale ); -} -template -inline void operator*=( BasicVector4& self, OtherElement scale ){ - vector4_scale( self, scale ); -} - -template -inline BasicVector4 vector4_divided( const BasicVector4& self, OtherElement divisor ){ - return BasicVector4( - float(self.x() / divisor), - float(self.y() / divisor), - float(self.z() / divisor), - float(self.w() / divisor) - ); -} -template -inline BasicVector4 operator/( const BasicVector4& self, OtherElement divisor ){ - return vector4_divided( self, divisor ); -} -template -inline void vector4_divide( BasicVector4& self, OtherElement divisor ){ - self.x() /= divisor; - self.y() /= divisor; - self.z() /= divisor; - self.w() /= divisor; -} -template -inline void operator/=( BasicVector4& self, OtherElement divisor ){ - vector4_divide( self, divisor ); -} - -template -inline double vector4_dot( const BasicVector4& self, const BasicVector4& other ){ - return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w(); -} - -template -inline BasicVector3 vector4_projected( const BasicVector4& self ){ - return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] ); -} - -#endif diff --git a/libs/md5lib/md5lib.c b/libs/md5lib/md5lib.c deleted file mode 100644 index d71a36f..0000000 --- a/libs/md5lib/md5lib.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5lib.c,v 1.1 2003/07/18 04:24:39 ydnar Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2003-07-17 ydnar added to gtkradiant project from - http://sourceforge.net/projects/libmd5-rfc/ - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5lib.h" /* ydnar */ -#include "globaldefs.h" -#include - -#if GDEF_ARCH_ENDIAN_BIG -#define ARCH_IS_BIG_ENDIAN 1 -#else -#define ARCH_IS_BIG_ENDIAN 0 -#endif -/* ydnar: end */ - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#define BYTE_ORDER ( ARCH_IS_BIG_ENDIAN ? 1 : -1 ) - -#define T_MASK ( ( md5_word_t ) ~0 ) -#define T1 /* 0xd76aa478 */ ( T_MASK ^ 0x28955b87 ) -#define T2 /* 0xe8c7b756 */ ( T_MASK ^ 0x173848a9 ) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ ( T_MASK ^ 0x3e423111 ) -#define T5 /* 0xf57c0faf */ ( T_MASK ^ 0x0a83f050 ) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ ( T_MASK ^ 0x57cfb9ec ) -#define T8 /* 0xfd469501 */ ( T_MASK ^ 0x02b96afe ) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ ( T_MASK ^ 0x74bb0850 ) -#define T11 /* 0xffff5bb1 */ ( T_MASK ^ 0x0000a44e ) -#define T12 /* 0x895cd7be */ ( T_MASK ^ 0x76a32841 ) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ ( T_MASK ^ 0x02678e6c ) -#define T15 /* 0xa679438e */ ( T_MASK ^ 0x5986bc71 ) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ ( T_MASK ^ 0x09e1da9d ) -#define T18 /* 0xc040b340 */ ( T_MASK ^ 0x3fbf4cbf ) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ ( T_MASK ^ 0x16493855 ) -#define T21 /* 0xd62f105d */ ( T_MASK ^ 0x29d0efa2 ) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ ( T_MASK ^ 0x275e197e ) -#define T24 /* 0xe7d3fbc8 */ ( T_MASK ^ 0x182c0437 ) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ ( T_MASK ^ 0x3cc8f829 ) -#define T27 /* 0xf4d50d87 */ ( T_MASK ^ 0x0b2af278 ) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ ( T_MASK ^ 0x561c16fa ) -#define T30 /* 0xfcefa3f8 */ ( T_MASK ^ 0x03105c07 ) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ ( T_MASK ^ 0x72d5b375 ) -#define T33 /* 0xfffa3942 */ ( T_MASK ^ 0x0005c6bd ) -#define T34 /* 0x8771f681 */ ( T_MASK ^ 0x788e097e ) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ ( T_MASK ^ 0x021ac7f3 ) -#define T37 /* 0xa4beea44 */ ( T_MASK ^ 0x5b4115bb ) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ ( T_MASK ^ 0x0944b49f ) -#define T40 /* 0xbebfbc70 */ ( T_MASK ^ 0x4140438f ) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ ( T_MASK ^ 0x155ed805 ) -#define T43 /* 0xd4ef3085 */ ( T_MASK ^ 0x2b10cf7a ) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ ( T_MASK ^ 0x262b2fc6 ) -#define T46 /* 0xe6db99e5 */ ( T_MASK ^ 0x1924661a ) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ ( T_MASK ^ 0x3b53a99a ) -#define T49 /* 0xf4292244 */ ( T_MASK ^ 0x0bd6ddbb ) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ ( T_MASK ^ 0x546bdc58 ) -#define T52 /* 0xfc93a039 */ ( T_MASK ^ 0x036c5fc6 ) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ ( T_MASK ^ 0x70f3336d ) -#define T55 /* 0xffeff47d */ ( T_MASK ^ 0x00100b82 ) -#define T56 /* 0x85845dd1 */ ( T_MASK ^ 0x7a7ba22e ) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ ( T_MASK ^ 0x01d3191f ) -#define T59 /* 0xa3014314 */ ( T_MASK ^ 0x5cfebceb ) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ ( T_MASK ^ 0x08ac817d ) -#define T62 /* 0xbd3af235 */ ( T_MASK ^ 0x42c50dca ) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ ( T_MASK ^ 0x14792c6e ) - - -static void -md5_process( md5_state_t *pms, const md5_byte_t *data /*[64]*/ ){ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if ( *( (const md5_byte_t *)&w ) ) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if ( !( ( data - (const md5_byte_t *)0 ) & 3 ) ) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } - else { - /* not aligned */ - memcpy( xbuf, data, 64 ); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -#if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -#else -#define xbuf X /* (static only) */ -#endif - for ( i = 0; i < 16; ++i, xp += 4 ) - xbuf[i] = xp[0] + ( xp[1] << 8 ) + ( xp[2] << 16 ) + ( xp[3] << 24 ); - } -#endif - } - -#define ROTATE_LEFT( x, n ) ( ( ( x ) << ( n ) ) | ( ( x ) >> ( 32 - ( n ) ) ) ) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F( x, y, z ) ( ( ( x ) & ( y ) ) | ( ~( x ) & ( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + F( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 0, 7, T1 ); - SET( d, a, b, c, 1, 12, T2 ); - SET( c, d, a, b, 2, 17, T3 ); - SET( b, c, d, a, 3, 22, T4 ); - SET( a, b, c, d, 4, 7, T5 ); - SET( d, a, b, c, 5, 12, T6 ); - SET( c, d, a, b, 6, 17, T7 ); - SET( b, c, d, a, 7, 22, T8 ); - SET( a, b, c, d, 8, 7, T9 ); - SET( d, a, b, c, 9, 12, T10 ); - SET( c, d, a, b, 10, 17, T11 ); - SET( b, c, d, a, 11, 22, T12 ); - SET( a, b, c, d, 12, 7, T13 ); - SET( d, a, b, c, 13, 12, T14 ); - SET( c, d, a, b, 14, 17, T15 ); - SET( b, c, d, a, 15, 22, T16 ); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G( x, y, z ) ( ( ( x ) & ( z ) ) | ( ( y ) & ~( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + G( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 1, 5, T17 ); - SET( d, a, b, c, 6, 9, T18 ); - SET( c, d, a, b, 11, 14, T19 ); - SET( b, c, d, a, 0, 20, T20 ); - SET( a, b, c, d, 5, 5, T21 ); - SET( d, a, b, c, 10, 9, T22 ); - SET( c, d, a, b, 15, 14, T23 ); - SET( b, c, d, a, 4, 20, T24 ); - SET( a, b, c, d, 9, 5, T25 ); - SET( d, a, b, c, 14, 9, T26 ); - SET( c, d, a, b, 3, 14, T27 ); - SET( b, c, d, a, 8, 20, T28 ); - SET( a, b, c, d, 13, 5, T29 ); - SET( d, a, b, c, 2, 9, T30 ); - SET( c, d, a, b, 7, 14, T31 ); - SET( b, c, d, a, 12, 20, T32 ); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H( x, y, z ) ( ( x ) ^ ( y ) ^ ( z ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + H( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 5, 4, T33 ); - SET( d, a, b, c, 8, 11, T34 ); - SET( c, d, a, b, 11, 16, T35 ); - SET( b, c, d, a, 14, 23, T36 ); - SET( a, b, c, d, 1, 4, T37 ); - SET( d, a, b, c, 4, 11, T38 ); - SET( c, d, a, b, 7, 16, T39 ); - SET( b, c, d, a, 10, 23, T40 ); - SET( a, b, c, d, 13, 4, T41 ); - SET( d, a, b, c, 0, 11, T42 ); - SET( c, d, a, b, 3, 16, T43 ); - SET( b, c, d, a, 6, 23, T44 ); - SET( a, b, c, d, 9, 4, T45 ); - SET( d, a, b, c, 12, 11, T46 ); - SET( c, d, a, b, 15, 16, T47 ); - SET( b, c, d, a, 2, 23, T48 ); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I( x, y, z ) ( ( y ) ^ ( ( x ) | ~( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + I( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 0, 6, T49 ); - SET( d, a, b, c, 7, 10, T50 ); - SET( c, d, a, b, 14, 15, T51 ); - SET( b, c, d, a, 5, 21, T52 ); - SET( a, b, c, d, 12, 6, T53 ); - SET( d, a, b, c, 3, 10, T54 ); - SET( c, d, a, b, 10, 15, T55 ); - SET( b, c, d, a, 1, 21, T56 ); - SET( a, b, c, d, 8, 6, T57 ); - SET( d, a, b, c, 15, 10, T58 ); - SET( c, d, a, b, 6, 15, T59 ); - SET( b, c, d, a, 13, 21, T60 ); - SET( a, b, c, d, 4, 6, T61 ); - SET( d, a, b, c, 11, 10, T62 ); - SET( c, d, a, b, 2, 15, T63 ); - SET( b, c, d, a, 9, 21, T64 ); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init( md5_state_t *pms ){ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append( md5_state_t *pms, const md5_byte_t *data, int nbytes ){ - const md5_byte_t *p = data; - int left = nbytes; - int offset = ( pms->count[0] >> 3 ) & 63; - md5_word_t nbits = (md5_word_t)( nbytes << 3 ); - - if ( nbytes <= 0 ) { - return; - } - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if ( pms->count[0] < nbits ) { - pms->count[1]++; - } - - /* Process an initial partial block. */ - if ( offset ) { - int copy = ( offset + nbytes > 64 ? 64 - offset : nbytes ); - - memcpy( pms->buf + offset, p, copy ); - if ( offset + copy < 64 ) { - return; - } - p += copy; - left -= copy; - md5_process( pms, pms->buf ); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64 ) - md5_process( pms, p ); - - /* Process a final partial block. */ - if ( left ) { - memcpy( pms->buf, p, left ); - } -} - -void -md5_finish( md5_state_t *pms, md5_byte_t digest[16] ){ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for ( i = 0; i < 8; ++i ) - data[i] = (md5_byte_t)( pms->count[i >> 2] >> ( ( i & 3 ) << 3 ) ); - /* Pad to 56 bytes mod 64. */ - md5_append( pms, pad, ( ( 55 - ( pms->count[0] >> 3 ) ) & 63 ) + 1 ); - /* Append the length. */ - md5_append( pms, data, 8 ); - for ( i = 0; i < 16; ++i ) - digest[i] = (md5_byte_t)( pms->abcd[i >> 2] >> ( ( i & 3 ) << 3 ) ); -} diff --git a/libs/memory/Makefile b/libs/memory/Makefile deleted file mode 100644 index 410b36f..0000000 --- a/libs/memory/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - allocator.o - -# binary target -../libmemory.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -allocator.o: allocator.cpp allocator.h - -clean: - -rm -f *.o ../libmemory.a diff --git a/libs/memory/allocator.cpp b/libs/memory/allocator.cpp deleted file mode 100644 index 0e4decf..0000000 --- a/libs/memory/allocator.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "memory/allocator.h" - -#include - -template -struct Vector -{ - typedef std::vector > Type; -}; - -namespace -{ -class Bleh -{ -int* m_blah; -public: -Bleh( int* blah ) : m_blah( blah ){ -} -~Bleh(){ - *m_blah = 15; -} -}; - -void TestAllocator(){ - Vector::Type test; - - int i = 0; - test.push_back( Bleh( &i ) ); -} - -void TestNewDelete(){ - { - NamedAllocator allocator( "test" ); - int* p = NamedNew::type( allocator ).scalar(); - //new int(); - NamedDelete::type( allocator ).scalar( p ); - } - - { - int* p = New().scalar( 3 ); - Delete().scalar( p ); - } - - { - int* p = New().scalar( int(15.9) ); - Delete().scalar( p ); - } - - { - int* p = New().vector( 15 ); - // new int[15] - Delete().vector( p, 15 ); - } -} -} \ No newline at end of file diff --git a/libs/memory/allocator.h b/libs/memory/allocator.h deleted file mode 100644 index 845ce14..0000000 --- a/libs/memory/allocator.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MEMORY_ALLOCATOR_H ) -#define INCLUDED_MEMORY_ALLOCATOR_H - -#include -#include - -#if 0 - -#define DefaultAllocator std::allocator - -#else - -/// \brief An allocator that uses c++ new/delete. -/// Compliant with the std::allocator interface. -template -class DefaultAllocator -{ -public: - -typedef Type value_type; -typedef value_type* pointer; -typedef const Type* const_pointer; -typedef Type& reference; -typedef const Type& const_reference; -typedef size_t size_type; -typedef ptrdiff_t difference_type; - -template -struct rebind -{ - typedef DefaultAllocator other; -}; - -DefaultAllocator(){ -} -DefaultAllocator( const DefaultAllocator& ){ -} -template DefaultAllocator( const DefaultAllocator& ){ -} -~DefaultAllocator(){ -} - -pointer address( reference instance ) const { - return &instance; -} -const_pointer address( const_reference instance ) const { - return &instance; -} -Type* allocate( size_type size, const void* = 0 ){ - return static_cast( ::operator new( size * sizeof( Type ) ) ); -} -void deallocate( pointer p, size_type ){ - ::operator delete( p ); -} -size_type max_size() const { - return std::size_t( -1 ) / sizeof( Type ); -} -void construct( pointer p, const Type& value ){ - new(p) Type( value ); -} -void destroy( pointer p ){ - p->~Type(); -} -}; - -template -inline bool operator==( const DefaultAllocator&, const DefaultAllocator& ){ - return true; -} -template -inline bool operator==( const DefaultAllocator&, const OtherAllocator& ){ - return false; -} - -#endif - - -template -class NamedAllocator : public DefaultAllocator -{ -typedef DefaultAllocator allocator_type; - -const char* m_name; -public: - -typedef Type value_type; -typedef value_type* pointer; -typedef const Type* const_pointer; -typedef Type& reference; -typedef const Type& const_reference; -typedef size_t size_type; -typedef ptrdiff_t difference_type; - -template -struct rebind -{ - typedef NamedAllocator other; -}; - -explicit NamedAllocator( const char* name ) : DefaultAllocator(), m_name( name ){ -} -NamedAllocator( const NamedAllocator& other ) : DefaultAllocator(), m_name( other.m_name ){ -} -template NamedAllocator( const NamedAllocator& other ) : DefaultAllocator(), m_name( other.m_name ){ -} -~NamedAllocator(){ -} - -pointer address( reference instance ) const { - return allocator_type::address( instance ); -} -const_pointer address( const_reference instance ) const { - return allocator_type::address( instance ); -} -Type* allocate( size_type size, const void* = 0 ){ - return allocator_type::allocate( size ); -} -void deallocate( pointer p, size_type size ){ - allocator_type::deallocate( p, size ); -} -size_type max_size() const { - return allocator_type::max_size(); -} -void construct( pointer p, const Type& value ){ - allocator_type::construct( p, value ); -} -void destroy( pointer p ){ - allocator_type::destroy( p ); -} - -template -bool operator==( const NamedAllocator& other ){ - return true; -} - -// returns true if the allocators are not interchangeable -template -bool operator!=( const NamedAllocator& other ){ - return false; -} -}; - - - -#include -#include "generic/object.h" - - - -template -class DefaultConstruct -{ -public: -void operator()( Type& t ){ - constructor( t ); -} -}; - -template -class Construct -{ -const T1& other; -public: -Construct( const T1& other_ ) : other( other_ ){ -} -void operator()( Type& t ){ - constructor( t, other ); -} -}; - -template -class Destroy -{ -public: -void operator()( Type& t ){ - destructor( t ); -} -}; - -template > -class New : public Allocator -{ -public: -New(){ -} -explicit New( const Allocator& allocator ) : Allocator( allocator ){ -} - -Type* scalar(){ - return new( Allocator::allocate( 1 ) )Type(); -} -template -Type* scalar( const T1& t1 ){ - return new( Allocator::allocate( 1 ) )Type( t1 ); -} -template -Type* scalar( const T1& t1, const T2& t2 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3, const T4& t4 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3, t4 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3, t4, t5 ); -} -Type* vector( std::size_t size ){ -#if 1 - Type* p = Allocator::allocate( size ); - std::for_each( p, p + size, DefaultConstruct() ); - return p; -#else - // this does not work with msvc71 runtime - return new( Allocator::allocate( size ) )Type[size]; -#endif -} -template -Type* vector( std::size_t size, const T1& t1 ){ - Type* p = Allocator::allocate( size ); - std::for_each( p, p + size, Construct( t1 ) ); - return p; -} -}; - -template > -class Delete : public Allocator -{ -public: -Delete(){ -} -explicit Delete( const Allocator& allocator ) : Allocator( allocator ){ -} - -void scalar( Type* p ){ - if ( p != 0 ) { - p->~Type(); - Allocator::deallocate( p, 1 ); - } -} -void vector( Type* p, std::size_t size ){ - // '::operator delete' handles null - // 'std::allocator::deallocate' requires non-null - if ( p != 0 ) { - std::for_each( p, p + size, Destroy() ); - Allocator::deallocate( p, size ); - } -} -}; - - -template -class NamedNew -{ -public: -typedef New > type; -}; - -template -class NamedDelete -{ -public: -typedef Delete > type; -}; - -#endif diff --git a/libs/moduleobservers.h b/libs/moduleobservers.h deleted file mode 100644 index 1ee91e2..0000000 --- a/libs/moduleobservers.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULEOBSERVERS_H ) -#define INCLUDED_MODULEOBSERVERS_H - -#include "debugging/debugging.h" -#include -#include "moduleobserver.h" - -class ModuleObservers -{ -typedef std::set Observers; -Observers m_observers; -public: -~ModuleObservers(){ - ASSERT_MESSAGE( m_observers.empty(), "ModuleObservers::~ModuleObservers: observers still attached" ); -} -void attach( ModuleObserver& observer ){ - ASSERT_MESSAGE( m_observers.find( &observer ) == m_observers.end(), "ModuleObservers::attach: cannot attach observer" ); - m_observers.insert( &observer ); -} -void detach( ModuleObserver& observer ){ - ASSERT_MESSAGE( m_observers.find( &observer ) != m_observers.end(), "ModuleObservers::detach: cannot detach observer" ); - m_observers.erase( &observer ); -} -void realise(){ - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->realise(); - } -} -void unrealise(){ - for ( Observers::reverse_iterator i = m_observers.rbegin(); i != m_observers.rend(); ++i ) - { - ( *i )->unrealise(); - } -} -}; - -#endif diff --git a/libs/modulesystem/Makefile b/libs/modulesystem/Makefile deleted file mode 100644 index 0eb7f27..0000000 --- a/libs/modulesystem/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - singletonmodule.o - -# binary target -../libmodulesystem.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -singletonmodule.o: singletonmodule.cpp singletonmodule.h moduleregistry.h modulesmap.h - -clean: - -rm -f *.o ../libmodulesystem.a diff --git a/libs/modulesystem/moduleregistry.h b/libs/modulesystem/moduleregistry.h deleted file mode 100644 index abea5a0..0000000 --- a/libs/modulesystem/moduleregistry.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_MODULEREGISTRY_H ) -#define INCLUDED_MODULESYSTEM_MODULEREGISTRY_H - -#include "generic/static.h" -#include - -class ModuleRegisterable -{ -public: -virtual void selfRegister() = 0; -}; - -class ModuleRegistryList -{ -typedef std::list RegisterableModules; -RegisterableModules m_modules; -public: -void addModule( ModuleRegisterable& module ){ - m_modules.push_back( &module ); -} -void registerModules() const { - for ( RegisterableModules::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - ( *i )->selfRegister(); - } -} -}; - -typedef SmartStatic StaticModuleRegistryList; - - -class StaticRegisterModule : public StaticModuleRegistryList -{ -public: -StaticRegisterModule( ModuleRegisterable& module ){ - StaticModuleRegistryList::instance().addModule( module ); -} -}; - - -#endif diff --git a/libs/modulesystem/modulesmap.h b/libs/modulesystem/modulesmap.h deleted file mode 100644 index a48a083..0000000 --- a/libs/modulesystem/modulesmap.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_MODULESMAP_H ) -#define INCLUDED_MODULESYSTEM_MODULESMAP_H - -#include "modulesystem.h" -#include "string/string.h" -#include -#include - -template -class ModulesMap : public Modules -{ -typedef std::map modules_t; -modules_t m_modules; -public: -~ModulesMap(){ - for ( modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - ( *i ).second->release(); - } -} - -typedef modules_t::const_iterator iterator; - -iterator begin() const { - return m_modules.begin(); -} -iterator end() const { - return m_modules.end(); -} - -void insert( const char* name, Module& module ){ - module.capture(); - if ( globalModuleServer().getError() ) { - module.release(); - globalModuleServer().setError( false ); - } - else - { - m_modules.insert( modules_t::value_type( name, &module ) ); - } -} - -Type* find( const char* name ){ - modules_t::iterator i = m_modules.find( name ); - if ( i != m_modules.end() ) { - return static_cast( Module_getTable( *( *i ).second ) ); - } - return 0; -} - -Type* findModule( const char* name ){ - return find( name ); -} -void foreachModule( const typename Modules::Visitor& visitor ){ - for ( modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - visitor.visit( ( *i ).first.c_str(), *static_cast( Module_getTable( *( *i ).second ) ) ); - } -} -}; - -template -class InsertModules : public ModuleServer::Visitor -{ -ModulesMap& m_modules; -public: -InsertModules( ModulesMap& modules ) - : m_modules( modules ){ -} -void visit( const char* name, Module& module ) const { - m_modules.insert( name, module ); -} -}; - -template -class ModulesRef -{ -ModulesMap m_modules; -public: -ModulesRef( const char* names ){ - if ( !globalModuleServer().getError() ) { - if ( string_equal( names, "*" ) ) { - InsertModules visitor( m_modules ); - globalModuleServer().foreachModule( typename Type::Name(), typename Type::Version(), visitor ); - } - else - { - StringTokeniser tokeniser( names ); - for (;; ) - { - const char* name = tokeniser.getToken(); - if ( string_empty( name ) ) { - break; - } - Module* module = globalModuleServer().findModule( typename Type::Name(), typename Type::Version(), name ); - if ( module == 0 ) { - globalModuleServer().setError( true ); - globalErrorStream() << "ModulesRef::initialise: type=" << makeQuoted( typename Type::Name() ) << " version=" << makeQuoted( typename Type::Version() ) << " name=" << makeQuoted( name ) << " - not found\n"; - break; - } - else - { - m_modules.insert( name, *module ); - } - } - } - } -} -ModulesMap& get(){ - return m_modules; -} -}; - -#endif diff --git a/libs/modulesystem/singletonmodule.cpp b/libs/modulesystem/singletonmodule.cpp deleted file mode 100644 index 207051a..0000000 --- a/libs/modulesystem/singletonmodule.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "singletonmodule.h" -#include "generic/constant.h" - -class NullType -{ -public: -INTEGER_CONSTANT( Version, 1 ); -STRING_CONSTANT( Name, "" ); -}; - -class NullModule -{ -public: -typedef NullType Type; -STRING_CONSTANT( Name, "" ); -void* getTable(){ - return NULL; -} -}; - -void TEST_SINGLETONMODULE(){ - SingletonModule null; - null.capture(); - null.release(); -} diff --git a/libs/modulesystem/singletonmodule.h b/libs/modulesystem/singletonmodule.h deleted file mode 100644 index 6dd9c52..0000000 --- a/libs/modulesystem/singletonmodule.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_SINGLETONMODULE_H ) -#define INCLUDED_MODULESYSTEM_SINGLETONMODULE_H - -#include "modulesystem.h" -#include -#include "debugging/debugging.h" -#include "modulesystem/moduleregistry.h" -#include "generic/reference.h" - -template -class DefaultAPIConstructor -{ -public: -const char* getName(){ - return typename API::Name(); -} - -API* constructAPI( Dependencies& dependencies ){ - return new API; -} -void destroyAPI( API* api ){ - delete api; -} -}; - -template -class DependenciesAPIConstructor -{ -public: -const char* getName(){ - return typename API::Name(); -} - -API* constructAPI( Dependencies& dependencies ){ - return new API( dependencies ); -} -void destroyAPI( API* api ){ - delete api; -} -}; - -class NullDependencies -{ -}; - - -template > -class SingletonModule : public APIConstructor, public Module, public ModuleRegisterable -{ -Dependencies* m_dependencies; -API* m_api; -std::size_t m_refcount; -bool m_dependencyCheck; -bool m_cycleCheck; -public: -typedef typename API::Type Type; - -SingletonModule() - : m_dependencies( 0 ), m_api( 0 ), m_refcount( 0 ), m_dependencyCheck( false ), m_cycleCheck( false ){ -} -explicit SingletonModule( const APIConstructor& constructor ) - : APIConstructor( constructor ), m_dependencies( 0 ), m_api( 0 ), m_refcount( 0 ), m_dependencyCheck( false ), m_cycleCheck( false ){ -} -~SingletonModule(){ - ASSERT_MESSAGE( m_refcount == 0, "module still referenced at shutdown" ); -} - -void selfRegister(){ - globalModuleServer().registerModule( typename Type::Name(), typename Type::Version(), APIConstructor::getName(), *this ); -} - -Dependencies& getDependencies(){ - return *m_dependencies; -} -void* getTable(){ - if ( m_api != 0 ) { - return m_api->getTable(); - } - return 0; -} -void capture(){ - if ( ++m_refcount == 1 ) { - globalOutputStream() << "Module Initialising: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - m_dependencies = new Dependencies(); - m_dependencyCheck = !globalModuleServer().getError(); - if ( m_dependencyCheck ) { - m_api = APIConstructor::constructAPI( *m_dependencies ); - globalOutputStream() << "Module Ready: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - } - else - { - globalOutputStream() << "Module Dependencies Failed: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - } - m_cycleCheck = true; - } - - ASSERT_MESSAGE( m_cycleCheck, "cyclic dependency detected" ); -} -void release(){ - if ( --m_refcount == 0 ) { - if ( m_dependencyCheck ) { - APIConstructor::destroyAPI( m_api ); - } - delete m_dependencies; - } -} -}; - - -#endif diff --git a/libs/os/Makefile b/libs/os/Makefile deleted file mode 100644 index 473f1cc..0000000 --- a/libs/os/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libos.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp dir.h file.h path.h - -clean: - -rm -f *.o ../libos.a diff --git a/libs/os/_.cpp b/libs/os/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/os/dir.h b/libs/os/dir.h deleted file mode 100644 index b199284..0000000 --- a/libs/os/dir.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_OS_DIR_H ) -#define INCLUDED_OS_DIR_H - -/// \file -/// \brief OS directory-listing object. - -#include - -typedef GDir Directory; - -inline bool directory_good( Directory* directory ){ - return directory != 0; -} - -inline Directory* directory_open( const char* name ){ - return g_dir_open( name, 0, 0 ); -} - -inline void directory_close( Directory* directory ){ - g_dir_close( directory ); -} - -inline const char* directory_read_and_increment( Directory* directory ){ - return g_dir_read_name( directory ); -} - -template -void Directory_forEach( const char* path, const Functor& functor ){ - Directory* dir = directory_open( path ); - - if ( directory_good( dir ) ) { - for (;; ) - { - const char* name = directory_read_and_increment( dir ); - if ( name == 0 ) { - break; - } - - functor( name ); - } - - directory_close( dir ); - } -} - - -#endif diff --git a/libs/os/file.h b/libs/os/file.h deleted file mode 100644 index 144627e..0000000 --- a/libs/os/file.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_OS_FILE_H ) -#define INCLUDED_OS_FILE_H - -#include "globaldefs.h" - -/// \file -/// \brief OS file-system querying and manipulation. - -#if GDEF_OS_WINDOWS -#define S_ISDIR( mode ) ( mode & _S_IFDIR ) -#include // _access() -#define access( path, mode ) _access( path, mode ) -#else -#include // access() -#endif - -#include // rename(), remove() -#include // stat() -#include // this is included by stat.h on win32 -#include -#include - -#include "debugging/debugging.h" - -/// \brief Attempts to move the file identified by \p from to \p to and returns true if the operation was successful. -/// -/// The operation will fail unless: -/// - The path \p from identifies an existing file which is accessible for writing. -/// - The directory component of \p from identifies an existing directory which is accessible for writing. -/// - The path \p to does not identify an existing file or directory. -/// - The directory component of \p to identifies an existing directory which is accessible for writing. -inline bool file_move( const char* from, const char* to ){ - ASSERT_MESSAGE( from != 0 && to != 0, "file_move: invalid path" ); - return rename( from, to ) == 0; -} - -/// \brief Attempts to remove the file identified by \p path and returns true if the operation was successful. -/// -/// The operation will fail unless: -/// - The \p path identifies an existing file. -/// - The parent-directory component of \p path identifies an existing directory which is accessible for writing. -inline bool file_remove( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_remove: invalid path" ); - return remove( path ) == 0; -} - -namespace FileAccess -{ -enum Mode -{ - Read = R_OK, - Write = W_OK, - ReadWrite = Read | Write, - Exists = F_OK -}; -} - -/// \brief Returns true if the file or directory identified by \p path exists and/or may be accessed for reading, writing or both, depending on the value of \p mode. -inline bool file_accessible( const char* path, FileAccess::Mode mode ){ - ASSERT_MESSAGE( path != 0, "file_accessible: invalid path" ); - return access( path, static_cast( mode ) ) == 0; -} - -/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading. -inline bool file_readable( const char* path ){ - return file_accessible( path, FileAccess::Read ); -} - -/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing. -inline bool file_writeable( const char* path ){ - return file_accessible( path, FileAccess::Write ); -} - -/// \brief Returns true if the file or directory identified by \p path exists. -inline bool file_exists( const char* path ){ - return file_accessible( path, FileAccess::Exists ); -} - -/// \brief Returns true if the file or directory identified by \p path exists and is a directory. -inline bool file_is_directory( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_is_directory: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return false; - } - return S_ISDIR( st.st_mode ) != 0; -} - -typedef std::size_t FileSize; - -/// \brief Returns the size in bytes of the file identified by \p path, or 0 if the file was not found. -inline FileSize file_size( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_size: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return 0; - } - return st.st_size; -} - -/// Seconds elapsed since Jan 1, 1970 -typedef std::time_t FileTime; -/// No file can have been modified earlier than this time. -const FileTime c_invalidFileTime = -1; - -/// \brief Returns the time that the file identified by \p path was last modified, or c_invalidFileTime if the file was not found. -inline FileTime file_modified( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_modified: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return c_invalidFileTime; - } - return st.st_mtime; -} - - - -#endif diff --git a/libs/os/path.h b/libs/os/path.h deleted file mode 100644 index 5b87a4d..0000000 --- a/libs/os/path.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_OS_PATH_H ) -#define INCLUDED_OS_PATH_H - -#include "globaldefs.h" - -/// \file -/// \brief OS file-system path comparison, decomposition and manipulation. -/// -/// - Paths are c-style null-terminated-character-arrays. -/// - Path separators must be forward slashes (unix style). -/// - Directory paths must end in a separator. -/// - Paths must not contain the ascii characters \\ : * ? " < > or |. -/// - Paths may be encoded in UTF-8 or any extended-ascii character set. - -#include "string/string.h" - -#if GDEF_OS_WINDOWS -#define OS_CASE_INSENSITIVE -#endif - -/// \brief Returns true if \p path is lexicographically sorted before \p other. -/// If both \p path and \p other refer to the same file, neither will be sorted before the other. -/// O(n) -inline bool path_less( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_less_nocase( path, other ); -#else - return string_less( path, other ); -#endif -} - -/// \brief Returns <0 if \p path is lexicographically less than \p other. -/// Returns >0 if \p path is lexicographically greater than \p other. -/// Returns 0 if both \p path and \p other refer to the same file. -/// O(n) -inline int path_compare( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_compare_nocase( path, other ); -#else - return string_compare( path, other ); -#endif -} - -/// \brief Returns true if \p path and \p other refer to the same file or directory. -/// O(n) -inline bool path_equal( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_equal_nocase( path, other ); -#else - return string_equal( path, other ); -#endif -} - -/// \brief Returns true if \p path and \p other refer to the same file or directory, case insensitively. -/// O(n) -inline bool path_equal_i( const char* path, const char* other ){ - return string_equal_nocase( path, other ); -} - -/// \brief Returns true if the first \p n bytes of \p path and \p other form paths that refer to the same file or directory. -/// If the paths are UTF-8 encoded, [\p path, \p path + \p n) must be a complete path. -/// O(n) -inline bool path_equal_n( const char* path, const char* other, std::size_t n ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_equal_nocase_n( path, other, n ); -#else - return string_equal_n( path, other, n ); -#endif -} - - -/// \brief Returns true if \p path is a fully qualified file-system path. -/// O(1) -inline bool path_is_absolute( const char* path ){ -#if GDEF_OS_WINDOWS - return path[0] == '/' - || ( path[0] != '\0' && path[1] == ':' ); // local drive -#elif GDEF_OS_POSIX - return path[0] == '/'; -#endif -} - -/// \brief Returns true if \p path is a directory. -/// O(n) -inline bool path_is_directory( const char* path ){ - std::size_t length = strlen( path ); - if ( length > 0 ) { - return path[length - 1] == '/'; - } - return false; -} - -/// \brief Returns a pointer to the first character of the component of \p path following the first directory component. -/// O(n) -inline const char* path_remove_directory( const char* path ){ - const char* first_separator = strchr( path, '/' ); - if ( first_separator != 0 ) { - return ++first_separator; - } - return ""; -} - -/// \brief Returns a pointer to the first character of the filename component of \p path. -/// O(n) -inline const char* path_get_filename_start( const char* path ){ - { - const char* last_forward_slash = strrchr( path, '/' ); - if ( last_forward_slash != 0 ) { - return last_forward_slash + 1; - } - } - - // not strictly necessary,since paths should not contain '\' - { - const char* last_backward_slash = strrchr( path, '\\' ); - if ( last_backward_slash != 0 ) { - return last_backward_slash + 1; - } - } - - return path; -} - -/// \brief Returns a pointer to the character after the end of the filename component of \p path - either the extension separator or the terminating null character. -/// O(n) -inline const char* path_get_filename_base_end( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - return ( last_period != 0 ) ? last_period : path + string_length( path ); -} - -/// \brief Returns the length of the filename component (not including extension) of \p path. -/// O(n) -inline std::size_t path_get_filename_base_length( const char* path ){ - return path_get_filename_base_end( path ) - path; -} - -/// \brief If \p path is a child of \p base, returns the subpath relative to \p base, else returns \p path. -/// O(n) -inline const char* path_make_relative( const char* path, const char* base ){ - const std::size_t length = string_length( base ); - if ( path_equal_n( path, base, length ) ) { - return path + length; - } - return path; -} - -/// \brief Returns a pointer to the first character of the file extension of \p path, or "" if not found. -/// O(n) -inline const char* path_get_extension( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - if ( last_period != 0 ) { - return ++last_period; - } - return ""; -} - -/// \brief Returns true if \p extension is of the same type as \p other. -/// O(n) -inline bool extension_equal( const char* extension, const char* other ){ - return path_equal( extension, other ); -} - -/// \brief Returns true if \p extension is of the same type as \p other, case insensitively. -/// O(n) -inline bool extension_equal_i( const char* extension, const char* other ){ - return path_equal_i( extension, other ); -} - -template -class MatchFileExtension -{ -const char* m_extension; -const Functor& m_functor; -public: -MatchFileExtension( const char* extension, const Functor& functor ) : m_extension( extension ), m_functor( functor ){ -} -void operator()( const char* name ) const { - const char* extension = path_get_extension( name ); - if ( extension_equal( extension, m_extension ) ) { - m_functor( name ); - } -} -}; - -/// \brief A functor which invokes its contained \p functor if the \p name argument matches its \p extension. -template -inline MatchFileExtension matchFileExtension( const char* extension, const Functor& functor ){ - return MatchFileExtension( extension, functor ); -} - -class PathCleaned -{ -public: -const char* m_path; -PathCleaned( const char* path ) : m_path( path ){ -} -}; - -/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators. -template -TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathCleaned& path ){ - const char* i = path.m_path; - for (; *i != '\0'; ++i ) - { - if ( *i == '\\' ) { - ostream << '/'; - } - else - { - ostream << *i; - } - } - return ostream; -} - -class DirectoryCleaned -{ -public: -const char* m_path; -DirectoryCleaned( const char* path ) : m_path( path ){ -} -}; - -/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators, and appends a separator if necessary. -template -TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const DirectoryCleaned& path ){ - const char* i = path.m_path; - for (; *i != '\0'; ++i ) - { - if ( *i == '\\' ) { - ostream << '/'; - } - else - { - ostream << *i; - } - } - char c = *( i - 1 ); - if ( c != '/' && c != '\\' ) { - ostream << '/'; - } - return ostream; -} - - -#endif diff --git a/libs/pivot.h b/libs/pivot.h deleted file mode 100644 index 93cb354..0000000 --- a/libs/pivot.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PIVOT_H ) -#define INCLUDED_PIVOT_H - -#include "math/matrix.h" - - -inline void billboard_viewplaneOriented( Matrix4& rotation, const Matrix4& world2screen ){ -#if 1 - rotation = g_matrix4_identity; - Vector3 x( vector3_normalised( vector4_to_vector3( world2screen.x() ) ) ); - Vector3 y( vector3_normalised( vector4_to_vector3( world2screen.y() ) ) ); - Vector3 z( vector3_normalised( vector4_to_vector3( world2screen.z() ) ) ); - vector4_to_vector3( rotation.y() ) = Vector3( x.y(), y.y(), z.y() ); - vector4_to_vector3( rotation.z() ) = vector3_negated( Vector3( x.z(), y.z(), z.z() ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#else - Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); - - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 0, -1, 1 ) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 0, 1, 1 ) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 1, -1, 1 ) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#endif -} - -inline void billboard_viewpointOriented( Matrix4& rotation, const Matrix4& world2screen ){ - Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); - -#if 1 - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector4_to_vector3( screen2world.y() ) ); - vector4_to_vector3( rotation.z() ) = vector3_negated( vector3_normalised( vector4_to_vector3( screen2world.z() ) ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#else - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], -1, 1 ) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], 1, 1 ) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15] + 1, -1, 1 ) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#endif -} - - -inline void ConstructObject2Screen( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ - object2screen = device2screen; - matrix4_multiply_by_matrix4( object2screen, view2device ); - matrix4_multiply_by_matrix4( object2screen, world2view ); - matrix4_multiply_by_matrix4( object2screen, object2world ); -} - -inline void ConstructObject2Device( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ - object2screen = view2device; - matrix4_multiply_by_matrix4( object2screen, world2view ); - matrix4_multiply_by_matrix4( object2screen, object2world ); -} - -inline void ConstructDevice2Object( Matrix4& device2object, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ - ConstructObject2Device( device2object, object2world, world2view, view2device ); - matrix4_full_invert( device2object ); -} - -//! S = ( Inverse(Object2Screen *post ScaleOf(Object2Screen) ) *post Object2Screen -inline void pivot_scale( Matrix4& scale, const Matrix4& pivot2screen ){ - Matrix4 pre_scale( g_matrix4_identity ); - pre_scale[0] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.x() ) ) ); - pre_scale[5] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.y() ) ) ); - pre_scale[10] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.z() ) ) ); - - scale = pivot2screen; - matrix4_multiply_by_matrix4( scale, pre_scale ); - matrix4_full_invert( scale ); - matrix4_multiply_by_matrix4( scale, pivot2screen ); -} - -// scale by (inverse) W -inline void pivot_perspective( Matrix4& scale, const Matrix4& pivot2screen ){ - scale = g_matrix4_identity; - scale[0] = scale[5] = scale[10] = pivot2screen[15]; -} - -inline void ConstructDevice2Manip( Matrix4& device2manip, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, object2world, world2view, view2device, device2screen ); - - ConstructObject2Device( device2manip, object2world, world2view, view2device ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( device2manip, scale ); - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( device2manip, scale ); - - matrix4_full_invert( device2manip ); -} - -inline void Pivot2World_worldSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - -inline void Pivot2World_viewpointSpace( Matrix4& manip2world, Vector3& axis, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - billboard_viewpointOriented( scale, pivot2screen ); - axis = vector4_to_vector3( scale.z() ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - -inline void Pivot2World_viewplaneSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - billboard_viewplaneOriented( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - - -#include "renderable.h" -#include "cullable.h" -#include "render.h" - -const Colour4b g_colour_x( 255, 0, 0, 255 ); -const Colour4b g_colour_y( 0, 255, 0, 255 ); -const Colour4b g_colour_z( 0, 0, 255, 255 ); - -class Shader; - -class RenderablePivot : public OpenGLRenderable -{ -VertexBuffer m_vertices; -public: -mutable Matrix4 m_localToWorld; -typedef Static StaticShader; -static Shader* getShader(){ - return StaticShader::instance(); -} - -RenderablePivot(){ - m_vertices.reserve( 6 ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_x ) ); - m_vertices.push_back( PointVertex( Vertex3f( 16, 0, 0 ), g_colour_x ) ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_y ) ); - m_vertices.push_back( PointVertex( Vertex3f( 0, 16, 0 ), g_colour_y ) ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_z ) ); - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 16 ), g_colour_z ) ); -} - -void render( RenderStateFlags state ) const { - if ( m_vertices.size() == 0 ) { - return; - } - if ( m_vertices.data() == 0 ) { - return; - } - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glDrawArrays( GL_LINES, 0, m_vertices.size() ); -} - -void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { - renderer.PushState(); - - Pivot2World_worldSpace( m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() ); - - renderer.Highlight( Renderer::ePrimitive, false ); - renderer.SetState( getShader(), Renderer::eWireframeOnly ); - renderer.SetState( getShader(), Renderer::eFullMaterials ); - renderer.addRenderable( *this, m_localToWorld ); - - renderer.PopState(); -} -}; - - - -#endif diff --git a/libs/profile/Makefile b/libs/profile/Makefile deleted file mode 100644 index edb08e3..0000000 --- a/libs/profile/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - file.o profile.o - -# binary target -../libprofile.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -file.o: file.cpp file.h -profile.o: profile.cpp profile.h - -clean: - -rm -f *.o ../libprofile.a diff --git a/libs/profile/file.cpp b/libs/profile/file.cpp deleted file mode 100644 index 9f83393..0000000 --- a/libs/profile/file.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// File class, can be a memory file or a regular disk file. -// Originally from LeoCAD, used with permission from the author. :) -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "file.h" - -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -// File construction/destruction - -MemStream::MemStream(){ - m_nGrowBytes = 1024; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - m_pBuffer = NULL; - m_bAutoDelete = true; -} - -MemStream::MemStream( size_type nLen ){ - m_nGrowBytes = 1024; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - m_pBuffer = NULL; - m_bAutoDelete = true; - - GrowFile( nLen ); -} - -FileStream::FileStream(){ - m_hFile = NULL; - m_bCloseOnDelete = false; -} - -MemStream::~MemStream(){ - if ( m_pBuffer ) { - Close(); - } - - m_nGrowBytes = 0; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; -} - -FileStream::~FileStream(){ - if ( m_hFile != NULL && m_bCloseOnDelete ) { - Close(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// File operations - -char* MemStream::ReadString( char* pBuf, size_type nMax ){ - int nRead = 0; - unsigned char ch; - - if ( nMax <= 0 ) { - return NULL; - } - if ( m_nPosition >= m_nFileSize ) { - return NULL; - } - - while ( ( --nMax ) ) - { - if ( m_nPosition == m_nFileSize ) { - break; - } - - ch = m_pBuffer[m_nPosition]; - m_nPosition++; - pBuf[nRead++] = ch; - - if ( ch == '\n' ) { - break; - } - } - - pBuf[nRead] = '\0'; - return pBuf; -} - -char* FileStream::ReadString( char* pBuf, size_type nMax ){ - return fgets( pBuf, static_cast( nMax ), m_hFile ); -} - -MemStream::size_type MemStream::read( byte_type* buffer, size_type length ){ - if ( length == 0 ) { - return 0; - } - - if ( m_nPosition > m_nFileSize ) { - return 0; - } - - size_type nRead; - if ( m_nPosition + length > m_nFileSize ) { - nRead = m_nFileSize - m_nPosition; - } - else{ - nRead = length; - } - - memcpy( (unsigned char*)buffer, (unsigned char*)m_pBuffer + m_nPosition, nRead ); - m_nPosition += nRead; - - return nRead; -} - -FileStream::size_type FileStream::read( byte_type* buffer, size_type length ){ - return fread( buffer, 1, length, m_hFile ); -} - -int MemStream::GetChar(){ - if ( m_nPosition > m_nFileSize ) { - return 0; - } - - unsigned char* ret = (unsigned char*)m_pBuffer + m_nPosition; - m_nPosition++; - - return *ret; -} - -int FileStream::GetChar(){ - return fgetc( m_hFile ); -} - -MemStream::size_type MemStream::write( const byte_type* buffer, size_type length ){ - if ( length == 0 ) { - return 0; - } - - if ( m_nPosition + length > m_nBufferSize ) { - GrowFile( m_nPosition + length ); - } - - memcpy( (unsigned char*)m_pBuffer + m_nPosition, (unsigned char*)buffer, length ); - - m_nPosition += size_type( length ); - - if ( m_nPosition > m_nFileSize ) { - m_nFileSize = m_nPosition; - } - - return length; -} - -FileStream::size_type FileStream::write( const byte_type* buffer, size_type length ){ - return fwrite( buffer, 1, length, m_hFile ); -} - -int MemStream::PutChar( int c ){ - if ( m_nPosition + 1 > m_nBufferSize ) { - GrowFile( m_nPosition + 1 ); - } - - unsigned char* bt = (unsigned char*)m_pBuffer + m_nPosition; - *bt = c; - - m_nPosition++; - - if ( m_nPosition > m_nFileSize ) { - m_nFileSize = m_nPosition; - } - - return 1; -} - -/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */ -void FileStream::printf( const char* s, ... ){ - va_list args; - - va_start( args, s ); - vfprintf( m_hFile, s, args ); - va_end( args ); -} - -/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */ -void MemStream::printf( const char* s, ... ){ - va_list args; - - char buffer[4096]; - va_start( args, s ); - vsprintf( buffer, s, args ); - va_end( args ); - write( reinterpret_cast( buffer ), strlen( buffer ) ); -} - -int FileStream::PutChar( int c ){ - return fputc( c, m_hFile ); -} - -bool FileStream::Open( const char *filename, const char *mode ){ - m_hFile = fopen( filename, mode ); - m_bCloseOnDelete = true; - - return ( m_hFile != NULL ); -} - -void MemStream::Close(){ - m_nGrowBytes = 0; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - if ( m_pBuffer && m_bAutoDelete ) { - free( m_pBuffer ); - } - m_pBuffer = NULL; -} - -void FileStream::Close(){ - if ( m_hFile != NULL ) { - fclose( m_hFile ); - } - - m_hFile = NULL; - m_bCloseOnDelete = false; -} - -int MemStream::Seek( offset_type lOff, int nFrom ){ - size_type lNewPos = m_nPosition; - - if ( nFrom == SEEK_SET ) { - lNewPos = lOff; - } - else if ( nFrom == SEEK_CUR ) { - lNewPos += lOff; - } - else if ( nFrom == SEEK_END ) { - lNewPos = m_nFileSize + lOff; - } - else{ - return -1; - } - - m_nPosition = lNewPos; - - return static_cast( m_nPosition ); -} - -int FileStream::Seek( offset_type lOff, int nFrom ){ - fseek( m_hFile, lOff, nFrom ); - - return ftell( m_hFile ); -} - -MemStream::position_type MemStream::GetPosition() const { - return m_nPosition; -} - -FileStream::position_type FileStream::GetPosition() const { - return ftell( m_hFile ); -} - -void MemStream::GrowFile( size_type nNewLen ){ - if ( nNewLen > m_nBufferSize ) { - // grow the buffer - size_type nNewBufferSize = m_nBufferSize; - - // determine new buffer size - while ( nNewBufferSize < nNewLen ) - nNewBufferSize += m_nGrowBytes; - - // allocate new buffer - unsigned char* lpNew; - if ( m_pBuffer == NULL ) { - lpNew = static_cast( malloc( nNewBufferSize ) ); - } - else{ - lpNew = static_cast( realloc( m_pBuffer, nNewBufferSize ) ); - } - - m_pBuffer = lpNew; - m_nBufferSize = nNewBufferSize; - } -} - -void MemStream::Flush(){ - // Nothing to be done -} - -void FileStream::Flush(){ - if ( m_hFile == NULL ) { - return; - } - - fflush( m_hFile ); -} - -void MemStream::Abort(){ - Close(); -} - -void FileStream::Abort(){ - if ( m_hFile != NULL ) { - // close but ignore errors - if ( m_bCloseOnDelete ) { - fclose( m_hFile ); - } - m_hFile = NULL; - m_bCloseOnDelete = false; - } -} - -void MemStream::SetLength( size_type nNewLen ){ - if ( nNewLen > m_nBufferSize ) { - GrowFile( nNewLen ); - } - - if ( nNewLen < m_nPosition ) { - m_nPosition = nNewLen; - } - - m_nFileSize = nNewLen; -} - -void FileStream::SetLength( size_type nNewLen ){ - fseek( m_hFile, static_cast( nNewLen ), SEEK_SET ); -} - -MemStream::size_type MemStream::GetLength() const { - return m_nFileSize; -} - -FileStream::size_type FileStream::GetLength() const { - size_type nLen, nCur; - - // Seek is a non const operation - nCur = ftell( m_hFile ); - fseek( m_hFile, 0, SEEK_END ); - nLen = ftell( m_hFile ); - fseek( m_hFile, static_cast( nCur ), SEEK_SET ); - - return nLen; -} diff --git a/libs/profile/file.h b/libs/profile/file.h deleted file mode 100644 index fbda1d5..0000000 --- a/libs/profile/file.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// file.h -//////////////////////////////////////////////////// - -#if !defined( INCLUDED_PROFILE_FILE_H ) -#define INCLUDED_PROFILE_FILE_H - -#include "idatastream.h" - -/*! - API for data streams - - Based on an initial implementation by Loki software - modified to be abstracted and shared across modules - - NOTE: why IDataStream and not IStream? because IStream is defined in windows IDL headers - */ - -class IDataStream : public InputStream, public OutputStream -{ -public: -typedef int offset_type; -typedef std::size_t position_type; - -virtual void IncRef() = 0; ///< Increment the number of references to this object -virtual void DecRef() = 0; ///< Decrement the reference count - -virtual position_type GetPosition() const = 0; -virtual int Seek( offset_type lOff, int nFrom ) = 0; - -virtual void SetLength( size_type nNewLen ) = 0; -virtual size_type GetLength() const = 0; - -virtual char* ReadString( char* pBuf, size_type nMax ) = 0; -virtual int GetChar() = 0; - -virtual int PutChar( int c ) = 0; -virtual void printf( const char*, ... ) = 0; ///< completely matches the usual printf behaviour - -virtual void Abort() = 0; -virtual void Flush() = 0; -virtual void Close() = 0; -}; - -#include - -class MemStream : public IDataStream -{ -public: -MemStream(); -MemStream( size_type nLen ); -virtual ~MemStream(); - -int refCount; -void IncRef() { - refCount++; -} -void DecRef() { - refCount--; if ( refCount <= 0 ) { - delete this; - } -} - -protected: -// MemFile specific: -size_type m_nGrowBytes; -size_type m_nPosition; -size_type m_nBufferSize; -size_type m_nFileSize; -unsigned char* m_pBuffer; -bool m_bAutoDelete; -void GrowFile( size_type nNewLen ); - -public: -position_type GetPosition() const; -int Seek( offset_type lOff, int nFrom ); -void SetLength( size_type nNewLen ); -size_type GetLength() const; - -unsigned char* GetBuffer() const -{ - return m_pBuffer; -} - -size_type read( byte_type* buffer, size_type length ); -size_type write( const byte_type* buffer, size_type length ); - -char* ReadString( char* pBuf, size_type nMax ); -int GetChar(); - -int PutChar( int c ); -void printf( const char*, ... ); ///< \todo implement on MemStream - -void Abort(); -void Flush(); -void Close(); -bool Open( const char *filename, const char *mode ); -}; - -class FileStream : public IDataStream -{ -public: -FileStream(); -virtual ~FileStream(); - -int refCount; -void IncRef() { - refCount++; -} -void DecRef() { - refCount--; if ( refCount <= 0 ) { - delete this; - } -} - -protected: -// DiscFile specific: -FILE* m_hFile; -bool m_bCloseOnDelete; - -public: -position_type GetPosition() const; -int Seek( offset_type lOff, int nFrom ); -void SetLength( size_type nNewLen ); -size_type GetLength() const; - -size_type read( byte_type* buffer, size_type length ); -size_type write( const byte_type* buffer, size_type length ); - -char* ReadString( char* pBuf, size_type nMax ); -int GetChar(); - -int PutChar( int c ); -void printf( const char*, ... ); ///< completely matches the usual printf behaviour - -void Abort(); -void Flush(); -void Close(); -bool Open( const char *filename, const char *mode ); -}; - -#endif diff --git a/libs/profile/profile.cpp b/libs/profile/profile.cpp deleted file mode 100644 index c1505e0..0000000 --- a/libs/profile/profile.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Application settings load/save -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "profile.h" - -#include -#include -#include - -#include "file.h" - -#include - -#include "str.h" - - -// ============================================================================= -// Static functions - -bool read_var( const char *filename, const char *section, const char *key, char *value ){ - char line[1024], *ptr; - FILE *rc; - - rc = fopen( filename, "rt" ); - - if ( rc == NULL ) { - return false; - } - - while ( fgets( line, 1024, rc ) != 0 ) - { - // First we find the section - if ( line[0] != '[' ) { - continue; - } - - ptr = strchr( line, ']' ); - *ptr = '\0'; - - if ( strcmp( &line[1], section ) == 0 ) { - while ( fgets( line, 1024, rc ) != 0 ) - { - ptr = strchr( line, '=' ); - - if ( ptr == NULL ) { - // reached the end of the section - fclose( rc ); - return false; - } - *ptr = '\0'; - - // remove spaces - while ( line[strlen( line ) - 1] == ' ' ) - line[strlen( line ) - 1] = '\0'; - - if ( strcmp( line, key ) == 0 ) { - strcpy( value, ptr + 1 ); - fclose( rc ); - - if ( value[strlen( value ) - 1] == 10 || value[strlen( value ) - 1] == 13 || value[strlen( value ) - 1] == 32 ) { - value[strlen( value ) - 1] = 0; - } - - return true; - } - } - } - } - - fclose( rc ); - return false; -} - -bool save_var( const char *filename, const char *section, const char *key, const char *value ){ - char line[1024], *ptr; - MemStream old_rc; - bool found; - FILE *rc; - - rc = fopen( filename, "rb" ); - - if ( rc != NULL ) { - unsigned int len; - void *buf; - - fseek( rc, 0, SEEK_END ); - len = ftell( rc ); - rewind( rc ); - buf = malloc( len ); - fread( buf, len, 1, rc ); - old_rc.write( reinterpret_cast( buf ), len ); - free( buf ); - fclose( rc ); - old_rc.Seek( 0, SEEK_SET ); - } - - // TTimo: changed to binary writing. It doesn't seem to affect linux version, and win32 version was happending a lot of '\n' - rc = fopen( filename, "wb" ); - - if ( rc == NULL ) { - return false; - } - - // First we need to find the section - found = false; - while ( old_rc.ReadString( line, 1024 ) != NULL ) - { - fputs( line, rc ); - - if ( line[0] == '[' ) { - ptr = strchr( line, ']' ); - *ptr = '\0'; - - if ( strcmp( &line[1], section ) == 0 ) { - found = true; - break; - } - } - } - - if ( !found ) { - fputs( "\n", rc ); - fprintf( rc, "[%s]\n", section ); - } - - fprintf( rc, "%s=%s\n", key, value ); - - while ( old_rc.ReadString( line, 1024 ) != NULL ) - { - ptr = strchr( line, '=' ); - - if ( ptr != NULL ) { - *ptr = '\0'; - - if ( strcmp( line, key ) == 0 ) { - break; - } - - *ptr = '='; - fputs( line, rc ); - } - else - { - fputs( line, rc ); - break; - } - } - - while ( old_rc.ReadString( line, 1024 ) != NULL ) - fputs( line, rc ); - - fclose( rc ); - return true; -} - -// ============================================================================= -// Global functions - -bool profile_save_int( const char *filename, const char *section, const char *key, int value ){ - char buf[16]; - sprintf( buf, "%d", value ); - return save_var( filename, section, key, buf ); -} - -bool profile_save_float( const char *filename, const char *section, const char *key, float value ){ - char buf[16]; - sprintf( buf, "%f", value ); - return save_var( filename, section, key, buf ); -} - -bool profile_save_string( const char * filename, const char *section, const char *key, const char *value ){ - return save_var( filename, section, key, value ); -} - -bool profile_save_buffer( const char * rc_path, const char *name, void *buffer, unsigned int size ){ - bool ret = false; - char filename[1024]; - sprintf( filename, "%s/%s.bin", rc_path, name ); - FILE *f; - - f = fopen( filename, "wb" ); - - if ( f != NULL ) { - if ( fwrite( buffer, size, 1, f ) == 1 ) { - ret = true; - } - - fclose( f ); - } - - return ret; -} - -bool profile_load_buffer( const char * rc_path, const char *name, void *buffer, unsigned int *plSize ){ - char filename[1024]; - sprintf( filename, "%s/%s.bin", rc_path, name ); - bool ret = false; - unsigned int len; - FILE *f; - - f = fopen( filename, "rb" ); - - if ( f != NULL ) { - fseek( f, 0, SEEK_END ); - len = ftell( f ); - rewind( f ); - - if ( len > *plSize ) { - len = *plSize; - } - else{ - *plSize = len; - } - - if ( fread( buffer, len, 1, f ) == 1 ) { - ret = true; - } - - fclose( f ); - } - - return ret; -} - -int profile_load_int( const char *filename, const char *section, const char *key, int default_value ){ - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - return atoi( value ); - } - else{ - return default_value; - } -} - -float profile_load_float( const char *filename, const char *section, const char *key, float default_value ){ - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - return static_cast( atof( value ) ); - } - else{ - return default_value; - } -} - -char* profile_load_string( const char *filename, const char *section, const char *key, const char *default_value ){ - static Str ret; - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - ret = value; - } - else{ - ret = default_value; - } - - return (char*)ret.GetBuffer(); -} diff --git a/libs/profile/profile.h b/libs/profile/profile.h deleted file mode 100644 index 493743f..0000000 --- a/libs/profile/profile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_PROFILE_PROFILE_H ) -#define INCLUDED_PROFILE_PROFILE_H - -// profile functions - kind of utility lib -// they are kind of dumb, they expect to get the path to the .ini file or to the prefs directory when called -// load_buffer and save_buffer expect the path only, theyll build a $(pszName).bin file -bool profile_save_int( const char *filename, const char *section, const char *key, int value ); -bool profile_save_float( const char *filename, const char *section, const char *key, float value ); -bool profile_save_string( const char *filename, const char *section, const char *key, const char *value ); -bool profile_save_buffer( const char *rc_path, const char *pszName, void *pvBuf, unsigned int lSize ); -bool profile_load_buffer( const char *rc_path, const char *pszName, void *pvBuf, unsigned int *plSize ); -int profile_load_int( const char *filename, const char *section, const char *key, int default_value ); -float profile_load_float( const char *filename, const char *section, const char *key, float default_value ); -char* profile_load_string( const char *filename, const char *section, const char *key, const char *default_value ); -// used in the command map code -bool read_var( const char *filename, const char *section, const char *key, char *value ); -bool save_var( const char *filename, const char *section, const char *key, const char *value ); - -#endif diff --git a/libs/property.h b/libs/property.h deleted file mode 100644 index 3b4f81f..0000000 --- a/libs/property.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef INCLUDED_IMPORTEXPORT_H -#define INCLUDED_IMPORTEXPORT_H - -#include "generic/callback.h" -#include "string/string.h" - -template -struct Property { - // todo: just return T, don't use continuation passing style - Callback &returnz)> get; - Callback set; -}; - -// implementation - -template -struct PropertyImpl { - static void Export(const Self &self, const Callback &returnz) { - returnz(self); - } - - static void Import(Self &self, T value) { - self = value; - } -}; - -namespace detail { - -template -using propertyimpl_self = typename std::remove_reference >::type; - -template -using propertyimpl_other = get_argument; - -template -using propertyimpl_other_free = get_argument; - -} - -// adaptor - -template< - class Self, - class T = Self, - class I = PropertyImpl - > -struct PropertyAdaptor { - using Type = Self; - using Other = T; - - using Get = ConstReferenceCaller &), I::Export>; - using Set = ReferenceCaller; -}; - -template< - class T, - class I - > -struct PropertyAdaptorFree { - using Other = T; - - using Get = FreeCaller &), I::Export>; - using Set = FreeCaller; -}; - -// explicit full - -template -Property make_property(typename A::Type &self) { - return {typename A::Get(self), typename A::Set(self)}; -} - -template -Property make_property() { - return {typename A::Get(), typename A::Set()}; -} - -// explicit impl - -template, class T = detail::propertyimpl_other > -using property_impl = PropertyAdaptor; - -template > -Property make_property(Self &self) { - return make_property >(self); -} - -template > -using property_impl_free = PropertyAdaptorFree; - -template > -Property make_property() { - return make_property >(); -} - -// implicit - -template -Property make_property(Self &self) { - return make_property >(self); -} - -// chain - -template -struct make_property_chain_I_1 { - static void ExportThunk(const Callback &self, SRC value) { - PropertyImpl::Export(value, self); - } - - static void Export(const X &self, const Callback &returnz) { - A::Get::thunk_(self, ConstReferenceCaller, void(SRC), ExportThunk>(returnz)); - } - - static void Import(X &self, DST value) { - SRC out; - PropertyImpl::Import(out, value); - A::Set::thunk_(self, out); - } -}; - -template -Property > make_property_chain(detail::propertyimpl_self &it) { - using DST = detail::propertyimpl_other; - using SRC = detail::propertyimpl_self; - using X = detail::propertyimpl_self; - - using A = property_impl; - using I = make_property_chain_I_1; - return make_property >(it); -} - -template -struct make_property_chain_I_2 { - static void ExportThunk(const Callback &self, SRC value) { - PropertyImpl::Export(value, self); - } - - static void Export(const Callback &returnz) { - A::Get::thunk_(nullptr, ConstReferenceCaller, void(SRC), ExportThunk>(returnz)); - } - - static void Import(DST value) { - SRC out; - PropertyImpl::Import(out, value); - A::Set::thunk_(nullptr, out); - } -}; - -template -Property > make_property_chain() { - using DST = detail::propertyimpl_other; - using SRC = detail::propertyimpl_self; - - using A = property_impl_free; - using I = make_property_chain_I_2; - return make_property >(); -} - -// specializations - -template<> -struct PropertyImpl { - static void Export(const CopiedString &self, const Callback &returnz) { - returnz(self.c_str()); - } - - static void Import(CopiedString &self, const char *value) { - self = value; - } -}; - -#endif diff --git a/libs/render.h b/libs/render.h deleted file mode 100644 index 127c6ad..0000000 --- a/libs/render.h +++ /dev/null @@ -1,1209 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDER_H ) -#define INCLUDED_RENDER_H - -/// \file -/// \brief High-level constructs for efficient OpenGL rendering. - -#include "irender.h" -#include "igl.h" - -#include "container/array.h" -#include "math/vector.h" -#include "math/pi.h" - -#include - -typedef unsigned int RenderIndex; -const GLenum RenderIndexTypeID = GL_UNSIGNED_INT; - -/// \brief A resizable buffer of indices. -class IndexBuffer -{ -typedef std::vector Indices; -Indices m_data; -public: -typedef Indices::iterator iterator; -typedef Indices::const_iterator const_iterator; - -iterator begin(){ - return m_data.begin(); -} -const_iterator begin() const { - return m_data.begin(); -} -iterator end(){ - return m_data.end(); -} -const_iterator end() const { - return m_data.end(); -} - -bool empty() const { - return m_data.empty(); -} -std::size_t size() const { - return m_data.size(); -} -const RenderIndex* data() const { - return &( *m_data.begin() ); -} -RenderIndex& operator[]( std::size_t index ){ - return m_data[index]; -} -const RenderIndex& operator[]( std::size_t index ) const { - return m_data[index]; -} -void clear(){ - m_data.clear(); -} -void reserve( std::size_t max_indices ){ - m_data.reserve( max_indices ); -} -void insert( RenderIndex index ){ - m_data.push_back( index ); -} -void swap( IndexBuffer& other ){ - std::swap( m_data, m_data ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( IndexBuffer& self, IndexBuffer& other ){ - self.swap( other ); -} -} - -/// \brief A resizable buffer of vertices. -/// \param Vertex The vertex data type. -template -class VertexBuffer -{ -typedef typename std::vector Vertices; -Vertices m_data; -public: -typedef typename Vertices::iterator iterator; -typedef typename Vertices::const_iterator const_iterator; - -iterator begin(){ - return m_data.begin(); -} -iterator end(){ - return m_data.end(); -} -const_iterator begin() const { - return m_data.begin(); -} -const_iterator end() const { - return m_data.end(); -} - -bool empty() const { - return m_data.empty(); -} -RenderIndex size() const { - return RenderIndex( m_data.size() ); -} -const Vertex* data() const { - return &( *m_data.begin() ); -} -Vertex& operator[]( std::size_t index ){ - return m_data[index]; -} -const Vertex& operator[]( std::size_t index ) const { - return m_data[index]; -} - -void clear(){ - m_data.clear(); -} -void reserve( std::size_t max_vertices ){ - m_data.reserve( max_vertices ); -} -void push_back( const Vertex& vertex ){ - m_data.push_back( vertex ); -} -}; - -/// \brief A wrapper around a VertexBuffer which inserts only vertices which have not already been inserted. -/// \param Vertex The vertex data type. Must support operator<, operator== and operator!=. -/// For best performance, quantise vertices before inserting them. -template -class UniqueVertexBuffer -{ -typedef VertexBuffer Vertices; -Vertices& m_data; - -struct bnode -{ - bnode() - : m_left( 0 ), m_right( 0 ){ - } - RenderIndex m_left; - RenderIndex m_right; -}; - -std::vector m_btree; -RenderIndex m_prev0; -RenderIndex m_prev1; -RenderIndex m_prev2; - -RenderIndex find_or_insert( const Vertex& vertex ){ - RenderIndex index = 0; - - while ( 1 ) - { - if ( vertex < m_data[index] ) { - bnode& node = m_btree[index]; - if ( node.m_left != 0 ) { - index = node.m_left; - continue; - } - else - { - node.m_left = RenderIndex( m_btree.size() ); - m_btree.push_back( bnode() ); - m_data.push_back( vertex ); - return RenderIndex( m_btree.size() - 1 ); - } - } - if ( m_data[index] < vertex ) { - bnode& node = m_btree[index]; - if ( node.m_right != 0 ) { - index = node.m_right; - continue; - } - else - { - node.m_right = RenderIndex( m_btree.size() ); - m_btree.push_back( bnode() ); - m_data.push_back( vertex ); - return RenderIndex( m_btree.size() - 1 ); - } - } - - return index; - } -} -public: -UniqueVertexBuffer( Vertices& data ) - : m_data( data ), m_prev0( 0 ), m_prev1( 0 ), m_prev2( 0 ){ -} - -typedef typename Vertices::const_iterator iterator; - -iterator begin() const { - return m_data.begin(); -} -iterator end() const { - return m_data.end(); -} - -std::size_t size() const { - return m_data.size(); -} -const Vertex* data() const { - return &( *m_data.begin() ); -} -Vertex& operator[]( std::size_t index ){ - return m_data[index]; -} -const Vertex& operator[]( std::size_t index ) const { - return m_data[index]; -} - -void clear(){ - m_prev0 = 0; - m_prev1 = 0; - m_prev2 = 0; - m_data.clear(); - m_btree.clear(); -} -void reserve( std::size_t max_vertices ){ - m_data.reserve( max_vertices ); - m_btree.reserve( max_vertices ); -} -/// \brief Returns the index of the element equal to \p vertex. -RenderIndex insert( const Vertex& vertex ){ - if ( m_data.empty() ) { - m_data.push_back( vertex ); - m_btree.push_back( bnode() ); - return 0; - } - - if ( m_data[m_prev0] == vertex ) { - return m_prev0; - } - if ( m_prev1 != m_prev0 && m_data[m_prev1] == vertex ) { - return m_prev1; - } - if ( m_prev2 != m_prev0 && m_prev2 != m_prev1 && m_data[m_prev2] == vertex ) { - return m_prev2; - } - - m_prev2 = m_prev1; - m_prev1 = m_prev0; - m_prev0 = find_or_insert( vertex ); - - return m_prev0; -} -}; - - -/// \brief A 4-byte colour. -struct Colour4b -{ - unsigned char r, g, b, a; - - Colour4b(){ - } - - Colour4b( unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a ) - : r( _r ), g( _g ), b( _b ), a( _a ){ - } -}; - -const Colour4b colour_vertex( 0, 255, 0, 255 ); -const Colour4b colour_selected( 0, 0, 255, 255 ); - -inline bool operator<( const Colour4b& self, const Colour4b& other ){ - if ( self.r != other.r ) { - return self.r < other.r; - } - if ( self.g != other.g ) { - return self.g < other.g; - } - if ( self.b != other.b ) { - return self.b < other.b; - } - if ( self.a != other.a ) { - return self.a < other.a; - } - return false; -} - -inline bool operator==( const Colour4b& self, const Colour4b& other ){ - return self.r == other.r && self.g == other.g && self.b == other.b && self.a == other.a; -} - -inline bool operator!=( const Colour4b& self, const Colour4b& other ){ - return !operator==( self, other ); -} - -/// \brief A 3-float vertex. -struct Vertex3f : public Vector3 -{ - Vertex3f(){ - } - - Vertex3f( float _x, float _y, float _z ) - : Vector3( _x, _y, _z ){ - } -}; - -inline bool operator<( const Vertex3f& self, const Vertex3f& other ){ - if ( self.x() != other.x() ) { - return self.x() < other.x(); - } - if ( self.y() != other.y() ) { - return self.y() < other.y(); - } - if ( self.z() != other.z() ) { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==( const Vertex3f& self, const Vertex3f& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} - -inline bool operator!=( const Vertex3f& self, const Vertex3f& other ){ - return !operator==( self, other ); -} - - -inline Vertex3f vertex3f_from_array( const float* array ){ - return Vertex3f( array[0], array[1], array[2] ); -} - -inline float* vertex3f_to_array( Vertex3f& vertex ){ - return reinterpret_cast( &vertex ); -} - -inline const float* vertex3f_to_array( const Vertex3f& vertex ){ - return reinterpret_cast( &vertex ); -} - -const Vertex3f vertex3f_identity( 0, 0, 0 ); - -inline Vertex3f vertex3f_for_vector3( const Vector3& vector3 ){ - return Vertex3f( vector3.x(), vector3.y(), vector3.z() ); -} - -inline const Vector3& vertex3f_to_vector3( const Vertex3f& vertex ){ - return vertex; -} - -inline Vector3& vertex3f_to_vector3( Vertex3f& vertex ){ - return vertex; -} - - -/// \brief A 3-float normal. -struct Normal3f : public Vector3 -{ - Normal3f(){ - } - - Normal3f( float _x, float _y, float _z ) - : Vector3( _x, _y, _z ){ - } -}; - -inline bool operator<( const Normal3f& self, const Normal3f& other ){ - if ( self.x() != other.x() ) { - return self.x() < other.x(); - } - if ( self.y() != other.y() ) { - return self.y() < other.y(); - } - if ( self.z() != other.z() ) { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==( const Normal3f& self, const Normal3f& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} - -inline bool operator!=( const Normal3f& self, const Normal3f& other ){ - return !operator==( self, other ); -} - - -inline Normal3f normal3f_from_array( const float* array ){ - return Normal3f( array[0], array[1], array[2] ); -} - -inline float* normal3f_to_array( Normal3f& normal ){ - return reinterpret_cast( &normal ); -} - -inline const float* normal3f_to_array( const Normal3f& normal ){ - return reinterpret_cast( &normal ); -} - -inline Normal3f normal3f_for_vector3( const Vector3& vector3 ){ - return Normal3f( vector3.x(), vector3.y(), vector3.z() ); -} - -inline const Vector3& normal3f_to_vector3( const Normal3f& normal ){ - return normal; -} - -inline Vector3& normal3f_to_vector3( Normal3f& normal ){ - return normal; -} - - -/// \brief A 2-float texture-coordinate set. -struct TexCoord2f : public Vector2 -{ - TexCoord2f(){ - } - - TexCoord2f( float _s, float _t ) - : Vector2( _s, _t ){ - } - - float& s(){ - return x(); - } - const float& s() const { - return x(); - } - float& t(){ - return y(); - } - const float& t() const { - return y(); - } -}; - -inline bool operator<( const TexCoord2f& self, const TexCoord2f& other ){ - if ( self.s() != other.s() ) { - return self.s() < other.s(); - } - if ( self.t() != other.t() ) { - return self.t() < other.t(); - } - return false; -} - -inline bool operator==( const TexCoord2f& self, const TexCoord2f& other ){ - return self.s() == other.s() && self.t() == other.t(); -} - -inline bool operator!=( const TexCoord2f& self, const TexCoord2f& other ){ - return !operator==( self, other ); -} - - -inline float* texcoord2f_to_array( TexCoord2f& texcoord ){ - return reinterpret_cast( &texcoord ); -} - -inline const float* texcoord2f_to_array( const TexCoord2f& texcoord ){ - return reinterpret_cast( &texcoord ); -} - -inline const TexCoord2f& texcoord2f_from_array( const float* array ){ - return *reinterpret_cast( array ); -} - -inline TexCoord2f texcoord2f_for_vector2( const Vector2& vector2 ){ - return TexCoord2f( vector2.x(), vector2.y() ); -} - -inline Vector4 colour4f_for_vector4( const Vector4& vector4 ){ - return vector4; -} - -inline const Vector2& texcoord2f_to_vector2( const TexCoord2f& vertex ){ - return vertex; -} - -inline Vector2& texcoord2f_to_vector2( TexCoord2f& vertex ){ - return vertex; -} -inline Vector4& colour4f_to_vector4( Vector4& vertex ){ - return vertex; -} - -/// \brief Returns \p normal rescaled to be unit-length. -inline Normal3f normal3f_normalised( const Normal3f& normal ){ - return normal3f_for_vector3( vector3_normalised( normal3f_to_vector3( normal ) ) ); -} - -enum UnitSphereOctant -{ - UNITSPHEREOCTANT_000 = 0 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_001 = 0 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_010 = 0 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_011 = 0 << 0 | 1 << 1 | 1 << 2, - UNITSPHEREOCTANT_100 = 1 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_101 = 1 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_110 = 1 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_111 = 1 << 0 | 1 << 1 | 1 << 2, -}; - -/// \brief Returns the octant for \p normal indicating the sign of the region of unit-sphere space it lies within. -inline UnitSphereOctant normal3f_classify_octant( const Normal3f& normal ){ - return static_cast( - ( ( normal.x() > 0 ) << 0 ) | ( ( normal.y() > 0 ) << 1 ) | ( ( normal.z() > 0 ) << 2 ) - ); -} - -/// \brief Returns \p normal with its components signs made positive based on \p octant. -inline Normal3f normal3f_fold_octant( const Normal3f& normal, UnitSphereOctant octant ){ - switch ( octant ) - { - case UNITSPHEREOCTANT_000: - return Normal3f( -normal.x(), -normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_001: - return Normal3f( normal.x(), -normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_010: - return Normal3f( -normal.x(), normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_011: - return Normal3f( normal.x(), normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_100: - return Normal3f( -normal.x(), -normal.y(), normal.z() ); - case UNITSPHEREOCTANT_101: - return Normal3f( normal.x(), -normal.y(), normal.z() ); - case UNITSPHEREOCTANT_110: - return Normal3f( -normal.x(), normal.y(), normal.z() ); - case UNITSPHEREOCTANT_111: - return Normal3f( normal.x(), normal.y(), normal.z() ); - } - return Normal3f(); -} - -/// \brief Reverses the effect of normal3f_fold_octant() on \p normal with \p octant. -/// \p normal must have been obtained with normal3f_fold_octant(). -/// \p octant must have been obtained with normal3f_classify_octant(). -inline Normal3f normal3f_unfold_octant( const Normal3f& normal, UnitSphereOctant octant ){ - return normal3f_fold_octant( normal, octant ); -} - -enum UnitSphereSextant -{ - UNITSPHERESEXTANT_XYZ = 0, - UNITSPHERESEXTANT_XZY = 1, - UNITSPHERESEXTANT_YXZ = 2, - UNITSPHERESEXTANT_YZX = 3, - UNITSPHERESEXTANT_ZXY = 4, - UNITSPHERESEXTANT_ZYX = 5, -}; - -/// \brief Returns the sextant for \p normal indicating how to sort its components so that x > y > z. -/// All components of \p normal must be positive. -/// \p normal must be normalised. -inline UnitSphereSextant normal3f_classify_sextant( const Normal3f& normal ){ - return - normal.x() >= normal.y() - ? normal.x() >= normal.z() - ? normal.y() >= normal.z() - ? UNITSPHERESEXTANT_XYZ - : UNITSPHERESEXTANT_XZY - : UNITSPHERESEXTANT_ZXY - : normal.y() >= normal.z() - ? normal.x() >= normal.z() - ? UNITSPHERESEXTANT_YXZ - : UNITSPHERESEXTANT_YZX - : UNITSPHERESEXTANT_ZYX; -} - -/// \brief Returns \p normal with its components sorted so that x > y > z based on \p sextant. -/// All components of \p normal must be positive. -/// \p normal must be normalised. -inline Normal3f normal3f_fold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ - switch ( sextant ) - { - case UNITSPHERESEXTANT_XYZ: - return Normal3f( normal.x(), normal.y(), normal.z() ); - case UNITSPHERESEXTANT_XZY: - return Normal3f( normal.x(), normal.z(), normal.y() ); - case UNITSPHERESEXTANT_YXZ: - return Normal3f( normal.y(), normal.x(), normal.z() ); - case UNITSPHERESEXTANT_YZX: - return Normal3f( normal.y(), normal.z(), normal.x() ); - case UNITSPHERESEXTANT_ZXY: - return Normal3f( normal.z(), normal.x(), normal.y() ); - case UNITSPHERESEXTANT_ZYX: - return Normal3f( normal.z(), normal.y(), normal.x() ); - } - return Normal3f(); -} - -/// \brief Reverses the effect of normal3f_fold_sextant() on \p normal with \p sextant. -/// \p normal must have been obtained with normal3f_fold_sextant(). -/// \p sextant must have been obtained with normal3f_classify_sextant(). -inline Normal3f normal3f_unfold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ - return normal3f_fold_sextant( normal, sextant ); -} - -const std::size_t c_quantise_normal = 1 << 6; - -/// \brief All the components of \p folded must be positive and sorted so that x > y > z. -inline Normal3f normal3f_folded_quantised( const Normal3f& folded ){ - // compress - double scale = static_cast( c_quantise_normal ) / ( folded.x() + folded.y() + folded.z() ); - unsigned int zbits = static_cast( folded.z() * scale ); - unsigned int ybits = static_cast( folded.y() * scale ); - - // decompress - return normal3f_normalised( Normal3f( - static_cast( c_quantise_normal - zbits - ybits ), - static_cast( ybits ), - static_cast( zbits ) - ) ); -} - -/// \brief Returns \p normal quantised by compressing and then decompressing its representation. -inline Normal3f normal3f_quantised_custom( const Normal3f& normal ){ - UnitSphereOctant octant = normal3f_classify_octant( normal ); - Normal3f folded = normal3f_fold_octant( normal, octant ); - UnitSphereSextant sextant = normal3f_classify_sextant( folded ); - folded = normal3f_fold_sextant( folded, sextant ); - return normal3f_unfold_octant( normal3f_unfold_sextant( normal3f_folded_quantised( folded ), sextant ), octant ); -} - - - -struct spherical_t -{ - double longditude, latitude; - - spherical_t( double _longditude, double _latitude ) - : longditude( _longditude ), latitude( _latitude ){ - } -}; - -/* - { - theta = 2pi * U; - phi = acos((2 * V) - 1); - - U = theta / 2pi; - V = (cos(phi) + 1) / 2; - } - - longitude = atan(y / x); - latitude = acos(z); - */ -struct uniformspherical_t -{ - double U, V; - - uniformspherical_t( double U_, double V_ ) - : U( U_ ), V( V_ ){ - } -}; - - -inline spherical_t spherical_from_normal3f( const Normal3f& normal ){ - return spherical_t( normal.x() == 0 ? c_pi / 2 : normal.x() > 0 ? atan( normal.y() / normal.x() ) : atan( normal.y() / normal.x() ) + c_pi, acos( normal.z() ) ); -} - -inline Normal3f normal3f_from_spherical( const spherical_t& spherical ){ - return Normal3f( - static_cast( cos( spherical.longditude ) * sin( spherical.latitude ) ), - static_cast( sin( spherical.longditude ) * sin( spherical.latitude ) ), - static_cast( cos( spherical.latitude ) ) - ); -} - -inline uniformspherical_t uniformspherical_from_spherical( const spherical_t& spherical ){ - return uniformspherical_t( spherical.longditude * c_inv_2pi, ( cos( spherical.latitude ) + 1 ) * 0.5 ); -} - -inline spherical_t spherical_from_uniformspherical( const uniformspherical_t& uniformspherical ){ - return spherical_t( c_2pi * uniformspherical.U, acos( ( 2 * uniformspherical.V ) - 1 ) ); -} - -inline uniformspherical_t uniformspherical_from_normal3f( const Normal3f& normal ){ - return uniformspherical_from_spherical( spherical_from_normal3f( normal ) ); - //return uniformspherical_t(atan2(normal.y / normal.x) * c_inv_2pi, (normal.z + 1) * 0.5); -} - -inline Normal3f normal3f_from_uniformspherical( const uniformspherical_t& uniformspherical ){ - return normal3f_from_spherical( spherical_from_uniformspherical( uniformspherical ) ); -} - -/// \brief Returns a single-precision \p component quantised to \p precision. -inline float float_quantise( float component, float precision ){ - return float_snapped( component, precision ); -} - -/// \brief Returns a double-precision \p component quantised to \p precision. -inline double double_quantise( double component, double precision ){ - return float_snapped( component, precision ); -} - -inline spherical_t spherical_quantised( const spherical_t& spherical, float snap ){ - return spherical_t( double_quantise( spherical.longditude, snap ), double_quantise( spherical.latitude, snap ) ); -} - -inline uniformspherical_t uniformspherical_quantised( const uniformspherical_t& uniformspherical, float snap ){ - return uniformspherical_t( double_quantise( uniformspherical.U, snap ), double_quantise( uniformspherical.V, snap ) ); -} - -/// \brief Returns a \p vertex quantised to \p precision. -inline Vertex3f vertex3f_quantised( const Vertex3f& vertex, float precision ){ - return Vertex3f( float_quantise( vertex.x(), precision ), float_quantise( vertex.y(), precision ), float_quantise( vertex.z(), precision ) ); -} - -/// \brief Returns a \p normal quantised to a fixed precision. -inline Normal3f normal3f_quantised( const Normal3f& normal ){ - return normal3f_quantised_custom( normal ); - //return normal3f_from_spherical(spherical_quantised(spherical_from_normal3f(normal), snap)); - //return normal3f_from_uniformspherical(uniformspherical_quantised(uniformspherical_from_normal3f(normal), snap)); - // float_quantise(normal.x, snap), float_quantise(normal.y, snap), float_quantise(normal.y, snap)); -} - -/// \brief Returns a \p texcoord quantised to \p precision. -inline TexCoord2f texcoord2f_quantised( const TexCoord2f& texcoord, float precision ){ - return TexCoord2f( float_quantise( texcoord.s(), precision ), float_quantise( texcoord.t(), precision ) ); -} - -/// \brief Standard vertex type for lines and points. -struct PointVertex -{ - Colour4b colour; - Vertex3f vertex; - - PointVertex(){ - } - PointVertex( Vertex3f _vertex ) - : colour( Colour4b( 255, 255, 255, 255 ) ), vertex( _vertex ){ - } - PointVertex( Vertex3f _vertex, Colour4b _colour ) - : colour( _colour ), vertex( _vertex ){ - } -}; - -inline bool operator<( const PointVertex& self, const PointVertex& other ){ - if ( self.vertex != other.vertex ) { - return self.vertex < other.vertex; - } - if ( self.colour != other.colour ) { - return self.colour < other.colour; - } - return false; -} - -inline bool operator==( const PointVertex& self, const PointVertex& other ){ - return self.colour == other.colour && self.vertex == other.vertex; -} - -inline bool operator!=( const PointVertex& self, const PointVertex& other ){ - return !operator==( self, other ); -} - -/// \brief Standard vertex type for lit/textured meshes. -struct ArbitraryMeshVertex -{ - TexCoord2f texcoord; - Normal3f normal; - Vertex3f vertex; - Normal3f tangent; - Normal3f bitangent; - Vector4 colour; - - ArbitraryMeshVertex() : tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ), colour( 1, 1, 1, 1 ){ - } - ArbitraryMeshVertex( Vertex3f _vertex, Normal3f _normal, TexCoord2f _texcoord ) - : texcoord( _texcoord ), normal( _normal ), vertex( _vertex ), tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ), colour( 1, 1, 1, 1 ){ - } -}; - -inline bool operator<( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - if ( self.texcoord != other.texcoord ) { - return self.texcoord < other.texcoord; - } - if ( self.normal != other.normal ) { - return self.normal < other.normal; - } - if ( self.vertex != other.vertex ) { - return self.vertex < other.vertex; - } - return false; -} - -inline bool operator==( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - return self.texcoord == other.texcoord && self.normal == other.normal && self.vertex == other.vertex; -} - -inline bool operator!=( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - return !operator==( self, other ); -} - -const float c_quantise_vertex = 1.f / static_cast( 1 << 3 ); - -/// \brief Returns \p v with vertex quantised to a fixed precision. -inline PointVertex pointvertex_quantised( const PointVertex& v ){ - return PointVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), v.colour ); -} - -const float c_quantise_texcoord = 1.f / static_cast( 1 << 8 ); - -/// \brief Returns \p v with vertex, normal and texcoord quantised to a fixed precision. -inline ArbitraryMeshVertex arbitrarymeshvertex_quantised( const ArbitraryMeshVertex& v ){ - return ArbitraryMeshVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), normal3f_quantised( v.normal ), texcoord2f_quantised( v.texcoord, c_quantise_texcoord ) ); -} - - -/// \brief Sets up the OpenGL colour and vertex arrays for \p array. -inline void pointvertex_gl_array( const PointVertex* array ){ - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &array->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &array->vertex ); -} - -class RenderablePointArray : public OpenGLRenderable -{ -const Array& m_array; -const GLenum m_mode; -public: -RenderablePointArray( const Array& array, GLenum mode ) - : m_array( array ), m_mode( mode ){ -} -void render( RenderStateFlags state ) const { -#define NV_DRIVER_BUG 1 -#if NV_DRIVER_BUG - glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 ); - glVertexPointer( 3, GL_FLOAT, 0, 0 ); - glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); -#endif - pointvertex_gl_array( m_array.data() ); - glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); -} -}; - -class RenderablePointVector : public OpenGLRenderable -{ -std::vector m_vector; -const GLenum m_mode; -public: -RenderablePointVector( GLenum mode ) - : m_mode( mode ){ -} - -void render( RenderStateFlags state ) const { - pointvertex_gl_array( &m_vector.front() ); - glDrawArrays( m_mode, 0, GLsizei( m_vector.size() ) ); -} - -std::size_t size() const { - return m_vector.size(); -} -bool empty() const { - return m_vector.empty(); -} -void clear(){ - m_vector.clear(); -} -void reserve( std::size_t size ){ - m_vector.reserve( size ); -} -void push_back( const PointVertex& point ){ - m_vector.push_back( point ); -} -}; - - -class RenderableVertexBuffer : public OpenGLRenderable -{ -const GLenum m_mode; -const VertexBuffer& m_vertices; -public: -RenderableVertexBuffer( GLenum mode, const VertexBuffer& vertices ) - : m_mode( mode ), m_vertices( vertices ){ -} - -void render( RenderStateFlags state ) const { - pointvertex_gl_array( m_vertices.data() ); - glDrawArrays( m_mode, 0, m_vertices.size() ); -} -}; - -class RenderableIndexBuffer : public OpenGLRenderable -{ -const GLenum m_mode; -const IndexBuffer& m_indices; -const VertexBuffer& m_vertices; -public: -RenderableIndexBuffer( GLenum mode, const IndexBuffer& indices, const VertexBuffer& vertices ) - : m_mode( mode ), m_indices( indices ), m_vertices( vertices ){ -} - -void render( RenderStateFlags state ) const { -#if 1 - pointvertex_gl_array( m_vertices.data() ); - glDrawElements( m_mode, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); -#else - glBegin( m_mode ); - if ( state & RENDER_COLOURARRAY != 0 ) { - for ( std::size_t i = 0; i < m_indices.size(); ++i ) - { - glColor4ubv( &m_vertices[m_indices[i]].colour.r ); - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); - } - } - else - { - for ( std::size_t i = 0; i < m_indices.size(); ++i ) - { - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); - } - } - glEnd(); -#endif -} -}; - - -class RemapXYZ -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = x; - vertex.y() = y; - vertex.z() = z; -} -}; - -class RemapYZX -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = z; - vertex.y() = x; - vertex.z() = y; -} -}; - -class RemapZXY -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = y; - vertex.y() = z; - vertex.z() = x; -} -}; - -template -inline void draw_circle( const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap ){ - const double increment = c_pi / double(segments << 2); - - std::size_t count = 0; - float x = radius; - float y = 0; - while ( count < segments ) - { - PointVertex* i = vertices + count; - PointVertex* j = vertices + ( ( segments << 1 ) - ( count + 1 ) ); - - PointVertex* k = i + ( segments << 1 ); - PointVertex* l = j + ( segments << 1 ); - - PointVertex* m = i + ( segments << 2 ); - PointVertex* n = j + ( segments << 2 ); - PointVertex* o = k + ( segments << 2 ); - PointVertex* p = l + ( segments << 2 ); - - remap_policy::set( i->vertex, x,-y, 0 ); - remap_policy::set( k->vertex,-y,-x, 0 ); - remap_policy::set( m->vertex,-x, y, 0 ); - remap_policy::set( o->vertex, y, x, 0 ); - - ++count; - - { - const double theta = increment * count; - x = static_cast( radius * cos( theta ) ); - y = static_cast( radius * sin( theta ) ); - } - - remap_policy::set( j->vertex, y,-x, 0 ); - remap_policy::set( l->vertex,-x,-y, 0 ); - remap_policy::set( n->vertex,-y, x, 0 ); - remap_policy::set( p->vertex, x, y, 0 ); - } -} - -#if 0 -class PointVertexArrayIterator -{ -PointVertex* m_point; -public: -PointVertexArrayIterator( PointVertex* point ) - : m_point( point ){ -} -PointVertexArrayIterator& operator++(){ - ++m_point; - return *this; -} -PointVertexArrayIterator operator++( int ){ - PointVertexArrayIterator tmp( *this ); - ++m_point; - return tmp; -} -Vertex3f& operator*(){ - return m_point.vertex; -} -Vertex3f* operator->(){ - return &( operator*() ); -} -} - -template 0.000001f ) { - s.x() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.x() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3( b.vertex.y(), b.texcoord.s(), b.texcoord.t() ), - Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) - ), - vector3_subtracted( - Vector3( c.vertex.y(), c.texcoord.s(), c.texcoord.t() ), - Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) - ) - ) - ); - - if ( fabs( cross.x() ) > 0.000001f ) { - s.y() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.y() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3( b.vertex.z(), b.texcoord.s(), b.texcoord.t() ), - Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) - ), - vector3_subtracted( - Vector3( c.vertex.z(), c.texcoord.s(), c.texcoord.t() ), - Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) - ) - ) - ); - - if ( fabs( cross.x() ) > 0.000001f ) { - s.z() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.z() = -cross.z() / cross.x(); - } - } -} - -inline void ArbitraryMeshTriangle_sumTangents( ArbitraryMeshVertex& a, ArbitraryMeshVertex& b, ArbitraryMeshVertex& c ){ - Vector3 s, t; - - ArbitraryMeshTriangle_calcTangents( a, b, c, s, t ); - - reinterpret_cast( a.tangent ) += s; - reinterpret_cast( b.tangent ) += s; - reinterpret_cast( c.tangent ) += s; - - reinterpret_cast( a.bitangent ) += t; - reinterpret_cast( b.bitangent ) += t; - reinterpret_cast( c.bitangent ) += t; -} - - -#endif diff --git a/libs/scenelib.h b/libs/scenelib.h deleted file mode 100644 index 0e6428b..0000000 --- a/libs/scenelib.h +++ /dev/null @@ -1,972 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SCENELIB_H ) -#define INCLUDED_SCENELIB_H - -#include "globaldefs.h" -#include "iscenegraph.h" -#include "iselection.h" - -#include "warnings.h" -#include -#include - -#include "math/aabb.h" -#include "transformlib.h" -#include "generic/callback.h" -#include "generic/reference.h" -#include "container/stack.h" -#include "typesystem.h" - -class Selector; -class SelectionTest; -class VolumeTest; -template class BasicVector3; -typedef BasicVector3 Vector3; -template class BasicVector4; -typedef BasicVector4 Vector4; -class Matrix4; -typedef Vector4 Quaternion; -class AABB; - -class ComponentSelectionTestable -{ -public: -STRING_CONSTANT( Name, "ComponentSelectionTestable" ); - -virtual bool isSelectedComponents() const = 0; -virtual void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ) = 0; -virtual void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ) = 0; -}; - -class ComponentEditable -{ -public: -STRING_CONSTANT( Name, "ComponentEditable" ); - -virtual const AABB& getSelectedComponentsBounds() const = 0; -}; - -class ComponentSnappable -{ -public: -STRING_CONSTANT( Name, "ComponentSnappable" ); - -virtual void snapComponents( float snap ) = 0; -}; - -class Bounded -{ -public: -STRING_CONSTANT( Name, "Bounded" ); - -virtual const AABB& localAABB() const = 0; -}; - -class BrushDoom3 -{ -public: -STRING_CONSTANT( Name, "BrushDoom3" ); - -virtual void setDoom3GroupOrigin( const Vector3& origin ) = 0; -}; - - - - -typedef TypeCastTable NodeTypeCastTable; - -template -class NodeType : public StaticTypeSystemInitialiser -{ -TypeId m_typeId; -public: -typedef typename Type::Name Name; -NodeType() : m_typeId( NODETYPEID_NONE ){ - StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) ); -} -void initialise(){ - m_typeId = GlobalSceneGraph().getNodeTypeId( Name() ); -} -typedef MemberCaller, void (), &NodeType::initialise> InitialiseCaller; -TypeId getTypeId(){ -#if GDEF_DEBUG - ASSERT_MESSAGE( m_typeId != NODETYPEID_NONE, "node-type " << makeQuoted( Name() ) << " used before being initialised" ); -#endif - return m_typeId; -} -}; - -template -class StaticNodeType -{ -public: -enum unnamed0 { SIZE = NODETYPEID_MAX }; -static TypeId getTypeId(){ - return Static< NodeType >::instance().getTypeId(); -} -}; - -template -class NodeStaticCast : - public CastInstaller< - StaticNodeType, - StaticCast - > -{ -}; - -template -class NodeContainedCast : - public CastInstaller< - StaticNodeType, - ContainedCast - > -{ -}; - -template -class NodeIdentityCast : - public CastInstaller< - StaticNodeType, - IdentityCast - > -{ -}; - -namespace scene -{ -class Node -{ -public: -enum unnamed0 { eVisible = 0 }; -enum unnamed1 { eHidden = 1 << 0 }; -enum unnamed2 { eFiltered = 1 << 1 }; -enum unnamed3 { eExcluded = 1 << 2 }; - -class Symbiot -{ -public: -virtual void release() = 0; -virtual ~Symbiot(){ -} -}; - -private: -unsigned int m_state; -std::size_t m_refcount; -Symbiot* m_symbiot; -void* m_node; -NodeTypeCastTable& m_casts; - -public: -bool m_isRoot; - -bool isRoot(){ - return m_isRoot; -} -bool isHidden(){ - return (m_state == eHidden) ? 1 : 0; -} - -Node( Symbiot* symbiot, void* node, NodeTypeCastTable& casts ) : - m_state( eVisible ), - m_refcount( 0 ), - m_symbiot( symbiot ), - m_node( node ), - m_casts( casts ), - m_isRoot( false ){ -} -~Node(){ -} - -void IncRef(){ - ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" ); - ++m_refcount; -} -void DecRef(){ - ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" ); - if ( --m_refcount == 0 ) { - m_symbiot->release(); - } -} -std::size_t getReferenceCount() const { - return m_refcount; -} - -void* cast( TypeId typeId ) const { - return m_casts.cast( typeId, m_node ); -} - -void enable( unsigned int state ){ - m_state |= state; -} -void disable( unsigned int state ){ - m_state &= ~state; -} -bool visible(){ - return m_state == eVisible; -} -bool excluded(){ - return ( m_state & eExcluded ) != 0; -} -bool operator<( const scene::Node& other ){ - return this < &other; -} -bool operator==( const scene::Node& other ){ - return this == &other; -} -bool operator!=( const scene::Node& other ){ - return this != &other; -} -}; - - -class NullNode : public Node::Symbiot -{ -NodeTypeCastTable m_casts; -Node m_node; -public: -NullNode() : m_node( this, 0, m_casts ){ -} -void release(){ - delete this; -} -scene::Node& node(){ - return m_node; -} -}; -} - -template -class NodeTypeCast -{ -public: -static Type* cast( scene::Node& node ){ - return static_cast( node.cast( StaticNodeType::getTypeId() ) ); -} -static const Type* cast( const scene::Node& node ){ - return static_cast( node.cast( StaticNodeType::getTypeId() ) ); -} -}; - - -inline scene::Instantiable* Node_getInstantiable( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - -inline scene::Traversable* Node_getTraversable( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - -inline void Node_traverseSubgraph( scene::Node& node, const scene::Traversable::Walker& walker ){ - if ( walker.pre( node ) ) { - scene::Traversable* traversable = Node_getTraversable( node ); - if ( traversable != 0 ) { - traversable->traverse( walker ); - } - } - walker.post( node ); -} - -inline TransformNode* Node_getTransformNode( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - - -inline scene::Node& NewNullNode(){ - return ( new scene::NullNode )->node(); -} - -inline void Path_deleteTop( const scene::Path& path ){ - Node_getTraversable( path.parent() )->erase( path.top() ); -} - - - - - -class delete_all : public scene::Traversable::Walker -{ -scene::Node& m_parent; -public: -delete_all( scene::Node& parent ) : m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - return false; -} -void post( scene::Node& node ) const { - Node_getTraversable( m_parent )->erase( node ); -} -}; - -inline void DeleteSubgraph( scene::Node& subgraph ){ - Node_getTraversable( subgraph )->traverse( delete_all( subgraph ) ); -} - - -class EntityUndefined -{ -public: -STRING_CONSTANT( Name, "Entity" ); -}; - -inline bool Node_isEntity( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -template -class EntityWalker : public scene::Graph::Walker -{ -const Functor& functor; -public: -EntityWalker( const Functor& functor ) : functor( functor ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( Node_isEntity( path.top() ) ) { - functor( instance ); - return false; - } - return true; -} -}; - -template -inline const Functor& Scene_forEachEntity( const Functor& functor ){ - GlobalSceneGraph().traverse( EntityWalker( functor ) ); - return functor; -} - -class BrushUndefined -{ -public: -STRING_CONSTANT( Name, "Brush" ); -}; - -inline bool Node_isBrush( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -class PatchUndefined -{ -public: -STRING_CONSTANT( Name, "Patch" ); -}; - -inline bool Node_isPatch( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -inline bool Node_isPrimitive( scene::Node& node ){ -#if 1 - return Node_isBrush( node ) || Node_isPatch( node ); -#else - return !node.isRoot(); -#endif -} - -inline bool Node_isHidden( scene::Node& node ){ - return node.isHidden(); -} - -class ParentBrushes : public scene::Traversable::Walker -{ -scene::Node& m_parent; -public: -ParentBrushes( scene::Node& parent ) - : m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - return false; -} -void post( scene::Node& node ) const { - if ( Node_isPrimitive( node ) ) { - Node_getTraversable( m_parent )->insert( node ); - } -} -}; - -inline void parentBrushes( scene::Node& subgraph, scene::Node& parent ){ - Node_getTraversable( subgraph )->traverse( ParentBrushes( parent ) ); -} - -class HasBrushes : public scene::Traversable::Walker -{ -bool& m_hasBrushes; -public: -HasBrushes( bool& hasBrushes ) - : m_hasBrushes( hasBrushes ){ - m_hasBrushes = true; -} -bool pre( scene::Node& node ) const { - if ( !Node_isPrimitive( node ) ) { - m_hasBrushes = false; - } - return false; -} -}; - -inline bool node_is_group( scene::Node& node ){ - scene::Traversable* traversable = Node_getTraversable( node ); - if ( traversable != 0 ) { - bool hasBrushes = false; - traversable->traverse( HasBrushes( hasBrushes ) ); - return hasBrushes; - } - return false; -} - -typedef TypeCastTable InstanceTypeCastTable; - -template -class InstanceType : public StaticTypeSystemInitialiser -{ -TypeId m_typeId; -public: -typedef typename Type::Name Name; -InstanceType() : m_typeId( INSTANCETYPEID_NONE ){ - StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) ); -} -void initialise(){ - m_typeId = GlobalSceneGraph().getInstanceTypeId( Name() ); -} -typedef MemberCaller, void (), &InstanceType::initialise> InitialiseCaller; -TypeId getTypeId(){ -#if GDEF_DEBUG - ASSERT_MESSAGE( m_typeId != INSTANCETYPEID_NONE, "instance-type " << makeQuoted( Name() ) << " used before being initialised" ); -#endif - return m_typeId; -} -}; - -template -class StaticInstanceType -{ -public: -enum unnamed0 { SIZE = INSTANCETYPEID_MAX }; -static TypeId getTypeId(){ - return Static< InstanceType >::instance().getTypeId(); -} -}; - -template -class InstanceStaticCast : - public CastInstaller< - StaticInstanceType, - StaticCast - > -{ -}; - -template -class InstanceContainedCast : - public CastInstaller< - StaticInstanceType, - ContainedCast - > -{ -}; - -template -class InstanceIdentityCast : - public CastInstaller< - StaticInstanceType, - IdentityCast - > -{ -}; - - -inline Selectable* Instance_getSelectable( scene::Instance& instance ); -inline const Selectable* Instance_getSelectable( const scene::Instance& instance ); - -inline Bounded* Instance_getBounded( scene::Instance& instance ); -inline const Bounded* Instance_getBounded( const scene::Instance& instance ); - -namespace scene -{ -class Instance -{ -class AABBAccumulateWalker : public scene::Graph::Walker -{ -AABB& m_aabb; -mutable std::size_t m_depth; -public: -AABBAccumulateWalker( AABB& aabb ) : m_aabb( aabb ), m_depth( 0 ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 ) { - aabb_extend_by_aabb_safe( m_aabb, instance.worldAABB() ); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - - -class TransformChangedWalker : public scene::Graph::Walker -{ -public: -bool pre( const scene::Path& path, scene::Instance& instance ) const { - instance.transformChangedLocal(); - return true; -} -}; - -class ParentSelectedChangedWalker : public scene::Graph::Walker -{ -public: -bool pre( const scene::Path& path, scene::Instance& instance ) const { - instance.parentSelectedChanged(); - return true; -} -}; - -class ChildSelectedWalker : public scene::Graph::Walker -{ -bool& m_childSelected; -mutable std::size_t m_depth; -public: -ChildSelectedWalker( bool& childSelected ) : m_childSelected( childSelected ), m_depth( 0 ){ - m_childSelected = false; -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 && !m_childSelected ) { - m_childSelected = instance.isSelected() || instance.childSelected(); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - -Path m_path; -Instance* m_parent; -void* m_instance; -InstanceTypeCastTable& m_casts; - -mutable Matrix4 m_local2world; -mutable AABB m_bounds; -mutable AABB m_childBounds; -mutable bool m_transformChanged; -mutable bool m_transformMutex; -mutable bool m_boundsChanged; -mutable bool m_boundsMutex; -mutable bool m_childBoundsChanged; -mutable bool m_childBoundsMutex; -mutable bool m_isSelected; -mutable bool m_isSelectedChanged; -mutable bool m_childSelected; -mutable bool m_childSelectedChanged; -mutable bool m_parentSelected; -mutable bool m_parentSelectedChanged; -Callback m_childSelectedChangedCallback; -Callback m_transformChangedCallback; - - -void evaluateTransform() const { - if ( m_transformChanged ) { - ASSERT_MESSAGE( !m_transformMutex, "re-entering transform evaluation" ); - m_transformMutex = true; - - m_local2world = ( m_parent != 0 ) ? m_parent->localToWorld() : g_matrix4_identity; - TransformNode* transformNode = Node_getTransformNode( m_path.top() ); - if ( transformNode != 0 ) { - matrix4_multiply_by_matrix4( m_local2world, transformNode->localToParent() ); - } - - m_transformMutex = false; - m_transformChanged = false; - } -} -void evaluateChildBounds() const { - if ( m_childBoundsChanged ) { - ASSERT_MESSAGE( !m_childBoundsMutex, "re-entering bounds evaluation" ); - m_childBoundsMutex = true; - - m_childBounds = AABB(); - - GlobalSceneGraph().traverse_subgraph( AABBAccumulateWalker( m_childBounds ), m_path ); - - m_childBoundsMutex = false; - m_childBoundsChanged = false; - } -} -void evaluateBounds() const { - if ( m_boundsChanged ) { - ASSERT_MESSAGE( !m_boundsMutex, "re-entering bounds evaluation" ); - m_boundsMutex = true; - - m_bounds = childBounds(); - - const Bounded* bounded = Instance_getBounded( *this ); - if ( bounded != 0 ) { - aabb_extend_by_aabb_safe( - m_bounds, - aabb_for_oriented_aabb_safe( bounded->localAABB(), localToWorld() ) - ); - } - - m_boundsMutex = false; - m_boundsChanged = false; - } -} - -Instance( const scene::Instance& other ); -Instance& operator=( const scene::Instance& other ); -public: - -Instance( const scene::Path& path, Instance* parent, void* instance, InstanceTypeCastTable& casts ) : - m_path( path ), - m_parent( parent ), - m_instance( instance ), - m_casts( casts ), - m_local2world( g_matrix4_identity ), - m_transformChanged( true ), - m_transformMutex( false ), - m_boundsChanged( true ), - m_boundsMutex( false ), - m_childBoundsChanged( true ), - m_childBoundsMutex( false ), - m_isSelectedChanged( true ), - m_childSelectedChanged( true ), - m_parentSelectedChanged( true ){ - ASSERT_MESSAGE( ( parent == 0 ) == ( path.size() == 1 ), "instance has invalid parent" ); -} -virtual ~Instance(){ -} - -const scene::Path& path() const { - return m_path; -} - -void* cast( TypeId typeId ) const { - return m_casts.cast( typeId, m_instance ); -} - -const Matrix4& localToWorld() const { - evaluateTransform(); - return m_local2world; -} -void transformChangedLocal(){ - ASSERT_NOTNULL( m_parent ); - m_transformChanged = true; - m_boundsChanged = true; - m_childBoundsChanged = true; - m_transformChangedCallback(); -} -void transformChanged(){ - GlobalSceneGraph().traverse_subgraph( TransformChangedWalker(), m_path ); - boundsChanged(); -} -void setTransformChangedCallback( const Callback& callback ){ - m_transformChangedCallback = callback; -} - - -const AABB& worldAABB() const { - evaluateBounds(); - return m_bounds; -} -const AABB& childBounds() const { - evaluateChildBounds(); - return m_childBounds; -} -void boundsChanged(){ - m_boundsChanged = true; - m_childBoundsChanged = true; - if ( m_parent != 0 ) { - m_parent->boundsChanged(); - } - GlobalSceneGraph().boundsChanged(); -} - -void childSelectedChanged(){ - m_childSelectedChanged = true; - m_childSelectedChangedCallback(); - if ( m_parent != 0 ) { - m_parent->childSelectedChanged(); - } -} -bool childSelected() const { - if ( m_childSelectedChanged ) { - m_childSelectedChanged = false; - GlobalSceneGraph().traverse_subgraph( ChildSelectedWalker( m_childSelected ), m_path ); - } - return m_childSelected; -} - -void setChildSelectedChangedCallback( const Callback& callback ){ - m_childSelectedChangedCallback = callback; -} -void selectedChanged(){ - m_isSelectedChanged = true; - if ( m_parent != 0 ) { - m_parent->childSelectedChanged(); - } - GlobalSceneGraph().traverse_subgraph( ParentSelectedChangedWalker(), m_path ); -} -bool isSelected() const { - if ( m_isSelectedChanged ) { - m_isSelectedChanged = false; - const Selectable* selectable = Instance_getSelectable( *this ); - m_isSelected = selectable != 0 && selectable->isSelected(); - } - return m_isSelected; -} - -void parentSelectedChanged(){ - m_parentSelectedChanged = true; -} -bool parentSelected() const { - if ( m_parentSelectedChanged ) { - m_parentSelectedChanged = false; - m_parentSelected = m_parent != 0 && ( m_parent->isSelected() || m_parent->parentSelected() ); - } - return m_parentSelected; -} -}; -} - -template -class InstanceTypeCast -{ -public: -static Type* cast( scene::Instance& instance ){ - return static_cast( instance.cast( StaticInstanceType::getTypeId() ) ); -} -static const Type* cast( const scene::Instance& instance ){ - return static_cast( instance.cast( StaticInstanceType::getTypeId() ) ); -} -}; - -template -class InstanceWalker : public scene::Graph::Walker -{ -const Functor& m_functor; -public: -InstanceWalker( const Functor& functor ) : m_functor( functor ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - m_functor( instance ); - return true; -} -}; - -template -class ChildInstanceWalker : public scene::Graph::Walker -{ -const Functor& m_functor; -mutable std::size_t m_depth; -public: -ChildInstanceWalker( const Functor& functor ) : m_functor( functor ), m_depth( 0 ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 ) { - m_functor( instance ); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - -template -class InstanceApply : public Functor -{ -public: -InstanceApply( const Functor& functor ) : Functor( functor ){ -} -void operator()( scene::Instance& instance ) const { - Type* result = InstanceTypeCast::cast( instance ); - if ( result != 0 ) { - Functor::operator()( *result ); - } -} -}; - -inline Selectable* Instance_getSelectable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Selectable* Instance_getSelectable( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -template -inline void Scene_forEachChildSelectable( const Functor& functor, const scene::Path& path ){ - GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply >( functor ), path ); -} - -class SelectableSetSelected -{ -bool m_selected; -public: -SelectableSetSelected( bool selected ) : m_selected( selected ){ -} -void operator()( Selectable& selectable ) const { - selectable.setSelected( m_selected ); -} -}; - -inline Bounded* Instance_getBounded( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Bounded* Instance_getBounded( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline Transformable* Instance_getTransformable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Transformable* Instance_getTransformable( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - - -inline ComponentSelectionTestable* Instance_getComponentSelectionTestable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline ComponentEditable* Instance_getComponentEditable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline ComponentSnappable* Instance_getComponentSnappable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - - -inline void Instance_setSelected( scene::Instance& instance, bool selected ){ - Selectable* selectable = Instance_getSelectable( instance ); - if ( selectable != 0 ) { - selectable->setSelected( selected ); - } -} - -inline bool Instance_isSelected( scene::Instance& instance ){ - Selectable* selectable = Instance_getSelectable( instance ); - if ( selectable != 0 ) { - return selectable->isSelected(); - } - return false; -} - -inline scene::Instance& findInstance( const scene::Path& path ){ - scene::Instance* instance = GlobalSceneGraph().find( path ); - ASSERT_MESSAGE( instance != 0, "findInstance: path not found in scene-graph" ); - return *instance; -} - -inline void selectPath( const scene::Path& path, bool selected ){ - Instance_setSelected( findInstance( path ), selected ); -} - -class SelectChildren : public scene::Traversable::Walker -{ -mutable scene::Path m_path; -public: -SelectChildren( const scene::Path& root ) - : m_path( root ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - selectPath( m_path, true ); - return false; -} -void post( scene::Node& node ) const { - m_path.pop(); -} -}; - -inline void Entity_setSelected( scene::Instance& entity, bool selected ){ - scene::Node& node = entity.path().top(); - if ( node_is_group( node ) ) { - Node_getTraversable( node )->traverse( SelectChildren( entity.path() ) ); - } - else - { - Instance_setSelected( entity, selected ); - } -} - -inline bool Entity_isSelected( scene::Instance& entity ){ - if ( node_is_group( entity.path().top() ) ) { - return entity.childSelected(); - } - return Instance_isSelected( entity ); -} - - - -class InstanceCounter -{ -public: -unsigned int m_count; -InstanceCounter() : m_count( 0 ){ -} -}; - - -class Counter -{ -public: -virtual void increment() = 0; -virtual void decrement() = 0; -}; - -#include "generic/callback.h" - -class SimpleCounter : public Counter -{ -Callback m_countChanged; -std::size_t m_count; -public: -void setCountChangedCallback( const Callback& countChanged ){ - m_countChanged = countChanged; -} -void increment(){ - ++m_count; - m_countChanged(); -} -void decrement(){ - --m_count; - m_countChanged(); -} -std::size_t get() const { - return m_count; -} -}; - - -template -class ConstReference; -typedef ConstReference PathConstReference; - -#include "generic/referencecounted.h" -typedef SmartReference > NodeSmartReference; - - -#endif diff --git a/libs/script/Makefile b/libs/script/Makefile deleted file mode 100644 index 24449cc..0000000 --- a/libs/script/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libscript.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp scripttokeniser.h scripttokenwriter.h - -clean: - -rm -f *.o ../libscript.a diff --git a/libs/script/_.cpp b/libs/script/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/script/scripttokeniser.h b/libs/script/scripttokeniser.h deleted file mode 100644 index 8744aec..0000000 --- a/libs/script/scripttokeniser.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCRIPT_SCRIPTTOKENISER_H ) -#define INCLUDED_SCRIPT_SCRIPTTOKENISER_H - -#include "iscriplib.h" - -class ScriptTokeniser : public Tokeniser -{ -enum CharType -{ - eWhitespace, - eCharToken, - eNewline, - eCharQuote, - eCharSolidus, - eCharStar, - eCharSpecial, -}; - -typedef bool ( ScriptTokeniser::*Tokenise )( char c ); - -Tokenise m_stack[3]; -Tokenise* m_state; -SingleCharacterInputStream m_istream; -std::size_t m_scriptline; -std::size_t m_scriptcolumn; - -char m_token[MAXTOKEN]; -char* m_write; - -char m_current; -bool m_eof; -bool m_crossline; -bool m_unget; -bool m_emit; - -bool m_special; - -CharType charType( const char c ){ - switch ( c ) - { - case '\n': return eNewline; - case '"': return eCharQuote; - case '/': return eCharSolidus; - case '*': return eCharStar; - case '{': case '(': case '}': case ')': case '[': case ']': case ',': case ':': return ( m_special ) ? eCharSpecial : eCharToken; - } - - if ( c > 32 ) { - return eCharToken; - } - return eWhitespace; -} - -Tokenise state(){ - return *m_state; -} -void push( Tokenise state ){ - ASSERT_MESSAGE( m_state != m_stack + 2, "token parser: illegal stack push" ); - *( ++m_state ) = state; -} -void pop(){ - ASSERT_MESSAGE( m_state != m_stack, "token parser: illegal stack pop" ); - --m_state; -} -void add( const char c ){ - if ( m_write < m_token + MAXTOKEN - 1 ) { - *m_write++ = c; - } -} -void remove(){ - ASSERT_MESSAGE( m_write > m_token, "no char to remove" ); - --m_write; -} - -bool tokeniseDefault( char c ){ - switch ( charType( c ) ) - { - case eNewline: - if ( !m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line before token\n"; - return false; - } - break; - case eCharToken: - case eCharStar: - push( Tokenise( &ScriptTokeniser::tokeniseToken ) ); - add( c ); - break; - case eCharSpecial: - push( Tokenise( &ScriptTokeniser::tokeniseSpecial ) ); - add( c ); - break; - case eCharQuote: - push( Tokenise( &ScriptTokeniser::tokeniseQuotedToken ) ); - break; - case eCharSolidus: - push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) ); - break; - default: - break; - } - return true; -} -bool tokeniseToken( char c ){ - switch ( charType( c ) ) - { - case eNewline: - case eWhitespace: - case eCharQuote: - case eCharSpecial: - pop(); - m_emit = true; // emit token - break; - case eCharSolidus: -#if 0 //SPoG: ignore comments in the middle of tokens. - push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) ); - break; -#endif - case eCharToken: - case eCharStar: - add( c ); - break; - default: - break; - } - return true; -} -bool tokeniseQuotedToken( char c ){ - switch ( charType( c ) ) - { - case eNewline: - if ( m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line in quoted token\n"; - return false; - } - break; - case eWhitespace: - case eCharToken: - case eCharSolidus: - case eCharStar: - case eCharSpecial: - add( c ); - break; - case eCharQuote: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseEndQuote ) ); - break; - default: - break; - } - return true; -} -bool tokeniseSolidus( char c ){ - switch ( charType( c ) ) - { - case eNewline: - case eWhitespace: - case eCharQuote: - case eCharSpecial: - pop(); - add( '/' ); - m_emit = true; // emit single slash - break; - case eCharToken: - pop(); - add( '/' ); - add( c ); - break; - case eCharSolidus: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseComment ) ); - break; // dont emit single slash - case eCharStar: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) ); - break; // dont emit single slash - default: - break; - } - return true; -} -bool tokeniseComment( char c ){ - if ( c == '\n' ) { - pop(); - if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) { - pop(); - m_emit = true; // emit token immediatly preceding comment - } - } - return true; -} -bool tokeniseBlockComment( char c ){ - if ( c == '*' ) { - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseEndBlockComment ) ); - } - return true; -} -bool tokeniseEndBlockComment( char c ){ - switch ( c ) - { - case '/': - pop(); - if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) { - pop(); - m_emit = true; // emit token immediatly preceding comment - } - break; // dont emit comment - case '*': - break; // no state change - default: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) ); - break; - } - return true; -} -bool tokeniseEndQuote( char c ){ - pop(); - m_emit = true; // emit quoted token - return true; -} -bool tokeniseSpecial( char c ){ - pop(); - m_emit = true; // emit single-character token - return true; -} - -/// Returns true if a token was successfully parsed. -bool tokenise(){ - m_write = m_token; - while ( !eof() ) - { - char c = m_current; - - if ( !( ( *this ).*state() )( c ) ) { - // parse error - m_eof = true; - return false; - } - if ( m_emit ) { - m_emit = false; - return true; - } - - if ( c == '\n' ) { - ++m_scriptline; - m_scriptcolumn = 1; - } - else - { - ++m_scriptcolumn; - } - - m_eof = !m_istream.readChar( m_current ); - } - return m_write != m_token; -} - -const char* fillToken(){ - if ( !tokenise() ) { - return 0; - } - - add( '\0' ); - return m_token; -} - -bool eof(){ - return m_eof; -} - -public: -ScriptTokeniser( TextInputStream& istream, bool special ) - : m_state( m_stack ), - m_istream( istream ), - m_scriptline( 1 ), - m_scriptcolumn( 1 ), - m_crossline( false ), - m_unget( false ), - m_emit( false ), - m_special( special ){ - m_stack[0] = Tokenise( &ScriptTokeniser::tokeniseDefault ); - m_eof = !m_istream.readChar( m_current ); - m_token[MAXTOKEN - 1] = '\0'; -} -void release(){ - delete this; -} -void nextLine(){ - m_crossline = true; -} -const char* getToken(){ - if ( m_unget ) { - m_unget = false; - return m_token; - } - - return fillToken(); -} -void ungetToken(){ - ASSERT_MESSAGE( !m_unget, "can't unget more than one token" ); - m_unget = true; -} -std::size_t getLine() const { - return m_scriptline; -} -std::size_t getColumn() const { - return m_scriptcolumn; -} -}; - - -inline Tokeniser& NewScriptTokeniser( TextInputStream& istream ){ - return *( new ScriptTokeniser( istream, true ) ); -} - -inline Tokeniser& NewSimpleTokeniser( TextInputStream& istream ){ - return *( new ScriptTokeniser( istream, false ) ); -} - -#endif diff --git a/libs/script/scripttokenwriter.h b/libs/script/scripttokenwriter.h deleted file mode 100644 index 49ee57a..0000000 --- a/libs/script/scripttokenwriter.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCRIPT_SCRIPTTOKENWRITER_H ) -#define INCLUDED_SCRIPT_SCRIPTTOKENWRITER_H - -#include "iscriplib.h" - -class SimpleTokenWriter : public TokenWriter -{ -public: -SimpleTokenWriter( TextOutputStream& ostream ) - : m_ostream( ostream ), m_separator( '\n' ){ -} -~SimpleTokenWriter(){ - writeSeparator(); -} -void release(){ - delete this; -} -void nextLine(){ - m_separator = '\n'; -} -void writeToken( const char* token ){ - ASSERT_MESSAGE( strchr( token, ' ' ) == 0, "token contains whitespace: " ); - writeSeparator(); - m_ostream << token; -} -void writeString( const char* string ){ - writeSeparator(); - m_ostream << '"' << string << '"'; -} -void writeInteger( int i ){ - writeSeparator(); - m_ostream << i; -} -void writeUnsigned( std::size_t i ){ - writeSeparator(); - m_ostream << Unsigned( i ); -} -void writeFloat( double f ){ - writeSeparator(); - m_ostream << Decimal( f ); -} - -private: -void writeSeparator(){ - m_ostream << m_separator; - m_separator = ' '; -} -TextOutputStream& m_ostream; -char m_separator; -}; - -inline TokenWriter& NewSimpleTokenWriter( TextOutputStream& ostream ){ - return *( new SimpleTokenWriter( ostream ) ); -} - -#endif diff --git a/libs/selectionlib.h b/libs/selectionlib.h deleted file mode 100644 index 6789046..0000000 --- a/libs/selectionlib.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SELECTIONLIB_H ) -#define INCLUDED_SELECTIONLIB_H - -#include "iselection.h" -#include "generic/callback.h" -#include "scenelib.h" -#include - -class SelectableBool : public Selectable -{ -bool m_selected; -public: -SelectableBool() - : m_selected( false ) -{ -} - -void setSelected( bool select = true ){ - m_selected = select; -} -bool isSelected() const { - return m_selected; -} -}; - -class ObservedSelectable : public Selectable -{ -SelectionChangeCallback m_onchanged; -bool m_selected; -public: -ObservedSelectable( const SelectionChangeCallback& onchanged ) : m_onchanged( onchanged ), m_selected( false ){ -} -ObservedSelectable( const ObservedSelectable& other ) : Selectable( other ), m_onchanged( other.m_onchanged ), m_selected( false ){ - setSelected( other.isSelected() ); -} -ObservedSelectable& operator=( const ObservedSelectable& other ){ - setSelected( other.isSelected() ); - return *this; -} -~ObservedSelectable(){ - setSelected( false ); -} - -void setSelected( bool select ){ - if ( select ^ m_selected ) { - m_selected = select; - - m_onchanged( *this ); - } -} -bool isSelected() const { - return m_selected; -} -}; - -class SelectableInstance : public scene::Instance -{ -class TypeCasts -{ -InstanceTypeCastTable m_casts; -public: -TypeCasts(){ - InstanceContainedCast::install( m_casts ); -} -InstanceTypeCastTable& get(){ - return m_casts; -} -}; - -ObservedSelectable m_selectable; -public: - -typedef LazyStatic StaticTypeCasts; - -SelectableInstance( const scene::Path& path, scene::Instance* parent, void* instance = 0, InstanceTypeCastTable& casts = StaticTypeCasts::instance().get() ) : - Instance( path, parent, instance != 0 ? instance : this, casts ), - m_selectable( SelectedChangedCaller( *this ) ){ -} - -Selectable& get( NullType){ - return m_selectable; -} - -Selectable& getSelectable(){ - return m_selectable; -} -const Selectable& getSelectable() const { - return m_selectable; -} - -void selectedChanged( const Selectable& selectable ){ - GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable ); - GlobalSelectionSystem().onSelectedChanged( *this, selectable ); - - Instance::selectedChanged(); -} -typedef MemberCaller SelectedChangedCaller; -}; - - -template -inline bool range_check( Iterator start, Iterator finish, Iterator iter ){ - for (; start != finish; ++start ) - { - if ( start == iter ) { - return true; - } - } - return false; -} - -#include - -template -class SelectionList -{ -typedef std::list List; -List m_selection; -public: -typedef typename List::iterator iterator; -typedef typename List::const_iterator const_iterator; - -iterator begin(){ - return m_selection.begin(); -} -const_iterator begin() const { - return m_selection.begin(); -} -iterator end(){ - return m_selection.end(); -} -const_iterator end() const { - return m_selection.end(); -} -bool empty() const { - return m_selection.empty(); -} -std::size_t size() const { - return m_selection.size(); -} -Selected& back(){ - return *m_selection.back(); -} -Selected& back() const { - return *m_selection.back(); -} -void append( Selected& selected ){ - m_selection.push_back( &selected ); -} -void erase( Selected& selected ){ - typename List::reverse_iterator i = std::find( m_selection.rbegin(), m_selection.rend(), &selected ); - ASSERT_MESSAGE( i != m_selection.rend(), "selection-tracking error" ); - ASSERT_MESSAGE( range_check( m_selection.begin(), m_selection.end(), --i.base() ), "selection-tracking error" ); - m_selection.erase( --i.base() ); -} -}; - - -#endif diff --git a/libs/shaderlib.h b/libs/shaderlib.h deleted file mode 100644 index bcd540e..0000000 --- a/libs/shaderlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SHADERLIB_H ) -#define INCLUDED_SHADERLIB_H - -#include "string/string.h" -#include "character.h" -#include "ishaders.h" - -inline bool shader_equal( const char* shader, const char* other ){ - return string_equal_nocase( shader, other ); -} - -inline bool shader_equal_n( const char* shader, const char* other, std::size_t n ){ - return string_equal_nocase_n( shader, other, n ); -} - -inline bool shader_less( const char* shader, const char* other ){ - return string_less_nocase( shader, other ); -} - -inline bool shader_equal_prefix( const char* string, const char* prefix ){ - return shader_equal_n( string, prefix, string_length( prefix ) ); -} - -class shader_less_t -{ -public: -bool operator()( const CopiedString& shader, const CopiedString& other ) const { - return shader_less( shader.c_str(), other.c_str() ); -} -}; - -inline bool shader_valid( const char* shader ){ - return string_is_ascii( shader ) - && strchr( shader, ' ' ) == 0 - && strchr( shader, '\n' ) == 0 - && strchr( shader, '\r' ) == 0 - && strchr( shader, '\t' ) == 0 - && strchr( shader, '\v' ) == 0 - && strchr( shader, '\\' ) == 0; -} - -inline const char* GlobalTexturePrefix_get(){ - return GlobalShaderSystem().getTexturePrefix(); -} - -inline bool shader_is_texture( const char* name ){ - return shader_equal_prefix( name, GlobalTexturePrefix_get() ); -} - -inline const char* shader_get_textureName( const char* name ){ - return name + string_length( GlobalTexturePrefix_get() ); -} - -inline bool texdef_name_valid( const char* name ){ - return shader_valid( name ) && shader_is_texture( name ); -} - -inline const char* texdef_name_default(){ - return GlobalTexturePrefix_get(); -} - - -#endif diff --git a/libs/signal/Makefile b/libs/signal/Makefile deleted file mode 100644 index bfd9233..0000000 --- a/libs/signal/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - signal.o - -# binary target -../libsignal.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -signal.o: signal.cpp isignal.h signal.h signalfwd.h - -clean: - -rm -f *.o ../libsignal.a diff --git a/libs/signal/isignal.h b/libs/signal/isignal.h deleted file mode 100644 index 66075be..0000000 --- a/libs/signal/isignal.h +++ /dev/null @@ -1,166 +0,0 @@ - -#if !defined( INCLUDED_ISIGNAL_H ) -#define INCLUDED_ISIGNAL_H - -#include "generic/callback.h" -#include "signal/signalfwd.h" - -class SignalHandlerResult -{ -bool value; -public: -explicit SignalHandlerResult( bool value ) : value( value ){ -} -bool operator==( SignalHandlerResult other ) const { - return value == other.value; -} -bool operator!=( SignalHandlerResult other ) const { - return !operator==( other ); -} -}; - -const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false ); -const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true ); - -template -class SignalHandlerCallerN; - -template -class SignalHandlerCallerN { -public: -using func = SignalHandlerResult(Ts ...); - -static SignalHandlerResult call(Ts... args) { - Caller::call(args ...); - return SIGNAL_CONTINUE_EMISSION; -} -}; - -template -using SignalHandlerCaller = SignalHandlerCallerN >; - -template -using SignalHandlerCaller1 = SignalHandlerCaller; - -template -using SignalHandlerCaller2 = SignalHandlerCaller; - -template -using SignalHandlerCaller3 = SignalHandlerCaller; - -template -using SignalHandlerCaller4 = SignalHandlerCaller; - -template -class TypeEqual { -public: -using type = False; -}; - -template -class TypeEqual { -public: -using type = True; -}; - -template class Wrapper> -class SignalHandlerN : public CB { -public: -template -SignalHandlerN(const BindFirstOpaque &caller) - : CB(BindFirstOpaque, - get_result_type - >::type>(caller.getBound())) { -} -}; - -class SignalHandler : public SignalHandlerN, SignalHandlerCaller1> { -using SignalHandlerN, SignalHandlerCaller1>::SignalHandlerN; -}; - -template -inline SignalHandler makeSignalHandler( const BindFirstOpaque& caller ){ - return SignalHandler( caller ); -} -template -inline SignalHandler makeSignalHandler(const Caller &caller, get_argument callee) { - return SignalHandler( BindFirstOpaque( callee ) ); -} - -template -class SignalHandler1 : public SignalHandlerN, SignalHandlerCaller2> { -using SignalHandlerN, SignalHandlerCaller2>::SignalHandlerN; -}; - -template -inline SignalHandler1 > makeSignalHandler1(const BindFirstOpaque &caller) { - return SignalHandler1 >(caller); -} -template -inline SignalHandler1 > -makeSignalHandler1(const Caller &caller, get_argument callee) { - return SignalHandler1 >(BindFirstOpaque(callee)); -} - -template -class SignalHandler2 - : public SignalHandlerN, SignalHandlerCaller3> { -using SignalHandlerN, SignalHandlerCaller3>::SignalHandlerN; -}; - -template -inline SignalHandler2< - get_argument, - get_argument - > makeSignalHandler2(const BindFirstOpaque &caller) { - return SignalHandler2< - get_argument, - get_argument - >( caller ); -} -template -inline SignalHandler2< - get_argument, - get_argument - > makeSignalHandler2(const Caller &caller, get_argument callee) { - return SignalHandler2< - get_argument, - get_argument - >(BindFirstOpaque(callee)); -} - -template -class SignalHandler3 - : public SignalHandlerN, SignalHandlerCaller4> { -using SignalHandlerN, SignalHandlerCaller4>::SignalHandlerN; -}; - -template -inline SignalHandler3< - get_argument, - get_argument, - get_argument - > makeSignalHandler3(const BindFirstOpaque &caller) { - return SignalHandler3< - get_argument, - get_argument, - get_argument - >( caller ); -} -template -inline SignalHandler3< - get_argument, - get_argument, - get_argument - > makeSignalHandler3(const Caller &caller, get_argument callee) { - return SignalHandler3< - get_argument, - get_argument, - get_argument - >(BindFirstOpaque(callee)); -} - -#endif diff --git a/libs/signal/signal.cpp b/libs/signal/signal.cpp deleted file mode 100644 index 703901d..0000000 --- a/libs/signal/signal.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -#include "signal.h" - - - -namespace -{ -class Test -{ -}; -class A1 -{ -}; -class A2 -{ -}; -class A3 -{ -}; - -SignalHandlerResult handler0( Test& ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler0; - -int function0( Test& ){ - return 7; -} -typedef Function TestFunction0; - -SignalHandlerResult handler1( Test&, A1 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler1; - -void function1( Test&, A1 ){ -} -typedef ReferenceCaller TestFunction1; - -SignalHandlerResult handler2( Test&, A1, A2 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler2; - -void function2( Test&, A1, A2 ){ -} -typedef Function TestFunction2; - -SignalHandlerResult handler3( Test&, A1, A2, A3 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler3; - -void function3( Test&, A1, A2, A3 ){ -} -typedef Function TestFunction3; - -void testSignals(){ - Test test; - { - Signal0 e0; - Signal0::handler_id_type a = e0.connectLast( makeSignalHandler( TestHandler0(), test ) ); // signal handler from direct caller returning result - Signal0::handler_id_type b = e0.connectFirst( makeSignalHandler( TestFunction0(), test ) ); // signal handler from direct caller returning int - e0(); - e0.disconnect( a ); - e0.disconnect( b ); - } - { - typedef Signal1 Signal1Test; - Signal1Test e1; - Signal1Test::handler_id_type a = e1.connectLast( makeSignalHandler1( TestHandler1(), test ) ); // signal handler from direct caller with one argument, returning result - Signal1Test::handler_id_type b = e1.connectFirst( makeSignalHandler1( TestFunction1( test ) ) ); // signal handler from opaque caller with one argument, returning void - e1( A1() ); - e1.disconnect( a ); - e1.disconnect( b ); - } - { - typedef Signal2 Signal2Test; - Signal2Test e2; - Signal2Test::handler_id_type a = e2.connectLast( makeSignalHandler2( TestHandler2(), test ) ); // signal handler from direct caller with two arguments, returning result - Signal2Test::handler_id_type b = e2.connectLast( makeSignalHandler2( TestFunction2(), test ) ); // signal handler from direct caller with two arguments, returning void - e2( A1(), A2() ); - e2.disconnect( a ); - e2.disconnect( b ); - } - { - typedef Signal3 Signal3Test; - Signal3Test e3; - Signal3Test::handler_id_type a = e3.connectLast( makeSignalHandler3( TestHandler3(), test ) ); // signal handler from direct caller with three arguments, returning result - Signal3Test::handler_id_type b = e3.connectLast( makeSignalHandler3( TestFunction3(), test ) ); // signal handler from direct caller with three arguments, returning void - e3( A1(), A2(), A3() ); - e3.disconnect( a ); - e3.disconnect( b ); - } -} -} diff --git a/libs/signal/signal.h b/libs/signal/signal.h deleted file mode 100644 index f10d8bb..0000000 --- a/libs/signal/signal.h +++ /dev/null @@ -1,342 +0,0 @@ - -#if !defined( INCLUDED_SIGNAL_H ) -#define INCLUDED_SIGNAL_H - -#include "isignal.h" -#include "memory/allocator.h" -#include "debugging/debugging.h" -#include - -namespace ListDetail -{ -struct ListNodeBase -{ - ListNodeBase* next; - ListNodeBase* prev; -}; - -inline void list_initialise( ListNodeBase& self ){ - self.next = self.prev = &self; -} - -inline void list_swap( ListNodeBase& self, ListNodeBase& other ){ - ListNodeBase tmp( self ); - if ( other.next == &other ) { - list_initialise( self ); - } - else - { - self = other; - self.next->prev = self.prev->next = &self; - } - if ( tmp.next == &self ) { - list_initialise( other ); - } - else - { - other = tmp; - other.next->prev = other.prev->next = &other; - } -} - -inline void node_link( ListNodeBase* node, ListNodeBase* next ){ - node->next = next; - node->prev = next->prev; - next->prev = node; - node->prev->next = node; -} -inline void node_unlink( ListNodeBase* node ){ - node->prev->next = node->next; - node->next->prev = node->prev; -} - -template -struct ListNode : public ListNodeBase -{ - Value value; - - ListNode( const Value& value ) : value( value ){ - } - ListNode* getNext() const { - return static_cast( next ); - } - ListNode* getPrev() const { - return static_cast( prev ); - } -}; - -template -class NonConstTraits -{ -public: -typedef Type value_type; -typedef value_type* pointer; -typedef value_type& reference; - -template -struct rebind -{ - typedef NonConstTraits other; -}; -}; - -template -class ConstTraits -{ -public: -typedef Type value_type; -typedef const value_type* pointer; -typedef const value_type& reference; - -template -struct rebind -{ - typedef ConstTraits other; -}; -}; - -template -class ListIterator -{ -public: -typedef std::bidirectional_iterator_tag iterator_category; -typedef std::ptrdiff_t difference_type; -typedef difference_type distance_type; -typedef typename Traits::value_type value_type; -typedef typename Traits::pointer pointer; -typedef typename Traits::reference reference; - -private: -typedef ListNode Node; -typedef typename Traits::template rebind::other NodeTraits; -typedef typename NodeTraits::pointer NodePointer; -typedef typename Traits::template rebind< Opaque >::other OpaqueTraits; -typedef typename OpaqueTraits::pointer OpaquePointer; -NodePointer m_node; - -void increment(){ - m_node = m_node->getNext(); -} -void decrement(){ - m_node = m_node->getPrev(); -} - - -public: -explicit ListIterator( NodePointer node ) : m_node( node ){ -} -explicit ListIterator( OpaquePointer p ) : m_node( reinterpret_cast( p ) ){ -} - -NodePointer node(){ - return m_node; -} -OpaquePointer opaque() const { - return reinterpret_cast( m_node ); -} - -bool operator==( const ListIterator& other ) const { - return m_node == other.m_node; -} -bool operator!=( const ListIterator& other ) const { - return !operator==( other ); -} -ListIterator& operator++(){ - increment(); - return *this; -} -ListIterator operator++( int ){ - ListIterator tmp = *this; - increment(); - return tmp; -} -ListIterator& operator--(){ - decrement(); - return *this; -} -ListIterator operator--( int ){ - ListIterator tmp = *this; - decrement(); - return tmp; -} -reference operator*() const { - return m_node->value; -} -pointer operator->() const { - return &( operator*() ); -} -}; -} - -template > -class List : private Allocator -{ -typedef ListDetail::ListNode Node; -ListDetail::ListNodeBase list; -typedef typename Allocator::template rebind::other NodeAllocator; - -Node* newNode( const Value& value ){ - return new ( NodeAllocator( *this ).allocate( 1 ) )Node( value ); -} -void deleteNode( Node* node ){ - node->~Node(); - NodeAllocator( *this ).deallocate( node, 1 ); -} -public: -typedef Value value_type; -typedef ListDetail::ListIterator< ListDetail::NonConstTraits > iterator; -typedef ListDetail::ListIterator< ListDetail::ConstTraits > const_iterator; - -List(){ - list_initialise( list ); -} -explicit List( const Allocator& allocator ) : Allocator( allocator ){ - list_initialise( list ); -} -~List(){ - for (; list.next != &list; ) - { - Node* node = static_cast( list.next ); - list.next = list.next->next; - deleteNode( node ); - } -} -iterator begin(){ - return iterator( static_cast( list.next ) ); -} -iterator end(){ - return iterator( static_cast( &list ) ); -} -const_iterator begin() const { - return const_iterator( static_cast( list.next ) ); -} -const_iterator end() const { - return const_iterator( static_cast( &list ) ); -} -void push_back( const Value& value ){ - insert( end(), value ); -} -void pop_back( const Value& value ){ - erase( --end(), value ); -} -void push_front( const Value& value ){ - insert( begin(), value ); -} -void pop_front( const Value& value ){ - erase( begin(), value ); -} -iterator insert( iterator pos, const Value& value ){ - Node* node = newNode( value ); - node_link( node, pos.node() ); - return iterator( node ); -} -iterator erase( iterator pos ){ - Node* node = pos.node(); - Node* next = node->getNext(); - node_unlink( node ); - deleteNode( node ); - return iterator( next ); -} -}; - -template -class SignalBase -{ -typedef List SignalList; -SignalList events; - -public: - -typedef Functor handler_type; -typedef Handle< Opaque > handler_id_type; -typedef typename SignalList::iterator iterator; -typedef typename SignalList::const_iterator const_iterator; -iterator begin(){ - return events.begin(); -} -iterator end(){ - return events.end(); -} -const_iterator begin() const { - return events.begin(); -} -const_iterator end() const { - return events.end(); -} -handler_id_type connectFirst( const Functor& event ){ - events.push_front( event ); - return handler_id_type( begin().opaque() ); -} -handler_id_type connectLast( const Functor& event ){ - events.push_back( event ); - return handler_id_type( ( --end() ).opaque() ); -} -bool isConnected( handler_id_type id ){ - for ( iterator i = begin(); i != end(); ++i ) - { - if ( id.get() == i.opaque() ) { - return true; - } - } - return false; -} -handler_id_type connectBefore( handler_id_type id, const Functor& event ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectBefore: invalid id" ); - return events.insert( iterator( id.get() ), event ).opaque(); -} -handler_id_type connectAfter( handler_id_type id, const Functor& event ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectAfter: invalid id" ); - return events.insert( ++iterator( id.get() ), event ).opaque(); -} -void disconnect( handler_id_type id ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::disconnect: invalid id" ); - events.erase( iterator( id.get() ) ); -} -}; - -///\brief -// It is safe to disconnect the signal handler currently being invoked. -template -inline void invokeSignalHandlers( InputIterator first, InputIterator last, SignalHandlerInvoke invoke ){ - while ( first != last && invoke( *first++ ) != SIGNAL_STOP_EMISSION ); -} - -class Signal0 : public SignalBase -{ -public: -void operator()() const { - invokeSignalHandlers( begin(), end(), FunctorInvoke() ); -} -}; - -template -class Signal1 : public SignalBase< SignalHandler1 > -{ -typedef SignalBase< SignalHandler1 > Base; -public: -void operator()( FirstArgument a1 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1 ) ); -} -}; - -template -class Signal2 : public SignalBase< SignalHandler2 > -{ -typedef SignalBase< SignalHandler2 > Base; -public: -void operator()( FirstArgument a1, SecondArgument a2 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2 ) ); -} -}; - -template -class Signal3 : public SignalBase< SignalHandler3 > -{ -typedef SignalBase< SignalHandler3 > Base; -public: -void operator()( FirstArgument a1, SecondArgument a2, ThirdArgument a3 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2, a3 ) ); -} -}; - -#endif diff --git a/libs/signal/signalfwd.h b/libs/signal/signalfwd.h deleted file mode 100644 index 507c0e7..0000000 --- a/libs/signal/signalfwd.h +++ /dev/null @@ -1,44 +0,0 @@ - -#if !defined( INCLUDED_SIGNALFWD_H ) -#define INCLUDED_SIGNALFWD_H - -class SignalHandler; -template -class SignalHandler1; -template -class SignalHandler2; -template -class SignalHandler3; - -template -class Opaque; - -///\brief A pointer that always has a well-defined value. -/// If no value is specified, the appropriate null value is used. -template -class Handle -{ -Type* p; -public: -Handle() : p( 0 ){ -} -explicit Handle( Type* p ) : p( p ){ -} -Type* get() const { - return p; -} -bool isNull() const { - return p == 0; -} -}; - -template -class SignalFwd -{ -public: -typedef Handle< Opaque > handler_id_type; -}; - -typedef SignalFwd::handler_id_type SignalHandlerId; - -#endif diff --git a/libs/splines/Makefile b/libs/splines/Makefile deleted file mode 100644 index d348302..0000000 --- a/libs/splines/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - math_angles.o \ - math_matrix.o \ - math_quaternion.o \ - math_vector.o \ - q_parse.o \ - q_shared.o \ - splines.o \ - util_str.o - -# binary target -../libsplines.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -math_angles.o: math_angles.cpp math_angles.h -math_matrix.o: math_matrix.cpp math_matrix.h -math_quaternion.o: math_quaternion.cpp math_quaternion.h -math_vector.o: math_vector.cpp math_vector.h -q_parse.o: q_parse.cpp -q_shared.o: q_shared.cpp q_shared.h -splines.o: splines.cpp splines.h -util_str.o: util_str.cpp util_str.h util_list.h - -clean: - -rm -f *.o ../libsplines.a diff --git a/libs/splines/math_angles.cpp b/libs/splines/math_angles.cpp deleted file mode 100644 index 81b7f21..0000000 --- a/libs/splines/math_angles.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" -#include - -angles_t ang_zero( 0.0f, 0.0f, 0.0f ); - -void toAngles( mat3_t &src, angles_t &dst ) { - double theta; - double cp; - double sp; - - sp = src[ 0 ][ 2 ]; - - // cap off our sin value so that we don't get any NANs - if ( sp > 1.0 ) { - sp = 1.0; - } - else if ( sp < -1.0 ) { - sp = -1.0; - } - - theta = -asin( sp ); - cp = cos( theta ); - - if ( cp > 8192 * FLT_EPSILON ) { - dst.pitch = theta * 180 / M_PI; - dst.yaw = atan2( src[ 0 ][ 1 ], src[ 0 ][ 0 ] ) * 180 / M_PI; - dst.roll = atan2( src[ 1 ][ 2 ], src[ 2 ][ 2 ] ) * 180 / M_PI; - } - else { - dst.pitch = theta * 180 / M_PI; - dst.yaw = -atan2( src[ 1 ][ 0 ], src[ 1 ][ 1 ] ) * 180 / M_PI; - dst.roll = 0; - } -} - -void toAngles( quat_t &src, angles_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toAngles( temp, dst ); -} - -void toAngles( idVec3 &src, angles_t &dst ) { - dst.pitch = src[ 0 ]; - dst.yaw = src[ 1 ]; - dst.roll = src[ 2 ]; -} - -void angles_t::toVectors( idVec3 *forward, idVec3 *right, idVec3 *up ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - angle = roll * ( M_PI * 2 / 360 ); - sr = sin( angle ); - cr = cos( angle ); - - if ( forward ) { - forward->set( cp * cy, cp * sy, -sp ); - } - - if ( right ) { - right->set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp ); - } - - if ( up ) { - up->set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); - } -} - -idVec3 angles_t::toForward( void ) { - float angle; - static float sp, sy, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - return idVec3( cp * cy, cp * sy, -sp ); -} - -/* - ================= - Normalize360 - - returns angles normalized to the range [0 <= angle < 360] - ================= - */ -angles_t& angles_t::Normalize360( void ) { - pitch = ( 360.0 / 65536 ) * ( ( int )( pitch * ( 65536 / 360.0 ) ) & 65535 ); - yaw = ( 360.0 / 65536 ) * ( ( int )( yaw * ( 65536 / 360.0 ) ) & 65535 ); - roll = ( 360.0 / 65536 ) * ( ( int )( roll * ( 65536 / 360.0 ) ) & 65535 ); - - return *this; -} - - -/* - ================= - Normalize180 - - returns angles normalized to the range [-180 < angle <= 180] - ================= - */ -angles_t& angles_t::Normalize180( void ) { - Normalize360(); - - if ( pitch > 180.0 ) { - pitch -= 360.0; - } - - if ( yaw > 180.0 ) { - yaw -= 360.0; - } - - if ( roll > 180.0 ) { - roll -= 360.0; - } - return *this; -} diff --git a/libs/splines/math_angles.h b/libs/splines/math_angles.h deleted file mode 100644 index 3c4dae0..0000000 --- a/libs/splines/math_angles.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_ANGLES_H__ -#define __MATH_ANGLES_H__ - -#include -#include - -#include "math_vector.h" - -class mat3_t; -class quat_t; -class idVec3; -typedef idVec3 &vec3_p; - -class angles_t { -public: -float pitch; -float yaw; -float roll; - -angles_t(); -angles_t( float pitch, float yaw, float roll ); -angles_t( const idVec3 &vec ); - -friend void toAngles( idVec3 &src, angles_t &dst ); -friend void toAngles( quat_t &src, angles_t &dst ); -friend void toAngles( mat3_t &src, angles_t &dst ); - -operator vec3_p(); - -float operator[]( int index ) const; -float& operator[]( int index ); - -void set( float pitch, float yaw, float roll ); - -void operator=( angles_t const &a ); -void operator=( idVec3 const &a ); - -friend angles_t operator+( const angles_t &a, const angles_t &b ); -angles_t &operator+=( angles_t const &a ); -angles_t &operator+=( idVec3 const &a ); - -friend angles_t operator-( angles_t &a, angles_t &b ); -angles_t &operator-=( angles_t &a ); - -friend angles_t operator*( const angles_t &a, float b ); -friend angles_t operator*( float a, const angles_t &b ); -angles_t &operator*=( float a ); - -friend int operator==( angles_t &a, angles_t &b ); - -friend int operator!=( angles_t &a, angles_t &b ); - -void toVectors( idVec3 *forward, idVec3 *right = NULL, idVec3 *up = NULL ); -idVec3 toForward( void ); - -angles_t &Zero( void ); - -angles_t &Normalize360( void ); -angles_t &Normalize180( void ); -}; - -extern angles_t ang_zero; - -inline angles_t::angles_t() { -} - -inline angles_t::angles_t( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline angles_t::angles_t( const idVec3 &vec ) { - this->pitch = vec.x; - this->yaw = vec.y; - this->roll = vec.z; -} - -inline float angles_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline float& angles_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline angles_t::operator vec3_p( void ) { - return *( idVec3 * )&pitch; -} - -inline void angles_t::set( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline void angles_t::operator=( angles_t const &a ) { - pitch = a.pitch; - yaw = a.yaw; - roll = a.roll; -} - -inline void angles_t::operator=( idVec3 const &a ) { - pitch = a[ 0 ]; - yaw = a[ 1 ]; - roll = a[ 2 ]; -} - -inline angles_t operator+( const angles_t &a, const angles_t &b ) { - return angles_t( a.pitch + b.pitch, a.yaw + b.yaw, a.roll + b.roll ); -} - -inline angles_t& angles_t::operator+=( angles_t const &a ) { - pitch += a.pitch; - yaw += a.yaw; - roll += a.roll; - - return *this; -} - -inline angles_t& angles_t::operator+=( idVec3 const &a ) { - pitch += a.x; - yaw += a.y; - roll += a.z; - - return *this; -} - -inline angles_t operator-( angles_t &a, angles_t &b ) { - return angles_t( a.pitch - b.pitch, a.yaw - b.yaw, a.roll - b.roll ); -} - -inline angles_t& angles_t::operator-=( angles_t &a ) { - pitch -= a.pitch; - yaw -= a.yaw; - roll -= a.roll; - - return *this; -} - -inline angles_t operator*( const angles_t &a, float b ) { - return angles_t( a.pitch * b, a.yaw * b, a.roll * b ); -} - -inline angles_t operator*( float a, const angles_t &b ) { - return angles_t( a * b.pitch, a * b.yaw, a * b.roll ); -} - -inline angles_t& angles_t::operator*=( float a ) { - pitch *= a; - yaw *= a; - roll *= a; - - return *this; -} - -inline int operator==( angles_t &a, angles_t &b ) { - return ( ( a.pitch == b.pitch ) && ( a.yaw == b.yaw ) && ( a.roll == b.roll ) ); -} - -inline int operator!=( angles_t &a, angles_t &b ) { - return ( ( a.pitch != b.pitch ) || ( a.yaw != b.yaw ) || ( a.roll != b.roll ) ); -} - -inline angles_t& angles_t::Zero( void ) { - pitch = 0.0f; - yaw = 0.0f; - roll = 0.0f; - - return *this; -} - -#endif /* !__MATH_ANGLES_H__ */ diff --git a/libs/splines/math_matrix.cpp b/libs/splines/math_matrix.cpp deleted file mode 100644 index 0f6f7c4..0000000 --- a/libs/splines/math_matrix.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" - -mat3_t mat3_default( idVec3( 1, 0, 0 ), idVec3( 0, 1, 0 ), idVec3( 0, 0, 1 ) ); - -void toMatrix( quat_t const &src, mat3_t &dst ) { - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - - x2 = src.x + src.x; - y2 = src.y + src.y; - z2 = src.z + src.z; - - xx = src.x * x2; - xy = src.x * y2; - xz = src.x * z2; - - yy = src.y * y2; - yz = src.y * z2; - zz = src.z * z2; - - wx = src.w * x2; - wy = src.w * y2; - wz = src.w * z2; - - dst[ 0 ][ 0 ] = 1.0f - ( yy + zz ); - dst[ 0 ][ 1 ] = xy - wz; - dst[ 0 ][ 2 ] = xz + wy; - - dst[ 1 ][ 0 ] = xy + wz; - dst[ 1 ][ 1 ] = 1.0f - ( xx + zz ); - dst[ 1 ][ 2 ] = yz - wx; - - dst[ 2 ][ 0 ] = xz - wy; - dst[ 2 ][ 1 ] = yz + wx; - dst[ 2 ][ 2 ] = 1.0f - ( xx + yy ); -} - -void toMatrix( angles_t const &src, mat3_t &dst ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = src.yaw * ( M_PI * 2.0f / 360.0f ); - sy = sin( angle ); - cy = cos( angle ); - - angle = src.pitch * ( M_PI * 2.0f / 360.0f ); - sp = sin( angle ); - cp = cos( angle ); - - angle = src.roll * ( M_PI * 2.0f / 360.0f ); - sr = sin( angle ); - cr = cos( angle ); - - dst[ 0 ].set( cp * cy, cp * sy, -sp ); - dst[ 1 ].set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); - dst[ 2 ].set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); -} - -void toMatrix( idVec3 const &src, mat3_t &dst ) { - angles_t sup = src; - toMatrix( sup, dst ); -} - -void mat3_t::ProjectVector( const idVec3 &src, idVec3 &dst ) const { - dst.x = src * mat[ 0 ]; - dst.y = src * mat[ 1 ]; - dst.z = src * mat[ 2 ]; -} - -void mat3_t::UnprojectVector( const idVec3 &src, idVec3 &dst ) const { - dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z; -} - -void mat3_t::Transpose( mat3_t &matrix ) { - int i; - int j; - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - matrix[ i ][ j ] = mat[ j ][ i ]; - } - } -} - -void mat3_t::Transpose( void ) { - float temp; - int i; - int j; - - for ( i = 0; i < 3; i++ ) { - for ( j = i + 1; j < 3; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } -} - -mat3_t mat3_t::Inverse( void ) const { - mat3_t inv( *this ); - - inv.Transpose(); - - return inv; -} - -void mat3_t::Clear( void ) { - mat[0].set( 1, 0, 0 ); - mat[1].set( 0, 1, 0 ); - mat[2].set( 0, 0, 1 ); -} diff --git a/libs/splines/math_matrix.h b/libs/splines/math_matrix.h deleted file mode 100644 index 741d4bb..0000000 --- a/libs/splines/math_matrix.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_MATRIX_H__ -#define __MATH_MATRIX_H__ - -#include -#include "math_vector.h" - -class quat_t; -class angles_t; - -class mat3_t { -public: -idVec3 mat[ 3 ]; - -mat3_t(); -mat3_t( float src[ 3 ][ 3 ] ); -mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ); -mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ); - -friend void toMatrix( quat_t const &src, mat3_t &dst ); -friend void toMatrix( angles_t const &src, mat3_t &dst ); -friend void toMatrix( idVec3 const &src, mat3_t &dst ); - -idVec3 operator[]( int index ) const; -idVec3 &operator[]( int index ); - -idVec3 operator*( const idVec3 &vec ) const; -mat3_t operator*( const mat3_t &a ) const; -mat3_t operator*( float a ) const; -mat3_t operator+( mat3_t const &a ) const; -mat3_t operator-( mat3_t const &a ) const; - -friend idVec3 operator*( const idVec3 &vec, const mat3_t &mat ); -friend mat3_t operator*( float a, mat3_t const &b ); - -mat3_t &operator*=( float a ); -mat3_t &operator+=( mat3_t const &a ); -mat3_t &operator-=( mat3_t const &a ); - -void Clear( void ); - -void ProjectVector( const idVec3 &src, idVec3 &dst ) const; -void UnprojectVector( const idVec3 &src, idVec3 &dst ) const; - -void OrthoNormalize( void ); -void Transpose( mat3_t &matrix ); -void Transpose( void ); -mat3_t Inverse( void ) const; -void Identity( void ); - -friend void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ); -friend mat3_t SkewSymmetric( idVec3 const &src ); -}; - -ID_INLINE mat3_t::mat3_t() { -} - -ID_INLINE mat3_t::mat3_t(float src[3][3]) { - memcpy(mat, src, sizeof(float) * 3 * 3); -} - -ID_INLINE mat3_t::mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ) { - mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z; - mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z; - mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z; -} - -ID_INLINE mat3_t::mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) { - mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz; - mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz; - mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz; -} - -ID_INLINE idVec3 mat3_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3& mat3_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3 mat3_t::operator*( const idVec3 &vec ) const { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t mat3_t::operator*( const mat3_t &a ) const { - return mat3_t( - mat[0].x * a[0].x + mat[0].y * a[1].x + mat[0].z * a[2].x, - mat[0].x * a[0].y + mat[0].y * a[1].y + mat[0].z * a[2].y, - mat[0].x * a[0].z + mat[0].y * a[1].z + mat[0].z * a[2].z, - mat[1].x * a[0].x + mat[1].y * a[1].x + mat[1].z * a[2].x, - mat[1].x * a[0].y + mat[1].y * a[1].y + mat[1].z * a[2].y, - mat[1].x * a[0].z + mat[1].y * a[1].z + mat[1].z * a[2].z, - mat[2].x * a[0].x + mat[2].y * a[1].x + mat[2].z * a[2].x, - mat[2].x * a[0].y + mat[2].y * a[1].y + mat[2].z * a[2].y, - mat[2].x * a[0].z + mat[2].y * a[1].z + mat[2].z * a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator*( float a ) const { - return mat3_t( - mat[0].x * a, mat[0].y * a, mat[0].z * a, - mat[1].x * a, mat[1].y * a, mat[1].z * a, - mat[2].x * a, mat[2].y * a, mat[2].z * a ); -} - -ID_INLINE mat3_t mat3_t::operator+( mat3_t const &a ) const { - return mat3_t( - mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, - mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, - mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator-( mat3_t const &a ) const { - return mat3_t( - mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, - mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, - mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z ); -} - -ID_INLINE idVec3 operator*( const idVec3 &vec, const mat3_t &mat ) { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t operator*( float a, mat3_t const &b ) { - return mat3_t( - b[0].x * a, b[0].y * a, b[0].z * a, - b[1].x * a, b[1].y * a, b[1].z * a, - b[2].x * a, b[2].y * a, b[2].z * a ); -} - -ID_INLINE mat3_t &mat3_t::operator*=( float a ) { - mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; - mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; - mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator+=( mat3_t const &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; - mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; - mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator-=( mat3_t const &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; - mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; - - return *this; -} - -ID_INLINE void mat3_t::OrthoNormalize( void ) { - mat[ 0 ].Normalize(); - mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); - mat[ 2 ].Normalize(); - mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); - mat[ 1 ].Normalize(); -} - -ID_INLINE void mat3_t::Identity( void ) { - mat[ 0 ].x = 1.f; mat[ 0 ].y = 0.f; mat[ 0 ].z = 0.f; - mat[ 1 ].x = 0.f; mat[ 1 ].y = 1.f; mat[ 1 ].z = 0.f; - mat[ 2 ].x = 0.f; mat[ 2 ].y = 0.f; mat[ 2 ].z = 1.f; -} - -ID_INLINE void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ) { - dst[0].x = inv[0].x * b[0].x + inv[1].x * b[1].x + inv[2].x * b[2].x; - dst[0].y = inv[0].x * b[0].y + inv[1].x * b[1].y + inv[2].x * b[2].y; - dst[0].z = inv[0].x * b[0].z + inv[1].x * b[1].z + inv[2].x * b[2].z; - dst[1].x = inv[0].y * b[0].x + inv[1].y * b[1].x + inv[2].y * b[2].x; - dst[1].y = inv[0].y * b[0].y + inv[1].y * b[1].y + inv[2].y * b[2].y; - dst[1].z = inv[0].y * b[0].z + inv[1].y * b[1].z + inv[2].y * b[2].z; - dst[2].x = inv[0].z * b[0].x + inv[1].z * b[1].x + inv[2].z * b[2].x; - dst[2].y = inv[0].z * b[0].y + inv[1].z * b[1].y + inv[2].z * b[2].y; - dst[2].z = inv[0].z * b[0].z + inv[1].z * b[1].z + inv[2].z * b[2].z; -} - -ID_INLINE mat3_t SkewSymmetric( idVec3 const &src ) { - return mat3_t( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f ); -} - -extern mat3_t mat3_default; - -#endif /* !__MATH_MATRIX_H__ */ diff --git a/libs/splines/math_quaternion.cpp b/libs/splines/math_quaternion.cpp deleted file mode 100644 index f37f879..0000000 --- a/libs/splines/math_quaternion.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "math_quaternion.h" -#include "math_matrix.h" - -void toQuat( idVec3 &src, quat_t &dst ) { - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; - dst.w = 0.0f; -} - -void toQuat( angles_t &src, quat_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toQuat( temp, dst ); -} - -void toQuat( mat3_t &src, quat_t &dst ) { - float trace; - float s; - int i; - int j; - int k; - - static int next[ 3 ] = { 1, 2, 0 }; - - trace = src[ 0 ][ 0 ] + src[ 1 ][ 1 ] + src[ 2 ][ 2 ]; - if ( trace > 0.0f ) { - s = ( float )sqrt( trace + 1.0f ); - dst.w = s * 0.5f; - s = 0.5f / s; - - dst.x = ( src[ 2 ][ 1 ] - src[ 1 ][ 2 ] ) * s; - dst.y = ( src[ 0 ][ 2 ] - src[ 2 ][ 0 ] ) * s; - dst.z = ( src[ 1 ][ 0 ] - src[ 0 ][ 1 ] ) * s; - } - else { - i = 0; - if ( src[ 1 ][ 1 ] > src[ 0 ][ 0 ] ) { - i = 1; - } - if ( src[ 2 ][ 2 ] > src[ i ][ i ] ) { - i = 2; - } - - j = next[ i ]; - k = next[ j ]; - - s = ( float )sqrt( ( src[ i ][ i ] - ( src[ j ][ j ] + src[ k ][ k ] ) ) + 1.0f ); - dst[ i ] = s * 0.5f; - - s = 0.5f / s; - - dst.w = ( src[ k ][ j ] - src[ j ][ k ] ) * s; - dst[ j ] = ( src[ j ][ i ] + src[ i ][ j ] ) * s; - dst[ k ] = ( src[ k ][ i ] + src[ i ][ k ] ) * s; - } -} diff --git a/libs/splines/math_quaternion.h b/libs/splines/math_quaternion.h deleted file mode 100644 index b33f442..0000000 --- a/libs/splines/math_quaternion.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_QUATERNION_H__ -#define __MATH_QUATERNION_H__ - -#include -#include - -class idVec3_t; -class angles_t; -class mat3_t; - -class quat_t { -public: -float x; -float y; -float z; -float w; - -quat_t(); -quat_t( float x, float y, float z, float w ); - -friend void toQuat( idVec3_t &src, quat_t &dst ); -friend void toQuat( angles_t &src, quat_t &dst ); -friend void toQuat( mat3_t &src, quat_t &dst ); - -float *vec4( void ); - -float operator[]( int index ) const; -float &operator[]( int index ); - -void set( float x, float y, float z, float w ); - -void operator=( quat_t a ); - -friend quat_t operator+( quat_t a, quat_t b ); -quat_t &operator+=( quat_t a ); - -friend quat_t operator-( quat_t a, quat_t b ); -quat_t &operator-=( quat_t a ); - -friend quat_t operator*( quat_t a, float b ); -friend quat_t operator*( float a, quat_t b ); -quat_t &operator*=( float a ); - -friend int operator==( quat_t a, quat_t b ); -friend int operator!=( quat_t a, quat_t b ); - -float Length( void ); -quat_t &Normalize( void ); - -quat_t operator-(); -}; - -inline quat_t::quat_t() { -} - -inline quat_t::quat_t( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline float *quat_t::vec4( void ) { - return &x; -} - -inline float quat_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline float& quat_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline void quat_t::set( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline void quat_t::operator=( quat_t a ) { - x = a.x; - y = a.y; - z = a.z; - w = a.w; -} - -inline quat_t operator+( quat_t a, quat_t b ) { - return quat_t( a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w ); -} - -inline quat_t& quat_t::operator+=( quat_t a ) { - x += a.x; - y += a.y; - z += a.z; - w += a.w; - - return *this; -} - -inline quat_t operator-( quat_t a, quat_t b ) { - return quat_t( a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w ); -} - -inline quat_t& quat_t::operator-=( quat_t a ) { - x -= a.x; - y -= a.y; - z -= a.z; - w -= a.w; - - return *this; -} - -inline quat_t operator*( quat_t a, float b ) { - return quat_t( a.x * b, a.y * b, a.z * b, a.w * b ); -} - -inline quat_t operator*( float a, quat_t b ) { - return b * a; -} - -inline quat_t& quat_t::operator*=( float a ) { - x *= a; - y *= a; - z *= a; - w *= a; - - return *this; -} - -inline int operator==( quat_t a, quat_t b ) { - return ( ( a.x == b.x ) && ( a.y == b.y ) && ( a.z == b.z ) && ( a.w == b.w ) ); -} - -inline int operator!=( quat_t a, quat_t b ) { - return ( ( a.x != b.x ) || ( a.y != b.y ) || (( a.z != b.z ) && ( a.w != b.w )) ); -} - -inline float quat_t::Length( void ) { - float length; - - length = x * x + y * y + z * z + w * w; - return ( float )sqrt( length ); -} - -inline quat_t& quat_t::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1 / length; - x *= ilength; - y *= ilength; - z *= ilength; - w *= ilength; - } - - return *this; -} - -inline quat_t quat_t::operator-() { - return quat_t( -x, -y, -z, -w ); -} - -#endif /* !__MATH_QUATERNION_H__ */ diff --git a/libs/splines/math_vector.cpp b/libs/splines/math_vector.cpp deleted file mode 100644 index 572f903..0000000 --- a/libs/splines/math_vector.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "math_vector.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h - -#define LERP_DELTA 1e-6 - -idVec3 vec_zero( 0.0f, 0.0f, 0.0f ); - -Bounds boundsZero; - -float idVec3::toYaw( void ) { - float yaw; - - if ( ( y == 0 ) && ( x == 0 ) ) { - yaw = 0; - } - else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - } - - return yaw; -} - -float idVec3::toPitch( void ) { - float forward; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - if ( z > 0 ) { - pitch = 90; - } - else { - pitch = 270; - } - } - else { - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return pitch; -} - -/* - angles_t idVec3::toAngles( void ) { - float forward; - float yaw; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - yaw = 0; - if ( z > 0 ) { - pitch = 90; - } else { - pitch = 270; - } - } else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return angles_t( -pitch, yaw, 0 ); - } - */ - -idVec3 LerpVector( idVec3 &w1, idVec3 &w2, const float t ) { - float omega, cosom, sinom, scale0, scale1; - - cosom = w1 * w2; - if ( ( 1.0 - cosom ) > LERP_DELTA ) { - omega = acos( cosom ); - sinom = sin( omega ); - scale0 = sin( ( 1.0 - t ) * omega ) / sinom; - scale1 = sin( t * omega ) / sinom; - } - else { - scale0 = 1.0 - t; - scale1 = t; - } - - return ( w1 * scale0 + w2 * scale1 ); -} - -/* - ============= - idVec3::string - - This is just a convenience function - for printing vectors - ============= - */ -char *idVec3::string( void ) { - static int index = 0; - static char str[ 8 ][ 36 ]; - char *s; - - // use an array so that multiple toString's won't collide - s = str[ index ]; - index = ( index + 1 ) & 7; - - sprintf( s, "%.2f %.2f %.2f", x, y, z ); - - return s; -} diff --git a/libs/splines/math_vector.h b/libs/splines/math_vector.h deleted file mode 100644 index 616116b..0000000 --- a/libs/splines/math_vector.h +++ /dev/null @@ -1,581 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_VECTOR_H__ -#define __MATH_VECTOR_H__ - -#include "globaldefs.h" - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4244) -#endif - -#include -#include - -//#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) -//#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2]) -//#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2]) -//#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) -//#define VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -//#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#define __VectorMA( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ) ) -//#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]) - -#define DotProduct4( x,y ) ( ( x )[0] * ( y )[0] + ( x )[1] * ( y )[1] + ( x )[2] * ( y )[2] + ( x )[3] * ( y )[3] ) -#define VectorSubtract4( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2],( c )[3] = ( a )[3] - ( b )[3] ) -#define VectorAdd4( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2],( c )[3] = ( a )[3] + ( b )[3] ) -#define VectorCopy4( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) -#define VectorScale4( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ),( o )[3] = ( v )[3] * ( s ) ) -#define VectorMA4( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ),( o )[3] = ( v )[3] + ( b )[3] * ( s ) ) - - -//#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate( a,b ) ( ( b )[0] = -( a )[0],( b )[1] = -( a )[1],( b )[2] = -( a )[2] ) -//#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) - -#define SnapVector( v ) {v[0] = (int)v[0]; v[1] = (int)v[1]; v[2] = (int)v[2]; } - - -//#include "util_heap.h" - -#ifndef EQUAL_EPSILON -#define EQUAL_EPSILON 0.001 -#endif - -float Q_fabs( float f ); - -#ifndef ID_INLINE -#define ID_INLINE GDEF_ATTRIBUTE_INLINE -#endif - -// if this is defined, vec3 will take four elements, which may allow -// easier SIMD optimizations -//#define FAT_VEC3 -//#ifdef __ppc__ -//#pragma align(16) -//#endif - -class angles_t; -#ifdef __ppc__ -// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, -// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson -// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost. -// We'll then multiply 1/sqrt times the original value to get the sqrt. -// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive) -// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments). - -static inline float idSqrt( float x ) { - const float half = 0.5; - const float one = 1.0; - float B, y0, y1; - - // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0 - if ( fabs( x ) == 0.0 ) { - return x; - } - B = x; - -#if GDEF_COMPILER_GNU - asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) ); -#else - y0 = __frsqrte( B ); -#endif - /* First refinement step */ - - y1 = y0 + half * y0 * ( one - B * y0 * y0 ); - - /* Second refinement step -- copy the output of the last step to the input of this step */ - - y0 = y1; - y1 = y0 + half * y0 * ( one - B * y0 * y0 ); - - /* Get sqrt(x) from x * 1/sqrt(x) */ - return x * y1; -} -#else -static inline double idSqrt( double x ) { - return sqrt( x ); -} -#endif - - -//class idVec3 : public idHeap { -class idVec3 { -public: -#ifndef FAT_VEC3 -float x,y,z; -#else -float x,y,z,dist; -#endif - -#ifndef FAT_VEC3 -idVec3() { -}; -#else -idVec3() { - dist = 0.0f; -}; -#endif -idVec3( const float x, const float y, const float z ); - -operator float *(); - -float operator[]( const int index ) const; -float &operator[]( const int index ); - -void set( const float x, const float y, const float z ); - -idVec3 operator-() const; - -idVec3 &operator=( const idVec3 &a ); - -float operator*( const idVec3 &a ) const; -idVec3 operator*( const float a ) const; -friend idVec3 operator*( float a, idVec3 b ); - -idVec3 operator+( const idVec3 &a ) const; -idVec3 operator-( const idVec3 &a ) const; - -idVec3 &operator+=( const idVec3 &a ); -idVec3 &operator-=( const idVec3 &a ); -idVec3 &operator*=( const float a ); - -int operator==( const idVec3 &a ) const; -int operator!=( const idVec3 &a ) const; - -idVec3 Cross( const idVec3 &a ) const; -idVec3 &Cross( const idVec3 &a, const idVec3 &b ); - -float Length( void ) const; -float Normalize( void ); - -void Zero( void ); -void Snap( void ); -void SnapTowards( const idVec3 &to ); - -float toYaw( void ); -float toPitch( void ); -angles_t toAngles( void ); -friend idVec3 LerpVector( const idVec3 &w1, const idVec3 &w2, const float t ); - -char *string( void ); -}; - -extern idVec3 vec_zero; - -ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -#ifdef FAT_VEC3 - this->dist = 0.0f; -#endif -} - -ID_INLINE float idVec3::operator[]( const int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float &idVec3::operator[]( const int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec3::operator float *( void ) { - return &x; -} - -ID_INLINE idVec3 idVec3::operator-() const { - return idVec3( -x, -y, -z ); -} - -ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) { - x = a.x; - y = a.y; - z = a.z; - - return *this; -} - -ID_INLINE void idVec3::set( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const { - return idVec3( x - a.x, y - a.y, z - a.z ); -} - -ID_INLINE float idVec3::operator*( const idVec3 &a ) const { - return x * a.x + y * a.y + z * a.z; -} - -ID_INLINE idVec3 idVec3::operator*( const float a ) const { - return idVec3( x * a, y * a, z * a ); -} - -ID_INLINE idVec3 operator*( const float a, const idVec3 b ) { - return idVec3( b.x * a, b.y * a, b.z * a ); -} - -ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const { - return idVec3( x + a.x, y + a.y, z + a.z ); -} - -ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) { - x += a.x; - y += a.y; - z += a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator*=( const float a ) { - x *= a; - y *= a; - z *= a; - - return *this; -} - -ID_INLINE int idVec3::operator==( const idVec3 &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return false; - } - - return true; -} - -ID_INLINE int idVec3::operator!=( const idVec3 &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return true; - } - - return false; -} - -ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const { - return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x ); -} - -ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) { - x = a.y * b.z - a.z * b.y; - y = a.z * b.x - a.x * b.z; - z = a.x * b.y - a.y * b.x; - - return *this; -} - -ID_INLINE float idVec3::Length( void ) const { - float length; - - length = x * x + y * y + z * z; - return ( float )idSqrt( length ); -} - -ID_INLINE float idVec3::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1.0f / length; - x *= ilength; - y *= ilength; - z *= ilength; - } - - return length; -} - -ID_INLINE void idVec3::Zero( void ) { - x = 0.0f; - y = 0.0f; - z = 0.0f; -} - -ID_INLINE void idVec3::Snap( void ) { - x = float( int( x ) ); - y = float( int( y ) ); - z = float( int( z ) ); -} - -/* - ====================== - SnapTowards - - Round a vector to integers for more efficient network - transmission, but make sure that it rounds towards a given point - rather than blindly truncating. This prevents it from truncating - into a wall. - ====================== - */ -ID_INLINE void idVec3::SnapTowards( const idVec3 &to ) { - if ( to.x <= x ) { - x = float( int( x ) ); - } - else { - x = float( int( x ) + 1 ); - } - - if ( to.y <= y ) { - y = float( int( y ) ); - } - else { - y = float( int( y ) + 1 ); - } - - if ( to.z <= z ) { - z = float( int( z ) ); - } - else { - z = float( int( z ) + 1 ); - } -} - -//=============================================================== - -class Bounds { -public: -idVec3 b[2]; - -Bounds(); -Bounds( const idVec3 &mins, const idVec3 &maxs ); - -void Clear(); -void Zero(); -float Radius(); // radius from origin, not from center -idVec3 Center(); -void AddPoint( const idVec3 &v ); -void AddBounds( const Bounds &bb ); -bool IsCleared(); -bool ContainsPoint( const idVec3 &p ); -bool IntersectsBounds( const Bounds &b2 ); // touching is NOT intersecting -}; - -extern Bounds boundsZero; - -ID_INLINE Bounds::Bounds(){ -} - -ID_INLINE bool Bounds::IsCleared() { - return b[0][0] > b[1][0]; -} - -ID_INLINE bool Bounds::ContainsPoint( const idVec3 &p ) { - if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] - || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) { - if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2] - || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE Bounds::Bounds( const idVec3 &mins, const idVec3 &maxs ) { - b[0] = mins; - b[1] = maxs; -} - -ID_INLINE idVec3 Bounds::Center() { - return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f ); -} - -ID_INLINE void Bounds::Clear() { - b[0][0] = b[0][1] = b[0][2] = 99999; - b[1][0] = b[1][1] = b[1][2] = -99999; -} - -ID_INLINE void Bounds::Zero() { - b[0][0] = b[0][1] = b[0][2] = - b[1][0] = b[1][1] = b[1][2] = 0; -} - -ID_INLINE void Bounds::AddPoint( const idVec3 &v ) { - if ( v[0] < b[0][0] ) { - b[0][0] = v[0]; - } - if ( v[0] > b[1][0] ) { - b[1][0] = v[0]; - } - if ( v[1] < b[0][1] ) { - b[0][1] = v[1]; - } - if ( v[1] > b[1][1] ) { - b[1][1] = v[1]; - } - if ( v[2] < b[0][2] ) { - b[0][2] = v[2]; - } - if ( v[2] > b[1][2] ) { - b[1][2] = v[2]; - } -} - - -ID_INLINE void Bounds::AddBounds( const Bounds &bb ) { - if ( bb.b[0][0] < b[0][0] ) { - b[0][0] = bb.b[0][0]; - } - if ( bb.b[0][1] < b[0][1] ) { - b[0][1] = bb.b[0][1]; - } - if ( bb.b[0][2] < b[0][2] ) { - b[0][2] = bb.b[0][2]; - } - - if ( bb.b[1][0] > b[1][0] ) { - b[1][0] = bb.b[1][0]; - } - if ( bb.b[1][1] > b[1][1] ) { - b[1][1] = bb.b[1][1]; - } - if ( bb.b[1][2] > b[1][2] ) { - b[1][2] = bb.b[1][2]; - } -} - -ID_INLINE float Bounds::Radius() { - int i; - float total; - float a, aa; - - total = 0; - for ( i = 0; i < 3; i++ ) { - a = (float)fabs( b[0][i] ); - aa = (float)fabs( b[1][i] ); - if ( aa > a ) { - a = aa; - } - total += a * a; - } - - return (float)idSqrt( total ); -} - -//=============================================================== - - -class idVec2 { -public: -float x; -float y; - -operator float *(); -float operator[]( int index ) const; -float &operator[]( int index ); -}; - -ID_INLINE float idVec2::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec2::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec2::operator float *( void ) { - return &x; -} - -class idVec4 : public idVec3 { -public: -#ifndef FAT_VEC3 -float dist; -#endif -idVec4(); -~idVec4() { -}; - -idVec4( float x, float y, float z, float dist ); -float operator[]( int index ) const; -float &operator[]( int index ); -}; - -ID_INLINE idVec4::idVec4() { -} -ID_INLINE idVec4::idVec4( float x, float y, float z, float dist ) { - this->x = x; - this->y = y; - this->z = z; - this->dist = dist; -} - -ID_INLINE float idVec4::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec4::operator[]( int index ) { - return ( &x )[ index ]; -} - - -class idVec5_t : public idVec3 { -public: -float s; -float t; -float operator[]( int index ) const; -float &operator[]( int index ); -}; - - -ID_INLINE float idVec5_t::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec5_t::operator[]( int index ) { - return ( &x )[ index ]; -} - -#endif /* !__MATH_VECTOR_H__ */ diff --git a/libs/splines/q_parse.cpp b/libs/splines/q_parse.cpp deleted file mode 100644 index b7954ed..0000000 --- a/libs/splines/q_parse.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// q_parse.c -- support for parsing text files - -#include "q_shared.h" - -/* - ============================================================================ - - PARSING - - ============================================================================ - */ - -// multiple character punctuation tokens -static const char *punctuation[] = { - "+=", "-=", "*=", "/=", "&=", "|=", "++", "--", - "&&", "||", "<=", ">=", "==", "!=", - NULL -}; - -typedef struct { - char token[MAX_TOKEN_CHARS]; - int lines; - qboolean ungetToken; - char parseFile[MAX_QPATH]; -} parseInfo_t; - -const int MAX_PARSE_INFO = 16; -static parseInfo_t parseInfo[MAX_PARSE_INFO]; -static int parseInfoNum; -static parseInfo_t *pi = &parseInfo[0]; - -/* - =================== - Com_BeginParseSession - =================== - */ -void Com_BeginParseSession( const char *filename ) { - if ( parseInfoNum == MAX_PARSE_INFO - 1 ) { - Com_Error( ERR_FATAL, "Com_BeginParseSession: session overflow" ); - } - parseInfoNum++; - pi = &parseInfo[parseInfoNum]; - - pi->lines = 1; - Q_strncpyz( pi->parseFile, filename, sizeof( pi->parseFile ) ); -} - -/* - =================== - Com_EndParseSession - =================== - */ -void Com_EndParseSession( void ) { - if ( parseInfoNum == 0 ) { - Com_Error( ERR_FATAL, "Com_EndParseSession: session underflow" ); - } - parseInfoNum--; - pi = &parseInfo[parseInfoNum]; -} - -/* - =================== - Com_GetCurrentParseLine - =================== - */ -int Com_GetCurrentParseLine( void ) { - return pi->lines; -} - -/* - =================== - Com_ScriptError - - Prints the script name and line number in the message - =================== - */ -void Com_ScriptError( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Error( ERR_DROP, "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - -void Com_ScriptWarning( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Printf( "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - - -/* - =================== - Com_UngetToken - - Calling this will make the next Com_Parse return - the current token instead of advancing the pointer - =================== - */ -void Com_UngetToken( void ) { - if ( pi->ungetToken ) { - Com_ScriptError( "UngetToken called twice" ); - } - pi->ungetToken = qtrue; -} - - -static const char *SkipWhitespace( const char (*data), qboolean *hasNewLines ) { - int c; - - while ( ( c = *data ) <= ' ' ) { - if ( !c ) { - return NULL; - } - if ( c == '\n' ) { - pi->lines++; - *hasNewLines = qtrue; - } - data++; - } - - return data; -} - -/* - ============== - Com_ParseExt - - Parse a token out of a string - Will never return NULL, just empty strings. - An empty string will only be returned at end of file. - - If "allowLineBreaks" is qtrue then an empty - string will be returned if the next token is - a newline. - ============== - */ -static char *Com_ParseExt( const char *( *data_p ), qboolean allowLineBreaks ) { - int c = 0, len; - qboolean hasNewLines = qfalse; - const char *data; - const char **punc; - - if ( !data_p ) { - Com_Error( ERR_FATAL, "Com_ParseExt: NULL data_p" ); - } - - data = *data_p; - len = 0; - pi->token[0] = 0; - - // make sure incoming data is valid - if ( !data ) { - *data_p = NULL; - return pi->token; - } - - // skip any leading whitespace - while ( 1 ) { - // skip whitespace - data = SkipWhitespace( data, &hasNewLines ); - if ( !data ) { - *data_p = NULL; - return pi->token; - } - if ( hasNewLines && !allowLineBreaks ) { - *data_p = data; - return pi->token; - } - - c = *data; - - // skip double slash comments - if ( c == '/' && data[1] == '/' ) { - while ( *data && *data != '\n' ) { - data++; - } - continue; - } - - // skip /* */ comments - if ( c == '/' && data[1] == '*' ) { - while ( *data && ( *data != '*' || data[1] != '/' ) ) { - if ( *data == '\n' ) { - pi->lines++; - } - data++; - } - if ( *data ) { - data += 2; - } - continue; - } - - // a real token to parse - break; - } - - // handle quoted strings - if ( c == '\"' ) { - data++; - while ( 1 ) { - c = *data++; - if ( ( c == '\\' ) && ( *data == '\"' ) ) { - // allow quoted strings to use \" to indicate the " character - data++; - } - else if ( c == '\"' || !c ) { - pi->token[len] = 0; - *data_p = ( char * ) data; - return pi->token; - } - else if ( *data == '\n' ) { - pi->lines++; - } - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - } - } - - // check for a number - // is this parsing of negative numbers going to cause expression problems - if ( ( c >= '0' && c <= '9' ) || ( c == '-' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) || - ( c == '.' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) ) { - do { - - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= '0' && c <= '9' ) || c == '.' ); - - // parse the exponent - if ( c == 'e' || c == 'E' ) { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - - if ( c == '-' || c == '+' ) { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - } - - do { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( c >= '0' && c <= '9' ); - } - - if ( len == MAX_TOKEN_CHARS ) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for a regular word - // we still allow forward and back slashes in name tokens for pathnames - // and also colons for drive letters - if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' || c == '/' || c == '\\' ) { - do { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' - || ( c >= '0' && c <= '9' ) || c == '/' || c == '\\' || c == ':' || c == '.' ); - - if ( len == MAX_TOKEN_CHARS ) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for multi-character punctuation token - for ( punc = punctuation; *punc; punc++ ) { - int l; - int j; - - l = strlen( *punc ); - for ( j = 0; j < l; j++ ) { - if ( data[j] != ( *punc )[j] ) { - break; - } - } - if ( j == l ) { - // a valid multi-character punctuation - memcpy( pi->token, *punc, l ); - pi->token[l] = 0; - data += l; - *data_p = (char *)data; - return pi->token; - } - } - - // single character punctuation - pi->token[0] = *data; - pi->token[1] = 0; - data++; - *data_p = (char *)data; - - return pi->token; -} - -/* - =================== - Com_Parse - =================== - */ -const char *Com_Parse( const char *( *data_p ) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qtrue ); -} - -/* - =================== - Com_ParseOnLine - =================== - */ -const char *Com_ParseOnLine( const char *( *data_p ) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qfalse ); -} - - - -/* - ================== - Com_MatchToken - ================== - */ -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( strcmp( token, match ) ) { - if ( warning ) { - Com_ScriptWarning( "MatchToken: %s != %s", token, match ); - } - else { - Com_ScriptError( "MatchToken: %s != %s", token, match ); - } - } -} - - -/* - ================= - Com_SkipBracedSection - - The next token should be an open brace. - Skips until a matching close brace is found. - Internal brace depths are properly skipped. - ================= - */ -void Com_SkipBracedSection( const char *( *program ) ) { - const char *token; - int depth; - - depth = 0; - do { - token = Com_Parse( program ); - if ( token[1] == 0 ) { - if ( token[0] == '{' ) { - depth++; - } - else if ( token[0] == '}' ) { - depth--; - } - } - } while ( depth && *program ); -} - -/* - ================= - Com_SkipRestOfLine - ================= - */ -void Com_SkipRestOfLine( const char *( *data ) ) { - const char *p; - int c; - - p = *data; - while ( ( c = *p++ ) != 0 ) { - if ( c == '\n' ) { - pi->lines++; - break; - } - } - - *data = p; -} - -/* - ==================== - Com_ParseRestOfLine - ==================== - */ -const char *Com_ParseRestOfLine( const char *( *data_p ) ) { - static char line[MAX_TOKEN_CHARS]; - const char *token; - - line[0] = 0; - while ( 1 ) { - token = Com_ParseOnLine( data_p ); - if ( !token[0] ) { - break; - } - if ( line[0] ) { - Q_strcat( line, sizeof( line ), " " ); - } - Q_strcat( line, sizeof( line ), token ); - } - - return line; -} - - -float Com_ParseFloat( const char *( *buf_p ) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return atof( token ); -} - -int Com_ParseInt( const char *( *buf_p ) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return (int)atof( token ); -} - - - -void Com_Parse1DMatrix( const char *( *buf_p ), int x, float *m ) { - const char *token; - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < x; i++ ) { - token = Com_Parse( buf_p ); - m[i] = atof( token ); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse2DMatrix( const char *( *buf_p ), int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < y; i++ ) { - Com_Parse1DMatrix( buf_p, x, m + i * x ); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse3DMatrix( const char *( *buf_p ), int z, int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < z; i++ ) { - Com_Parse2DMatrix( buf_p, y, x, m + i * x * y ); - } - - Com_MatchToken( buf_p, ")" ); -} diff --git a/libs/splines/q_shared.cpp b/libs/splines/q_shared.cpp deleted file mode 100644 index 8cec7bf..0000000 --- a/libs/splines/q_shared.cpp +++ /dev/null @@ -1,1011 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// q_shared.c -- stateless support routines that are included in each code dll -#include "q_shared.h" - -/* - ============================================================================ - - GROWLISTS - - ============================================================================ - */ - -// malloc / free all in one place for debugging -extern "C" void *Com_Allocate( int bytes ); -extern "C" void Com_Dealloc( void *ptr ); - -void Com_InitGrowList( growList_t *list, int maxElements ) { - list->maxElements = maxElements; - list->currentElements = 0; - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); -} - -int Com_AddToGrowList( growList_t *list, void *data ) { - void **old; - - if ( list->currentElements != list->maxElements ) { - list->elements[list->currentElements] = data; - return list->currentElements++; - } - - // grow, reallocate and move - old = list->elements; - - if ( list->maxElements < 0 ) { - Com_Error( ERR_FATAL, "Com_AddToGrowList: maxElements = %i", list->maxElements ); - } - - if ( list->maxElements == 0 ) { - // initialize the list to hold 100 elements - Com_InitGrowList( list, 100 ); - return Com_AddToGrowList( list, data ); - } - - list->maxElements *= 2; - - Com_DPrintf( "Resizing growlist to %i maxElements\n", list->maxElements ); - - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); - - if ( !list->elements ) { - Com_Error( ERR_DROP, "Growlist alloc failed" ); - } - - memcpy( list->elements, old, list->currentElements * sizeof( void * ) ); - - Com_Dealloc( old ); - - return Com_AddToGrowList( list, data ); -} - -void *Com_GrowListElement( const growList_t *list, int index ) { - if ( index < 0 || index >= list->currentElements ) { - Com_Error( ERR_DROP, "Com_GrowListElement: %i out of range of %i", - index, list->currentElements ); - } - return list->elements[index]; -} - -int Com_IndexForGrowListElement( const growList_t *list, const void *element ) { - int i; - - for ( i = 0; i < list->currentElements; i++ ) { - if ( list->elements[i] == element ) { - return i; - } - } - return -1; -} - -//============================================================================ - - -float Com_Clamp( float min, float max, float value ) { - if ( value < min ) { - return min; - } - if ( value > max ) { - return max; - } - return value; -} - -/* - ============ - Com_StringContains - ============ - */ -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ) { - int len, i, j; - - len = strlen( str1 ) - strlen( str2 ); - for ( i = 0; i <= len; i++, str1++ ) { - for ( j = 0; str2[j]; j++ ) { - if ( casesensitive ) { - if ( str1[j] != str2[j] ) { - break; - } - } - else { - if ( toupper( str1[j] ) != toupper( str2[j] ) ) { - break; - } - } - } - if ( !str2[j] ) { - return str1; - } - } - return NULL; -} - -/* - ============ - Com_Filter - ============ - */ -int Com_Filter( const char *filter, const char *name, int casesensitive ){ - char buf[MAX_TOKEN_CHARS]; - const char *ptr; - int i, found; - - while ( *filter ) { - if ( *filter == '*' ) { - filter++; - for ( i = 0; *filter; i++ ) { - if ( *filter == '*' || *filter == '?' ) { - break; - } - buf[i] = *filter; - filter++; - } - buf[i] = '\0'; - if ( strlen( buf ) ) { - ptr = Com_StringContains( name, buf, casesensitive ); - if ( !ptr ) { - return qfalse; - } - name = ptr + strlen( buf ); - } - } - else if ( *filter == '?' ) { - filter++; - name++; - } - else if ( *filter == '[' && *( filter + 1 ) == '[' ) { - filter++; - } - else if ( *filter == '[' ) { - filter++; - found = qfalse; - while ( *filter && !found ) { - if ( *filter == ']' && *( filter + 1 ) != ']' ) { - break; - } - if ( *( filter + 1 ) == '-' && *( filter + 2 ) && ( *( filter + 2 ) != ']' || *( filter + 3 ) == ']' ) ) { - if ( casesensitive ) { - if ( *name >= *filter && *name <= *( filter + 2 ) ) { - found = qtrue; - } - } - else { - if ( toupper( *name ) >= toupper( *filter ) && - toupper( *name ) <= toupper( *( filter + 2 ) ) ) { - found = qtrue; - } - } - filter += 3; - } - else { - if ( casesensitive ) { - if ( *filter == *name ) { - found = qtrue; - } - } - else { - if ( toupper( *filter ) == toupper( *name ) ) { - found = qtrue; - } - } - filter++; - } - } - if ( !found ) { - return qfalse; - } - while ( *filter ) { - if ( *filter == ']' && *( filter + 1 ) != ']' ) { - break; - } - filter++; - } - filter++; - name++; - } - else { - if ( casesensitive ) { - if ( *filter != *name ) { - return qfalse; - } - } - else { - if ( toupper( *filter ) != toupper( *name ) ) { - return qfalse; - } - } - filter++; - name++; - } - } - return qtrue; -} - - -/* - ================ - Com_HashString - - ================ - */ -int Com_HashString( const char *fname ) { - int i; - long hash; - char letter; - - hash = 0; - i = 0; - while ( fname[i] != '\0' ) { - letter = tolower( fname[i] ); - if ( letter == '.' ) { - break; // don't include extension - } - if ( letter == '\\' ) { - letter = '/'; // damn path names - } - hash += (long)( letter ) * ( i + 119 ); - i++; - } - hash &= ( FILE_HASH_SIZE - 1 ); - return hash; -} - - -/* - ============ - Com_SkipPath - ============ - */ -char *Com_SkipPath( char *pathname ){ - char *last; - - last = pathname; - while ( *pathname ) - { - if ( *pathname == '/' ) { - last = pathname + 1; - } - pathname++; - } - return last; -} - -/* - ============ - Com_StripExtension - ============ - */ -void Com_StripExtension( const char *in, char *out ) { - while ( *in && *in != '.' ) { - *out++ = *in++; - } - *out = 0; -} - - -/* - ================== - Com_DefaultExtension - ================== - */ -void Com_DefaultExtension( char *path, int maxSize, const char *extension ) { - char oldPath[MAX_QPATH]; - char *src; - -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// - src = path + strlen( path ) - 1; - - while ( *src != '/' && src != path ) { - if ( *src == '.' ) { - return; // it has an extension - } - src--; - } - - Q_strncpyz( oldPath, path, sizeof( oldPath ) ); - Com_sprintf( path, maxSize, "%s%s", oldPath, extension ); -} - -/* - ============================================================================ - - BYTE ORDER FUNCTIONS - - ============================================================================ - */ - -// can't just use function pointers, or dll linkage can -// mess up when qcommon is included in multiple places -static short ( *_BigShort )( short l ); -static short ( *_LittleShort )( short l ); -static int ( *_BigLong )( int l ); -static int ( *_LittleLong )( int l ); -static float ( *_BigFloat )( float l ); -static float ( *_LittleFloat )( float l ); - -short BigShort( short l ){ - return _BigShort( l ); -} -short LittleShort( short l ) { - return _LittleShort( l ); -} -int BigLong( int l ) { - return _BigLong( l ); -} -int LittleLong( int l ) { - return _LittleLong( l ); -} -float BigFloat( float l ) { - return _BigFloat( l ); -} -float LittleFloat( float l ) { - return _LittleFloat( l ); -} - -short ShortSwap( short l ){ - byte b1,b2; - - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - - return ( b1 << 8 ) + b2; -} - -short ShortNoSwap( short l ){ - return l; -} - -int LongSwap( int l ){ - byte b1,b2,b3,b4; - - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; - - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; -} - -int LongNoSwap( int l ){ - return l; -} - -float FloatSwap( float f ){ - union - { - float f; - byte b[4]; - } dat1, dat2; - - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; -} - -float FloatNoSwap( float f ){ - return f; -} - -/* - ================ - Swap_Init - ================ - */ -void Swap_Init( void ){ - byte swaptest[2] = {1,0}; - -// set the byte swapping variables in a portable manner - if ( *(short *)swaptest == 1 ) { - _BigShort = ShortSwap; - _LittleShort = ShortNoSwap; - _BigLong = LongSwap; - _LittleLong = LongNoSwap; - _BigFloat = FloatSwap; - _LittleFloat = FloatNoSwap; - } - else - { - _BigShort = ShortNoSwap; - _LittleShort = ShortSwap; - _BigLong = LongNoSwap; - _LittleLong = LongSwap; - _BigFloat = FloatNoSwap; - _LittleFloat = FloatSwap; - } - -} - -/* - =============== - Com_ParseInfos - =============== - */ -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ) { - const char *token; - int count; - char key[MAX_TOKEN_CHARS]; - - count = 0; - - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - break; - } - if ( strcmp( token, "{" ) ) { - Com_Printf( "Missing { in info file\n" ); - break; - } - - if ( count == max ) { - Com_Printf( "Max infos exceeded\n" ); - break; - } - - infos[count][0] = 0; - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - Com_Printf( "Unexpected end of info file\n" ); - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - Q_strncpyz( key, token, sizeof( key ) ); - - token = Com_ParseOnLine( &buf ); - if ( !token[0] ) { - token = ""; - } - Info_SetValueForKey( infos[count], key, token ); - } - count++; - } - - return count; -} - - - -/* - ============================================================================ - - LIBRARY REPLACEMENT FUNCTIONS - - ============================================================================ - */ - -int Q_isprint( int c ){ - if ( c >= 0x20 && c <= 0x7E ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_islower( int c ){ - if ( c >= 'a' && c <= 'z' ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_isupper( int c ){ - if ( c >= 'A' && c <= 'Z' ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_isalpha( int c ){ - if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) { - return ( 1 ); - } - return ( 0 ); -} - -char* Q_strrchr( const char* string, int c ){ - char cc = c; - char *s; - char *sp = (char *)0; - - s = (char*)string; - - while ( *s ) - { - if ( *s == cc ) { - sp = s; - } - s++; - } - if ( cc == 0 ) { - sp = s; - } - - return sp; -} - -/* - ============= - Q_strncpyz - - Safe strncpy that ensures a trailing zero - ============= - */ -void Q_strncpyz( char *dest, const char *src, std::size_t destsize ) { - if ( !src ) { - Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); - } - if ( destsize < 1 ) { - Com_Error( ERR_FATAL,"Q_strncpyz: destsize < 1" ); - } - - strncpy( dest, src, destsize - 1 ); - dest[destsize - 1] = 0; -} - -int Q_stricmpn( const char *s1, const char *s2, int n ) { - int c1, c2; - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - if ( c1 != c2 ) { - return c1 < c2 ? -1 : 1; - } - } - } while ( c1 ); - - return 0; // strings are equal -} - -int Q_strncmp( const char *s1, const char *s2, int n ) { - int c1, c2; - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - if ( c1 != c2 ) { - return c1 < c2 ? -1 : 1; - } - } while ( c1 ); - - return 0; // strings are equal -} - -int Q_stricmp( const char *s1, const char *s2 ) { - return Q_stricmpn( s1, s2, 99999 ); -} - - -char *Q_strlwr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = tolower( *s ); - s++; - } - return s1; -} - -char *Q_strupr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = toupper( *s ); - s++; - } - return s1; -} - - -// never goes past bounds or leaves without a terminating 0 -void Q_strcat( char *dest, std::size_t size, const char *src ) { - auto l1 = strlen( dest ); - if ( l1 >= size ) { - Com_Error( ERR_FATAL, "Q_strcat: already overflowed" ); - } - Q_strncpyz( dest + l1, src, size - l1 ); -} - - -int Q_PrintStrlen( const char *string ) { - int len; - const char *p; - - if ( !string ) { - return 0; - } - - len = 0; - p = string; - while ( *p ) { - if ( Q_IsColorString( p ) ) { - p += 2; - continue; - } - p++; - len++; - } - - return len; -} - - -char *Q_CleanStr( char *string ) { - char* d; - char* s; - int c; - - s = string; - d = string; - while ( ( c = *s ) != 0 ) { - if ( Q_IsColorString( s ) ) { - s++; - } - else if ( c >= 0x20 && c <= 0x7E ) { - *d++ = c; - } - s++; - } - *d = '\0'; - - return string; -} - - -void QDECL Com_sprintf( char *dest, std::size_t size, const char *fmt, ... ) { - va_list argptr; - char bigbuffer[32000]; // big, but small enough to fit in PPC stack - - va_start( argptr,fmt ); - int ret = vsprintf( bigbuffer,fmt,argptr ); - va_end( argptr ); - if ( ret < 0 ) { - Com_Error(ERR_FATAL, "Com_sprintf: vsprintf failed"); - } - auto len = static_cast(ret); - if ( len >= sizeof( bigbuffer ) ) { - Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" ); - } - if ( len >= size ) { - Com_Printf( "Com_sprintf: overflow of %i in %i\n", len, size ); - } - Q_strncpyz( dest, bigbuffer, size ); -} - - -/* - ============ - va - - does a varargs printf into a temp buffer, so I don't need to have - varargs versions of all text functions. - FIXME: make this buffer size safe someday - ============ - */ -char *QDECL va( const char *format, ... ) { - va_list argptr; - static char string[2][32000]; // in case va is called by nested functions - static int index = 0; - char *buf; - - buf = string[index & 1]; - index++; - - va_start( argptr, format ); - vsprintf( buf, format,argptr ); - va_end( argptr ); - - return buf; -} - - -/* - ===================================================================== - - INFO STRINGS - - ===================================================================== - */ - -/* - =============== - Info_ValueForKey - - Searches the string for the given - key and returns the associated value, or an empty string. - FIXME: overflow check? - =============== - */ -const char *Info_ValueForKey( const char *s, const char *key ) { - char pkey[MAX_INFO_KEY]; - static char value[2][MAX_INFO_VALUE]; // use two buffers so compares - // work without stomping on each other - static int valueindex = 0; - char *o; - - if ( !s || !key ) { - return ""; - } - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" ); - } - - valueindex ^= 1; - if ( *s == '\\' ) { - s++; - } - while ( 1 ) - { - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) { - return ""; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value[valueindex]; - - while ( *s != '\\' && *s ) - { - *o++ = *s++; - } - *o = 0; - - if ( !Q_stricmp( key, pkey ) ) { - return value[valueindex]; - } - - if ( !*s ) { - break; - } - s++; - } - - return ""; -} - - -/* - =================== - Info_NextPair - - Used to itterate through all the key/value pairs in an info string - =================== - */ -void Info_NextPair( const char *( *head ), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ) { - char *o; - const char *s; - - s = *head; - - if ( *s == '\\' ) { - s++; - } - key[0] = 0; - value[0] = 0; - - o = key; - while ( *s != '\\' ) { - if ( !*s ) { - *o = 0; - *head = s; - return; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while ( *s != '\\' && *s ) { - *o++ = *s++; - } - *o = 0; - - *head = s; -} - - -/* - =================== - Info_RemoveKey - =================== - */ -void Info_RemoveKey( char *s, const char *key ) { - char *start; - char pkey[MAX_INFO_KEY]; - char value[MAX_INFO_VALUE]; - char *o; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" ); - } - - if ( strchr( key, '\\' ) ) { - return; - } - - while ( 1 ) - { - start = s; - if ( *s == '\\' ) { - s++; - } - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) { - return; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while ( *s != '\\' && *s ) - { - if ( !*s ) { - return; - } - *o++ = *s++; - } - *o = 0; - - if ( !strcmp( key, pkey ) ) { - strcpy( start, s ); // remove this part - return; - } - - if ( !*s ) { - return; - } - } - -} - - -/* - ================== - Info_Validate - - Some characters are illegal in info strings because they - can mess up the server's parsing - ================== - */ -qboolean Info_Validate( const char *s ) { - if ( strchr( s, '\"' ) ) { - return qfalse; - } - if ( strchr( s, ';' ) ) { - return qfalse; - } - return qtrue; -} - -/* - ================== - Info_SetValueForKey - - Changes or adds a key/value pair - ================== - */ -void Info_SetValueForKey( char *s, const char *key, const char *value ) { - char newi[MAX_INFO_STRING]; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" ); - } - - if ( strchr( key, '\\' ) || strchr( value, '\\' ) ) { - Com_Printf( "Can't use keys or values with a \\\n" ); - return; - } - - if ( strchr( key, ';' ) || strchr( value, ';' ) ) { - Com_Printf( "Can't use keys or values with a semicolon\n" ); - return; - } - - if ( strchr( key, '\"' ) || strchr( value, '\"' ) ) { - Com_Printf( "Can't use keys or values with a \"\n" ); - return; - } - - Info_RemoveKey( s, key ); - if ( !value || !strlen( value ) ) { - return; - } - - Com_sprintf( newi, sizeof( newi ), "\\%s\\%s", key, value ); - - if ( strlen( newi ) + strlen( s ) > MAX_INFO_STRING ) { - Com_Printf( "Info string length exceeded\n" ); - return; - } - - strcat( s, newi ); -} - -//==================================================================== - - -/* - =============== - ParseHex - =============== - */ -int ParseHex( const char *text ) { - int value; - int c; - - value = 0; - while ( ( c = *text++ ) != 0 ) { - if ( c >= '0' && c <= '9' ) { - value = value * 16 + c - '0'; - continue; - } - if ( c >= 'a' && c <= 'f' ) { - value = value * 16 + 10 + c - 'a'; - continue; - } - if ( c >= 'A' && c <= 'F' ) { - value = value * 16 + 10 + c - 'A'; - continue; - } - } - - return value; -} diff --git a/libs/splines/q_shared.h b/libs/splines/q_shared.h deleted file mode 100644 index 10a7562..0000000 --- a/libs/splines/q_shared.h +++ /dev/null @@ -1,803 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __Q_SHARED_H -#define __Q_SHARED_H - -#include "globaldefs.h" - -// q_shared.h -- included first by ALL program modules. -// these are the definitions that have no dependance on -// central system services, and can be used by any part -// of the program without any state issues. - -// A user mod should never modify this file - -#define Q3_VERSION "DOOM 0.01" - -// alignment macros for SIMD -#define ALIGN_ON -#define ALIGN_OFF - -#if GDEF_COMPILER_MSVC - -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057) // slightly different base types -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) // truncation from const double to float -#pragma warning(disable : 4310) // cast truncates constant value -#pragma warning(disable : 4514) -#pragma warning(disable : 4711) // selected for automatic inline expansion -#pragma warning(disable : 4220) // varargs matches remaining parameters - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if GDEF_OS_WINDOWS // mac doesn't have malloc.h -#include // for _alloca() -#endif -#if GDEF_COMPILER_MSVC - -//#pragma intrinsic( memset, memcpy ) - -#endif - - -// this is the define for determining if we have an asm version of a C function -#if GDEF_ARCH_BITS_32 && !defined __sun__ && !defined __LCC__ -#define id386 1 -#else -#define id386 0 -#endif - -// for windows fastcall option - -#define QDECL - -//======================= WIN32 DEFINES ================================= - -#if GDEF_OS_WINDOWS - -#define MAC_STATIC - -#undef QDECL -#define QDECL __cdecl - -// buildstring will be incorporated into the version string -#ifdef NDEBUG -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "win-x86" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP" -#endif -#else -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "win-x86-debug" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP-debug" -#endif -#endif - - -#define PATH_SEP '\\' - -#endif - -//======================= MAC OS X SERVER DEFINES ===================== - -#if GDEF_OS_MACOS && defined( __MACH__ ) - -#define MAC_STATIC - -#ifdef __ppc__ -#define CPUSTRING "MacOSXS-ppc" -#elif GDEF_ARCH_BITS_32 -#define CPUSTRING "MacOSXS-i386" -#else -#define CPUSTRING "MacOSXS-other" -#endif - -#define PATH_SEP '/' - -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define _alloca alloca - -#undef ALIGN_ON -#undef ALIGN_OFF -#define ALIGN_ON #pragma align( 16 ) -#define ALIGN_OFF #pragma align() - -#ifdef __cplusplus -extern "C" { -#endif - -void *osxAllocateMemory( long size ); -void osxFreeMemory( void *pointer ); - -#ifdef __cplusplus -} -#endif - -#endif - -//======================= MAC DEFINES ================================= - -#ifdef __MACOS__ - -#define MAC_STATIC static - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#endif - -#ifdef __MRC__ - -#define MAC_STATIC - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#undef QDECL -#define QDECL __cdecl - -#define _alloca alloca -#endif - -//======================= LINUX DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#if GDEF_OS_LINUX - -#define MAC_STATIC - -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "linux-i386" -#elif defined __axp__ -#define CPUSTRING "linux-alpha" -#else -#define CPUSTRING "linux-other" -#endif - -#define PATH_SEP '/' - -#endif - -//============================================================= - -typedef enum {qfalse, qtrue} qboolean; - -typedef unsigned char byte; - -#define EQUAL_EPSILON 0.001 - -typedef int qhandle_t; -typedef int sfxHandle_t; -typedef int fileHandle_t; -typedef int clipHandle_t; - -typedef enum { - INVALID_JOINT = -1 -} jointHandle_t; - -#ifndef NULL -#define NULL ( (void *)0 ) -#endif - -#define MAX_QINT 0x7fffffff -#define MIN_QINT ( -MAX_QINT - 1 ) - -#if !defined(__cplusplus) && !defined(max) -#define max( x, y ) ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) ) -#define min( x, y ) ( ( ( x ) < ( y ) ) ? ( x ) : ( y ) ) -#endif - -#ifndef sign -#define sign( f ) ( ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ) ) -#endif - -// angle indexes -#define PITCH 0 // up / down -#define YAW 1 // left / right -#define ROLL 2 // fall over - -// the game guarantees that no string from the network will ever -// exceed MAX_STRING_CHARS -#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString -#define MAX_TOKEN_CHARS 1024 // max length of an individual token - -#define MAX_INFO_STRING 1024 -#define MAX_INFO_KEY 1024 -#define MAX_INFO_VALUE 1024 - - -#define MAX_QPATH 64 // max length of a quake game pathname -#ifdef PATH_MAX -#define MAX_OSPATH PATH_MAX // max length of a filesystem pathname -#else -#define MAX_OSPATH 128 // max length of a filesystem pathname -#endif - -#define MAX_NAME_LENGTH 32 // max length of a client name - -// paramters for command buffer stuffing -typedef enum { - EXEC_NOW, // don't return until completed, a VM should NEVER use this, - // because some commands might cause the VM to be unloaded... - EXEC_INSERT, // insert at current position, but don't run yet - EXEC_APPEND // add to end of the command buffer (normal case) -} cbufExec_t; - - -// -// these aren't needed by any of the VMs. put in another header? -// -#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility - -#undef ERR_FATAL // malloc.h on unix - -// parameters to the main Error routine -typedef enum { - ERR_NONE, - ERR_FATAL, // exit the entire game with a popup window - ERR_DROP, // print to console and disconnect from game - ERR_DISCONNECT, // don't kill server - ERR_NEED_CD // pop up the need-cd dialog -} errorParm_t; - - -// font rendering values used by ui and cgame - -#define PROP_GAP_WIDTH 3 -#define PROP_SPACE_WIDTH 8 -#define PROP_HEIGHT 27 -#define PROP_SMALL_SIZE_SCALE 0.75 - -#define BLINK_DIVISOR 200 -#define PULSE_DIVISOR 75 - -#define UI_LEFT 0x00000000 // default -#define UI_CENTER 0x00000001 -#define UI_RIGHT 0x00000002 -#define UI_FORMATMASK 0x00000007 -#define UI_SMALLFONT 0x00000010 -#define UI_BIGFONT 0x00000020 // default -#define UI_GIANTFONT 0x00000040 -#define UI_DROPSHADOW 0x00000800 -#define UI_BLINK 0x00001000 -#define UI_INVERSE 0x00002000 -#define UI_PULSE 0x00004000 - - -/* - ============================================================== - - MATHLIB - - ============================================================== - */ -#ifdef __cplusplus // so we can include this in C code -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS 3 - -#define Q_PI 3.14159265358979323846 -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#include "math_vector.h" -#include "math_angles.h" -#include "math_matrix.h" -#include "math_quaternion.h" - -class idVec3; // for defining vectors -typedef idVec3 &vec3_p; // for passing vectors as function arguments -typedef const idVec3 &vec3_c; // for passing vectors as const function arguments - -class angles_t; // for defining angle vectors -typedef angles_t &angles_p; // for passing angles as function arguments -typedef const angles_t &angles_c; // for passing angles as const function arguments - -class mat3_t; // for defining matrices -typedef mat3_t &mat3_p; // for passing matrices as function arguments -typedef const mat3_t &mat3_c; // for passing matrices as const function arguments - - - -#define NUMVERTEXNORMALS 162 -extern idVec3 bytedirs[NUMVERTEXNORMALS]; - -// all drawing is done to a 640*480 virtual screen size -// and will be automatically scaled to the real resolution -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define TINYCHAR_WIDTH ( SMALLCHAR_WIDTH ) -#define TINYCHAR_HEIGHT ( SMALLCHAR_HEIGHT / 2 ) - -#define SMALLCHAR_WIDTH 8 -#define SMALLCHAR_HEIGHT 16 - -#define BIGCHAR_WIDTH 16 -#define BIGCHAR_HEIGHT 16 - -#define GIANTCHAR_WIDTH 32 -#define GIANTCHAR_HEIGHT 48 - -extern idVec4 colorBlack; -extern idVec4 colorRed; -extern idVec4 colorGreen; -extern idVec4 colorBlue; -extern idVec4 colorYellow; -extern idVec4 colorMagenta; -extern idVec4 colorCyan; -extern idVec4 colorWhite; -extern idVec4 colorLtGrey; -extern idVec4 colorMdGrey; -extern idVec4 colorDkGrey; - -#define Q_COLOR_ESCAPE '^' -#define Q_IsColorString( p ) ( p && *( p ) == Q_COLOR_ESCAPE && *( ( p ) + 1 ) && *( ( p ) + 1 ) != Q_COLOR_ESCAPE ) - -#define COLOR_BLACK '0' -#define COLOR_RED '1' -#define COLOR_GREEN '2' -#define COLOR_YELLOW '3' -#define COLOR_BLUE '4' -#define COLOR_CYAN '5' -#define COLOR_MAGENTA '6' -#define COLOR_WHITE '7' -#define ColorIndex( c ) ( ( ( c ) - '0' ) & 7 ) - -#define S_COLOR_BLACK "^0" -#define S_COLOR_RED "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW "^3" -#define S_COLOR_BLUE "^4" -#define S_COLOR_CYAN "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" - -extern idVec4 g_color_table[8]; - -#define MAKERGB( v, r, g, b ) v[0] = r; v[1] = g; v[2] = b -#define MAKERGBA( v, r, g, b, a ) v[0] = r; v[1] = g; v[2] = b; v[3] = a - -#define DEG2RAD( a ) ( ( ( a ) * M_PI ) / 180.0F ) -#define RAD2DEG( a ) ( ( ( a ) * 180.0f ) / M_PI ) - -struct cplane_s; - -extern idVec3 vec3_origin; -extern idVec4 vec4_origin; -extern mat3_t axisDefault; - -#define nanmask ( 255 << 23 ) - -#define IS_NAN( x ) ( ( ( *(int *)&x ) & nanmask ) == nanmask ) - -float Q_fabs( float f ); -float Q_rsqrt( float f ); // reciprocal square root - -#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) ) - -signed char ClampChar( int i ); -signed short ClampShort( int i ); - -// this isn't a real cheap function to call! -int DirToByte( const idVec3 &dir ); -void ByteToDir( int b, vec3_p dir ); - -#define DotProduct( a,b ) ( ( a )[0] * ( b )[0] + ( a )[1] * ( b )[1] + ( a )[2] * ( b )[2] ) -#define VectorSubtract( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2] ) -#define VectorAdd( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2] ) -#define VectorCopy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2] ) -//#define VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -#define VectorScale( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ) ) -#define VectorMA( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ) ) -#define CrossProduct( a,b,c ) ( ( c )[0] = ( a )[1] * ( b )[2] - ( a )[2] * ( b )[1],( c )[1] = ( a )[2] * ( b )[0] - ( a )[0] * ( b )[2],( c )[2] = ( a )[0] * ( b )[1] - ( a )[1] * ( b )[0] ) - -#define DotProduct4( x,y ) ( ( x )[0] * ( y )[0] + ( x )[1] * ( y )[1] + ( x )[2] * ( y )[2] + ( x )[3] * ( y )[3] ) -#define VectorSubtract4( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2],( c )[3] = ( a )[3] - ( b )[3] ) -#define VectorAdd4( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2],( c )[3] = ( a )[3] + ( b )[3] ) -#define VectorCopy4( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) -#define VectorScale4( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ),( o )[3] = ( v )[3] * ( s ) ) -#define VectorMA4( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ),( o )[3] = ( v )[3] + ( b )[3] * ( s ) ) - - -#define VectorClear( a ) ( ( a )[0] = ( a )[1] = ( a )[2] = 0 ) -#define VectorNegate( a,b ) ( ( b )[0] = -( a )[0],( b )[1] = -( a )[1],( b )[2] = -( a )[2] ) -#define VectorSet( v, x, y, z ) ( ( v )[0] = ( x ), ( v )[1] = ( y ), ( v )[2] = ( z ) ) -#define Vector4Copy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) - -#define SnapVector( v ) {v[0] = (int)v[0]; v[1] = (int)v[1]; v[2] = (int)v[2]; } - -float NormalizeColor( vec3_c in, vec3_p out ); - -int VectorCompare( vec3_c v1, vec3_c v2 ); -float VectorLength( vec3_c v ); -float Distance( vec3_c p1, vec3_c p2 ); -float DistanceSquared( vec3_c p1, vec3_c p2 ); -float VectorNormalize( vec3_p v ); // returns vector length -void VectorNormalizeFast( vec3_p v ); // does NOT return vector length, uses rsqrt approximation -float VectorNormalize2( vec3_c v, vec3_p out ); -void VectorInverse( vec3_p v ); -void VectorRotate( vec3_c in, mat3_c matrix, vec3_p out ); -void VectorPolar( vec3_p v, float radius, float theta, float phi ); -void VectorSnap( vec3_p v ); -void Vector53Copy( const idVec5_t &in, vec3_p out ); -void Vector5Scale( const idVec5_t &v, float scale, idVec5_t &out ); -void Vector5Add( const idVec5_t &va, const idVec5_t &vb, idVec5_t &out ); -void VectorRotate3( vec3_c vIn, vec3_c vRotation, vec3_p out ); -void VectorRotate3Origin( vec3_c vIn, vec3_c vRotation, vec3_c vOrigin, vec3_p out ); - - -int Q_log2( int val ); - -int Q_rand( int *seed ); -float Q_random( int *seed ); -float Q_crandom( int *seed ); - -#define random() ( ( rand() & 0x7fff ) / ( (float)0x7fff ) ) -#define crandom() ( 2.0 * ( random() - 0.5 ) ) - -float Q_rint( float in ); - -void vectoangles( vec3_c value1, angles_p angles ); -void AnglesToAxis( angles_c angles, mat3_p axis ); - -void AxisCopy( mat3_c in, mat3_p out ); -qboolean AxisRotated( mat3_c in ); // assumes a non-degenerate axis - -int SignbitsForNormal( vec3_c normal ); -int BoxOnPlaneSide( const Bounds &b, struct cplane_s *p ); - -float AngleMod( float a ); -float LerpAngle( float from, float to, float frac ); -float AngleSubtract( float a1, float a2 ); -void AnglesSubtract( angles_c v1, angles_c v2, angles_p v3 ); - -float AngleNormalize360( float angle ); -float AngleNormalize180( float angle ); -float AngleDelta( float angle1, float angle2 ); - -qboolean PlaneFromPoints( idVec4 &plane, vec3_c a, vec3_c b, vec3_c c ); -void ProjectPointOnPlane( vec3_p dst, vec3_c p, vec3_c normal ); -void RotatePointAroundVector( vec3_p dst, vec3_c dir, vec3_c point, float degrees ); -void RotateAroundDirection( mat3_p axis, float yaw ); -void MakeNormalVectors( vec3_c forward, vec3_p right, vec3_p up ); -// perpendicular vector could be replaced by this - -int PlaneTypeForNormal( vec3_c normal ); - -void MatrixMultiply( mat3_c in1, mat3_c in2, mat3_p out ); -void MatrixInverseMultiply( mat3_c in1, mat3_c in2, mat3_p out ); // in2 is transposed during multiply -void MatrixTransformVector( vec3_c in, mat3_c matrix, vec3_p out ); -void MatrixProjectVector( vec3_c in, mat3_c matrix, vec3_p out ); // Places the vector into a new coordinate system. -void AngleVectors( angles_c angles, vec3_p forward, vec3_p right, vec3_p up ); -void PerpendicularVector( vec3_p dst, vec3_c src ); - -float TriangleArea( vec3_c a, vec3_c b, vec3_c c ); -#endif // __cplusplus - -//============================================= - -float Com_Clamp( float min, float max, float value ); - -#define FILE_HASH_SIZE 1024 -int Com_HashString( const char *fname ); - -char *Com_SkipPath( char *pathname ); - -// it is ok for out == in -void Com_StripExtension( const char *in, char *out ); - -// "extension" should include the dot: ".map" -void Com_DefaultExtension( char *path, int maxSize, const char *extension ); - -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ); - -/* - ===================================================================================== - - SCRIPT PARSING - - ===================================================================================== - */ - -// this just controls the comment printing, it doesn't actually load a file -void Com_BeginParseSession( const char *filename ); -void Com_EndParseSession( void ); - -int Com_GetCurrentParseLine( void ); - -// Will never return NULL, just empty strings. -// An empty string will only be returned at end of file. -// ParseOnLine will return empty if there isn't another token on this line - -// this funny typedef just means a moving pointer into a const char * buffer -const char *Com_Parse( const char *( *data_p ) ); -const char *Com_ParseOnLine( const char *( *data_p ) ); -const char *Com_ParseRestOfLine( const char *( *data_p ) ); - -void Com_UngetToken( void ); - -#ifdef __cplusplus -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning = qfalse ); -#else -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning ); -#endif - -void Com_ScriptError( const char *msg, ... ); -void Com_ScriptWarning( const char *msg, ... ); - -void Com_SkipBracedSection( const char *( *program ) ); -void Com_SkipRestOfLine( const char *( *data ) ); - -float Com_ParseFloat( const char *( *buf_p ) ); -int Com_ParseInt( const char *( *buf_p ) ); - -void Com_Parse1DMatrix( const char *( *buf_p ), int x, float *m ); -void Com_Parse2DMatrix( const char *( *buf_p ), int y, int x, float *m ); -void Com_Parse3DMatrix( const char *( *buf_p ), int z, int y, int x, float *m ); - -//===================================================================================== -#ifdef __cplusplus -extern "C" { -#endif - -void QDECL Com_sprintf( char *dest, std::size_t size, const char *fmt, ... ); - - -// mode parm for FS_FOpenFile -typedef enum { - FS_READ, - FS_WRITE, - FS_APPEND, - FS_APPEND_SYNC -} fsMode_t; - -typedef enum { - FS_SEEK_CUR, - FS_SEEK_END, - FS_SEEK_SET -} fsOrigin_t; - -//============================================= - -int Q_isprint( int c ); -int Q_islower( int c ); -int Q_isupper( int c ); -int Q_isalpha( int c ); - -// portable case insensitive compare -int Q_stricmp( const char *s1, const char *s2 ); -int Q_strncmp( const char *s1, const char *s2, int n ); -int Q_stricmpn( const char *s1, const char *s2, int n ); -char *Q_strlwr( char *s1 ); -char *Q_strupr( char *s1 ); -char *Q_strrchr( const char* string, int c ); - -// buffer size safe library replacements -void Q_strncpyz( char *dest, const char *src, std::size_t destsize ); -void Q_strcat( char *dest, std::size_t size, const char *src ); - -// strlen that discounts Quake color sequences -int Q_PrintStrlen( const char *string ); -// removes color sequences from string -char *Q_CleanStr( char *string ); - -int Com_Filter( const char *filter, const char *name, int casesensitive ); -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ); - - -//============================================= - -short BigShort( short l ); -short LittleShort( short l ); -int BigLong( int l ); -int LittleLong( int l ); -float BigFloat( float l ); -float LittleFloat( float l ); - -void Swap_Init( void ); -char *QDECL va( const char *format, ... ); - -#ifdef __cplusplus -} -#endif - - -//============================================= -#ifdef __cplusplus -// -// mapfile parsing -// -typedef struct ePair_s { - char *key; - char *value; -} ePair_t; - -typedef struct mapSide_s { - char material[MAX_QPATH]; - idVec4 plane; - idVec4 textureVectors[2]; -} mapSide_t; - -typedef struct { - int numSides; - mapSide_t **sides; -} mapBrush_t; - -typedef struct { - idVec3 xyz; - float st[2]; -} patchVertex_t; - -typedef struct { - char material[MAX_QPATH]; - int width, height; - patchVertex_t *patchVerts; -} mapPatch_t; - -typedef struct { - char modelName[MAX_QPATH]; - float matrix[16]; -} mapModel_t; - -typedef struct mapPrimitive_s { - int numEpairs; - ePair_t **ePairs; - - // only one of these will be non-NULL - mapBrush_t *brush; - mapPatch_t *patch; - mapModel_t *model; -} mapPrimitive_t; - -typedef struct mapEntity_s { - int numPrimitives; - mapPrimitive_t **primitives; - - int numEpairs; - ePair_t **ePairs; -} mapEntity_t; - -typedef struct { - int numEntities; - mapEntity_t **entities; -} mapFile_t; - - -// the order of entities, brushes, and sides will be maintained, the -// lists won't be swapped on each load or save -mapFile_t *ParseMapFile( const char *text ); -void FreeMapFile( mapFile_t *mapFile ); -void WriteMapFile( const mapFile_t *mapFile, FILE *f ); - -// key names are case-insensitive -const char *ValueForMapEntityKey( const mapEntity_t *ent, const char *key ); -float FloatForMapEntityKey( const mapEntity_t *ent, const char *key ); -qboolean GetVectorForMapEntityKey( const mapEntity_t *ent, const char *key, idVec3 &vec ); - -typedef struct { - idVec3 xyz; - idVec2 st; - idVec3 normal; - idVec3 tangents[2]; - byte smoothing[4]; // colors for silhouette smoothing -} drawVert_t; - -typedef struct { - int width, height; - drawVert_t *verts; -} drawVertMesh_t; - -// Tesselate a map patch into smoothed, drawable vertexes -// MaxError of around 4 is reasonable -drawVertMesh_t *SubdivideMapPatch( const mapPatch_t *patch, float maxError ); -#endif // __cplusplus - -//========================================= - -#ifdef __cplusplus -extern "C" { -#endif - -void QDECL Com_Error( int level, const char *error, ... ); -void QDECL Com_Printf( const char *msg, ... ); -void QDECL Com_DPrintf( const char *msg, ... ); - -#ifdef __cplusplus -} -#endif - - -typedef struct { - qboolean frameMemory; - int currentElements; - int maxElements; // will reallocate and move when exceeded - void **elements; -} growList_t; - -// you don't need to init the growlist if you don't mind it growing and moving -// the list as it expands -void Com_InitGrowList( growList_t *list, int maxElements ); -int Com_AddToGrowList( growList_t *list, void *data ); -void *Com_GrowListElement( const growList_t *list, int index ); -int Com_IndexForGrowListElement( const growList_t *list, const void *element ); - - -// -// key / value info strings -// -const char *Info_ValueForKey( const char *s, const char *key ); -void Info_RemoveKey( char *s, const char *key ); -void Info_SetValueForKey( char *s, const char *key, const char *value ); -qboolean Info_Validate( const char *s ); -void Info_NextPair( const char *( *s ), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ); - -// get cvar defs, collision defs, etc -//#include "../shared/interface.h" - -// get key code numbers for events -//#include "../shared/keycodes.h" - -#ifdef __cplusplus -// get the polygon winding functions -//#include "../shared/windings.h" - -// get the flags class -//#include "../shared/idflags.h" -#endif // __cplusplus - -#endif // __Q_SHARED_H diff --git a/libs/splines/splines.cpp b/libs/splines/splines.cpp deleted file mode 100644 index e35d82b..0000000 --- a/libs/splines/splines.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" -#include "splines.h" - -extern "C" { -int FS_Write( const void *buffer, int len, fileHandle_t h ); -int FS_ReadFile( const char *qpath, void **buffer ); -void FS_FreeFile( void *buffer ); -fileHandle_t FS_FOpenFileWrite( const char *filename ); -void FS_FCloseFile( fileHandle_t f ); -void Cbuf_AddText( const char *text ); -void Cbuf_Execute( void ); -} - -float Q_fabs( float f ) { - int tmp = *( int * ) &f; - tmp &= 0x7FFFFFFF; - return *( float * ) &tmp; -} - -// (SA) making a list of cameras so I can use -// the splines as targets for other things. -// Certainly better ways to do this, but this lets -// me get underway quickly with ents that need spline -// targets. -const int MAX_CAMERAS = 64; - -idCameraDef camera[MAX_CAMERAS]; - -extern "C" { -qboolean loadCamera( int camNum, const char *name ) { - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return qfalse; - } - camera[camNum].clear(); - return (qboolean)camera[camNum].load( name ); -} - -qboolean getCameraInfo( int camNum, int time, float *origin, float *angles, float *fov ) { - idVec3 dir, org; - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return qfalse; - } - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - if ( camera[camNum].getCameraInfo( time, org, dir, fov ) ) { - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; - angles[0] = asin( dir[2] ) * 180 / 3.14159; - return qtrue; - } - return qfalse; -} - -void startCamera( int camNum, int time ) { - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return; - } - camera[camNum].startCamera( time ); -} - -} - - -//#include "../shared/windings.h" -//#include "../qcommon/qcommon.h" -//#include "../sys/sys_public.h" -//#include "../game/game_entity.h" - -idCameraDef splineList; -idCameraDef *g_splineList = &splineList; - -idVec3 idSplineList::zero( 0,0,0 ); - -void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label ) { - glColor3fv( color ); - glPointSize( size ); - glBegin( GL_POINTS ); - glVertex3fv( point ); - glEnd(); - idVec3 v = point; - v.x += 1; - v.y += 1; - v.z += 1; - glRasterPos3fv( v ); - glCallLists( strlen( label ), GL_UNSIGNED_BYTE, label ); -} - - -void glBox( idVec3 &color, idVec3 &point, float size ) { - idVec3 mins( point ); - idVec3 maxs( point ); - mins[0] -= size; - mins[1] += size; - mins[2] -= size; - maxs[0] += size; - maxs[1] -= size; - maxs[2] += size; - glColor3fv( color ); - glBegin( GL_LINE_LOOP ); - glVertex3f( mins[0],mins[1],mins[2] ); - glVertex3f( maxs[0],mins[1],mins[2] ); - glVertex3f( maxs[0],maxs[1],mins[2] ); - glVertex3f( mins[0],maxs[1],mins[2] ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex3f( mins[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],maxs[2] ); - glEnd(); - - glBegin( GL_LINES ); - glVertex3f( mins[0],mins[1],mins[2] ); - glVertex3f( mins[0],mins[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],mins[2] ); - glVertex3f( maxs[0],mins[1],mins[2] ); - glVertex3f( maxs[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],mins[2] ); - glEnd(); - -} - -void splineTest() { - //g_splineList->load("p:/doom/base/maps/test_base1.camera"); -} - -void splineDraw() { - //g_splineList->addToRenderer(); -} - - -//extern void D_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end ); - -void debugLine( idVec3 &color, float x, float y, float z, float x2, float y2, float z2 ) { - idVec3 from( x, y, z ); - idVec3 to( x2, y2, z2 ); - //D_DebugLine(color, from, to); -} - -void idSplineList::addToRenderer() { - - if ( controlPoints.Num() == 0 ) { - return; - } - - idVec3 mins, maxs; - idVec3 yellow( 1.0, 1.0, 0 ); - idVec3 white( 1.0, 1.0, 1.0 ); - int i; - - for ( i = 0; i < controlPoints.Num(); i++ ) { - VectorCopy( *controlPoints[i], mins ); - VectorCopy( mins, maxs ); - mins[0] -= 8; - mins[1] += 8; - mins[2] -= 8; - maxs[0] += 8; - maxs[1] -= 8; - maxs[2] += 8; - debugLine( yellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2] ); - debugLine( yellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2] ); - debugLine( yellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2] ); - debugLine( yellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2] ); - - debugLine( yellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2] ); - debugLine( yellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2] ); - debugLine( yellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2] ); - debugLine( yellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2] ); - - } - - int step = 0; - idVec3 step1; - for ( i = 3; i < controlPoints.Num(); i++ ) { - for ( float tension = 0.0f; tension < 1.001f; tension += 0.1f ) { - float x = 0; - float y = 0; - float z = 0; - for ( int j = 0; j < 4; j++ ) { - x += controlPoints[i - ( 3 - j )]->x * calcSpline( j, tension ); - y += controlPoints[i - ( 3 - j )]->y * calcSpline( j, tension ); - z += controlPoints[i - ( 3 - j )]->z * calcSpline( j, tension ); - } - if ( step == 0 ) { - step1[0] = x; - step1[1] = y; - step1[2] = z; - step = 1; - } - else { - debugLine( white, step1[0], step1[1], step1[2], x, y, z ); - step = 0; - } - - } - } -} - -void idSplineList::buildSpline() { - //int start = Sys_Milliseconds(); - clearSpline(); - for ( int i = 3; i < controlPoints.Num(); i++ ) { - for ( float tension = 0.0f; tension < 1.001f; tension += granularity ) { - float x = 0; - float y = 0; - float z = 0; - for ( int j = 0; j < 4; j++ ) { - x += controlPoints[i - ( 3 - j )]->x * calcSpline( j, tension ); - y += controlPoints[i - ( 3 - j )]->y * calcSpline( j, tension ); - z += controlPoints[i - ( 3 - j )]->z * calcSpline( j, tension ); - } - splinePoints.Append( new idVec3( x, y, z ) ); - } - } - dirty = false; - //Com_Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000); -} - - -void idSplineList::draw( bool editMode ) { - int i; - idVec4 yellow( 1, 1, 0, 1 ); - - if ( controlPoints.Num() == 0 ) { - return; - } - - if ( dirty ) { - buildSpline(); - } - - - glColor3fv( controlColor ); - glPointSize( 5 ); - - glBegin( GL_POINTS ); - for ( i = 0; i < controlPoints.Num(); i++ ) { - glVertex3fv( *controlPoints[i] ); - } - glEnd(); - - if ( editMode ) { - for ( i = 0; i < controlPoints.Num(); i++ ) { - glBox( activeColor, *controlPoints[i], 4 ); - } - } - - //Draw the curve - glColor3fv( pathColor ); - glBegin( GL_LINE_STRIP ); - int count = splinePoints.Num(); - for ( i = 0; i < count; i++ ) { - glVertex3fv( *splinePoints[i] ); - } - glEnd(); - - if ( editMode ) { - glColor3fv( segmentColor ); - glPointSize( 3 ); - glBegin( GL_POINTS ); - for ( i = 0; i < count; i++ ) { - glVertex3fv( *splinePoints[i] ); - } - glEnd(); - } - if ( count > 0 ) { - //assert(activeSegment >=0 && activeSegment < count); - if ( activeSegment >= 0 && activeSegment < count ) { - glBox( activeColor, *splinePoints[activeSegment], 6 ); - glBox( yellow, *splinePoints[activeSegment], 8 ); - } - } - -} - -float idSplineList::totalDistance() { - - // FIXME: save dist and return - // - if ( controlPoints.Num() == 0 ) { - return 0.0; - } - - if ( dirty ) { - buildSpline(); - } - - float dist = 0.0; - idVec3 temp; - int count = splinePoints.Num(); - for ( int i = 1; i < count; i++ ) { - temp = *splinePoints[i - 1]; - temp -= *splinePoints[i]; - dist += temp.Length(); - } - return dist; -} - -void idSplineList::initPosition( long bt, long totalTime ) { - - if ( dirty ) { - buildSpline(); - } - - if ( splinePoints.Num() == 0 ) { - return; - } - - baseTime = bt; - time = totalTime; - - // calc distance to travel ( this will soon be broken into time segments ) - splineTime.Clear(); - splineTime.Append( bt ); - double dist = totalDistance(); - double distSoFar = 0.0; - idVec3 temp; - int count = splinePoints.Num(); - //for(int i = 2; i < count - 1; i++) { - for ( int i = 1; i < count; i++ ) { - temp = *splinePoints[i - 1]; - temp -= *splinePoints[i]; - distSoFar += temp.Length(); - double percent = distSoFar / dist; - percent *= totalTime; - splineTime.Append( percent + bt ); - } - assert( splineTime.Num() == splinePoints.Num() ); - activeSegment = 0; -} - - - -float idSplineList::calcSpline( int step, float tension ) { - switch ( step ) { - case 0: return ( pow( 1 - tension, 3 ) ) / 6; - case 1: return ( 3 * pow( tension, 3 ) - 6 * pow( tension, 2 ) + 4 ) / 6; - case 2: return ( -3 * pow( tension, 3 ) + 3 * pow( tension, 2 ) + 3 * tension + 1 ) / 6; - case 3: return pow( tension, 3 ) / 6; - } - return 0.0; -} - - - -void idSplineList::updateSelection( const idVec3 &move ) { - if ( selected ) { - dirty = true; - VectorAdd( *selected, move, *selected ); - } -} - - -void idSplineList::setSelectedPoint( idVec3 *p ) { - if ( p ) { - p->Snap(); - for ( int i = 0; i < controlPoints.Num(); i++ ) { - if ( *p == *controlPoints[i] ) { - selected = controlPoints[i]; - } - } - } - else { - selected = NULL; - } -} - -const idVec3 *idSplineList::getPosition( long t ) { - static idVec3 interpolatedPos; - - int count = splineTime.Num(); - if ( count == 0 ) { - return &zero; - } - -// Com_Printf("Time: %d\n", t); - assert( splineTime.Num() == splinePoints.Num() ); - - while ( activeSegment < count ) { - if ( splineTime[activeSegment] >= t ) { - if ( activeSegment > 0 && activeSegment < count - 1 ) { - double timeHi = splineTime[activeSegment + 1]; - double timeLo = splineTime[activeSegment - 1]; - double percent = ( timeHi - t ) / ( timeHi - timeLo ); - // pick two bounding points - idVec3 v1 = *splinePoints[activeSegment - 1]; - idVec3 v2 = *splinePoints[activeSegment + 1]; - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; - return &interpolatedPos; - } - return splinePoints[activeSegment]; - } - else { - activeSegment++; - } - } - return splinePoints[count - 1]; -} - -void idSplineList::parse( const char *( *text ) ) { - const char *token; - //Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !Q_stricmp( token, "(" ) || !Q_stricmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "granularity" ) == 0 ) { - granularity = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "name" ) == 0 ) { - name = token; - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - // read the control point - idVec3 point; - Com_Parse1DMatrix( text, 3, point ); - addPoint( point.x, point.y, point.z ); - } while ( 1 ); - - //Com_UngetToken(); - //Com_MatchToken( text, "}" ); - dirty = true; -} - -void idSplineList::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - //s = va("\t\tname %s\n", name.c_str()); - //FS_Write(s.c_str(), s.length(), file); - s = va( "\t\t\tgranularity %f\n", granularity ); - FS_Write( s.c_str(), s.length(), file ); - int count = controlPoints.Num(); - for ( int i = 0; i < count; i++ ) { - s = va( "\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z ); - FS_Write( s.c_str(), s.length(), file ); - } - s = "\t\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -void idCameraDef::getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fov ) { -#if 0 - if ( !cameraSpline.validTime() ) { - buildCamera(); - } - double d = (double)segment / numSegments(); - getCameraInfo( d * totalTime * 1000, origin, direction, fov ); -#endif -/* - if (!cameraSpline.validTime()) { - buildCamera(); - } - origin = *cameraSpline.getSegmentPoint(segment); - - - idVec3 temp; - - int numTargets = getTargetSpline()->controlPoints.Num(); - int count = cameraSpline.splineTime.Num(); - if (numTargets == 0) { - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - } - } else if (numTargets == 1) { - temp = *getTargetSpline()->controlPoints[0]; - } else { - temp = *getTargetSpline()->getSegmentPoint(segment); - } - - temp -= origin; - temp.Normalize(); - direction = temp; - */ -} - -bool idCameraDef::getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv ) { - - char buff[1024]; - - if ( ( time - startTime ) / 1000 > totalTime ) { - return false; - } - - - for ( int i = 0; i < events.Num(); i++ ) { - if ( time >= startTime + events[i]->getTime() && !events[i]->getTriggered() ) { - events[i]->setTriggered( true ); - if ( events[i]->getType() == idCameraEvent::EVENT_TARGET ) { - setActiveTargetByName( events[i]->getParam() ); - getActiveTarget()->start( startTime + events[i]->getTime() ); - //Com_Printf("Triggered event switch to target: %s\n",events[i]->getParam()); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_TRIGGER ) { - //idEntity *ent = NULL; - //ent = level.FindTarget( ent, events[i]->getParam()); - //if (ent) { - // ent->signal( SIG_TRIGGER ); - // ent->ProcessEvent( &EV_Activate, world ); - //} - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FOV ) { - memset( buff, 0, sizeof( buff ) ); - strcpy( buff, events[i]->getParam() ); - const char *param1 = strtok( buff, " \t,\0" ); - const char *param2 = strtok( NULL, " \t,\0" ); - float len = ( param2 ) ? atof( param2 ) : 0; - float newfov = ( param1 ) ? atof( param1 ) : 90; - fov.reset( fov.getFOV( time ), newfov, time, len ); - //*fv = fov = atof(events[i]->getParam()); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FADEIN ) { - float time = atof( events[i]->getParam() ); - Cbuf_AddText( va( "fade 0 0 0 0 %f", time ) ); - Cbuf_Execute(); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FADEOUT ) { - float time = atof( events[i]->getParam() ); - Cbuf_AddText( va( "fade 0 0 0 255 %f", time ) ); - Cbuf_Execute(); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_CAMERA ) { - memset( buff, 0, sizeof( buff ) ); - strcpy( buff, events[i]->getParam() ); - const char *param1 = strtok( buff, " \t,\0" ); - const char *param2 = strtok( NULL, " \t,\0" ); - - if ( param2 ) { - loadCamera( atoi( param1 ), va( "cameras/%s.camera", param2 ) ); - startCamera( time ); - } - else { - loadCamera( 0, va( "cameras/%s.camera", events[i]->getParam() ) ); - startCamera( time ); - } - return true; - } - else if ( events[i]->getType() == idCameraEvent::EVENT_STOP ) { - return false; - } - } - } - - origin = *cameraPosition->getPosition( time ); - - *fv = fov.getFOV( time ); - - idVec3 temp = origin; - - int numTargets = targetPositions.Num(); - if ( numTargets == 0 ) { -/* - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - if (temp == origin) { - int index = cameraSpline.getActiveSegment() + 2; - while (temp == origin && index < count - 1) { - temp = *cameraSpline.splinePoints[index++]; - } - } - } - */ - } - else { - if ( getActiveTarget()->numPoints() > 0 ) { - temp = *getActiveTarget()->getPosition( time ); - } - } - - temp -= origin; - temp.Normalize(); - direction = temp; - - return true; -} - -bool idCameraDef::waitEvent( int index ) { - //for (int i = 0; i < events.Num(); i++) { - // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) { - // return true; - // } - //} - return false; -} - - -const int NUM_CCELERATION_SEGS = 10; -const int CELL_AMT = 5; - -void idCameraDef::buildCamera() { - int i; - idList waits; - idList targets; - - totalTime = baseTime; - cameraPosition->setTime( (long)totalTime * 1000 ); - // we have a base time layout for the path and the target path - // now we need to layer on any wait or speed changes - for ( i = 0; i < events.Num(); i++ ) { - events[i]->setTriggered( false ); - switch ( events[i]->getType() ) { - default: break; - case idCameraEvent::EVENT_TARGET: { - targets.Append( i ); - break; - } - case idCameraEvent::EVENT_FEATHER: { - long startTime = 0; - float speed = 0; - long loopTime = 10; - float stepGoal = cameraPosition->getBaseVelocity() / ( 1000 / loopTime ); - while ( startTime <= 1000 ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed += stepGoal; - if ( speed > cameraPosition->getBaseVelocity() ) { - speed = cameraPosition->getBaseVelocity(); - } - startTime += loopTime; - } - - startTime = (long)( totalTime * 1000 - 1000 ); - long endTime = startTime + 1000; - speed = cameraPosition->getBaseVelocity(); - while ( startTime < endTime ) { - speed -= stepGoal; - if ( speed < 0 ) { - speed = 0; - } - cameraPosition->addVelocity( startTime, loopTime, speed ); - startTime += loopTime; - } - break; - - } - case idCameraEvent::EVENT_WAIT: { - waits.Append( atof( events[i]->getParam() ) ); - - //FIXME: this is quite hacky for Wolf E3, accel and decel needs - // do be parameter based etc.. - long startTime = events[i]->getTime() - 1000; - if ( startTime < 0 ) { - startTime = 0; - } - float speed = cameraPosition->getBaseVelocity(); - long loopTime = 10; - float steps = speed / ( ( events[i]->getTime() - startTime ) / loopTime ); - while ( startTime <= events[i]->getTime() - loopTime ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed -= steps; - startTime += loopTime; - } - cameraPosition->addVelocity( events[i]->getTime(), (long)atof( events[i]->getParam() ) * 1000, 0 ); - - startTime = (long)( events[i]->getTime() + atof( events[i]->getParam() ) * 1000 ); - long endTime = startTime + 1000; - speed = 0; - while ( startTime <= endTime ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed += steps; - startTime += loopTime; - } - break; - } - case idCameraEvent::EVENT_TARGETWAIT: { - //targetWaits.Append(i); - break; - } - case idCameraEvent::EVENT_SPEED: { -/* - // take the average delay between up to the next five segments - float adjust = atof(events[i]->getParam()); - int index = events[i]->getSegment(); - total = 0; - count = 0; - - // get total amount of time over the remainder of the segment - for (j = index; j < cameraSpline.numSegments() - 1; j++) { - total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j); - count++; - } - - // multiply that by the adjustment - double newTotal = total * adjust; - // what is the difference.. - newTotal -= total; - totalTime += newTotal / 1000; - - // per segment difference - newTotal /= count; - int additive = newTotal; - - // now propogate that difference out to each segment - for (j = index; j < cameraSpline.numSegments(); j++) { - cameraSpline.addSegmentTime(j, additive); - additive += newTotal; - } - break; - */ - } - } - } - - - for ( i = 0; i < waits.Num(); i++ ) { - totalTime += waits[i]; - } - - // on a new target switch, we need to take time to this point ( since last target switch ) - // and allocate it across the active target, then reset time to this point - long timeSoFar = 0; - long total = (long)( totalTime * 1000 ); - for ( i = 0; i < targets.Num(); i++ ) { - long t; - if ( i < targets.Num() - 1 ) { - t = events[targets[i + 1]]->getTime(); - } - else { - t = total - timeSoFar; - } - // t is how much time to use for this target - setActiveTargetByName( events[targets[i]]->getParam() ); - getActiveTarget()->setTime( t ); - timeSoFar += t; - } - - -} - -void idCameraDef::startCamera( long t ) { - cameraPosition->clearVelocities(); - cameraPosition->start( t ); - buildCamera(); - fov.reset( 90, 90, t, 0 ); - //for (int i = 0; i < targetPositions.Num(); i++) { - // targetPositions[i]-> - //} - startTime = t; - cameraRunning = true; -} - - -void idCameraDef::parse( const char *( *text ) ) { - - const char *token; - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - if ( Q_stricmp( token, "time" ) == 0 ) { - baseTime = Com_ParseFloat( text ); - } - else if ( Q_stricmp( token, "camera_fixed" ) == 0 ) { - cameraPosition = new idFixedPosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "camera_interpolated" ) == 0 ) { - cameraPosition = new idInterpolatedPosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "camera_spline" ) == 0 ) { - cameraPosition = new idSplinePosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "target_fixed" ) == 0 ) { - idFixedPosition *pos = new idFixedPosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "target_interpolated" ) == 0 ) { - idInterpolatedPosition *pos = new idInterpolatedPosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "target_spline" ) == 0 ) { - idSplinePosition *pos = new idSplinePosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "fov" ) == 0 ) { - fov.parse( text ); - } - else if ( Q_stricmp( token, "event" ) == 0 ) { - idCameraEvent *event = new idCameraEvent(); - event->parse( text ); - addEvent( event ); - } - - - } while ( 1 ); - - if ( !cameraPosition ) { - Com_Printf( "no camera position specified\n" ); - // prevent a crash later on - cameraPosition = new idFixedPosition(); - } - - Com_UngetToken(); - Com_MatchToken( text, "}" ); - -} - -bool idCameraDef::load( const char *filename ) { - char *buf; - const char *buf_p; - - FS_ReadFile( filename, (void **)&buf ); - if ( !buf ) { - return false; - } - - clear(); - Com_BeginParseSession( filename ); - buf_p = buf; - parse( &buf_p ); - Com_EndParseSession(); - FS_FreeFile( buf ); - - return true; -} - -void idCameraDef::save( const char *filename ) { - fileHandle_t file = FS_FOpenFileWrite( filename ); - if ( file ) { - int i; - idStr s = "cameraPathDef { \n"; - FS_Write( s.c_str(), s.length(), file ); - s = va( "\ttime %f\n", baseTime ); - FS_Write( s.c_str(), s.length(), file ); - - cameraPosition->write( file, va( "camera_%s",cameraPosition->typeStr() ) ); - - for ( i = 0; i < numTargets(); i++ ) { - targetPositions[i]->write( file, va( "target_%s", targetPositions[i]->typeStr() ) ); - } - - for ( i = 0; i < events.Num(); i++ ) { - events[i]->write( file, "event" ); - } - - fov.write( file, "fov" ); - - s = "}\n"; - FS_Write( s.c_str(), s.length(), file ); - } - FS_FCloseFile( file ); -} - -int idCameraDef::sortEvents( const void *p1, const void *p2 ) { - idCameraEvent *ev1 = (idCameraEvent*)( p1 ); - idCameraEvent *ev2 = (idCameraEvent*)( p2 ); - - if ( ev1->getTime() > ev2->getTime() ) { - return -1; - } - if ( ev1->getTime() < ev2->getTime() ) { - return 1; - } - return 0; -} - -void idCameraDef::addEvent( idCameraEvent *event ) { - events.Append( event ); - //events.Sort(&sortEvents); - -} -void idCameraDef::addEvent( idCameraEvent::eventType t, const char *param, long time ) { - addEvent( new idCameraEvent( t, param, time ) ); - buildCamera(); -} - -void idCameraDef::removeEvent( int index ) { - events.RemoveIndex( index ); - buildCamera(); -} - - -const char *idCameraEvent::eventStr[] = { - "NA", - "WAIT", - "TARGETWAIT", - "SPEED", - "TARGET", - "SNAPTARGET", - "FOV", - "CMD", - "TRIGGER", - "STOP", - "CAMERA", - "FADEOUT", - "FADEIN", - "FEATHER" -}; - -void idCameraEvent::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "type" ) == 0 ) { - type = static_cast( atoi( token ) ); - } - else if ( Q_stricmp( key.c_str(), "param" ) == 0 ) { - paramStr = token; - } - else if ( Q_stricmp( key.c_str(), "time" ) == 0 ) { - time = atoi( token ); - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idCameraEvent::write( fileHandle_t file, const char *name ) { - idStr s = va( "\t%s {\n", name ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\ttype %d\n", static_cast( type ) ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\tparam \"%s\"\n", paramStr.c_str() ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\ttime %d\n", time ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -const char *idCameraPosition::positionStr[] = { - "Fixed", - "Interpolated", - "Spline", -}; - - - -const idVec3 *idInterpolatedPosition::getPosition( long t ) { - static idVec3 interpolatedPos; - - float velocity = getVelocity( t ); - float timePassed = t - lastTime; - lastTime = t; - - // convert to seconds - timePassed /= 1000; - - float distToTravel = timePassed * velocity; - - idVec3 temp = startPos; - temp -= endPos; - float distance = temp.Length(); - - distSoFar += distToTravel; - float percent = (float)( distSoFar ) / distance; - - if ( percent > 1.0 ) { - percent = 1.0; - } - else if ( percent < 0.0 ) { - percent = 0.0; - } - - // the following line does a straigt calc on percentage of time - // float percent = (float)(startTime + time - t) / time; - - idVec3 v1 = startPos; - idVec3 v2 = endPos; - v1 *= ( 1.0 - percent ); - v2 *= percent; - v1 += v2; - interpolatedPos = v1; - return &interpolatedPos; -} - - -void idCameraFOV::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "fov" ) == 0 ) { - fov = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "startFOV" ) == 0 ) { - startFOV = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "endFOV" ) == 0 ) { - endFOV = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "time" ) == 0 ) { - time = atoi( token ); - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -bool idCameraPosition::parseToken( const char *key, const char *( *text ) ) { - const char *token = Com_Parse( text ); - if ( Q_stricmp( key, "time" ) == 0 ) { - time = atol( token ); - return true; - } - else if ( Q_stricmp( key, "type" ) == 0 ) { - type = static_cast( atoi( token ) ); - return true; - } - else if ( Q_stricmp( key, "velocity" ) == 0 ) { - long t = atol( token ); - token = Com_Parse( text ); - long d = atol( token ); - token = Com_Parse( text ); - float s = atof( token ); - addVelocity( t, d, s ); - return true; - } - else if ( Q_stricmp( key, "baseVelocity" ) == 0 ) { - baseVelocity = atof( token ); - return true; - } - else if ( Q_stricmp( key, "name" ) == 0 ) { - name = token; - return true; - } - else if ( Q_stricmp( key, "time" ) == 0 ) { - time = atoi( token ); - return true; - } - Com_UngetToken(); - return false; -} - - - -void idFixedPosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "pos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, pos ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idInterpolatedPosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "startPos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, startPos ); - } - else if ( Q_stricmp( key.c_str(), "endPos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, endPos ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - -void idSplinePosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "target" ) == 0 ) { - target.parse( text ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - - -void idCameraFOV::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tfov %f\n", fov ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tstartFOV %f\n", startFOV ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tendFOV %f\n", endFOV ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\ttime %i\n", time ); - FS_Write( s.c_str(), s.length(), file ); - - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -void idCameraPosition::write( fileHandle_t file, const char *p ) { - - idStr s = va( "\t\ttime %i\n", time ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\ttype %i\n", static_cast( type ) ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tname %s\n", name.c_str() ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tbaseVelocity %f\n", baseVelocity ); - FS_Write( s.c_str(), s.length(), file ); - - for ( int i = 0; i < velocities.Num(); i++ ) { - s = va( "\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed ); - FS_Write( s.c_str(), s.length(), file ); - } - -} - -void idFixedPosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - s = va( "\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idInterpolatedPosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - s = va( "\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idSplinePosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - target.write( file, "target" ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idCameraDef::addTarget( const char *name, idCameraPosition::positionType type ) { - idCameraPosition *pos = newFromType( type ); - if ( pos ) { - pos->setName( name ); - targetPositions.Append( pos ); - activeTarget = numTargets() - 1; - if ( activeTarget == 0 ) { - // first one - addEvent( idCameraEvent::EVENT_TARGET, name, 0 ); - } - } -} - -const idVec3 *idSplinePosition::getPosition( long t ) { - static idVec3 interpolatedPos; - - float velocity = getVelocity( t ); - float timePassed = t - lastTime; - lastTime = t; - - // convert to seconds - timePassed /= 1000; - - float distToTravel = timePassed * velocity; - - distSoFar += distToTravel; - double tempDistance = target.totalDistance(); - - double percent = (double)( distSoFar ) / tempDistance; - - double targetDistance = percent * tempDistance; - tempDistance = 0; - - double lastDistance1,lastDistance2; - lastDistance1 = lastDistance2 = 0; - idVec3 temp; - int count = target.numSegments(); - int i; - for ( i = 1; i < count; i++ ) { - temp = *target.getSegmentPoint( i - 1 ); - temp -= *target.getSegmentPoint( i ); - tempDistance += temp.Length(); - if ( i & 1 ) { - lastDistance1 = tempDistance; - } - else { - lastDistance2 = tempDistance; - } - if ( tempDistance >= targetDistance ) { - break; - } - } - - if ( i >= count - 1 ) { - interpolatedPos = *target.getSegmentPoint( i - 1 ); - } - else { -#if 0 - double timeHi = target.getSegmentTime( i + 1 ); - double timeLo = target.getSegmentTime( i - 1 ); - double percent = ( timeHi - t ) / ( timeHi - timeLo ); - idVec3 v1 = *target.getSegmentPoint( i - 1 ); - idVec3 v2 = *target.getSegmentPoint( i + 1 ); - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; -#else - if ( lastDistance1 > lastDistance2 ) { - double d = lastDistance2; - lastDistance2 = lastDistance1; - lastDistance1 = d; - } - - idVec3 v1 = *target.getSegmentPoint( i - 1 ); - idVec3 v2 = *target.getSegmentPoint( i ); - double percent = ( lastDistance2 - targetDistance ) / ( lastDistance2 - lastDistance1 ); - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; -#endif - } - return &interpolatedPos; - -} diff --git a/libs/splines/splines.h b/libs/splines/splines.h deleted file mode 100644 index 051f76b..0000000 --- a/libs/splines/splines.h +++ /dev/null @@ -1,1140 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __SPLINES_H -#define __SPLINES_H - -#define GTKRADIANT - -#ifdef GTKRADIANT -#include "igl.h" -#endif - -#include "util_list.h" -#include "util_str.h" -#include "math_vector.h" - -typedef int fileHandle_t; - -extern void glBox( idVec3 &color, idVec3 &point, float size ); -extern void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label ); - -static idVec4 blue( 0, 0, 1, 1 ); -static idVec4 red( 1, 0, 0, 1 ); - -class idPointListInterface { -public: -idPointListInterface() { - selectedPoints.Clear(); -}; -virtual ~idPointListInterface() { -}; - -virtual int numPoints() { - return 0; -} - -virtual void addPoint( const float x, const float y, const float z ) { -} -virtual void addPoint( const idVec3 &v ) { -} -virtual void removePoint( int index ) { -} -virtual idVec3 *getPoint( int index ) { - return NULL; -} - -int selectPointByRay( float ox, float oy, float oz, float dx, float dy, float dz, bool single ) { - idVec3 origin( ox, oy, oz ); - idVec3 dir( dx, dy, dz ); - return selectPointByRay( origin, dir, single ); -} - -int selectPointByRay( const idVec3 origin, const idVec3 direction, bool single ) { - int i, besti, count; - float d, bestd; - idVec3 temp, temp2; - - // find the point closest to the ray - besti = -1; - bestd = 8; - count = numPoints(); - - for ( i = 0; i < count; i++ ) { - temp = *getPoint( i ); - temp2 = temp; - temp -= origin; - d = DotProduct( temp, direction ); - __VectorMA( origin, d, direction, temp ); - temp2 -= temp; - d = temp2.Length(); - if ( d <= bestd ) { - bestd = d; - besti = i; - } - } - - if ( besti >= 0 ) { - selectPoint( besti, single ); - } - - return besti; -} - -int isPointSelected( int index ) { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - if ( selectedPoints[i] == index ) { - return i; - } - } - return -1; -} - -int selectPoint( int index, bool single ) { - if ( index >= 0 && index < numPoints() ) { - if ( single ) { - deselectAll(); - } - else { - if ( isPointSelected( index ) >= 0 ) { - selectedPoints.Remove( index ); - } - } - return selectedPoints.Append( index ); - } - return -1; -} - -void selectAll() { - selectedPoints.Clear(); - for ( int i = 0; i < numPoints(); i++ ) { - selectedPoints.Append( i ); - } -} - -void deselectAll() { - selectedPoints.Clear(); -} - -int numSelectedPoints(); - -idVec3 *getSelectedPoint( int index ) { - assert( index >= 0 && index < numSelectedPoints() ); - return getPoint( selectedPoints[index] ); -} - -virtual void updateSelection( float x, float y, float z ) { - idVec3 move( x, y, z ); - updateSelection( move ); -} - -virtual void updateSelection( const idVec3 &move ) { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - *getPoint( selectedPoints[i] ) += move; - } -} - -void drawSelection() { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - glBox( red, *getPoint( selectedPoints[i] ), 4 ); - } -} - -protected: -idList selectedPoints; - -}; - - -class idSplineList { - -public: - -idSplineList() { - clear(); -} - -idSplineList( const char *p ) { - clear(); - name = p; -}; - -~idSplineList() { - clear(); -}; - -void clearControl() { - for ( int i = 0; i < controlPoints.Num(); i++ ) { - delete controlPoints[i]; - } - controlPoints.Clear(); -} - -void clearSpline() { - for ( int i = 0; i < splinePoints.Num(); i++ ) { - delete splinePoints[i]; - } - splinePoints.Clear(); -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -void clear() { - clearControl(); - clearSpline(); - splineTime.Clear(); - selected = NULL; - dirty = true; - activeSegment = 0; - granularity = 0.025f; - pathColor.set( 1.0f, 0.5f, 0.0f ); - controlColor.set( 0.7f, 0.0f, 1.0f ); - segmentColor.set( 0.0f, 0.0f, 1.0f ); - activeColor.set( 1.0f, 0.0f, 0.0f ); -} - -void initPosition( long startTime, long totalTime ); -const idVec3 *getPosition( long time ); - - -void draw( bool editMode ); -void addToRenderer(); - -void setSelectedPoint( idVec3 *p ); -idVec3 *getSelectedPoint() { - return selected; -} - -void addPoint( const idVec3 &v ) { - controlPoints.Append( new idVec3( v ) ); - dirty = true; -} - -void addPoint( float x, float y, float z ) { - controlPoints.Append( new idVec3( x, y, z ) ); - dirty = true; -} - -void updateSelection( const idVec3 &move ); - -void startEdit() { - editMode = true; -} - -void stopEdit() { - editMode = false; -} - -void buildSpline(); - -void setGranularity( float f ) { - granularity = f; -} - -float getGranularity() { - return granularity; -} - -int numPoints() { - return controlPoints.Num(); -} - -idVec3 *getPoint( int index ) { - assert( index >= 0 && index < controlPoints.Num() ); - return controlPoints[index]; -} - -idVec3 *getSegmentPoint( int index ) { - assert( index >= 0 && index < splinePoints.Num() ); - return splinePoints[index]; -} - - -void setSegmentTime( int index, int time ) { - assert( index >= 0 && index < splinePoints.Num() ); - splineTime[index] = time; -} - -int getSegmentTime( int index ) { - assert( index >= 0 && index < splinePoints.Num() ); - return (int)splineTime[index]; -} -void addSegmentTime( int index, int time ) { - assert( index >= 0 && index < splinePoints.Num() ); - splineTime[index] += time; -} - -float totalDistance(); - -static idVec3 zero; - -int getActiveSegment() { - return activeSegment; -} - -void setActiveSegment( int i ) { - //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num())); - activeSegment = i; -} - -int numSegments() { - return splinePoints.Num(); -} - -void setColors( idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active ) { - pathColor = path; - segmentColor = segment; - controlColor = control; - activeColor = active; -} - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -bool validTime() { - if ( dirty ) { - buildSpline(); - } - // gcc doesn't allow static casting away from bools - // why? I've no idea... - return (bool)( splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num() ); -} - -void setTime( long t ) { - time = t; -} - -void setBaseTime( long t ) { - baseTime = t; -} - -protected: -idStr name; -float calcSpline( int step, float tension ); -idList controlPoints; -idList splinePoints; -idList splineTime; -idVec3 *selected; -idVec3 pathColor, segmentColor, controlColor, activeColor; -float granularity; -bool editMode; -bool dirty; -int activeSegment; -long baseTime; -long time; -friend class idCamera; -}; - -// time in milliseconds -// velocity where 1.0 equal rough walking speed -struct idVelocity { - idVelocity( long start, long duration, float s ) { - startTime = start; - time = duration; - speed = s; - } - long startTime; - long time; - float speed; -}; - -// can either be a look at or origin position for a camera -// -class idCameraPosition : public idPointListInterface { -public: - -virtual void clearVelocities() { - for ( int i = 0; i < velocities.Num(); i++ ) { - delete velocities[i]; - velocities[i] = NULL; - } - velocities.Clear(); -} - -virtual void clear() { - editMode = false; - clearVelocities(); -} - -idCameraPosition( const char *p ) { - name = p; -} - -idCameraPosition() { - time = 0; - name = "position"; -} - -idCameraPosition( long t ) { - time = t; -} - -virtual ~idCameraPosition() { - clear(); -} - - -// this can be done with RTTI syntax but i like the derived classes setting a type -// makes serialization a bit easier to see -// -enum positionType { - FIXED = 0x00, - INTERPOLATED, - SPLINE, - POSITION_COUNT -}; - - -virtual void start( long t ) { - startTime = t; -} - -long getTime() { - return time; -} - -virtual void setTime( long t ) { - time = t; -} - -float getBaseVelocity() { - return baseVelocity; -} - -float getVelocity( long t ) { - long check = t - startTime; - for ( int i = 0; i < velocities.Num(); i++ ) { - if ( check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time ) { - return velocities[i]->speed; - } - } - return baseVelocity; -} - -void addVelocity( long start, long duration, float speed ) { - velocities.Append( new idVelocity( start, duration, speed ) ); -} - -virtual const idVec3 *getPosition( long t ) { - assert( true ); - return NULL; -} - -virtual void draw( bool editMode ) { -}; - -virtual void parse( const char *( *text ) ) { -}; -virtual void write( fileHandle_t file, const char *name ); -virtual bool parseToken( const char *key, const char *( *text ) ); - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -virtual void startEdit() { - editMode = true; -} - -virtual void stopEdit() { - editMode = false; -} - -virtual void draw() { -}; - -const char *typeStr() { - return positionStr[static_cast( type )]; -} - -void calcVelocity( float distance ) { - float secs = (float)time / 1000; - baseVelocity = distance / secs; -} - -protected: -static const char* positionStr[POSITION_COUNT]; -long startTime; -long time; -idCameraPosition::positionType type; -idStr name; -bool editMode; -idList velocities; -float baseVelocity; -}; - -class idFixedPosition : public idCameraPosition { -public: - -void init() { - pos.Zero(); - type = idCameraPosition::FIXED; -} - -idFixedPosition() : idCameraPosition() { - init(); -} - -idFixedPosition( idVec3 p ) : idCameraPosition() { - init(); - pos = p; -} - -virtual void addPoint( const idVec3 &v ) { - pos = v; -} - -virtual void addPoint( const float x, const float y, const float z ) { - pos.set( x, y, z ); -} - - -~idFixedPosition() { -} - -virtual const idVec3 *getPosition( long t ) { - return &pos; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return 1; -} - -virtual idVec3 *getPoint( int index ) { - if ( index != 0 ) { - assert( true ); - } - ; - return &pos; -} - -virtual void draw( bool editMode ) { - glLabeledPoint( blue, pos, ( editMode ) ? 5 : 3, "Fixed point" ); -} - -protected: -idVec3 pos; -}; - -class idInterpolatedPosition : public idCameraPosition { -public: - -void init() { - type = idCameraPosition::INTERPOLATED; - first = true; - startPos.Zero(); - endPos.Zero(); -} - -idInterpolatedPosition() : idCameraPosition() { - init(); -} - -idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition( time ) { - init(); - startPos = start; - endPos = end; -} - -~idInterpolatedPosition() { -} - -virtual const idVec3 *getPosition( long t ); - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return 2; -} - -virtual idVec3 *getPoint( int index ) { - assert( index >= 0 && index < 2 ); - if ( index == 0 ) { - return &startPos; - } - return &endPos; -} - -virtual void addPoint( const float x, const float y, const float z ) { - if ( first ) { - startPos.set( x, y, z ); - first = false; - } - else { - endPos.set( x, y, z ); - first = true; - } -} - -virtual void addPoint( const idVec3 &v ) { - if ( first ) { - startPos = v; - first = false; - } - else { - endPos = v; - first = true; - } -} - -virtual void draw( bool editMode ) { - glLabeledPoint( blue, startPos, ( editMode ) ? 5 : 3, "Start interpolated" ); - glLabeledPoint( blue, endPos, ( editMode ) ? 5 : 3, "End interpolated" ); - glBegin( GL_LINES ); - glVertex3fv( startPos ); - glVertex3fv( endPos ); - glEnd(); -} - -virtual void start( long t ) { - idCameraPosition::start( t ); - lastTime = startTime; - distSoFar = 0.0; - idVec3 temp = startPos; - temp -= endPos; - calcVelocity( temp.Length() ); -} - -protected: -bool first; -idVec3 startPos; -idVec3 endPos; -long lastTime; -float distSoFar; -}; - -class idSplinePosition : public idCameraPosition { -public: - -void init() { - type = idCameraPosition::SPLINE; -} - -idSplinePosition() : idCameraPosition() { - init(); -} - -idSplinePosition( long time ) : idCameraPosition( time ) { - init(); -} - -~idSplinePosition() { -} - -virtual void start( long t ) { - idCameraPosition::start( t ); - target.initPosition( t, time ); - lastTime = startTime; - distSoFar = 0.0; - calcVelocity( target.totalDistance() ); -} - -//virtual const idVec3 *getPosition(long t) { -// return target.getPosition(t); -//} -virtual const idVec3 *getPosition( long t ); - - -//virtual const idVec3 *getPosition(long t) const { - -void addControlPoint( idVec3 &v ) { - target.addPoint( v ); -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return target.numPoints(); -} - -virtual idVec3 *getPoint( int index ) { - return target.getPoint( index ); -} - -virtual void addPoint( const idVec3 &v ) { - target.addPoint( v ); -} - -virtual void addPoint( const float x, const float y, const float z ) { - target.addPoint( x, y, z ); -} - -virtual void draw( bool editMode ) { - target.draw( editMode ); -} - -virtual void updateSelection( const idVec3 &move ) { - idCameraPosition::updateSelection( move ); - target.buildSpline(); -} - -protected: -idSplineList target; -long lastTime; -float distSoFar; -}; - -class idCameraFOV { -public: - -idCameraFOV() { - time = 0; - length = 0; - fov = 90; -} - -idCameraFOV( int v ) { - time = 0; - length = 0; - fov = v; -} - -idCameraFOV( int s, int e, long t ) { - startFOV = s; - endFOV = e; - length = t; -} - - -~idCameraFOV(){ -} - -void setFOV( float f ) { - fov = f; -} - -float getFOV( long t ) { - if ( length ) { - float percent = ( t - startTime ) / length; - if ( percent < 0.0 ) { - percent = 0.0; - } - else if ( percent > 1.0 ) { - percent = 1.0; - } - float temp = endFOV - startFOV; - temp *= percent; - fov = startFOV + temp; - - if ( percent == 1.0 ) { - length = 0.0; - } - } - return fov; -} - -void start( long t ) { - startTime = t; -} - -void reset( float startfov, float endfov, int start, float len ) { - startFOV = startfov; - endFOV = endfov; - startTime = start; - length = len * 1000; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -protected: -float fov; -float startFOV; -float endFOV; -int startTime; -int time; -float length; -}; - - - - -class idCameraEvent { -public: // parameters -enum eventType { - EVENT_NA = 0x00, - EVENT_WAIT, // - EVENT_TARGETWAIT, // - EVENT_SPEED, // - EVENT_TARGET, // char(name) - EVENT_SNAPTARGET, // - EVENT_FOV, // int(time), int(targetfov) - EVENT_CMD, // - EVENT_TRIGGER, // - EVENT_STOP, // - EVENT_CAMERA, // - EVENT_FADEOUT, // int(time) - EVENT_FADEIN, // int(time) - EVENT_FEATHER, // - EVENT_COUNT -}; - -static const char* eventStr[EVENT_COUNT]; - -idCameraEvent() { - paramStr = ""; - type = EVENT_NA; - time = 0; -} - -idCameraEvent( eventType t, const char *param, long n ) { - type = t; - paramStr = param; - time = n; -} - -~idCameraEvent() { -}; - -eventType getType() { - return type; -} - -const char *typeStr() { - return eventStr[static_cast( type )]; -} - -const char *getParam() { - return paramStr.c_str(); -} - -long getTime() { - return time; -} - -void setTime( long n ) { - time = n; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -void setTriggered( bool b ) { - triggered = b; -} - -bool getTriggered() { - return triggered; -} - -protected: -eventType type; -idStr paramStr; -long time; -bool triggered; - -}; - -class idCameraDef { -public: - -void clear() { - currentCameraPosition = 0; - cameraRunning = false; - lastDirection.Zero(); - baseTime = 30; - activeTarget = 0; - name = "camera01"; - fov.setFOV( 90 ); - int i; - for ( i = 0; i < targetPositions.Num(); i++ ) { - delete targetPositions[i]; - } - for ( i = 0; i < events.Num(); i++ ) { - delete events[i]; - } - delete cameraPosition; - cameraPosition = NULL; - events.Clear(); - targetPositions.Clear(); -} - -idCameraPosition *startNewCamera( idCameraPosition::positionType type ) { - clear(); - if ( type == idCameraPosition::SPLINE ) { - cameraPosition = new idSplinePosition(); - } - else if ( type == idCameraPosition::INTERPOLATED ) { - cameraPosition = new idInterpolatedPosition(); - } - else { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; -} - -idCameraDef() { - cameraPosition = NULL; - clear(); -} - -~idCameraDef() { - clear(); -} - -void addEvent( idCameraEvent::eventType t, const char *param, long time ); - -void addEvent( idCameraEvent *event ); - -void removeEvent( int index ); - -static int sortEvents( const void *p1, const void *p2 ); - -int numEvents() { - return events.Num(); -} - -idCameraEvent *getEvent( int index ) { - assert( index >= 0 && index < events.Num() ); - return events[index]; -} - -void parse( const char *( *text ) ); -bool load( const char *filename ); -void save( const char *filename ); - -void buildCamera(); - -//idSplineList *getcameraPosition() { -// return &cameraPosition; -//} - -static idCameraPosition *newFromType( idCameraPosition::positionType t ) { - switch ( t ) { - case idCameraPosition::FIXED: return new idFixedPosition(); - case idCameraPosition::INTERPOLATED: return new idInterpolatedPosition(); - case idCameraPosition::SPLINE: return new idSplinePosition(); - default: - break; - }; - return NULL; -} - -void addTarget( const char *name, idCameraPosition::positionType type ); - -idCameraPosition *getActiveTarget() { - if ( targetPositions.Num() == 0 ) { - addTarget( NULL, idCameraPosition::FIXED ); - } - return targetPositions[activeTarget]; -} - -idCameraPosition *getActiveTarget( int index ) { - if ( targetPositions.Num() == 0 ) { - addTarget( NULL, idCameraPosition::FIXED ); - return targetPositions[0]; - } - return targetPositions[index]; -} - -int numTargets() { - return targetPositions.Num(); -} - - -void setActiveTargetByName( const char *name ) { - for ( int i = 0; i < targetPositions.Num(); i++ ) { - if ( Q_stricmp( name, targetPositions[i]->getName() ) == 0 ) { - setActiveTarget( i ); - return; - } - } -} - -void setActiveTarget( int index ) { - assert( index >= 0 && index < targetPositions.Num() ); - activeTarget = index; -} - -void setRunning( bool b ) { - cameraRunning = b; -} - -void setBaseTime( float f ) { - baseTime = f; -} - -float getBaseTime() { - return baseTime; -} - -float getTotalTime() { - return totalTime; -} - -void startCamera( long t ); -void stopCamera() { - cameraRunning = true; -} -void getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fv ); - -bool getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv ); -bool getCameraInfo( long time, float *origin, float *direction, float *fv ) { - idVec3 org, dir; - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - dir[0] = direction[0]; - dir[1] = direction[1]; - dir[2] = direction[2]; - bool b = getCameraInfo( time, org, dir, fv ); - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - direction[0] = dir[0]; - direction[1] = dir[1]; - direction[2] = dir[2]; - return b; -} - -void draw( bool editMode ) { - // gcc doesn't allow casting away from bools - // why? I've no idea... - if ( cameraPosition ) { - cameraPosition->draw( (bool)( ( editMode || cameraRunning ) && cameraEdit ) ); - int count = targetPositions.Num(); - for ( int i = 0; i < count; i++ ) { - targetPositions[i]->draw( (bool)( ( editMode || cameraRunning ) && i == activeTarget && !cameraEdit ) ); - } - } -} - -/* - int numSegments() { - if (cameraEdit) { - return cameraPosition.numSegments(); - } - return getTargetSpline()->numSegments(); - } - - int getActiveSegment() { - if (cameraEdit) { - return cameraPosition.getActiveSegment(); - } - return getTargetSpline()->getActiveSegment(); - } - - void setActiveSegment(int i) { - if (cameraEdit) { - cameraPosition.setActiveSegment(i); - } else { - getTargetSpline()->setActiveSegment(i); - } - } - */ -int numPoints() { - if ( cameraEdit ) { - return cameraPosition->numPoints(); - } - return getActiveTarget()->numPoints(); -} - -const idVec3 *getPoint( int index ) { - if ( cameraEdit ) { - return cameraPosition->getPoint( index ); - } - return getActiveTarget()->getPoint( index ); -} - -void stopEdit() { - editMode = false; - if ( cameraEdit ) { - cameraPosition->stopEdit(); - } - else { - getActiveTarget()->stopEdit(); - } -} - -void startEdit( bool camera ) { - cameraEdit = camera; - if ( camera ) { - cameraPosition->startEdit(); - for ( int i = 0; i < targetPositions.Num(); i++ ) { - targetPositions[i]->stopEdit(); - } - } - else { - getActiveTarget()->startEdit(); - cameraPosition->stopEdit(); - } - editMode = true; -} - -bool waitEvent( int index ); - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -idCameraPosition *getPositionObj() { - if ( cameraPosition == NULL ) { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; -} - -protected: -idStr name; -int currentCameraPosition; -idVec3 lastDirection; -bool cameraRunning; -idCameraPosition *cameraPosition; -idList targetPositions; -idList events; -idCameraFOV fov; -int activeTarget; -float totalTime; -float baseTime; -long startTime; - -bool cameraEdit; -bool editMode; -}; - -extern bool g_splineMode; - -extern idCameraDef *g_splineList; - - -#endif diff --git a/libs/splines/util_list.h b/libs/splines/util_list.h deleted file mode 100644 index dfa92fb..0000000 --- a/libs/splines/util_list.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __UTIL_LIST_H__ -#define __UTIL_LIST_H__ - -#include -#include - -template< class type > -class idList { -private: -int m_num; -int m_size; -int m_granularity; -type *m_list; - -public: -idList( int granularity = 16 ); -~idList(); -void Clear( void ); -int Num( void ); -void SetNum( int num ); -void SetGranularity( int granularity ); -void Condense( void ); -int Size( void ); -void Resize( int size ); -type operator[]( int index ) const; -type &operator[]( int index ); -int Append( type const & obj ); -int AddUnique( type const & obj ); -type *Find( type const & obj, int *index = NULL ); -bool RemoveIndex( int index ); -bool Remove( type const & obj ); -typedef int cmp_t ( const void *, const void * ); -void Sort( cmp_t *compare ); -}; - -/* - ================ - idList::idList( int ) - ================ - */ -template< class type > -inline idList::idList( int granularity ) { - assert( granularity > 0 ); - - m_list = NULL; - m_granularity = granularity; - Clear(); -} - -/* - ================ - idList::~idList - ================ - */ -template< class type > -inline idList::~idList() { - Clear(); -} - -/* - ================ - idList::Clear - ================ - */ -template< class type > -inline void idList::Clear( void ) { - if ( m_list ) { - delete[] m_list; - } - - m_list = NULL; - m_num = 0; - m_size = 0; -} - -/* - ================ - idList::Num - ================ - */ -template< class type > -inline int idList::Num( void ) { - return m_num; -} - -/* - ================ - idList::SetNum - ================ - */ -template< class type > -inline void idList::SetNum( int num ) { - assert( num >= 0 ); - if ( num > m_size ) { - // resize it up to the closest level of granularity - Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity ); - } - m_num = num; -} - -/* - ================ - idList::SetGranularity - ================ - */ -template< class type > -inline void idList::SetGranularity( int granularity ) { - int newsize; - - assert( granularity > 0 ); - m_granularity = granularity; - - if ( m_list ) { - // resize it to the closest level of granularity - newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity; - if ( newsize != m_size ) { - Resize( newsize ); - } - } -} - -/* - ================ - idList::Condense - - Resizes the array to exactly the number of elements it contains - ================ - */ -template< class type > -inline void idList::Condense( void ) { - if ( m_list ) { - if ( m_num ) { - Resize( m_num ); - } - else { - Clear(); - } - } -} - -/* - ================ - idList::Size - ================ - */ -template< class type > -inline int idList::Size( void ) { - return m_size; -} - -/* - ================ - idList::Resize - ================ - */ -template< class type > -inline void idList::Resize( int size ) { - type *temp; - int i; - - assert( size > 0 ); - - if ( size <= 0 ) { - Clear(); - return; - } - - temp = m_list; - m_size = size; - if ( m_size < m_num ) { - m_num = m_size; - } - - m_list = new type[ m_size ]; - for ( i = 0; i < m_num; i++ ) { - m_list[ i ] = temp[ i ]; - } - - if ( temp ) { - delete[] temp; - } -} - -/* - ================ - idList::operator[] const - ================ - */ -template< class type > -inline type idList::operator[]( int index ) const { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* - ================ - idList::operator[] - ================ - */ -template< class type > -inline type &idList::operator[]( int index ) { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* - ================ - idList::Append - ================ - */ -template< class type > -inline int idList::Append( type const & obj ) { - if ( !m_list ) { - Resize( m_granularity ); - } - - if ( m_num == m_size ) { - Resize( m_size + m_granularity ); - } - - m_list[ m_num ] = obj; - m_num++; - - return m_num - 1; -} - -/* - ================ - idList::AddUnique - ================ - */ -template< class type > -inline int idList::AddUnique( type const & obj ) { - int index; - - if ( !Find( obj, &index ) ) { - index = Append( obj ); - } - - return index; -} - -/* - ================ - idList::Find - ================ - */ -template< class type > -inline type *idList::Find( type const & obj, int *index ) { - int i; - - for ( i = 0; i < m_num; i++ ) { - if ( m_list[ i ] == obj ) { - if ( index ) { - *index = i; - } - return &m_list[ i ]; - } - } - - return NULL; -} - -/* - ================ - idList::RemoveIndex - ================ - */ -template< class type > -inline bool idList::RemoveIndex( int index ) { - int i; - - if ( !m_list || !m_num ) { - return false; - } - - assert( index >= 0 ); - assert( index < m_num ); - - if ( ( index < 0 ) || ( index >= m_num ) ) { - return false; - } - - m_num--; - for ( i = index; i < m_num; i++ ) { - m_list[ i ] = m_list[ i + 1 ]; - } - - return true; -} - -/* - ================ - idList::Remove - ================ - */ -template< class type > -inline bool idList::Remove( type const & obj ) { - int index; - - if ( Find( obj, &index ) ) { - return RemoveIndex( index ); - } - - return false; -} - -/* - ================ - idList::Sort - ================ - */ -template< class type > -inline void idList::Sort( cmp_t *compare ) { - if ( !m_list ) { - return; - } - - qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare ); -} - -#endif /* !__UTIL_LIST_H__ */ diff --git a/libs/splines/util_str.cpp b/libs/splines/util_str.cpp deleted file mode 100644 index c64ca73..0000000 --- a/libs/splines/util_str.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//need to rewrite this - -#include "util_str.h" -#include -#include -#include -#include - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -static const int STR_ALLOC_GRAN = 20; - -// screwy but intentional -#ifdef __APPLE_BUG__ -char *idStr::__tolower -#else -char *idStr::tolower -#endif -( - char *s1 -){ - char *s; - - s = s1; - while ( *s ) - { - *s = ::tolower( *s ); - s++; - } - - return s1; -} - -// screwy but intentional -#ifdef __APPLE_BUG__ -char *idStr::__toupper -#else -char *idStr::toupper -#endif -( - char *s1 -){ - char *s; - - s = s1; - while ( *s ) - { - *s = ::toupper( *s ); - s++; - } - - return s1; -} - -int idStr::icmpn -( - const char *s1, - const char *s2, - int n -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - // idStrings are equal until end point - return 0; - } - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::icmp -( - const char *s1, - const char *s2 -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::cmpn -( - const char *s1, - const char *s2, - int n -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - // strings are equal until end point - return 0; - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::cmp -( - const char *s1, - const char *s2 -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -/* - ============ - IsNumeric - - Checks a string to see if it contains only numerical values. - ============ - */ -bool idStr::isNumeric -( - const char *str -){ - int len; - int i; - bool dot; - - if ( *str == '-' ) { - str++; - } - - dot = false; - len = strlen( str ); - for ( i = 0; i < len; i++ ) - { - if ( !isdigit( str[ i ] ) ) { - if ( ( str[ i ] == '.' ) && !dot ) { - dot = true; - continue; - } - return false; - } - } - - return true; -} - -idStr operator+ -( - const idStr& a, - const float b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%f", b ); - result.append( text ); - - return result; -} - -idStr operator+ -( - const idStr& a, - const int b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%d", b ); - result.append( text ); - - return result; -} - -idStr operator+ -( - const idStr& a, - const unsigned b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%u", b ); - result.append( text ); - - return result; -} - -idStr& idStr::operator+= -( - const float a -){ - char text[ 20 ]; - - sprintf( text, "%f", a ); - append( text ); - - return *this; -} - -idStr& idStr::operator+= -( - const int a -){ - char text[ 20 ]; - - sprintf( text, "%d", a ); - append( text ); - - return *this; -} - -idStr& idStr::operator+= -( - const unsigned a -){ - char text[ 20 ]; - - sprintf( text, "%u", a ); - append( text ); - - return *this; -} - -void idStr::CapLength -( - int newlen -){ - assert( m_data ); - - if ( length() <= newlen ) { - return; - } - - EnsureDataWritable(); - - m_data->data[newlen] = 0; - m_data->len = newlen; -} - -void idStr::EnsureDataWritable -( - void -){ - assert( m_data ); - strdata *olddata; - int len; - - if ( !m_data->refcount ) { - return; - } - - olddata = m_data; - len = length(); - - m_data = new strdata; - - EnsureAlloced( len + 1, false ); - strncpy( m_data->data, olddata->data, len + 1 ); - m_data->len = len; - - olddata->DelRef(); -} - -void idStr::EnsureAlloced( int amount, bool keepold ) { - - if ( !m_data ) { - m_data = new strdata(); - } - - // Now, let's make sure it's writable - EnsureDataWritable(); - - char *newbuffer; - bool wasalloced = ( m_data->alloced != 0 ); - - if ( amount < m_data->alloced ) { - return; - } - - assert( amount ); - if ( amount == 1 ) { - m_data->alloced = 1; - } - else { - int newsize, mod; - mod = amount % STR_ALLOC_GRAN; - if ( !mod ) { - newsize = amount; - } - else { - newsize = amount + STR_ALLOC_GRAN - mod; - } - m_data->alloced = newsize; - } - - newbuffer = new char[m_data->alloced]; - if ( wasalloced && keepold ) { - strcpy( newbuffer, m_data->data ); - } - - if ( m_data->data ) { - delete [] m_data->data; - } - m_data->data = newbuffer; -} - -void idStr::BackSlashesToSlashes -( - void -){ - int i; - - EnsureDataWritable(); - - for ( i = 0; i < m_data->len; i++ ) - { - if ( m_data->data[i] == '\\' ) { - m_data->data[i] = '/'; - } - } -} - -void idStr::snprintf -( - char *dst, - int size, - const char *fmt, - ... -){ - char buffer[0x10000]; - int len; - va_list argptr; - - va_start( argptr,fmt ); - len = vsprintf( buffer,fmt,argptr ); - va_end( argptr ); - - assert( len < size ); - - strncpy( dst, buffer, size - 1 ); -} - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4189) // local variable is initialized but not referenced -#endif - -/* - ================= - TestStringClass - - This is a fairly rigorous test of the idStr class's functionality. - Because of the fairly global and subtle ramifications of a bug occuring - in this class, it should be run after any changes to the class. - Add more tests as functionality is changed. Tests should include - any possible bounds violation and NULL data tests. - ================= - */ -void TestStringClass -( - void -){ - char ch; // ch == ? - (void) ch; - idStr *t; // t == ? - idStr a; // a.len == 0, a.data == "\0" - idStr b; // b.len == 0, b.data == "\0" - idStr c( "test" ); // c.len == 4, c.data == "test\0" - idStr d( c ); // d.len == 4, d.data == "test\0" - idStr e( static_cast( NULL ) ); - // e.len == 0, e.data == "\0" ASSERT! - int i; // i == ? - (void) i; - - i = a.length(); // i == 0 - i = c.length(); // i == 4 - - t = new idStr(); // t->len == 0, t->data == "\0" - delete t; // t == ? - - b = "test"; // b.len == 4, b.data == "test\0" - t = new idStr( "test" ); // t->len == 4, t->data == "test\0" - delete t; // t == ? - - a = c; // a.len == 4, a.data == "test\0" -// a = ""; - a = NULL; // a.len == 0, a.data == "\0" ASSERT! - a = c + d; // a.len == 8, a.data == "testtest\0" - a = c + "wow"; // a.len == 7, a.data == "testwow\0" - a = c + static_cast( NULL ); - // a.len == 4, a.data == "test\0" ASSERT! - a = "this" + d; // a.len == 8, a.data == "thistest\0" - a = static_cast( NULL ) + d; - // a.len == 4, a.data == "test\0" ASSERT! - a += c; // a.len == 8, a.data == "testtest\0" - a += "wow"; // a.len == 11, a.data == "testtestwow\0" - a += static_cast( NULL ); - // a.len == 11, a.data == "testtestwow\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - ch = a[ 0 ]; // ch == 't' - ch = a[ -1 ]; // ch == 0 ASSERT! - ch = a[ 1000 ]; // ch == 0 ASSERT! - ch = a[ 0 ]; // ch == 't' - ch = a[ 1 ]; // ch == 'e' - ch = a[ 2 ]; // ch == 's' - ch = a[ 3 ]; // ch == 't' - ch = a[ 4 ]; // ch == '\0' ASSERT! - ch = a[ 5 ]; // ch == '\0' ASSERT! - - a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0" - a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT! - a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0" - a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0" - a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0" - a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0" - a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - b = "no"; // b.len == 2, b.data == "no\0" - - i = ( a == b ); // i == 0 - i = ( a == c ); // i == 1 - - i = ( a == "blow" ); // i == 0 - i = ( a == "test" ); // i == 1 - i = ( a == NULL ); // i == 0 ASSERT! - - i = ( "test" == b ); // i == 0 - i = ( "test" == a ); // i == 1 - i = ( NULL == a ); // i == 0 ASSERT! - - i = ( a != b ); // i == 1 - i = ( a != c ); // i == 0 - - i = ( a != "blow" ); // i == 1 - i = ( a != "test" ); // i == 0 - i = ( a != NULL ); // i == 1 ASSERT! - - i = ( "test" != b ); // i == 1 - i = ( "test" != a ); // i == 0 - i = ( NULL != a ); // i == 1 ASSERT! - - a = "test"; // a.data == "test" - b = a; // b.data == "test" - - a = "not"; // a.data == "not", b.data == "test" - - a = b; // a.data == b.data == "test" - - a += b; // a.data == "testtest", b.data = "test" - - a = b; - - a[1] = '1'; // a.data = "t1st", b.data = "test" -} - -#if GDEF_COMPILER_MSVC -#pragma warning(default : 4189) // local variable is initialized but not referenced -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#endif diff --git a/libs/splines/util_str.h b/libs/splines/util_str.h deleted file mode 100644 index b7cb976..0000000 --- a/libs/splines/util_str.h +++ /dev/null @@ -1,724 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//need to rewrite this - -#ifndef __UTIL_STR_H__ -#define __UTIL_STR_H__ - -#include -#include -#include - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -void TestStringClass(); - -class strdata -{ -public: -strdata () : len( 0 ), refcount( 0 ), data( NULL ), alloced( 0 ) { -} -~strdata (){ - if ( data ) { - delete [] data; - } -} - -void AddRef() { - refcount++; -} -bool DelRef(){ // True if killed - refcount--; - if ( refcount < 0 ) { - delete this; - return true; - } - - return false; -} - -int len; -int refcount; -char *data; -int alloced; -}; - -class idStr { -protected: -strdata *m_data; -void EnsureAlloced( int, bool keepold = true ); -void EnsureDataWritable(); - -public: -~idStr(); -idStr(); -idStr( const char *text ); -idStr( const idStr& string ); -idStr( const idStr string, int start, int end ); -idStr( const char ch ); -idStr( const int num ); -idStr( const float num ); -idStr( const unsigned num ); -int length( void ) const; -int allocated( void ) const; -const char * c_str( void ) const; - -void append( const char *text ); -void append( const idStr& text ); -char operator[]( int index ) const; -char& operator[]( int index ); - -void operator=( const idStr& text ); -void operator=( const char *text ); - -friend idStr operator+( const idStr& a, const idStr& b ); -friend idStr operator+( const idStr& a, const char *b ); -friend idStr operator+( const char *a, const idStr& b ); - -friend idStr operator+( const idStr& a, const float b ); -friend idStr operator+( const idStr& a, const int b ); -friend idStr operator+( const idStr& a, const unsigned b ); -friend idStr operator+( const idStr& a, const bool b ); -friend idStr operator+( const idStr& a, const char b ); - -idStr& operator+=( const idStr& a ); -idStr& operator+=( const char *a ); -idStr& operator+=( const float a ); -idStr& operator+=( const char a ); -idStr& operator+=( const int a ); -idStr& operator+=( const unsigned a ); -idStr& operator+=( const bool a ); - -friend bool operator==( const idStr& a, const idStr& b ); -friend bool operator==( const idStr& a, const char *b ); -friend bool operator==( const char *a, const idStr& b ); - -friend bool operator!=( const idStr& a, const idStr& b ); -friend bool operator!=( const idStr& a, const char *b ); -friend bool operator!=( const char *a, const idStr& b ); - -operator const char *() const; -operator const char *(); - -int icmpn( const char *text, int n ) const; -int icmpn( const idStr& text, int n ) const; -int icmp( const char *text ) const; -int icmp( const idStr& text ) const; -int cmpn( const char *text, int n ) const; -int cmpn( const idStr& text, int n ) const; -int cmp( const char *text ) const; -int cmp( const idStr& text ) const; - -void tolower( void ); -void toupper( void ); - -static char *tolower( char *s1 ); -static char *toupper( char *s1 ); - -static int icmpn( const char *s1, const char *s2, int n ); -static int icmp( const char *s1, const char *s2 ); -static int cmpn( const char *s1, const char *s2, int n ); -static int cmp( const char *s1, const char *s2 ); - -static void snprintf( char *dst, int size, const char *fmt, ... ); - -static bool isNumeric( const char *str ); -bool isNumeric( void ) const; - -void CapLength( int ); - -void BackSlashesToSlashes(); - -}; - -inline idStr::~idStr(){ - if ( m_data ) { - m_data->DelRef(); - m_data = NULL; - } -} - -inline idStr::idStr() : m_data( NULL ){ - EnsureAlloced( 1 ); - m_data->data[ 0 ] = 0; -} - -inline idStr::idStr -( - const char *text -) : m_data( NULL ){ - int len; - - assert( text ); - - if ( text ) { - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - else - { - EnsureAlloced( 1 ); - m_data->data[ 0 ] = 0; - m_data->len = 0; - } -} - -inline idStr::idStr -( - const idStr& text -) : m_data( NULL ){ - m_data = text.m_data; - m_data->AddRef(); -} - -inline idStr::idStr -( - const idStr text, - int start, - int end -) : m_data( NULL ){ - int i; - int len; - - if ( end > text.length() ) { - end = text.length(); - } - - if ( start > text.length() ) { - start = text.length(); - } - - len = end - start; - if ( len < 0 ) { - len = 0; - } - - EnsureAlloced( len + 1 ); - - for ( i = 0; i < len; i++ ) - { - m_data->data[ i ] = text[ start + i ]; - } - - m_data->data[ len ] = 0; - m_data->len = len; -} - -inline idStr::idStr -( - const char ch -) : m_data( NULL ){ - EnsureAlloced( 2 ); - - m_data->data[ 0 ] = ch; - m_data->data[ 1 ] = 0; - m_data->len = 1; -} - -inline idStr::idStr -( - const float num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%.3f", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr::idStr -( - const int num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%d", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr::idStr -( - const unsigned num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%u", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline int idStr::length( void ) const { - return ( m_data != NULL ) ? m_data->len : 0; -} - -inline int idStr::allocated( void ) const { - return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0; -} - -inline const char *idStr::c_str( void ) const { - assert( m_data ); - - return m_data->data; -} - -inline void idStr::append -( - const char *text -){ - int len; - - assert( text ); - - if ( text ) { - len = length() + strlen( text ); - EnsureAlloced( len + 1 ); - - strcat( m_data->data, text ); - m_data->len = len; - } -} - -inline void idStr::append -( - const idStr& text -){ - int len; - - len = length() + text.length(); - EnsureAlloced( len + 1 ); - - strcat( m_data->data, text.c_str() ); - m_data->len = len; -} - -inline char idStr::operator[]( int index ) const { - assert( m_data ); - - if ( !m_data ) { - return 0; - } - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, give them a null character - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) { - return 0; - } - - return m_data->data[ index ]; -} - -inline char& idStr::operator[] -( - int index -){ - // Used for result for invalid indices - static char dummy = 0; - assert( m_data ); - - // We don't know if they'll write to it or not - // if it's not a const object - EnsureDataWritable(); - - if ( !m_data ) { - return dummy; - } - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, let them change a safe variable - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) { - return dummy; - } - - return m_data->data[ index ]; -} - -inline void idStr::operator= -( - const idStr& text -){ - // adding the reference before deleting our current reference prevents - // us from deleting our string if we are copying from ourself - text.m_data->AddRef(); - m_data->DelRef(); - m_data = text.m_data; -} - -inline void idStr::operator= -( - const char *text -){ - int len; - - assert( text ); - - if ( !text ) { - // safe behaviour if NULL - EnsureAlloced( 1, false ); - m_data->data[0] = 0; - m_data->len = 0; - return; - } - - if ( !m_data ) { - len = strlen( text ); - EnsureAlloced( len + 1, false ); - strcpy( m_data->data, text ); - m_data->len = len; - return; - } - - if ( text == m_data->data ) { - return; // Copying same thing. Punt. - - } - // If we alias and I don't do this, I could corrupt other strings... This - // will get called with EnsureAlloced anyway - EnsureDataWritable(); - - // Now we need to check if we're aliasing.. - if ( text >= m_data->data && text <= m_data->data + m_data->len ) { - // Great, we're aliasing. We're copying from inside ourselves. - // This means that I don't have to ensure that anything is alloced, - // though I'll assert just in case. - int diff = text - m_data->data; - int i; - - assert( strlen( text ) < (unsigned) m_data->len ); - - for ( i = 0; text[i]; i++ ) - { - m_data->data[i] = text[i]; - } - - m_data->data[i] = 0; - - m_data->len -= diff; - - return; - } - - len = strlen( text ); - EnsureAlloced( len + 1, false ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr operator+ -( - const idStr& a, - const idStr& b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const char *b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const char *a, - const idStr& b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const bool b -){ - idStr result( a ); - - result.append( b ? "true" : "false" ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const char b -){ - char text[ 2 ]; - - text[ 0 ] = b; - text[ 1 ] = 0; - - return a + text; -} - -inline idStr& idStr::operator+= -( - const idStr& a -){ - append( a ); - return *this; -} - -inline idStr& idStr::operator+= -( - const char *a -){ - append( a ); - return *this; -} - -inline idStr& idStr::operator+= -( - const char a -){ - char text[ 2 ]; - - text[ 0 ] = a; - text[ 1 ] = 0; - append( text ); - - return *this; -} - -inline idStr& idStr::operator+= -( - const bool a -){ - append( a ? "true" : "false" ); - return *this; -} - -inline bool operator== -( - const idStr& a, - const idStr& b -){ - return ( !strcmp( a.c_str(), b.c_str() ) ); -} - -inline bool operator== -( - const idStr& a, - const char *b -){ - assert( b ); - if ( !b ) { - return false; - } - return ( !strcmp( a.c_str(), b ) ); -} - -inline bool operator== -( - const char *a, - const idStr& b -){ - assert( a ); - if ( !a ) { - return false; - } - return ( !strcmp( a, b.c_str() ) ); -} - -inline bool operator!= -( - const idStr& a, - const idStr& b -){ - return !( a == b ); -} - -inline bool operator!= -( - const idStr& a, - const char *b -){ - return !( a == b ); -} - -inline bool operator!= -( - const char *a, - const idStr& b -){ - return !( a == b ); -} - -inline int idStr::icmpn -( - const char *text, - int n -) const { - assert( m_data ); - assert( text ); - - return idStr::icmpn( m_data->data, text, n ); -} - -inline int idStr::icmpn -( - const idStr& text, - int n -) const { - assert( m_data ); - assert( text.m_data ); - - return idStr::icmpn( m_data->data, text.m_data->data, n ); -} - -inline int idStr::icmp -( - const char *text -) const { - assert( m_data ); - assert( text ); - - return idStr::icmp( m_data->data, text ); -} - -inline int idStr::icmp -( - const idStr& text -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::icmp( c_str(), text.c_str() ); -} - -inline int idStr::cmp -( - const char *text -) const { - assert( m_data ); - assert( text ); - - return idStr::cmp( m_data->data, text ); -} - -inline int idStr::cmp -( - const idStr& text -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::cmp( c_str(), text.c_str() ); -} - -inline int idStr::cmpn -( - const char *text, - int n -) const { - assert( c_str() ); - assert( text ); - - return idStr::cmpn( c_str(), text, n ); -} - -inline int idStr::cmpn -( - const idStr& text, - int n -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::cmpn( c_str(), text.c_str(), n ); -} - -inline void idStr::tolower -( - void -){ - assert( m_data ); - - EnsureDataWritable(); - - idStr::tolower( m_data->data ); -} - -inline void idStr::toupper -( - void -){ - assert( m_data ); - - EnsureDataWritable(); - - idStr::toupper( m_data->data ); -} - -inline bool idStr::isNumeric -( - void -) const { - assert( m_data ); - return idStr::isNumeric( m_data->data ); -} - -inline idStr::operator const char *() { - return c_str(); -} - -inline idStr::operator const char * -( - void -) const { - return c_str(); -} - -#endif diff --git a/libs/str.h b/libs/str.h deleted file mode 100644 index fb2b269..0000000 --- a/libs/str.h +++ /dev/null @@ -1,502 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __STR__ -#define __STR__ - -#include "globaldefs.h" - -// -// class Str -// loose replacement for CString from MFC -// - -#include -#include - -#include -#include - -#include - -#if GDEF_COMPILER_MSVC -#define strcasecmp strcmpi -#if _MSC_VER < 1400 -#define vsnprintf std::vsnprintf -#endif -#else -#include -#endif - -// NOTE TTimo __StrDup was initially implemented in pakstuff.cpp -// causing a bunch of issues for broader targets that use Str.h (such as plugins and modules) -// Q_StrDup should be used now, using a #define __StrDup for easy transition - -#define __StrDup Q_StrDup - -inline char* Q_StrDup( const char* pStr ){ - if ( pStr == 0 ) { - pStr = ""; - } - - return strcpy( new char[strlen( pStr ) + 1], pStr ); -} - -#if !GDEF_OS_WINDOWS -#define strcmpi strcasecmp -#define stricmp strcasecmp -#define strnicmp strncasecmp - -inline char* strlwr( char* string ){ - char *cp; - for ( cp = string; *cp; ++cp ) - { - if ( 'A' <= *cp && *cp <= 'Z' ) { - *cp += 'a' - 'A'; - } - } - - return string; -} - -inline char* strupr( char* string ){ - char *cp; - for ( cp = string; *cp; ++cp ) - { - if ( 'a' <= *cp && *cp <= 'z' ) { - *cp += 'A' - 'a'; - } - } - - return string; -} -#endif - -static char *g_pStrWork = 0; - -class Str -{ -protected: -bool m_bIgnoreCase; -char *m_pStr; - -public: -Str(){ - m_bIgnoreCase = true; - m_pStr = new char[1]; - m_pStr[0] = '\0'; -} - -Str( char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( p ); -} - -Str( const char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( p ); -} - -Str( const unsigned char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( reinterpret_cast( p ) ); -} - -Str( const char c ){ - m_bIgnoreCase = true; - m_pStr = new char[2]; - m_pStr[0] = c; - m_pStr[1] = '\0'; -} - -const char* GetBuffer() const { - return m_pStr; -} - -char* GetBuffer(){ - return m_pStr; -} - -Str( const Str &s ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( s.GetBuffer() ); -} - -void Deallocate(){ - delete []m_pStr; - m_pStr = 0; -} - -void Allocate( std::size_t n ){ - Deallocate(); - m_pStr = new char[n]; -} - -void MakeEmpty(){ - Deallocate(); - m_pStr = __StrDup( "" ); -} - -~Str(){ - Deallocate(); - // NOTE TTimo: someone explain this g_pStrWork to me? - if ( g_pStrWork ) { - delete []g_pStrWork; - } - g_pStrWork = 0; -} - -void MakeLower(){ - if ( m_pStr ) { - strlwr( m_pStr ); - } -} - -void MakeUpper(){ - if ( m_pStr ) { - strupr( m_pStr ); - } -} - -void TrimRight(){ - char* lpsz = m_pStr; - char* lpszLast = 0; - while ( *lpsz != '\0' ) - { - if ( isspace( *lpsz ) ) { - if ( lpszLast == 0 ) { - lpszLast = lpsz; - } - } - else{ - lpszLast = 0; - } - lpsz++; - } - - if ( lpszLast != 0 ) { - // truncate at trailing space start - *lpszLast = '\0'; - } -} - -void TrimLeft(){ - // find first non-space character - char* lpsz = m_pStr; - while ( isspace( *lpsz ) ) - lpsz++; - - // fix up data and length - std::size_t nDataLength = GetLength() - ( lpsz - m_pStr ); - memmove( m_pStr, lpsz, ( nDataLength + 1 ) ); -} - -char* Find( const char *p ){ - return strstr( m_pStr, p ); -} - -// search starting at a given offset -char* Find( const char *p, std::size_t offset ){ - return strstr( m_pStr + offset, p ); -} - -char* Find( const char ch ){ - return strchr( m_pStr, ch ); -} - -char* ReverseFind( const char ch ){ - return strrchr( m_pStr, ch ); -} - -int Compare( const char* str ) const { - return strcmp( m_pStr, str ); -} - -int CompareNoCase( const char* str ) const { - return strcasecmp( m_pStr, str ); -} - -std::size_t GetLength(){ - return ( m_pStr ) ? strlen( m_pStr ) : 0; -} - -const char* Left( std::size_t n ){ - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - strncpy( g_pStrWork, m_pStr, n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -const char* Right( std::size_t n ){ - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - std::size_t nStart = GetLength() - n; - strncpy( g_pStrWork, &m_pStr[nStart], n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -const char* Mid( std::size_t nFirst ) const { - return Mid( nFirst, strlen( m_pStr ) - nFirst ); -} - -const char* Mid( std::size_t first, std::size_t n ) const { - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - strncpy( g_pStrWork, m_pStr + first, n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -#if 0 // defined(__G_LIB_H__) -void Format( const char* fmt, ... ){ - va_list args; - char *buffer; - - va_start( args, fmt ); - buffer = g_strdup_vprintf( fmt, args ); - va_end( args ); - - delete[] m_pStr; - m_pStr = __StrDup( buffer ); - g_free( buffer ); -} -#else -void Format( const char* fmt, ... ){ - char buffer[1024]; - - { - va_list args; - va_start( args, fmt ); - vsnprintf( buffer, 1023, fmt, args ); - va_end( args ); - } - - delete[] m_pStr; - m_pStr = __StrDup( buffer ); -} -#endif - -void SetAt( std::size_t n, char ch ){ - if ( n < GetLength() ) { - m_pStr[n] = ch; - } -} - -// NOTE: unlike CString, this looses the pointer -void ReleaseBuffer( std::size_t n ){ - char* tmp = m_pStr; - tmp[n] = '\0'; - m_pStr = __StrDup( tmp ); - delete []tmp; -} -void ReleaseBuffer(){ - ReleaseBuffer( GetLength() ); -} - -char* GetBufferSetLength( std::size_t n ){ - char *p = new char[n + 1]; - strncpy( p, m_pStr, n ); - p[n] = '\0'; - delete []m_pStr; - m_pStr = p; - return m_pStr; -} - -// char& operator *() { return *m_pStr; } -// char& operator *() const { return *const_cast(this)->m_pStr; } -operator void*() { - return m_pStr; -} -operator char*() { - return m_pStr; -} -operator const char*() const { return reinterpret_cast( m_pStr ); } -operator unsigned char*() { - return reinterpret_cast( m_pStr ); -} -operator const unsigned char*() const { return reinterpret_cast( m_pStr ); } -Str& operator =( const Str& rhs ){ - if ( &rhs != this ) { - delete[] m_pStr; - m_pStr = __StrDup( rhs.m_pStr ); - } - return *this; -} - -Str& operator =( const char* pStr ){ - if ( m_pStr != pStr ) { - delete[] m_pStr; - m_pStr = __StrDup( pStr ); - } - return *this; -} - -Str& operator +=( const char ch ){ - std::size_t len = GetLength(); - char *p = new char[len + 1 + 1]; - - if ( m_pStr ) { - strcpy( p, m_pStr ); - delete[] m_pStr; - } - - m_pStr = p; - m_pStr[len] = ch; - m_pStr[len + 1] = '\0'; - - return *this; -} - -Str& operator +=( const char *pStr ){ - if ( pStr ) { - if ( m_pStr ) { - char *p = new char[strlen( m_pStr ) + strlen( pStr ) + 1]; - strcpy( p, m_pStr ); - strcat( p, pStr ); - delete[] m_pStr; - m_pStr = p; - } - else - { - m_pStr = __StrDup( pStr ); - } - } - return *this; -} - - -bool operator ==( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) == 0 : strcmp( m_pStr, rhs.m_pStr ) == 0; -} -bool operator ==( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) == 0 : strcmp( m_pStr, pStr ) == 0; -} -bool operator ==( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) == 0 : strcmp( m_pStr, pStr ) == 0; -} -bool operator !=( Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) != 0 : strcmp( m_pStr, rhs.m_pStr ) != 0; -} -bool operator !=( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) != 0 : strcmp( m_pStr, pStr ) != 0; -} -bool operator !=( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) != 0 : strcmp( m_pStr, pStr ) != 0; -} -bool operator <( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) < 0 : strcmp( m_pStr, rhs.m_pStr ) < 0; -} -bool operator <( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) < 0 : strcmp( m_pStr, pStr ) < 0; -} -bool operator <( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) < 0 : strcmp( m_pStr, pStr ) < 0; -} -bool operator >( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) > 0 : strcmp( m_pStr, rhs.m_pStr ) > 0; -} -bool operator >( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) > 0 : strcmp( m_pStr, pStr ) > 0; -} -bool operator >( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) > 0 : strcmp( m_pStr, pStr ) > 0; -} -char& operator []( std::size_t nIndex ) { - return m_pStr[nIndex]; -} -const char& operator []( std::size_t nIndex ) const { - return m_pStr[nIndex]; -} -char GetAt( std::size_t nIndex ) { - return m_pStr[nIndex]; -} -}; - - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Str& str ){ - return ostream << str.GetBuffer(); -} - - -inline void AddSlash( Str& strPath ){ - if ( strPath.GetLength() > 0 ) { - if ( ( strPath.GetAt( strPath.GetLength() - 1 ) != '/' ) && - ( strPath.GetAt( strPath.GetLength() - 1 ) != '\\' ) ) { - strPath += '/'; - } - } -} - -inline bool ExtractPath_and_Filename( const char* pPath, Str& strPath, Str& strFilename ){ - Str strPathName; - strPathName = pPath; - const char* substr = strPathName.ReverseFind( '\\' ); - if ( substr == 0 ) { - // TTimo: try forward slash, some are using forward - substr = strPathName.ReverseFind( '/' ); - } - if ( substr != 0 ) { - std::size_t nSlash = substr - strPathName.GetBuffer(); - strPath = strPathName.Left( nSlash + 1 ); - strFilename = strPathName.Right( strPathName.GetLength() - nSlash - 1 ); - } - else{ - strFilename = pPath; - } - return true; -} - - - -#endif diff --git a/libs/stream/Makefile b/libs/stream/Makefile deleted file mode 100644 index 1d701b7..0000000 --- a/libs/stream/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - _.o - -# binary target -../libstream.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp filestream.h memstream.h stringstream.h textfilestream.h textstream.h - -clean: - -rm -f *.o ../libstream.a diff --git a/libs/stream/_.cpp b/libs/stream/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/stream/filestream.h b/libs/stream/filestream.h deleted file mode 100644 index 826f6b5..0000000 --- a/libs/stream/filestream.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_FILESTREAM_H ) -#define INCLUDED_STREAM_FILESTREAM_H - -#include "idatastream.h" -#include -#include - -namespace FileStreamDetail -{ -inline int whence_for_seekdir( SeekableStream::seekdir direction ){ - switch ( direction ) - { - case SeekableStream::cur: - return SEEK_CUR; - case SeekableStream::end: - return SEEK_END; - default: - break; - } - return SEEK_SET; -} -} - - -/// \brief A wrapper around a file input stream opened for reading in binary mode. Similar to std::ifstream. -/// -/// - Maintains a valid file handle associated with a name passed to the constructor. -/// - Implements SeekableInputStream. -class FileInputStream : public SeekableInputStream -{ -std::FILE* m_file; -public: -FileInputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "rb" ); -} -~FileInputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -size_type read( byte_type* buffer, size_type length ){ - return fread( buffer, 1, length, m_file ); -} - -size_type seek( size_type position ){ - return fseek( m_file, static_cast( position ), SEEK_SET ); -} -size_type seek( offset_type offset, seekdir direction ){ - return fseek( m_file, offset, FileStreamDetail::whence_for_seekdir( direction ) ); -} -size_type tell() const { - return ftell( m_file ); -} - -std::FILE* file(){ - return m_file; -} -}; - -/// \brief A wrapper around a FileInputStream limiting access. -/// -/// - Maintains an input stream. -/// - Provides input starting at an offset in the file for a limited range. -class SubFileInputStream : public InputStream -{ -FileInputStream& m_istream; -size_type m_remaining; -public: -typedef FileInputStream::position_type position_type; - -SubFileInputStream( FileInputStream& istream, position_type offset, size_type size ) - : m_istream( istream ), m_remaining( size ){ - m_istream.seek( offset ); -} - -size_type read( byte_type* buffer, size_type length ){ - size_type result = m_istream.read( buffer, std::min( length, m_remaining ) ); - m_remaining -= result; - return result; -} -}; - - -/// \brief A wrapper around a stdc file stream opened for writing in binary mode. Similar to std::ofstream.. -/// -/// - Maintains a valid file handle associated with a name passed to the constructor. -/// - Implements SeekableInputStream. -class FileOutputStream : public SeekableOutputStream -{ -std::FILE* m_file; -public: -FileOutputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "wb" ); -} -~FileOutputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -size_type write( const byte_type* buffer, size_type length ){ - return fwrite( buffer, 1, length, m_file ); -} - -size_type seek( size_type position ){ - return fseek( m_file, static_cast( position ), SEEK_SET ); -} -size_type seek( offset_type offset, seekdir direction ){ - return fseek( m_file, offset, FileStreamDetail::whence_for_seekdir( direction ) ); -} -size_type tell() const { - return ftell( m_file ); -} -}; - -inline bool file_copy( const char* source, const char* target ){ - const std::size_t buffer_size = 1024; - unsigned char buffer[buffer_size]; - - FileInputStream sourceFile( source ); - if ( sourceFile.failed() ) { - return false; - } - FileOutputStream targetFile( target ); - if ( targetFile.failed() ) { - return false; - } - - for (;; ) - { - std::size_t size = sourceFile.read( buffer, buffer_size ); - if ( size == 0 ) { - break; - } - if ( targetFile.write( buffer, size ) != size ) { - return false; - } - } - return true; -} - - -#endif diff --git a/libs/stream/memstream.h b/libs/stream/memstream.h deleted file mode 100644 index 75bd23a..0000000 --- a/libs/stream/memstream.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_MEMSTREAM_H ) -#define INCLUDED_STREAM_MEMSTREAM_H - -#include "itextstream.h" -#include -#include - -class BufferOutputStream : public TextOutputStream -{ -std::vector m_buffer; -public: -std::size_t write( const char* buffer, std::size_t length ){ - m_buffer.insert( m_buffer.end(), buffer, buffer + length ); - return length; -} -const char* data() const { - return &( *m_buffer.begin() ); -} -std::size_t size() const { - return m_buffer.size(); -} -void clear(){ - std::vector empty; - std::swap( empty, m_buffer ); -} -}; - -template -inline BufferOutputStream& operator<<( BufferOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -class BufferInputStream : public TextInputStream -{ -const char* m_read; -const char* m_end; -public: -BufferInputStream( const char* buffer, std::size_t length ) - : m_read( buffer ), m_end( buffer + length ){ -} -std::size_t read( char* buffer, std::size_t length ){ - std::size_t count = std::min( std::size_t( m_end - m_read ), length ); - const char* end = m_read + count; - while ( m_read != end ) - { - *buffer++ = *m_read++; - } - return count; -} -}; - -#endif diff --git a/libs/stream/stringstream.h b/libs/stream/stringstream.h deleted file mode 100644 index 8511bd4..0000000 --- a/libs/stream/stringstream.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_STRINGSTREAM_H ) -#define INCLUDED_STREAM_STRINGSTREAM_H - -#include "itextstream.h" -#include "string/string.h" -#include - - -/// \brief A wrapper around a STL vector of char. -/// Maintains a null-terminated array of char. -/// Provides a limited STL-style interface to push and pop characters at the end of the string. -class StringBuffer -{ -std::vector m_string; -public: -StringBuffer(){ - m_string.push_back( '\0' ); -} -explicit StringBuffer( std::size_t capacity ){ - m_string.reserve( capacity ); - m_string.push_back( '\0' ); -} -explicit StringBuffer( const char* string ) : m_string( string, string + string_length( string ) + 1 ){ -} - -typedef std::vector::iterator iterator; -typedef std::vector::const_iterator const_iterator; - -iterator begin(){ - return m_string.begin(); -} -const_iterator begin() const { - return m_string.begin(); -} -iterator end(){ - return m_string.end() - 1; -} -const_iterator end() const { - return m_string.end() - 1; -} - -void push_back( char c ){ - m_string.insert( end(), c ); -} -void pop_back(){ - m_string.erase( end() - 1 ); -} -void push_range( const char* first, const char* last ){ - m_string.insert( end(), first, last ); -} -void push_string( const char* string ){ - push_range( string, string + string_length( string ) ); -} -char* c_str(){ - return &( *m_string.begin() ); -} -const char* c_str() const { - return &( *m_string.begin() ); -} - -char& back(){ - return *( end() - 1 ); -} -const char& back() const { - return *( end() - 1 ); -} -bool empty() const { - return m_string.size() == 1; -} -void clear(){ - m_string.clear(); - m_string.push_back( '\0' ); -} -}; - -/// \brief A TextOutputStream which writes to a StringBuffer. -/// Similar to std::stringstream. -class StringOutputStream : public TextOutputStream -{ -StringBuffer m_string; -public: -typedef StringBuffer::iterator iterator; -typedef StringBuffer::const_iterator const_iterator; - -StringOutputStream(){ -} -explicit StringOutputStream( std::size_t capacity ) : m_string( capacity ){ -} -std::size_t write( const char* buffer, std::size_t length ){ - m_string.push_range( buffer, buffer + length ); - return length; -} - -iterator begin(){ - return m_string.begin(); -} -const_iterator begin() const { - return m_string.begin(); -} -iterator end(){ - return m_string.end(); -} -const_iterator end() const { - return m_string.end(); -} - -bool empty() const { - return m_string.empty(); -} -char* c_str(){ - return m_string.c_str(); -} -const char* c_str() const { - return m_string.c_str(); -} -void clear(){ - m_string.clear(); -} -}; - -template -inline StringOutputStream& operator<<( StringOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -#endif diff --git a/libs/stream/textfilestream.h b/libs/stream/textfilestream.h deleted file mode 100644 index 41dc938..0000000 --- a/libs/stream/textfilestream.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_TEXTFILESTREAM_H ) -#define INCLUDED_STREAM_TEXTFILESTREAM_H - -#include "itextstream.h" -#include - -/// \brief A wrapper around a file input stream opened for reading in text mode. Similar to std::ifstream. -class TextFileInputStream : public TextInputStream -{ -FILE* m_file; -public: -TextFileInputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "rt" ); -} -~TextFileInputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -std::size_t read( char* buffer, std::size_t length ){ - return fread( buffer, 1, length, m_file ); -} -}; - -/// \brief A wrapper around a file input stream opened for writing in text mode. Similar to std::ofstream. -class TextFileOutputStream : public TextOutputStream -{ -FILE* m_file; -public: -TextFileOutputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "wt" ); -} -~TextFileOutputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -std::size_t write( const char* buffer, std::size_t length ){ - return fwrite( buffer, 1, length, m_file ); -} -}; - -template -inline TextFileOutputStream& operator<<( TextFileOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -#endif diff --git a/libs/stream/textstream.h b/libs/stream/textstream.h deleted file mode 100644 index ad1a0be..0000000 --- a/libs/stream/textstream.h +++ /dev/null @@ -1,475 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_TEXTSTREAM_H ) -#define INCLUDED_STREAM_TEXTSTREAM_H - -#include "globaldefs.h" - -/// \file -/// \brief Text-output-formatting. - -#include "itextstream.h" -#include "string/string.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "generic/arrayrange.h" - -namespace TextOutputDetail -{ -inline char* write_unsigned_nonzero_decimal_backward( char* ptr, unsigned int decimal ){ - for (; decimal != 0; decimal /= 10 ) - { - *--ptr = char('0' + int(decimal % 10) ); - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_nonzero_decimal_backward( char* ptr, size_t decimal ){ - for (; decimal != 0; decimal /= 10 ) - { - *--ptr = char('0' + (size_t)( decimal % 10 ) ); - } - return ptr; -} - #endif - -inline char* write_signed_nonzero_decimal_backward( char* ptr, int decimal, bool show_positive ){ - const bool negative = decimal < 0; - ptr = write_unsigned_nonzero_decimal_backward( ptr, negative ? -decimal : decimal ); - if ( negative ) { - *--ptr = '-'; - } - else if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - -inline char* write_unsigned_nonzero_decimal_backward( char* ptr, unsigned int decimal, bool show_positive ){ - ptr = write_unsigned_nonzero_decimal_backward( ptr, decimal ); - if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_nonzero_decimal_backward( char* ptr, size_t decimal, bool show_positive ){ - ptr = write_size_t_nonzero_decimal_backward( ptr, decimal ); - if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - #endif - -inline char* write_signed_decimal_backward( char* ptr, int decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_signed_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - -inline char* write_unsigned_decimal_backward( char* ptr, unsigned int decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_unsigned_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_decimal_backward( char* ptr, size_t decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_size_t_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - #endif -} - - -#if GDEF_OS_WINDOWS -#define snprintf _snprintf -#endif - -/// \brief Writes a single character \p c to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, char c ){ - ostream.write( &c, 1 ); - return ostream; -} - -/// \brief Writes a double-precision floating point value \p d to \p ostream. -/// The value will be formatted either as decimal with trailing zeros removed, or with scientific 'e' notation, whichever is shorter. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const double d ){ - const std::size_t bufferSize = 16; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%g", d ) ); - return ostream; -} - -/// \brief Writes a single-precision floating point value \p f to \p ostream. -/// The value will be formatted either as decimal with trailing zeros removed, or with scientific 'e' notation, whichever is shorter. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const float f ){ - return ostream_write( ostream, static_cast( f ) ); -} - -/// \brief Writes a signed integer \p i to \p ostream in decimal form. -/// A '-' sign will be added if the value is negative. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const int i ){ - const std::size_t bufferSize = 16; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_signed_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%i", i ) ); -#endif - return ostream; -} - -typedef unsigned int Unsigned; - -/// \brief Writes an unsigned integer \p i to \p ostream in decimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Unsigned i ){ - const std::size_t bufferSize = 16; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_unsigned_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%u", i ) ); -#endif - return ostream; -} - -#if GDEF_ARCH_BITS_64 - -/// \brief Writes a size_t \p i to \p ostream in decimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const size_t i ){ - // max is 18446744073709551615, buffer of 32 chars should always be enough - const std::size_t bufferSize = 32; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_size_t_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%u", i ) ); -#endif - return ostream; -} - -#endif - -/// \brief Writes a null-terminated \p string to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const char* string ){ - ostream.write( string, strlen( string ) ); - return ostream; -} - -class HexChar -{ -public: -char m_value; -HexChar( char value ) : m_value( value ){ -} -}; - -/// \brief Writes a single character \p c to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const HexChar& c ){ - const std::size_t bufferSize = 16; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%X", c.m_value & 0xFF ) ); - return ostream; -} - -class FloatFormat -{ -public: -double m_f; -int m_width; -int m_precision; -FloatFormat( double f, int width, int precision ) - : m_f( f ), m_width( width ), m_precision( precision ){ -} -}; - -/// \brief Writes a floating point value to \p ostream with a specific width and precision. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const FloatFormat& formatted ){ - const std::size_t bufferSize = 32; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%*.*lf", formatted.m_width, formatted.m_precision, formatted.m_f ) ); - return ostream; -} - -// never displays exponent, prints up to 10 decimal places -class Decimal -{ -public: -double m_f; -Decimal( double f ) : m_f( f ){ -} -}; - -/// \brief Writes a floating point value to \p ostream in decimal form with trailing zeros removed. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Decimal& decimal ){ - const int bufferSize = 22; - char buf[bufferSize]; - std::size_t length = snprintf( buf, bufferSize, "%10.10lf", decimal.m_f ); - const char* first = buf; - for (; *first == ' '; ++first ) - { - } - const char* last = buf + length - 1; - for (; *last == '0'; --last ) - { - } - if ( *last == '.' ) { - --last; - } - ostream.write( first, last - first + 1 ); - return ostream; -} - - -/// \brief Writes a \p range of characters to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const StringRange& range ){ - ostream.write( range.first, range.last - range.first ); - return ostream; -} - -template -class Quoted -{ -public: -const Type& m_type; -Quoted( const Type& type ) - : m_type( type ){ -} -}; - -template -inline Quoted makeQuoted( const Type& type ){ - return Quoted( type ); -} - -/// \brief Writes any type to \p ostream with a quotation mark character before and after it. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Quoted& quoted ){ - return ostream << '"' << quoted.m_type << '"'; -} - - -class LowerCase -{ -public: -const char* m_string; -LowerCase( const char* string ) : m_string( string ){ -} -}; - -/// \brief Writes a string to \p ostream converted to lower-case. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const LowerCase& lower ){ - for ( const char* p = lower.m_string; *p != '\0'; ++p ) - { - ostream << static_cast( std::tolower( *p ) ); - } - return ostream; -} - - -/// \brief A wrapper for a TextInputStream optimised for reading a single character at a time. -template -class SingleCharacterInputStream -{ -TextInputStreamType& m_inputStream; -char m_buffer[SIZE]; -char* m_cur; -char* m_end; - -bool fillBuffer(){ - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - return m_cur != m_end; -} -public: - -SingleCharacterInputStream( TextInputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer ), m_end( m_buffer ){ -} -bool readChar( char& c ){ - if ( m_cur == m_end && !fillBuffer() ) { - return false; - } - - c = *m_cur++; - return true; -} -}; - -/// \brief A wrapper for a TextOutputStream, optimised for writing a single character at a time. -class SingleCharacterOutputStream : public TextOutputStream -{ -enum unnamed0 { m_bufsize = 1024 }; -TextOutputStream& m_ostream; -char m_buffer[m_bufsize]; -char* m_pos; -const char* m_end; - -const char* end() const { - return m_end; -} -void reset(){ - m_pos = m_buffer; -} -void flush(){ - m_ostream.write( m_buffer, m_pos - m_buffer ); - reset(); -} -public: -SingleCharacterOutputStream( TextOutputStream& ostream ) : m_ostream( ostream ), m_pos( m_buffer ), m_end( m_buffer + m_bufsize ){ -} -~SingleCharacterOutputStream(){ - flush(); -} -void write( const char c ){ - if ( m_pos == end() ) { - flush(); - } - *m_pos++ = c; -} -std::size_t write( const char* buffer, std::size_t length ){ - const char*const end = buffer + length; - for ( const char* p = buffer; p != end; ++p ) - { - write( *p ); - } - return length; -} -}; - - -/// \brief A wrapper for a TextInputStream used for reading one text line at a time. -template -class TextLinesInputStream -{ -TextInputStreamType& m_inputStream; -char m_buffer[SIZE + 1]; -char* m_cur; -char* m_end; - -int fillBuffer(){ - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - m_buffer[SIZE] = '\0'; - *m_end = '\0'; - return m_end - m_cur; -} -public: - -TextLinesInputStream( TextInputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer ), m_end( m_buffer ){ - m_buffer[0] = '\0'; -} - -CopiedString readLine(){ - std::string s; - char* m_fin; - - while ( (m_fin = strchr( m_cur, '\n' )) == 0 ) - { - s.append( m_cur, m_end - m_cur ); - if ( fillBuffer() <= 0 ) break; - } - if ( m_fin != 0 ) { - s.append( m_cur, m_fin - m_cur + 1 ); - m_cur = m_fin + 1; - } - - return CopiedString( s.c_str() ); -} -}; - - -/// \brief A wrapper for a TextOutputStream, optimised for writing a few characters at a time. -template -class BufferedTextOutputStream : public TextOutputStream -{ -TextOutputStreamType outputStream; -char m_buffer[SIZE]; -char* m_cur; - -public: -BufferedTextOutputStream( TextOutputStreamType& outputStream ) : outputStream( outputStream ), m_cur( m_buffer ){ -} -~BufferedTextOutputStream(){ - outputStream.write( m_buffer, m_cur - m_buffer ); -} -std::size_t write( const char* buffer, std::size_t length ){ - std::size_t remaining = length; - for (;; ) - { - std::size_t n = std::min( remaining, std::size_t( ( m_buffer + SIZE ) - m_cur ) ); - m_cur = std::copy( buffer, buffer + n, m_cur ); - remaining -= n; - if ( remaining == 0 ) { - return 0; - } - outputStream.write( m_buffer, SIZE ); - m_cur = m_buffer; - } -} -}; - -#endif diff --git a/libs/string/Makefile b/libs/string/Makefile deleted file mode 100644 index 02cdcae..0000000 --- a/libs/string/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - pooledstring.o - -# binary target -../libstring.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -pooledstring.o: pooledstring.cpp pooledstring.h string.h stringfwd.h - -clean: - -rm -f *.o ../libstring.a diff --git a/libs/string/pooledstring.cpp b/libs/string/pooledstring.cpp deleted file mode 100644 index d438633..0000000 --- a/libs/string/pooledstring.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include "pooledstring.h" -#include "globaldefs.h" -#include "generic/static.h" - -#if GDEF_DEBUG - -namespace ExamplePooledString -{ -void testStuff(){ - PooledString< LazyStatic > a, b; - a = "monkey"; - b = "monkey"; - a = ""; -} - -struct Always -{ - Always(){ - testStuff(); - } -} always; -} - -#endif diff --git a/libs/string/pooledstring.h b/libs/string/pooledstring.h deleted file mode 100644 index a388acf..0000000 --- a/libs/string/pooledstring.h +++ /dev/null @@ -1,93 +0,0 @@ - -#if !defined( INCLUDED_POOLEDSTRING_H ) -#define INCLUDED_POOLEDSTRING_H - -#include -#include "generic/static.h" -#include "string/string.h" -#include "container/hashtable.h" -#include "container/hashfunc.h" - -/// \brief The string pool class. -class StringPool : public HashTable -{ -}; - -inline void StringPool_analyse( StringPool& pool ){ - typedef std::multimap Ordered; - Ordered ordered; - std::size_t total = 0; - std::size_t pooled = 0; - for ( StringPool::iterator i = pool.begin(); i != pool.end(); ++i ) - { - std::size_t size = string_length( ( *i ).key ) + 1; - total += size * ( *i ).value; - pooled += size + 20; - ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) ); - } - globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n"; - for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i ) - { - globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n"; - } -} - - -/// \brief A string which can be copied with zero memory cost and minimal runtime cost. -/// -/// \param PoolContext The string pool context to use. -template -class PooledString -{ -StringPool::iterator m_i; -static StringPool::iterator increment( StringPool::iterator i ){ - ++( *i ).value; - return i; -} -static StringPool::iterator insert( const char* string ){ - StringPool::iterator i = PoolContext::instance().find( const_cast( string ) ); - if ( i == PoolContext::instance().end() ) { - return PoolContext::instance().insert( string_clone( string ), 1 ); - } - return increment( i ); -} -static void erase( StringPool::iterator i ){ - if ( --( *i ).value == 0 ) { - char* string = ( *i ).key; - PoolContext::instance().erase( i ); - string_release( string, string_length( string ) ); - } -} -public: -PooledString() : m_i( insert( "" ) ){ -} -PooledString( const PooledString& other ) : m_i( increment( other.m_i ) ){ -} -PooledString( const char* string ) : m_i( insert( string ) ){ -} -~PooledString(){ - erase( m_i ); -} -PooledString& operator=( const PooledString& other ){ - PooledString tmp( other ); - tmp.swap( *this ); - return *this; -} -PooledString& operator=( const char* string ){ - PooledString tmp( string ); - tmp.swap( *this ); - return *this; -} -void swap( PooledString& other ){ - std::swap( m_i, other.m_i ); -} -bool operator==( const PooledString& other ) const { - return m_i == other.m_i; -} -const char* c_str() const { - return ( *m_i ).key; -} -}; - - -#endif diff --git a/libs/string/string.h b/libs/string/string.h deleted file mode 100644 index 8c76a91..0000000 --- a/libs/string/string.h +++ /dev/null @@ -1,548 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STRING_STRING_H ) -#define INCLUDED_STRING_STRING_H - -#include "globaldefs.h" - -/// \file -/// C-style null-terminated-character-array string library. - -#include -#include -#include - -#include "memory/allocator.h" -#include "generic/arrayrange.h" - -/// \brief Returns true if \p string length is zero. -/// O(1) -inline bool string_empty( const char* string ){ - return *string == '\0'; -} - -/// \brief Returns true if \p string length is not zero. -/// O(1) -inline bool string_not_empty( const char* string ){ - return !string_empty( string ); -} - -/// \brief Returns <0 if \p string is lexicographically less than \p other. -/// Returns >0 if \p string is lexicographically greater than \p other. -/// Returns 0 if \p string is lexicographically equal to \p other. -/// O(n) -inline int string_compare( const char* string, const char* other ){ - return std::strcmp( string, other ); -} - -/// \brief Returns true if \p string is lexicographically equal to \p other. -/// O(n) -inline bool string_equal( const char* string, const char* other ){ - return string_compare( string, other ) == 0; -} - -/// \brief Returns true if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// O(n) -inline bool string_equal_n( const char* string, const char* other, std::size_t n ){ - return std::strncmp( string, other, n ) == 0; -} - -/// \brief Returns true if \p string is lexicographically less than \p other. -/// O(n) -inline bool string_less( const char* string, const char* other ){ - return string_compare( string, other ) < 0; -} - -/// \brief Returns true if \p string is lexicographically greater than \p other. -/// O(n) -inline bool string_greater( const char* string, const char* other ){ - return string_compare( string, other ) > 0; -} - -/// \brief Returns <0 if \p string is lexicographically less than \p other after converting both to lower-case. -/// Returns >0 if \p string is lexicographically greater than \p other after converting both to lower-case. -/// Returns 0 if \p string is lexicographically equal to \p other after converting both to lower-case. -/// O(n) -inline int string_compare_nocase( const char* string, const char* other ){ -#if GDEF_OS_WINDOWS - return _stricmp( string, other ); -#else - return strcasecmp( string, other ); -#endif -} - -/// \brief Returns <0 if [\p string, \p string + \p n) is lexicographically less than [\p other, \p other + \p n). -/// Returns >0 if [\p string, \p string + \p n) is lexicographically greater than [\p other, \p other + \p n). -/// Returns 0 if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline int string_compare_nocase_n( const char* string, const char* other, std::size_t n ){ -#if GDEF_OS_WINDOWS - return _strnicmp( string, other, n ); -#else - return strncasecmp( string, other, n ); -#endif -} - -/// \brief Returns true if \p string is lexicographically equal to \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_equal_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) == 0; -} - -/// \brief Returns true if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_equal_nocase_n( const char* string, const char* other, std::size_t n ){ - return string_compare_nocase_n( string, other, n ) == 0; -} - -/// \brief Returns true if \p string is lexicographically less than \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_less_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) < 0; -} - -/// \brief Returns true if \p string is lexicographically greater than \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_greater_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) > 0; -} - -/// \brief Returns the number of non-null characters in \p string. -/// O(n) -inline std::size_t string_length( const char* string ){ - return std::strlen( string ); -} - -/// \brief Returns true if the beginning of \p string is equal to \p prefix. -/// O(n) -inline bool string_equal_prefix( const char* string, const char* prefix ){ - return string_equal_n( string, prefix, string_length( prefix ) ); -} - -/// \brief Returns true if the ending of \p string is equal to \p suffix. -/// O(n) -inline bool string_equal_suffix( const char* string, const char* suffix){ - const char *s = string + string_length( string ) - string_length( suffix ); - return string_equal_n( s, suffix, string_length( suffix ) ); -} - -/// \brief Copies \p other into \p string and returns \p string. -/// Assumes that the space allocated for \p string is at least string_length(other) + 1. -/// O(n) -inline char* string_copy( char* string, const char* other ){ - return std::strcpy( string, other ); -} - -/// \brief Allocates a string buffer large enough to hold \p length characters, using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_new( std::size_t length, Allocator& allocator ){ - return allocator.allocate( length + 1 ); -} - -/// \brief Deallocates the \p buffer large enough to hold \p length characters, using \p allocator. -template -inline void string_release( char* buffer, std::size_t length, Allocator& allocator ){ - allocator.deallocate( buffer, length + 1 ); -} - -/// \brief Returns a newly-allocated string which is a clone of \p other, using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_clone( const char* other, Allocator& allocator ){ - char* copied = string_new( string_length( other ), allocator ); - std::strcpy( copied, other ); - return copied; -} - -/// \brief Returns a newly-allocated string which is a clone of [\p first, \p last), using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_clone_range( StringRange range, Allocator& allocator ){ - std::size_t length = range.last - range.first; - char* copied = strncpy( string_new( length, allocator ), range.first, length ); - copied[length] = '\0'; - return copied; -} - -/// \brief Allocates a string buffer large enough to hold \p length characters. -/// The returned buffer must be released with \c string_release. -inline char* string_new( std::size_t length ){ - DefaultAllocator allocator; - return string_new( length, allocator ); -} - -/// \brief Allocates a new buffer large enough to hold two concatenated strings and fills it with strings. -inline char* string_new_concat( const char* a, const char* b ){ - char* str = string_new( string_length( a ) + string_length( b ) ); - strcpy( str, a ); - strcat( str, b ); - return str; -} - -/// \brief Deallocates the \p buffer large enough to hold \p length characters. -inline void string_release( char* string, std::size_t length ){ - DefaultAllocator allocator; - string_release( string, length, allocator ); -} - -/// \brief Returns a newly-allocated string which is a clone of \p other. -/// The returned buffer must be released with \c string_release. -inline char* string_clone( const char* other ){ - DefaultAllocator allocator; - return string_clone( other, allocator ); -} - -/// \brief Returns a newly-allocated string which is a clone of [\p first, \p last). -/// The returned buffer must be released with \c string_release. -inline char* string_clone_range( StringRange range ){ - DefaultAllocator allocator; - return string_clone_range( range, allocator ); -} - -typedef char* char_pointer; -/// \brief Swaps the values of \p string and \p other. -inline void string_swap( char_pointer& string, char_pointer& other ){ - std::swap( string, other ); -} - -typedef const char* char_const_pointer; -/// \brief Swaps the values of \p string and \p other. -inline void string_swap( char_const_pointer& string, char_const_pointer& other ){ - std::swap( string, other ); -} - -/// \brief Converts each character of \p string to lower-case and returns \p string. -/// O(n) -inline char* string_to_lowercase( char* string ){ - for ( char* p = string; *p != '\0'; ++p ) - { - *p = (char)std::tolower( *p ); - } - return string; -} - -/// \brief Converts each character of \p string to upper-case and returns \p string. -/// O(n) -inline char* string_to_uppercase( char* string ){ - for ( char* p = string; *p != '\0'; ++p ) - { - *p = (char)std::toupper( *p ); - } - return string; -} - -/// \brief A re-entrant string tokeniser similar to strchr. -class StringTokeniser -{ -bool istoken( char c ) const { - if ( strchr( m_delimiters, c ) != 0 ) { - return false; - } - return true; -} -const char* advance(){ - const char* token = m_pos; - bool intoken = true; - while ( !string_empty( m_pos ) ) - { - if ( !istoken( *m_pos ) ) { - *m_pos = '\0'; - intoken = false; - } - else if ( !intoken ) { - return token; - } - ++m_pos; - } - return token; -} -std::size_t m_length; -char* m_string; -char* m_pos; -const char* m_delimiters; -public: -StringTokeniser( const char* string, const char* delimiters = " \n\r\t\v" ) : - m_length( string_length( string ) ), - m_string( string_copy( string_new( m_length ), string ) ), - m_pos( m_string ), - m_delimiters( delimiters ){ - while ( !string_empty( m_pos ) && !istoken( *m_pos ) ) - { - ++m_pos; - } -} -~StringTokeniser(){ - string_release( m_string, m_length ); -} -/// \brief Returns the next token or "" if there are no more tokens available. -const char* getToken(){ - return advance(); -} -}; - -/// \brief A non-mutable c-style string. -/// -/// \param Buffer The string storage implementation. Must be DefaultConstructible, CopyConstructible and Assignable. Must implement: -/// \li Buffer(const char* string) - constructor which copies a c-style \p string. -/// \li Buffer(const char* first, const char*) - constructor which copies a c-style string range [\p first, \p last). -/// \li void swap(Buffer& other) - swaps contents with \p other. -/// \li const char* c_str() - returns the stored non-mutable c-style string. -template -class String : public Buffer -{ -public: - -String() - : Buffer(){ -} -String( const char* string ) - : Buffer( string ){ -} -String( StringRange range ) - : Buffer( range ){ -} - -String& operator=( const String& other ){ - String temp( other ); - temp.swap( *this ); - return *this; -} -String& operator=( const char* string ){ - String temp( string ); - temp.swap( *this ); - return *this; -} -String& operator=( StringRange range ){ - String temp( range ); - temp.swap( *this ); - return *this; -} - -void swap( String& other ){ - Buffer::swap( other ); -} - -bool empty() const { - return string_empty( Buffer::c_str() ); -} -}; - -template -inline bool operator<( const String& self, const String& other ){ - return string_less( self.c_str(), other.c_str() ); -} - -template -inline bool operator>( const String& self, const String& other ){ - return string_greater( self.c_str(), other.c_str() ); -} - -template -inline bool operator==( const String& self, const String& other ){ - return string_equal( self.c_str(), other.c_str() ); -} - -template -inline bool operator!=( const String& self, const String& other ){ - return !string_equal( self.c_str(), other.c_str() ); -} - -template -inline bool operator==( const String& self, const char* other ){ - return string_equal( self.c_str(), other ); -} - -template -inline bool operator!=( const String& self, const char* other ){ - return !string_equal( self.c_str(), other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( String& self, String& other ){ - self.swap( other ); -} -} - - -/// \brief A non-mutable string buffer which manages memory allocation. -template -class CopiedBuffer : private Allocator -{ -char* m_string; - -char* copy_range( StringRange range ){ - return string_clone_range( range, static_cast( *this ) ); -} -char* copy( const char* other ){ - return string_clone( other, static_cast( *this ) ); -} -void destroy( char* string ){ - string_release( string, string_length( string ), static_cast( *this ) ); -} - -protected: -~CopiedBuffer(){ - destroy( m_string ); -} -public: -CopiedBuffer() - : m_string( copy( "" ) ){ -} -explicit CopiedBuffer( const Allocator& allocator ) - : Allocator( allocator ), m_string( copy( "" ) ){ -} -CopiedBuffer( const CopiedBuffer& other ) - : Allocator( other ), m_string( copy( other.m_string ) ){ -} -CopiedBuffer( const char* string, const Allocator& allocator = Allocator() ) - : Allocator( allocator ), m_string( copy( string ) ){ -} -CopiedBuffer( StringRange range, const Allocator& allocator = Allocator() ) - : Allocator( allocator ), m_string( copy_range( range ) ){ -} -const char* c_str() const { - return m_string; -} -void swap( CopiedBuffer& other ){ - string_swap( m_string, other.m_string ); -} -}; - -/// \brief A non-mutable string which uses copy-by-value for assignment. -typedef String< CopiedBuffer< DefaultAllocator > > CopiedString; - - -/// \brief A non-mutable string buffer which uses reference-counting to avoid unnecessary allocations. -template -class SmartBuffer : private Allocator -{ -char* m_buffer; - -char* copy_range( StringRange range ){ - char* buffer = Allocator::allocate( sizeof( std::size_t ) + ( range.last - range.first ) + 1 ); - strncpy( buffer + sizeof( std::size_t ), range.first, range.last - range.first ); - buffer[sizeof( std::size_t ) + ( range.last - range.first )] = '\0'; - *reinterpret_cast( buffer ) = 0; - return buffer; -} -char* copy( const char* string ){ - char* buffer = Allocator::allocate( sizeof( std::size_t ) + string_length( string ) + 1 ); - strcpy( buffer + sizeof( std::size_t ), string ); - *reinterpret_cast( buffer ) = 0; - return buffer; -} -void destroy( char* buffer ){ - Allocator::deallocate( buffer, sizeof( std::size_t ) + string_length( c_str() ) + 1 ); -} - -void incref( char* buffer ){ - ++( *reinterpret_cast( buffer ) ); -} -void decref( char* buffer ){ - if ( --( *reinterpret_cast( buffer ) ) == 0 ) { - destroy( buffer ); - } -} - -protected: -~SmartBuffer(){ - decref( m_buffer ); -} -public: -SmartBuffer() - : m_buffer( copy( "" ) ){ - incref( m_buffer ); -} -explicit SmartBuffer( const Allocator& allocator ) - : Allocator( allocator ), m_buffer( copy( "" ) ){ - incref( m_buffer ); -} -SmartBuffer( const SmartBuffer& other ) - : Allocator( other ), m_buffer( other.m_buffer ){ - incref( m_buffer ); -} -SmartBuffer( const char* string, const Allocator& allocator = Allocator() ) - : Allocator( allocator ), m_buffer( copy( string ) ){ - incref( m_buffer ); -} -SmartBuffer( StringRange range, const Allocator& allocator = Allocator() ) - : Allocator( allocator ), m_buffer( copy_range( range ) ){ - incref( m_buffer ); -} -const char* c_str() const { - return m_buffer + sizeof( std::size_t ); -} -void swap( SmartBuffer& other ){ - string_swap( m_buffer, other.m_buffer ); -} -}; - -/// \brief A non-mutable string which uses copy-by-reference for assignment of SmartString. -typedef String< SmartBuffer< DefaultAllocator > > SmartString; - -class StringEqualNoCase -{ -public: -bool operator()( const CopiedString& key, const CopiedString& other ) const { - return string_equal_nocase( key.c_str(), other.c_str() ); -} -}; - -struct StringLessNoCase -{ - bool operator()( const CopiedString& x, const CopiedString& y ) const { - return string_less_nocase( x.c_str(), y.c_str() ); - } -}; - -struct RawStringEqual -{ - bool operator()( const char* x, const char* y ) const { - return string_equal( x, y ); - } -}; - -struct RawStringLess -{ - bool operator()( const char* x, const char* y ) const { - return string_less( x, y ); - } -}; - -struct RawStringLessNoCase -{ - bool operator()( const char* x, const char* y ) const { - return string_less_nocase( x, y ); - } -}; - -#endif diff --git a/libs/string/stringfwd.h b/libs/string/stringfwd.h deleted file mode 100644 index d3d634e..0000000 --- a/libs/string/stringfwd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STRING_STRINGFWD_H ) -#define INCLUDED_STRING_STRINGFWD_H - -// forward-declaration of CopiedString - -template -class DefaultAllocator; -template -class CopiedBuffer; -template -class String; -typedef String< CopiedBuffer< DefaultAllocator > > CopiedString; - -#endif diff --git a/libs/stringio.h b/libs/stringio.h deleted file mode 100644 index 962adf3..0000000 --- a/libs/stringio.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_STRINGIO_H ) -#define INCLUDED_STRINGIO_H - -#include -#include - -#include "generic/vector.h" -#include "iscriplib.h" -#include "string/string.h" -#include "generic/callback.h" -#include "property.h" - -inline float string_read_float( const char* string ){ - return static_cast( atof( string ) ); -} - -inline int string_read_int( const char* string ){ - return atoi( string ); -} - -inline bool char_is_whitespace( char c ){ - return c == ' ' || c == '\t'; -} - -inline const char* string_remove_whitespace( const char* string ){ - for (;; ) - { - if ( !char_is_whitespace( *string ) ) { - break; - } - ++string; - } - return string; -} - -inline const char* string_remove_zeros( const char* string ){ - for (;; ) - { - char c = *string; - if ( c != '0' ) { - break; - } - ++string; - } - return string; -} - -inline const char* string_remove_sign( const char* string ){ - if ( *string == '-' || *string == '+' ) { // signed zero - acceptable - return ++string; - } - return string; -} - -inline bool string_is_unsigned_zero( const char* string ){ - for (; *string != '\0'; ++string ) - { - if ( *string != '0' ) { - return false; - } - } - return true; -} - -inline bool string_is_signed_zero( const char* string ){ - return string_is_unsigned_zero( string_remove_sign( string ) ); -} - -//[whitespaces][+|-][nnnnn][.nnnnn][e|E[+|-]nnnn] -//(where whitespaces are any tab or space character and nnnnn may be any number of digits) -inline bool string_is_float_zero( const char* string ){ - string = string_remove_whitespace( string ); - if ( string_empty( string ) ) { - return false; - } - - string = string_remove_sign( string ); - if ( string_empty( string ) ) { - // no whole number or fraction part - return false; - } - - // whole-number part - string = string_remove_zeros( string ); - if ( string_empty( string ) ) { - // no fraction or exponent - return true; - } - if ( *string == '.' ) { - // fraction part - if ( *string++ != '0' ) { - // invalid fraction - return false; - } - string = string_remove_zeros( ++string ); - if ( string_empty( string ) ) { - // no exponent - return true; - } - } - if ( *string == 'e' || *string == 'E' ) { - // exponent part - string = string_remove_sign( ++string ); - if ( *string++ != '0' ) { - // invalid exponent - return false; - } - string = string_remove_zeros( ++string ); - if ( string_empty( string ) ) { - // no trailing whitespace - return true; - } - } - string = string_remove_whitespace( string ); - return string_empty( string ); -} - -inline double buffer_parse_floating_literal( const char*& buffer ){ - return strtod( buffer, const_cast( &buffer ) ); -} - -inline int buffer_parse_signed_decimal_integer_literal( const char*& buffer ){ - return strtol( buffer, const_cast( &buffer ), 10 ); -} - -inline int buffer_parse_unsigned_decimal_integer_literal( const char*& buffer ){ - return strtoul( buffer, const_cast( &buffer ), 10 ); -} - -// [+|-][nnnnn][.nnnnn][e|E[+|-]nnnnn] -inline bool string_parse_float( const char* string, float& f ){ - if ( string_empty( string ) ) { - return false; - } - f = float(buffer_parse_floating_literal( string ) ); - return string_empty( string ); -} - -// format same as float -inline bool string_parse_double( const char* string, double& f ){ - if ( string_empty( string ) ) { - return false; - } - f = buffer_parse_floating_literal( string ); - return string_empty( string ); -} - -// -template -inline bool string_parse_vector3( const char* string, BasicVector3& v ){ - if ( string_empty( string ) || *string == ' ' ) { - return false; - } - v[0] = float(buffer_parse_floating_literal( string ) ); - if ( *string++ != ' ' ) { - return false; - } - v[1] = float(buffer_parse_floating_literal( string ) ); - if ( *string++ != ' ' ) { - return false; - } - v[2] = float(buffer_parse_floating_literal( string ) ); - return string_empty( string ); -} - -template -inline bool string_parse_vector( const char* string, Float* first, Float* last ){ - if ( first != last && ( string_empty( string ) || *string == ' ' ) ) { - return false; - } - for (;; ) - { - *first = float(buffer_parse_floating_literal( string ) ); - if ( ++first == last ) { - return string_empty( string ); - } - if ( *string++ != ' ' ) { - return false; - } - } -} - -// decimal signed integer -inline bool string_parse_int( const char* string, int& i ){ - if ( string_empty( string ) ) { - return false; - } - i = buffer_parse_signed_decimal_integer_literal( string ); - return string_empty( string ); -} - -// decimal unsigned integer -inline bool string_parse_size( const char* string, std::size_t& i ){ - if ( string_empty( string ) ) { - return false; - } - i = buffer_parse_unsigned_decimal_integer_literal( string ); - return string_empty( string ); -} - - -#define RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) return false; } while (0) - -inline void Tokeniser_unexpectedError( Tokeniser& tokeniser, const char* token, const char* expected ){ - globalErrorStream() << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n"; -} - - -inline bool Tokeniser_getFloat( Tokeniser& tokeniser, float& f ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_float( token, f ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#number" ); - return false; -} - -inline bool Tokeniser_getDouble( Tokeniser& tokeniser, double& f ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_double( token, f ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#number" ); - return false; -} - -inline bool Tokeniser_getInteger( Tokeniser& tokeniser, int& i ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_int( token, i ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#integer" ); - return false; -} - -inline bool Tokeniser_getSize( Tokeniser& tokeniser, std::size_t& i ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_size( token, i ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#unsigned-integer" ); - return false; -} - -inline bool Tokeniser_nextTokenMatches( Tokeniser& tokeniser, const char* expected ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_equal( token, expected ) ) { - return true; - } - tokeniser.ungetToken(); - return false; -} - -inline bool Tokeniser_parseToken( Tokeniser& tokeniser, const char* expected ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_equal( token, expected ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, expected ); - return false; -} - -inline bool Tokeniser_nextTokenIsDigit( Tokeniser& tokeniser ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - return false; - } - char c = *token; - tokeniser.ungetToken(); - return std::isdigit( c ) != 0; -} - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream, const Vector3& v ){ - return outputStream << '(' << v.x() << ' ' << v.y() << ' ' << v.z() << ')'; -} - - -template<> -struct PropertyImpl { - static void Export(const bool &self, const Callback &returnz) { - returnz(self ? "true" : "false"); - } - - static void Import(bool &self, const char *value) { - self = string_equal(value, "true"); - } -}; - -template<> -struct PropertyImpl { - static void Export(const int &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%d", self); - returnz(buffer); - } - - static void Import(int &self, const char *value) { - if (!string_parse_int(value, self)) { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const std::size_t &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(self)); - returnz(buffer); - } - - static void Import(std::size_t &self, const char *value) { - int i; - if (string_parse_int(value, i) && i >= 0) { - self = i; - } else { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const float &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%g", self); - returnz(buffer); - } - - static void Import(float &self, const char *value) { - if (!string_parse_float(value, self)) { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const Vector3 &self, const Callback &returnz) { - char buffer[64]; - sprintf(buffer, "%g %g %g", self[0], self[1], self[2]); - returnz(buffer); - } - - static void Import(Vector3 &self, const char *value) { - if (!string_parse_vector3(value, self)) { - self = Vector3(0, 0, 0); - } - } -}; - -#endif diff --git a/libs/texturelib.h b/libs/texturelib.h deleted file mode 100644 index d9da1e8..0000000 --- a/libs/texturelib.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TEXTURELIB_H ) -#define INCLUDED_TEXTURELIB_H - -#include "generic/vector.h" -typedef Vector3 Colour3; -typedef unsigned int GLuint; -class LoadImageCallback; - -// describes a GL texture -struct qtexture_t -{ - qtexture_t( const LoadImageCallback& load, const char* name ) : load( load ), name( name ){ - } - const LoadImageCallback& load; - const char* name; - std::size_t width, height; - GLuint texture_number; // gl bind number - Colour3 color; // for flat shade mode - int surfaceFlags, contentFlags, value; -}; - -#endif diff --git a/libs/transformlib.h b/libs/transformlib.h deleted file mode 100644 index 10dc14f..0000000 --- a/libs/transformlib.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TRANSFORMLIB_H ) -#define INCLUDED_TRANSFORMLIB_H - -#include "generic/constant.h" -#include "math/matrix.h" -#include "math/quaternion.h" - - -/// \brief A transform node. -class TransformNode -{ -public: -STRING_CONSTANT( Name, "TransformNode" ); -/// \brief Returns the transform which maps the node's local-space into the local-space of its parent node. -virtual const Matrix4& localToParent() const = 0; -}; - -/// \brief A transform node which has no effect. -class IdentityTransform : public TransformNode -{ -public: -/// \brief Returns the identity matrix. -const Matrix4& localToParent() const { - return g_matrix4_identity; -} -}; - -/// \brief A transform node which stores a generic transformation matrix. -class MatrixTransform : public TransformNode -{ -Matrix4 m_localToParent; -public: -MatrixTransform() : m_localToParent( g_matrix4_identity ){ -} - -Matrix4& localToParent(){ - return m_localToParent; -} -/// \brief Returns the stored local->parent transform. -const Matrix4& localToParent() const { - return m_localToParent; -} -}; - - -#include "generic/callback.h" - -typedef Vector3 Translation; -typedef Quaternion Rotation; -typedef Vector3 Scale; - -inline Matrix4 matrix4_transform_for_components( const Translation& translation, const Rotation& rotation, const Scale& scale ){ - Matrix4 result( matrix4_rotation_for_quaternion_quantised( rotation ) ); - vector4_to_vector3( result.x() ) *= scale.x(); - vector4_to_vector3( result.y() ) *= scale.y(); - vector4_to_vector3( result.z() ) *= scale.z(); - result.tx() = translation.x(); - result.ty() = translation.y(); - result.tz() = translation.z(); - return result; -} - -typedef bool TransformModifierType; -const TransformModifierType TRANSFORM_PRIMITIVE = false; -const TransformModifierType TRANSFORM_COMPONENT = true; - -/// \brief A transformable scene-graph instance. -/// -/// A transformable instance may be translated, rotated or scaled. -/// The state of the instanced node's geometrical representation -/// will be the product of its geometry and the transforms of each -/// of its instances, applied in the order they appear in a graph -/// traversal. -/// Freezing the transform on an instance will cause its transform -/// to be permanently applied to the geometry of the node. -class Transformable -{ -public: -STRING_CONSTANT( Name, "Transformable" ); - -virtual void setType( TransformModifierType type ) = 0; -virtual void setTranslation( const Translation& value ) = 0; -virtual void setRotation( const Rotation& value ) = 0; -virtual void setScale( const Scale& value ) = 0; -virtual void freezeTransform() = 0; -}; - -const Translation c_translation_identity = Translation( 0, 0, 0 ); -const Rotation c_rotation_identity = c_quaternion_identity; -const Scale c_scale_identity = Scale( 1, 1, 1 ); - - -class TransformModifier : public Transformable -{ -Translation m_translation; -Rotation m_rotation; -Scale m_scale; -Callback m_changed; -Callback m_apply; -TransformModifierType m_type; -public: - -TransformModifier( const Callback& changed, const Callback& apply ) : - m_translation( c_translation_identity ), - m_rotation( c_quaternion_identity ), - m_scale( c_scale_identity ), - m_changed( changed ), - m_apply( apply ), - m_type( TRANSFORM_PRIMITIVE ){ -} -void setType( TransformModifierType type ){ - m_type = type; -} -TransformModifierType getType() const { - return m_type; -} -void setTranslation( const Translation& value ){ - m_translation = value; - m_changed(); -} -void setRotation( const Rotation& value ){ - m_rotation = value; - m_changed(); -} -void setScale( const Scale& value ){ - m_scale = value; - m_changed(); -} -void freezeTransform(){ - if ( m_translation != c_translation_identity - || m_rotation != c_rotation_identity - || m_scale != c_scale_identity ) { - m_apply(); - m_translation = c_translation_identity; - m_rotation = c_rotation_identity; - m_scale = c_scale_identity; - m_changed(); - } -} -const Translation& getTranslation() const { - return m_translation; -} -const Rotation& getRotation() const { - return m_rotation; -} -const Scale& getScale() const { - return m_scale; -} -Matrix4 calculateTransform() const { - return matrix4_transform_for_components( getTranslation(), getRotation(), getScale() ); -} -}; - - -#endif diff --git a/libs/traverselib.h b/libs/traverselib.h deleted file mode 100644 index d19ca9b..0000000 --- a/libs/traverselib.h +++ /dev/null @@ -1,362 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TRAVERSELIB_H ) -#define INCLUDED_TRAVERSELIB_H - -#include "debugging/debugging.h" - -#include "scenelib.h" -#include "undolib.h" -#include "container/container.h" - -#include -#include -#include - -class TraversableObserverInsertOutputIterator -{ -protected: -scene::Traversable::Observer* m_observer; -public: -typedef std::output_iterator_tag iterator_category; -typedef void difference_type; -typedef void value_type; -typedef void pointer; -typedef void reference; - -TraversableObserverInsertOutputIterator( scene::Traversable::Observer* observer ) - : m_observer( observer ){ -} -TraversableObserverInsertOutputIterator& operator=( const NodeReference& node ){ - m_observer->insert( node ); - return *this; -} -TraversableObserverInsertOutputIterator& operator=( const NodeSmartReference& node ){ - m_observer->insert( node ); - return *this; -} -TraversableObserverInsertOutputIterator& operator*() { - return *this; -} -TraversableObserverInsertOutputIterator& operator++() { - return *this; -} -TraversableObserverInsertOutputIterator& operator++( int ) { - return *this; -} -}; - -class TraversableObserverEraseOutputIterator -{ -protected: -scene::Traversable::Observer* m_observer; -public: -typedef std::output_iterator_tag iterator_category; -typedef void difference_type; -typedef void value_type; -typedef void pointer; -typedef void reference; - -TraversableObserverEraseOutputIterator( scene::Traversable::Observer* observer ) - : m_observer( observer ){ -} -TraversableObserverEraseOutputIterator& operator=( const NodeReference& node ){ - m_observer->erase( node ); - return *this; -} -TraversableObserverEraseOutputIterator& operator=( const NodeSmartReference& node ){ - m_observer->erase( node ); - return *this; -} -TraversableObserverEraseOutputIterator& operator*() { - return *this; -} -TraversableObserverEraseOutputIterator& operator++() { - return *this; -} -TraversableObserverEraseOutputIterator& operator++( int ) { - return *this; -} -}; -typedef UnsortedSet UnsortedNodeSet; - -/// \brief Calls \p observer->\c insert for each node that exists only in \p other and \p observer->\c erase for each node that exists only in \p self -inline void nodeset_diff( const UnsortedNodeSet& self, const UnsortedNodeSet& other, scene::Traversable::Observer* observer ){ - std::vector sorted( self.begin(), self.end() ); - std::vector other_sorted( other.begin(), other.end() ); - - std::sort( sorted.begin(), sorted.end() ); - std::sort( other_sorted.begin(), other_sorted.end() ); - - std::set_difference( sorted.begin(), sorted.end(), other_sorted.begin(), other_sorted.end(), TraversableObserverEraseOutputIterator( observer ) ); - std::set_difference( other_sorted.begin(), other_sorted.end(), sorted.begin(), sorted.end(), TraversableObserverInsertOutputIterator( observer ) ); -} - -/// \brief A sequence of node references which notifies an observer of inserts and deletions, and uses the global undo system to provide undo for modifications. -class TraversableNodeSet : public scene::Traversable -{ -UnsortedNodeSet m_children; -UndoableObject m_undo; -Observer* m_observer; - -void copy( const TraversableNodeSet& other ){ - m_children = other.m_children; -} -void notifyInsertAll(){ - if ( m_observer ) { - for ( UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i ) - { - m_observer->insert( *i ); - } - } -} -void notifyEraseAll(){ - if ( m_observer ) { - for ( UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i ) - { - m_observer->erase( *i ); - } - } -} -public: -TraversableNodeSet() - : m_undo( *this ), m_observer( 0 ){ -} -TraversableNodeSet( const TraversableNodeSet& other ) - : scene::Traversable( other ), m_undo( *this ), m_observer( 0 ){ - copy( other ); - notifyInsertAll(); -} -~TraversableNodeSet(){ - notifyEraseAll(); -} -TraversableNodeSet& operator=( const TraversableNodeSet& other ){ -#if 1 // optimised change-tracking using diff algorithm - if ( m_observer ) { - nodeset_diff( m_children, other.m_children, m_observer ); - } - copy( other ); -#else - TraversableNodeSet tmp( other ); - tmp.swap( *this ); -#endif - return *this; -} -void swap( TraversableNodeSet& other ){ - std::swap( m_children, other.m_children ); - std::swap( m_observer, other.m_observer ); -} - -void attach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == 0, "TraversableNodeSet::attach: observer cannot be attached" ); - m_observer = observer; - notifyInsertAll(); -} -void detach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == observer, "TraversableNodeSet::detach: observer cannot be detached" ); - notifyEraseAll(); - m_observer = 0; -} -/// \brief \copydoc scene::Traversable::insert() -void insert( scene::Node& node ){ - m_undo.save(); - - ASSERT_MESSAGE( m_children.find( NodeSmartReference( node ) ) == m_children.end(), "TraversableNodeSet::insert - element already exists" ); - - m_children.insert( NodeSmartReference( node ) ); - - if ( m_observer ) { - m_observer->insert( node ); - } -} -/// \brief \copydoc scene::Traversable::erase() -void erase( scene::Node& node ){ - m_undo.save(); - - ASSERT_MESSAGE( m_children.find( NodeSmartReference( node ) ) != m_children.end(), "TraversableNodeSet::erase - failed to find element" ); - - if ( m_observer ) { - m_observer->erase( node ); - } - - m_children.erase( NodeSmartReference( node ) ); -} -/// \brief \copydoc scene::Traversable::traverse() -void traverse( const Walker& walker ){ - UnsortedNodeSet::iterator i = m_children.begin(); - while ( i != m_children.end() ) - { - // post-increment the iterator - Node_traverseSubgraph( *i++, walker ); - // the Walker can safely remove the current node from - // this container without invalidating the iterator - } -} -/// \brief \copydoc scene::Traversable::empty() -bool empty() const { - return m_children.empty(); -} - -void instanceAttach( MapFile* map ){ - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - m_undo.instanceDetach( map ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( TraversableNodeSet& self, TraversableNodeSet& other ){ - self.swap( other ); -} -} - - -class TraversableNode : public scene::Traversable -{ -public: -TraversableNode() : m_node( 0 ), m_observer( 0 ){ -} - -// traverse -void attach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == 0, "TraversableNode::attach - cannot attach observer" ); - m_observer = observer; - if ( m_node != 0 ) { - m_observer->insert( *m_node ); - } -} -void detach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == observer, "TraversableNode::detach - cannot detach observer" ); - if ( m_node != 0 ) { - m_observer->erase( *m_node ); - } - m_observer = 0; -} -void insert( scene::Node& node ){ - ASSERT_MESSAGE( m_node == 0, "TraversableNode::insert - element already exists" ); - - m_node = &node; - node.IncRef(); - - if ( m_observer != 0 ) { - m_observer->insert( node ); - } -} -void erase( scene::Node& node ){ - ASSERT_MESSAGE( m_node == &node, "TraversableNode::erase - failed to find element" ); - - if ( m_observer != 0 ) { - m_observer->erase( node ); - } - - m_node = 0; - node.DecRef(); -} -void traverse( const scene::Traversable::Walker& walker ){ - if ( m_node != 0 ) { - Node_traverseSubgraph( *m_node, walker ); - } -} -bool empty() const { - return m_node != 0; -} - -scene::Node& get(){ - return *m_node; -} - -private: -scene::Node* m_node; -Observer* m_observer; -}; - -class TraversableObserverInsert -{ -scene::Node& node; -public: -TraversableObserverInsert( scene::Node& node ) : node( node ){ -} -void operator()( scene::Traversable::Observer& observer ) const { - observer.insert( node ); -} -}; - -class TraversableObserverErase -{ -scene::Node& node; -public: -TraversableObserverErase( scene::Node& node ) : node( node ){ -} -void operator()( scene::Traversable::Observer& observer ) const { - observer.erase( node ); -} -}; - -class TraversableObserverPairRelay : public ReferencePair, public scene::Traversable::Observer -{ -public: -void insert( scene::Node& node ){ - forEach( TraversableObserverInsert( node ) ); -} -void erase( scene::Node& node ){ - forEach( TraversableObserverErase( node ) ); -} -}; - -template -class ReferenceSet -{ -typedef UniqueSet Values; -Values m_values; -public: -void attach( Type& t ){ - m_values.insert( &t ); -} -void detach( Type& t ){ - m_values.erase( &t ); -} -template -void forEach( const Functor& functor ){ - for ( typename Values::iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - functor( *( *i ) ); - } -} -}; - -class TraversableObserverRelay : public ReferenceSet, public scene::Traversable::Observer -{ -public: -void insert( scene::Node& node ){ - forEach( TraversableObserverInsert( node ) ); -} -void erase( scene::Node& node ){ - forEach( TraversableObserverErase( node ) ); -} -}; - - -#endif diff --git a/libs/typesystem.h b/libs/typesystem.h deleted file mode 100644 index 5dc6778..0000000 --- a/libs/typesystem.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TYPESYSTEM_H ) -#define INCLUDED_TYPESYSTEM_H - - -#include -#include -#include "generic/callback.h" -#include "generic/static.h" - -class InitialiserList -{ -typedef std::list > Initialisers; -Initialisers m_initialisers; -mutable bool m_initialised; -public: -InitialiserList() : m_initialised( false ){ -} -void addInitialiser( const Callback& callback ){ - m_initialisers.push_back( callback ); -} -void initialise() const { - if ( !m_initialised ) { - m_initialised = true; - - for ( Initialisers::const_iterator i = m_initialisers.begin(); i != m_initialisers.end(); ++i ) - { - ( *i )( ); - } - } -} -}; - -//--Type System------------------- - -class TypeSystemInitialiser : public InitialiserList -{ -}; - -typedef SmartStatic StaticTypeSystemInitialiser; - -class TypeSystemRef : public StaticTypeSystemInitialiser -{ -public: -TypeSystemRef(){ - StaticTypeSystemInitialiser::instance().initialise(); -} -}; - - - -typedef std::size_t TypeId; -typedef void*( *TypeCast )( void* ); - -template -class TypeCastTable -{ -TypeCast m_casts[SIZE]; -public: -TypeCastTable(){ - std::uninitialized_fill( m_casts, m_casts + SIZE, TypeCast( 0 ) ); -} -void install( TypeId typeId, TypeCast typeCast ){ - m_casts[typeId] = typeCast; -} -void* cast( TypeId typeId, void* p ){ - TypeCast typeCast = m_casts[typeId]; - if ( typeCast != 0 ) { - return typeCast( p ); - } - return 0; -} -}; - -template -class CastInstaller -{ -public: -static void install( TypeCastTable& table ){ - table.install( Type::getTypeId(), Cast::cast ); -} -}; - -template -class IdentityCast -{ -public: -static void* cast( void* p ){ - return p; -} -}; - -template -class StaticCast -{ -public: -static void* cast( void* p ){ - return static_cast( reinterpret_cast( p ) ); -} -}; - -template -class NullType -{ -}; - -template -class ContainedCast -{ -public: -static void* cast( void* p ){ - return &reinterpret_cast( p )->get( NullType() ); -} -}; - - -#endif diff --git a/libs/uilib/Makefile b/libs/uilib/Makefile deleted file mode 100644 index 62d24dc..0000000 --- a/libs/uilib/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -LIB_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - uilib.o - -# binary target -../libuilib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -uilib.o: uilib.cpp uilib.h - -clean: - -rm -f *.o ../libuilib.a diff --git a/libs/uilib/uilib.cpp b/libs/uilib/uilib.cpp deleted file mode 100644 index 46d3332..0000000 --- a/libs/uilib/uilib.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include "uilib.h" - -#include - -#include - -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/window.h" - -namespace ui { - -bool init(int *argc, char **argv[], char const *parameter_string, char const **error) -{ - gtk_disable_setlocale(); - static GOptionEntry entries[] = {{}}; - char const *translation_domain = NULL; - GError *gerror = NULL; - bool ret = gtk_init_with_args(argc, argv, parameter_string, entries, translation_domain, &gerror) != 0; - if (!ret) { - *error = gerror->message; - } - return ret; -} - -void main() -{ - gtk_main(); -} - -void process() -{ - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -#define IMPL(T, F) template<> _IMPL(T, F) -#define _IMPL(T, F) struct verify { using self = T; static self test(self it) { return self::from(F(it)); } } - -template -struct verify; - -template _IMPL(T,); - -template -using pointer_remove_const = std::add_pointer< - typename std::remove_const< - typename std::remove_pointer::type - >::type - >; - -#define this (verify::test(*static_cast(const_cast::type>(this)))) - -IMPL(Editable, GTK_EDITABLE); - -void IEditable::editable(bool value) -{ - gtk_editable_set_editable(this, value); -} - -IMPL(TreeModel, GTK_TREE_MODEL); - -IMPL(Widget, GTK_WIDGET); - -Widget::Widget(ui::New_t) : Widget(nullptr) -{ -} - -Window IWidget::window() -{ - return Window::from(gtk_widget_get_toplevel(this)); -} - -const char * -IWidget::file_dialog(bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - return ::file_dialog(this.window(), open, title, path, pattern, want_load, want_import, want_save); -} - -bool IWidget::visible() -{ - return gtk_widget_get_visible(this) != 0; -} - -void IWidget::visible(bool shown) -{ - if (shown) { - this.show(); - } else { - this.hide(); - } -} - -void IWidget::show() -{ - gtk_widget_show(this); -} - -void IWidget::hide() -{ - gtk_widget_hide(this); -} - -Dimensions IWidget::dimensions() -{ - GtkAllocation allocation; - gtk_widget_get_allocation(this, &allocation); - return Dimensions{allocation.width, allocation.height}; -} - -void IWidget::dimensions(int width, int height) -{ - gtk_widget_set_size_request(this, width, height); -} - -void IWidget::destroy() -{ - gtk_widget_destroy(this); -} - -IMPL(Container, GTK_CONTAINER); - -void IContainer::add(Widget widget) -{ - gtk_container_add(this, widget); -} - -void IContainer::remove(Widget widget) -{ - gtk_container_remove(this, widget); -} - -IMPL(Bin, GTK_BIN); - -IMPL(Window, GTK_WINDOW); - -Window::Window(window_type type) : Window(GTK_WINDOW(gtk_window_new( - type == window_type::TOP ? GTK_WINDOW_TOPLEVEL : - type == window_type::POPUP ? GTK_WINDOW_POPUP : - GTK_WINDOW_TOPLEVEL - ))) -{ -} - -Window IWindow::create_dialog_window(const char *title, void func(), void *data, int default_w, int default_h) -{ - return Window(::create_dialog_window(this, title, func, data, default_w, default_h)); -} - -Window IWindow::create_modal_dialog_window(const char *title, ModalDialog &dialog, int default_w, int default_h) -{ - return Window(::create_modal_dialog_window(this, title, dialog, default_w, default_h)); -} - -Window IWindow::create_floating_window(const char *title) -{ - return Window(::create_floating_window(title, this)); -} - -std::uint64_t IWindow::on_key_press(bool (*f)(Widget widget, _GdkEventKey *event, void *extra), void *extra) -{ - using f_t = decltype(f); - struct user_data { - f_t f; - void *extra; - } *pass = new user_data{f, extra}; - auto dtor = [](user_data *data, GClosure *) { - delete data; - }; - auto func = [](_GtkWidget *widget, GdkEventKey *event, user_data *args) -> bool { - return args->f(Widget::from(widget), event, args->extra); - }; - auto clos = g_cclosure_new(G_CALLBACK(+func), pass, reinterpret_cast(+dtor)); - return g_signal_connect_closure(G_OBJECT(this), "key-press-event", clos, false); -} - -void IWindow::add_accel_group(AccelGroup group) -{ - gtk_window_add_accel_group(this, group); -} - -IMPL(Alignment, GTK_ALIGNMENT); - -Alignment::Alignment(float xalign, float yalign, float xscale, float yscale) - : Alignment(GTK_ALIGNMENT(gtk_alignment_new(xalign, yalign, xscale, yscale))) -{ -} - -IMPL(Frame, GTK_FRAME); - -Frame::Frame(const char *label) : Frame(GTK_FRAME(gtk_frame_new(label))) -{ -} - -IMPL(Button, GTK_BUTTON); - -Button::Button(ui::New_t) : Button(GTK_BUTTON(gtk_button_new())) -{ -} - -Button::Button(const char *label) : Button(GTK_BUTTON(gtk_button_new_with_label(label))) -{ -} - -IMPL(ToggleButton, GTK_TOGGLE_BUTTON); - -bool IToggleButton::active() const -{ - return gtk_toggle_button_get_active(this) != 0; -} - -void IToggleButton::active(bool value) -{ - gtk_toggle_button_set_active(this, value); -} - -IMPL(CheckButton, GTK_CHECK_BUTTON); - -CheckButton::CheckButton(ui::New_t) : CheckButton(GTK_CHECK_BUTTON(gtk_check_button_new())) -{ -} - -CheckButton::CheckButton(const char *label) : CheckButton(GTK_CHECK_BUTTON(gtk_check_button_new_with_label(label))) -{ -} - -IMPL(MenuItem, GTK_MENU_ITEM); - -MenuItem::MenuItem(ui::New_t) : MenuItem(GTK_MENU_ITEM(gtk_menu_item_new())) -{ -} - -MenuItem::MenuItem(const char *label, bool mnemonic) : MenuItem( - GTK_MENU_ITEM((mnemonic ? gtk_menu_item_new_with_mnemonic : gtk_menu_item_new_with_label)(label))) -{ -} - -IMPL(TearoffMenuItem, GTK_TEAROFF_MENU_ITEM); - -TearoffMenuItem::TearoffMenuItem(ui::New_t) : TearoffMenuItem(GTK_TEAROFF_MENU_ITEM(gtk_tearoff_menu_item_new())) -{ -} - -IMPL(ComboBoxText, GTK_COMBO_BOX_TEXT); - -ComboBoxText::ComboBoxText(ui::New_t) : ComboBoxText(GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new_with_entry())) -{ -} - -IMPL(ScrolledWindow, GTK_SCROLLED_WINDOW); - -ScrolledWindow::ScrolledWindow(ui::New_t) : ScrolledWindow(GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(nullptr, nullptr))) -{ -} - -void IScrolledWindow::overflow(Policy x, Policy y) -{ - gtk_scrolled_window_set_policy(this, static_cast(x), static_cast(y)); -} - -IMPL(Box, GTK_BOX); - -void IBox::pack_start(ui::Widget child, bool expand, bool fill, unsigned int padding) -{ - gtk_box_pack_start(this, child, expand, fill, padding); -} - -void IBox::pack_end(ui::Widget child, bool expand, bool fill, unsigned int padding) -{ - gtk_box_pack_end(this, child, expand, fill, padding); -} - -IMPL(VBox, GTK_VBOX); - -VBox::VBox(bool homogenous, int spacing) : VBox(GTK_VBOX(gtk_vbox_new(homogenous, spacing))) -{ -} - -IMPL(HBox, GTK_HBOX); - -HBox::HBox(bool homogenous, int spacing) : HBox(GTK_HBOX(gtk_hbox_new(homogenous, spacing))) -{ -} - -IMPL(HPaned, GTK_HPANED); - -HPaned::HPaned(ui::New_t) : HPaned(GTK_HPANED(gtk_hpaned_new())) -{ -} - -IMPL(VPaned, GTK_VPANED); - -VPaned::VPaned(ui::New_t) : VPaned(GTK_VPANED(gtk_vpaned_new())) -{ -} - -IMPL(Menu, GTK_MENU); - -Menu::Menu(ui::New_t) : Menu(GTK_MENU(gtk_menu_new())) -{ -} - -IMPL(Table, GTK_TABLE); - -Table::Table(std::size_t rows, std::size_t columns, bool homogenous) : Table( - GTK_TABLE(gtk_table_new(rows, columns, homogenous)) - ) -{ -} - -void ITable::attach(Widget child, TableAttach attach, TableAttachOptions options, TablePadding padding) { - gtk_table_attach(this, child, - attach.left, attach.right, attach.top, attach.bottom, - static_cast(options.x), static_cast(options.y), - padding.x, padding.y - ); -} - -IMPL(TextView, GTK_TEXT_VIEW); - -TextView::TextView(ui::New_t) : TextView(GTK_TEXT_VIEW(gtk_text_view_new())) -{ -} - -void ITextView::text(char const *str) -{ - GtkTextBuffer *buffer = gtk_text_view_get_buffer(this); - gtk_text_buffer_set_text(buffer, str, -1); -} - -TreeView::TreeView(ui::New_t) : TreeView(GTK_TREE_VIEW(gtk_tree_view_new())) -{ -} - -TreeView::TreeView(TreeModel model) : TreeView(GTK_TREE_VIEW(gtk_tree_view_new_with_model(model))) -{ -} - -IMPL(Label, GTK_LABEL); - -Label::Label(const char *label) : Label(GTK_LABEL(gtk_label_new(label))) -{ -} - -void ILabel::text(char const *str) -{ - gtk_label_set_text(this, str); -} - -IMPL(Image, GTK_IMAGE); - -Image::Image(ui::New_t) : Image(GTK_IMAGE(gtk_image_new())) -{ -} - -IMPL(Entry, GTK_ENTRY); - -Entry::Entry(ui::New_t) : Entry(GTK_ENTRY(gtk_entry_new())) -{ -} - -Entry::Entry(std::size_t max_length) : Entry(ui::New) -{ - gtk_entry_set_max_length(this, static_cast(max_length)); -} - -char const *IEntry::text() -{ - return gtk_entry_get_text(this); -} - -void IEntry::text(char const *str) -{ - return gtk_entry_set_text(this, str); -} - -IMPL(SpinButton, GTK_SPIN_BUTTON); - -SpinButton::SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits) : SpinButton( - GTK_SPIN_BUTTON(gtk_spin_button_new(adjustment, climb_rate, digits))) -{ -} - -IMPL(HScale, GTK_HSCALE); - -HScale::HScale(Adjustment adjustment) : HScale(GTK_HSCALE(gtk_hscale_new(adjustment))) -{ -} - -HScale::HScale(double min, double max, double step) : HScale(GTK_HSCALE(gtk_hscale_new_with_range(min, max, step))) -{ -} - -IMPL(Adjustment, GTK_ADJUSTMENT); - -Adjustment::Adjustment(double value, - double lower, double upper, - double step_increment, double page_increment, - double page_size) - : Adjustment( - GTK_ADJUSTMENT(gtk_adjustment_new(value, lower, upper, step_increment, page_increment, page_size))) -{ -} - -IMPL(CellRendererText, GTK_CELL_RENDERER_TEXT); - -CellRendererText::CellRendererText(ui::New_t) : CellRendererText(GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new())) -{ -} - -IMPL(TreeViewColumn, GTK_TREE_VIEW_COLUMN); - -TreeViewColumn::TreeViewColumn(const char *title, CellRenderer renderer, - std::initializer_list attributes) - : TreeViewColumn(gtk_tree_view_column_new_with_attributes(title, renderer, nullptr)) -{ - for (auto &it : attributes) { - gtk_tree_view_column_add_attribute(this, renderer, it.attribute, it.column); - } -} - -IMPL(AccelGroup, GTK_ACCEL_GROUP); - -AccelGroup::AccelGroup(ui::New_t) : AccelGroup(GTK_ACCEL_GROUP(gtk_accel_group_new())) -{ -} - -IMPL(ListStore, GTK_LIST_STORE); - -void IListStore::clear() -{ - gtk_list_store_clear(this); -} - -void IListStore::append() -{ - gtk_list_store_append(this, nullptr); -} - -IMPL(TreeStore, GTK_TREE_STORE); - -// IMPL(TreePath, GTK_TREE_PATH); - -TreePath::TreePath(ui::New_t) : TreePath(gtk_tree_path_new()) -{ -} - -TreePath::TreePath(const char *path) : TreePath(gtk_tree_path_new_from_string(path)) -{ -} - -// Custom - -#if GTK_TARGET == 3 - -IMPL(GLArea, (void *)); - -#elif GTK_TARGET == 2 - -IMPL(GLArea, GTK_DRAWING_AREA); - -#endif - -guint IGLArea::on_render(GCallback pFunction, void *data) -{ -#if GTK_TARGET == 3 - return this.connect("render", pFunction, data); -#endif -#if GTK_TARGET == 2 - return this.connect("expose_event", pFunction, data); -#endif -} - -// global - -Window root{ui::null}; - -alert_response alert(Window parent, std::string text, std::string title, alert_type type, alert_icon icon) -{ - auto ret = gtk_MessageBox(parent, text.c_str(), - title.c_str(), - type == alert_type::OK ? eMB_OK : - type == alert_type::OKCANCEL ? eMB_OKCANCEL : - type == alert_type::YESNO ? eMB_YESNO : - type == alert_type::YESNOCANCEL ? eMB_YESNOCANCEL : - type == alert_type::NOYES ? eMB_NOYES : - eMB_OK, - icon == alert_icon::Default ? eMB_ICONDEFAULT : - icon == alert_icon::Error ? eMB_ICONERROR : - icon == alert_icon::Warning ? eMB_ICONWARNING : - icon == alert_icon::Question ? eMB_ICONQUESTION : - icon == alert_icon::Asterisk ? eMB_ICONASTERISK : - eMB_ICONDEFAULT - ); - return - ret == eIDOK ? alert_response::OK : - ret == eIDCANCEL ? alert_response::CANCEL : - ret == eIDYES ? alert_response::YES : - ret == eIDNO ? alert_response::NO : - alert_response::OK; -} - -} diff --git a/libs/uilib/uilib.h b/libs/uilib/uilib.h deleted file mode 100644 index ebe6ef9..0000000 --- a/libs/uilib/uilib.h +++ /dev/null @@ -1,649 +0,0 @@ -#ifndef INCLUDED_UILIB_H -#define INCLUDED_UILIB_H - -#include -#include - -struct _GdkEventKey; -struct _GtkAccelGroup; -struct _GtkAdjustment; -struct _GtkAlignment; -struct _GtkBin; -struct _GtkBox; -struct _GtkButton; -struct _GtkCellEditable; -struct _GtkCellRenderer; -struct _GtkCellRendererText; -struct _GtkCheckButton; -struct _GtkCheckMenuItem; -struct _GtkComboBox; -struct _GtkComboBoxText; -struct _GtkContainer; -struct _GtkDialog; -struct _GtkEditable; -struct _GtkEntry; -struct _GtkEntryCompletion; -struct _GtkFrame; -struct _GtkHBox; -struct _GtkHPaned; -struct _GtkHScale; -struct _GtkImage; -struct _GtkItem; -struct _GtkLabel; -struct _GtkListStore; -struct _GtkTreeIter; -struct _GtkMenu; -struct _GtkMenuBar; -struct _GtkMenuItem; -struct _GtkMenuShell; -struct _GtkMisc; -struct _GtkObject; -struct _GtkPaned; -struct _GtkRadioButton; -struct _GtkRadioMenuItem; -struct _GtkRadioToolButton; -struct _GtkRange; -struct _GtkScale; -struct _GtkScrolledWindow; -struct _GtkSpinButton; -struct _GtkTable; -struct _GtkTearoffMenuItem; -struct _GtkTextView; -struct _GtkToggleButton; -struct _GtkToggleToolButton; -struct _GtkToolbar; -struct _GtkToolButton; -struct _GtkToolItem; -struct _GtkTreeModel; -struct _GtkTreePath; -struct _GtkTreeSelection; -struct _GtkTreeStore; -struct _GtkTreeView; -struct _GtkTreeViewColumn; -struct _GtkVBox; -struct _GtkVPaned; -struct _GtkWidget; -struct _GtkWindow; -struct _GTypeInstance; - -#if GTK_TARGET == 3 -struct _GtkGLArea; -#endif - -#if GTK_TARGET == 2 -using _GtkGLArea = struct _GtkDrawingArea; -#endif - -struct ModalDialog; - -namespace ui { - -bool init(int *argc, char **argv[], char const *parameter_string, char const **error); - -void main(); - -void process(); - -enum class window_type { - TOP, - POPUP -}; - -enum class Shadow { - NONE, - IN, - OUT, - ETCHED_IN, - ETCHED_OUT -}; - -enum class Policy { - ALWAYS, - AUTOMATIC, - NEVER -}; - -namespace details { - -enum class Convert { - Implicit, Explicit -}; - -template -struct Convertible; - -template -struct Convertible { - operator T() const - { return reinterpret_cast(static_cast(this)->_handle); } -}; - -template -struct Convertible { - explicit operator T() const - { return reinterpret_cast(static_cast(this)->_handle); } -}; - -template -struct All : T ... { - All() - { - }; -}; - -template -struct Mixin; -template -struct Mixin { - using type = All; -}; -template -struct Mixin { - using type = All; -}; -} - -const struct Null {} null = {}; -const struct New_t {} New = {}; - -class Object : - public details::Convertible, - public details::Convertible { -public: -using self = Object *; -using native = _GtkObject *; -native _handle; - -explicit Object(native h) : _handle(h) -{ -} - -explicit operator bool() const -{ return _handle != nullptr; } - -explicit operator void *() const -{ return _handle; } - -void unref() -{ - g_object_unref(_handle); -} - -void ref() -{ - g_object_ref(_handle); -} - -template -gulong connect(char const *detailed_signal, Lambda &&c_handler, void *data); - -template -gulong connect(char const *detailed_signal, Lambda &&c_handler, Object data); -}; -static_assert(sizeof(Object) == sizeof(Object::native), "object slicing"); - -#define WRAP(name, super, T, interfaces, ctors, methods) \ - class name; \ - class I ## name : public details::Convertible { \ -public: \ - using self = name *; \ - methods \ - }; \ - class name : public super, public I ## name, public details::Mixin::type { \ -public: \ - using self = name *; \ - using native = T *; \ -protected: \ - explicit name(native h) noexcept : super(reinterpret_cast(h)) {} \ -public: \ - explicit name(Null n) noexcept : name((native) nullptr) {} \ - explicit name(New_t); \ - static name from(native h) { return name(h); } \ - static name from(void *ptr) { return name((native) ptr); } \ - ctors \ - }; \ - inline bool operator<(name self, name other) { return self._handle < other._handle; } \ - static_assert(sizeof(name) == sizeof(super), "object slicing") - -// https://developer.gnome.org/gtk2/stable/ch01.html - -// GInterface - -WRAP(CellEditable, Object, _GtkCellEditable, (), - , - ); - -WRAP(Editable, Object, _GtkEditable, (), - , - void editable(bool value); - ); - -WRAP(TreeModel, Object, _GtkTreeModel, (), - , - ); - -// GObject - -struct Dimensions { - int width; - int height; -}; - -class Window; -WRAP(Widget, Object, _GtkWidget, (), - , - Window window(); - const char *file_dialog( - bool open, - const char *title, - const char *path = nullptr, - const char *pattern = nullptr, - bool want_load = false, - bool want_import = false, - bool want_save = false - ); - bool visible(); - void visible(bool shown); - void show(); - void hide(); - Dimensions dimensions(); - void dimensions(int width, int height); - void destroy(); - ); - -WRAP(Container, Widget, _GtkContainer, (), - , - void add(Widget widget); - - void remove(Widget widget); - - template - void foreach(Lambda &&lambda); - ); - -WRAP(Bin, Container, _GtkBin, (), - , - ); - -class AccelGroup; -WRAP(Window, Bin, _GtkWindow, (), - explicit Window(window_type type); - , - Window create_dialog_window( - const char *title, - void func(), - void *data, - int default_w = -1, - int default_h = -1 - ); - - Window create_modal_dialog_window( - const char *title, - ModalDialog &dialog, - int default_w = -1, - int default_h = -1 - ); - - Window create_floating_window(const char *title); - - std::uint64_t on_key_press( - bool (*f)(Widget widget, _GdkEventKey *event, void *extra), - void *extra = nullptr - ); - - void add_accel_group(AccelGroup group); - ); - -WRAP(Dialog, Window, _GtkDialog, (), - , - ); - -WRAP(Alignment, Bin, _GtkAlignment, (), - Alignment(float xalign, float yalign, float xscale, float yscale); - , - ); - -WRAP(Frame, Bin, _GtkFrame, (), - explicit Frame(const char *label = nullptr); - , - ); - -WRAP(Button, Bin, _GtkButton, (), - explicit Button(const char *label); - , - ); - -WRAP(ToggleButton, Button, _GtkToggleButton, (), - , - bool active() const; - void active(bool value); - ); - -WRAP(CheckButton, ToggleButton, _GtkCheckButton, (), - explicit CheckButton(const char *label); - , - ); - -WRAP(RadioButton, CheckButton, _GtkRadioButton, (), - , - ); - -WRAP(Item, Bin, _GtkItem, (), - , - ); - -WRAP(MenuItem, Item, _GtkMenuItem, (), - explicit MenuItem(const char *label, bool mnemonic = false); - , - ); - -WRAP(CheckMenuItem, MenuItem, _GtkCheckMenuItem, (), - , - ); - -WRAP(RadioMenuItem, CheckMenuItem, _GtkRadioMenuItem, (), - , - ); - -WRAP(TearoffMenuItem, MenuItem, _GtkTearoffMenuItem, (), - , - ); - -WRAP(ComboBox, Bin, _GtkComboBox, (), - , - ); - -WRAP(ComboBoxText, ComboBox, _GtkComboBoxText, (), - , - ); - -WRAP(ToolItem, Bin, _GtkToolItem, (), - , - ); - -WRAP(ToolButton, ToolItem, _GtkToolButton, (), - , - ); - -WRAP(ToggleToolButton, ToolButton, _GtkToggleToolButton, (), - , - ); - -WRAP(RadioToolButton, ToggleToolButton, _GtkRadioToolButton, (), - , - ); - -WRAP(ScrolledWindow, Bin, _GtkScrolledWindow, (), - , - void overflow(Policy x, Policy y); - ); - -WRAP(Box, Container, _GtkBox, (), - , - void pack_start(ui::Widget child, bool expand, bool fill, unsigned int padding); - void pack_end(ui::Widget child, bool expand, bool fill, unsigned int padding); - ); - -WRAP(VBox, Box, _GtkVBox, (), - VBox(bool homogenous, int spacing); - , - ); - -WRAP(HBox, Box, _GtkHBox, (), - HBox(bool homogenous, int spacing); - , - ); - -WRAP(Paned, Container, _GtkPaned, (), - , - ); - -WRAP(HPaned, Paned, _GtkHPaned, (), - , - ); - -WRAP(VPaned, Paned, _GtkVPaned, (), - , - ); - -WRAP(MenuShell, Container, _GtkMenuShell, (), - , - ); - -WRAP(MenuBar, MenuShell, _GtkMenuBar, (), - , - ); - -WRAP(Menu, MenuShell, _GtkMenu, (), - , - ); - -struct TableAttach { - unsigned int left, right, top, bottom; -}; - -struct TableAttachOptions { - // todo: type safety - unsigned int x, y; -}; - -struct TablePadding { - unsigned int x, y; -}; - -WRAP(Table, Container, _GtkTable, (), - Table(std::size_t rows, std::size_t columns, bool homogenous); - , - // 5 = expand | fill - void attach(Widget child, TableAttach attach, TableAttachOptions options = {5, 5}, TablePadding padding = {0, 0}); - ); - -WRAP(TextView, Container, _GtkTextView, (), - , - void text(char const *str); - ); - -WRAP(Toolbar, Container, _GtkToolbar, (), - , - ); - -class TreeModel; -WRAP(TreeView, Widget, _GtkTreeView, (), - TreeView(TreeModel model); - , - ); - -WRAP(Misc, Widget, _GtkMisc, (), - , - ); - -WRAP(Label, Widget, _GtkLabel, (), - explicit Label(const char *label); - , - void text(char const *str); - ); - -WRAP(Image, Widget, _GtkImage, (), - , - ); - -WRAP(Entry, Widget, _GtkEntry, (IEditable, ICellEditable), - explicit Entry(std::size_t max_length); - , - char const *text(); - void text(char const *str); - ); - -class Adjustment; -WRAP(SpinButton, Entry, _GtkSpinButton, (), - SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits); - , - ); - -WRAP(Range, Widget, _GtkRange, (), - , - ); - -WRAP(Scale, Range, _GtkScale, (), - , - ); - -WRAP(HScale, Scale, _GtkHScale, (), - explicit HScale(Adjustment adjustment); - HScale(double min, double max, double step); - , - ); - -WRAP(Adjustment, Object, _GtkAdjustment, (), - Adjustment(double value, - double lower, double upper, - double step_increment, double page_increment, - double page_size); - , - ); - -WRAP(CellRenderer, Object, _GtkCellRenderer, (), - , - ); - -WRAP(CellRendererText, CellRenderer, _GtkCellRendererText, (), - , - ); - -struct TreeViewColumnAttribute { - const char *attribute; - int column; -}; -WRAP(TreeViewColumn, Object, _GtkTreeViewColumn, (), - TreeViewColumn(const char *title, CellRenderer renderer, std::initializer_list attributes); - , - ); - -WRAP(AccelGroup, Object, _GtkAccelGroup, (), - , - ); - -WRAP(EntryCompletion, Object, _GtkEntryCompletion, (), - , - ); - -WRAP(ListStore, Object, _GtkListStore, (ITreeModel), - , - void clear(); - - template - void append(T ... args); - - void append(); - ); - -WRAP(TreeStore, Object, _GtkTreeStore, (ITreeModel), - , - ); - -WRAP(TreeSelection, Object, _GtkTreeSelection, (), - , - ); - -// GBoxed - -WRAP(TreePath, Object, _GtkTreePath, (), - explicit TreePath(const char *path); - , - ); - -// Custom - -WRAP(GLArea, Widget, _GtkGLArea, (), - , - guint on_render(GCallback pFunction, void *data); - ); - -#undef WRAP - -// global - -enum class alert_response { - OK, - CANCEL, - YES, - NO, -}; - -enum class alert_type { - OK, - OKCANCEL, - YESNO, - YESNOCANCEL, - NOYES, -}; - -enum class alert_icon { - Default, - Error, - Warning, - Question, - Asterisk, -}; - -extern class Window root; - -alert_response alert( - Window parent, - std::string text, - std::string title = "WorldSpawn", - alert_type type = alert_type::OK, - alert_icon icon = alert_icon::Default - ); - -// callbacks - -namespace { -using GtkCallback = void (*)(_GtkWidget *, void *); -extern "C" { -void gtk_container_foreach(_GtkContainer *, GtkCallback, void *); -} -} - -#define this (*static_cast(this)) - -template -gulong Object::connect(char const *detailed_signal, Lambda &&c_handler, void *data) -{ - return g_signal_connect(G_OBJECT(this), detailed_signal, c_handler, data); -} - -template -gulong Object::connect(char const *detailed_signal, Lambda &&c_handler, Object data) -{ - return g_signal_connect(G_OBJECT(this), detailed_signal, c_handler, (_GtkObject *) data); -} - -template -void IContainer::foreach(Lambda &&lambda) -{ - GtkCallback cb = [](_GtkWidget *widget, void *data) -> void { - using Function = typename std::decay::type; - Function *f = static_cast(data); - (*f)(Widget::from(widget)); - }; - gtk_container_foreach(this, cb, &lambda); -} - -namespace { -extern "C" { -void gtk_list_store_insert_with_values(_GtkListStore *, _GtkTreeIter *, gint position, ...); -} -} - -template -void IListStore::append(T... args) { - static_assert(sizeof...(args) % 2 == 0, "received an odd number of arguments"); - gtk_list_store_insert_with_values(this, NULL, -1, args ..., -1); -} - -#undef this - -} - -#endif diff --git a/libs/undolib.h b/libs/undolib.h deleted file mode 100644 index 957971f..0000000 --- a/libs/undolib.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_UNDOLIB_H ) -#define INCLUDED_UNDOLIB_H - -#include "iundo.h" -#include "mapfile.h" -#include "warnings.h" -#include "generic/callback.h" - -template -class BasicUndoMemento : public UndoMemento -{ -Copyable m_data; -public: -BasicUndoMemento( const Copyable& data ) - : m_data( data ){ -} - -void release(){ - delete this; -} - -const Copyable& get() const { - return m_data; -} -}; - - -template -class ObservedUndoableObject : public Undoable -{ -typedef Callback ImportCallback; - -Copyable& m_object; -ImportCallback m_importCallback; -UndoObserver* m_undoQueue; -MapFile* m_map; -public: - -ObservedUndoableObject( Copyable & object, const ImportCallback &importCallback ) - : m_object( object ), m_importCallback( importCallback ), m_undoQueue( 0 ), m_map( 0 ) -{ -} -~ObservedUndoableObject(){ -} - -MapFile* map(){ - return m_map; -} - -void instanceAttach( MapFile* map ){ - m_map = map; - m_undoQueue = GlobalUndoSystem().observer( this ); -} -void instanceDetach( MapFile* map ){ - m_map = 0; - m_undoQueue = 0; - GlobalUndoSystem().release( this ); -} - -void save(){ - if ( m_map != 0 ) { - m_map->changed(); - } - if ( m_undoQueue != 0 ) { - m_undoQueue->save( this ); - } -} - -UndoMemento* exportState() const { - return new BasicUndoMemento( m_object ); -} -void importState( const UndoMemento* state ){ - save(); - m_importCallback( ( static_cast*>( state ) )->get() ); -} -}; - -template -class UndoableObject : public Undoable -{ -Copyable& m_object; -UndoObserver* m_undoQueue; -MapFile* m_map; - -public: -UndoableObject( Copyable& object ) - : m_object( object ), m_undoQueue( 0 ), m_map( 0 ) -{ -} -~UndoableObject(){ -} - -void instanceAttach( MapFile* map ){ - m_map = map; - m_undoQueue = GlobalUndoSystem().observer( this ); -} -void instanceDetach( MapFile* map ){ - m_map = 0; - m_undoQueue = 0; - GlobalUndoSystem().release( this ); -} - -void save(){ - if ( m_map != 0 ) { - m_map->changed(); - } - if ( m_undoQueue != 0 ) { - m_undoQueue->save( this ); - } -} - -UndoMemento* exportState() const { - return new BasicUndoMemento( m_object ); -} -void importState( const UndoMemento* state ){ - save(); - m_object = ( static_cast*>( state ) )->get(); -} -}; - -#endif diff --git a/libs/uniquenames.h b/libs/uniquenames.h deleted file mode 100644 index 09ebde9..0000000 --- a/libs/uniquenames.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_UNIQUENAMES_H ) -#define INCLUDED_UNIQUENAMES_H - -#include "debugging/debugging.h" -#include -#include "string/string.h" -#include "generic/static.h" - -#if 1 -class Postfix -{ -unsigned int m_value; -public: -Postfix( const char* postfix ) : m_value( atoi( postfix ) ){ -} -unsigned int number() const { - return m_value; -} -void write( char* buffer ) const { - sprintf( buffer, "%u", m_value ); -} -Postfix& operator++(){ - ++m_value; - return *this; -} -bool operator<( const Postfix& other ) const { - return m_value < other.m_value; -} -bool operator==( const Postfix& other ) const { - return m_value == other.m_value; -} -bool operator!=( const Postfix& other ) const { - return !operator==( other ); -} -}; - -#else -class Postfix -{ -std::pair m_value; -public: -Postfix( unsigned int number, unsigned int leading_zeros ) - : m_value( leading_zeros, number ){ -} -Postfix( const char* postfix ) - : m_value( number_count_leading_zeros( postfix ), atoi( postfix ) ){ -} -unsigned int number() const { - return m_value.second; -} -unsigned int leading_zeros() const { - return m_value.first; -} -void write( char* buffer ){ - for ( unsigned int count = 0; count < m_value.first; ++count, ++buffer ) - *buffer = '0'; - sprintf( buffer, "%u", m_value.second ); -} -Postfix& operator++(){ - ++m_value.second; - if ( m_value.first != 0 && m_value.second % 10 == 0 ) { - --m_value.first; - } - return *this; -} -bool operator<( const Postfix& other ) const { - return m_value < other.m_value; -} -bool operator==( const Postfix& other ) const { - return m_value == other.m_value; -} -bool operator!=( const Postfix& other ) const { - return !operator==( other ); -} -}; - -#endif - -typedef std::pair name_t; - -inline void name_write( char* buffer, name_t name ){ - strcpy( buffer, name.first.c_str() ); - name.second.write( buffer + strlen( name.first.c_str() ) ); -} - -inline name_t name_read( const char* name ){ - const char* end = name + strlen( name ); - for ( const char* p = end; end != name; --p ) - { - if ( strrchr( "1234567890", *p ) == NULL ) { - break; - } - end = p; - } - - return name_t( CopiedString( StringRange( name, end ) ), Postfix( end ) ); -} - - -class PostFixes -{ -public: -typedef std::map postfixes_t; -postfixes_t m_postfixes; - -private: -Postfix find_first_empty() const { - Postfix postfix( "1" ); - for ( postfixes_t::const_iterator i = m_postfixes.find( postfix ); i != m_postfixes.end(); ++i, ++postfix ) - { - if ( ( *i ).first != postfix ) { - break; - } - } - return postfix; -} - -public: -Postfix make_unique( Postfix postfix ) const { - postfixes_t::const_iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - return postfix; - } - else - { - return find_first_empty(); - } -} - -void insert( Postfix postfix ){ - postfixes_t::iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - m_postfixes.insert( postfixes_t::value_type( postfix, 1 ) ); - } - else - { - ++( *i ).second; - } -} - -void erase( Postfix postfix ){ - postfixes_t::iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - // error - } - else - { - if ( --( *i ).second == 0 ) { - m_postfixes.erase( i ); - } - } -} - -bool empty() const { - return m_postfixes.empty(); -} -}; - - -class UniqueNames -{ -typedef std::map names_t; -names_t m_names; -public: -name_t make_unique( const name_t& name ) const { - char buf[80]; - name_t r( "","" ); - name_write( buf, name ); - globalErrorStream() << "find unique name for " << buf << "\n"; - globalErrorStream() << "> currently registered names:\n"; - for ( names_t::const_iterator i = m_names.begin(); i != m_names.end(); ++i ) - { - globalErrorStream() << ">> " << i->first.c_str() << ": "; - for ( PostFixes::postfixes_t::const_iterator j = i->second.m_postfixes.begin(); j != i->second.m_postfixes.end(); ++j ) - { - j->first.write( buf ); - globalErrorStream() << " '" << buf << "'"; - } - globalErrorStream() << "\n"; - } - names_t::const_iterator i = m_names.find( name.first ); - if ( i == m_names.end() ) { - r = name; - } - else - { - r = name_t( name.first, ( *i ).second.make_unique( name.second ) ); - } - name_write( buf, r ); - globalErrorStream() << "> unique name is " << buf << "\n"; - return r; -} - -void insert( const name_t& name ){ - m_names[name.first].insert( name.second ); -} - -void erase( const name_t& name ){ - names_t::iterator i = m_names.find( name.first ); - if ( i == m_names.end() ) { - ASSERT_MESSAGE( true, "erase: name not found" ); - } - else - { - ( *i ).second.erase( name.second ); - if ( ( *i ).second.empty() ) { - m_names.erase( i ); - } - } -} - -bool empty() const { - return m_names.empty(); -} -}; - - - -#if 0 - -#undef ERROR_MESSAGE -#define ERROR_MESSAGE( message ) - -class TestUniqueName -{ -void name_check_equal( const name_t& name, const char* string, unsigned int postfix ){ - ASSERT_MESSAGE( strcmp( name.first.c_str(), string ) == 0 - && name.second.number() == postfix, - "test failed!" ); -} -void test_refcount(){ - Names names; - - names.insert( name_t( "func_bleh_", "100" ) ); - names.insert( name_t( "func_bleh_", "100" ) ); - names.insert( name_t( "func_bleh_", "100" ) ); - - - names.erase( name_t( "func_bleh_", "100" ) ); - names.erase( name_t( "func_bleh_", "100" ) ); - names.erase( name_t( "func_bleh_", "100" ) ); - - ASSERT_MESSAGE( names.empty(), "test failed!" ); -} - -void test_make_unique(){ - Names names; - - { - name_t name( names.make_unique( name_t( "func_bleh_", "01" ) ) ); - name_check_equal( name, "func_bleh_", 1 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "04" ) ) ); - name_check_equal( name, "func_bleh_", 4 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "04" ) ) ); - name_check_equal( name, "func_bleh_", 2 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "1" ) ) ); - name_check_equal( name, "func_bleh_", 3 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "2" ) ) ); - name_check_equal( name, "func_bleh_", 5 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "3" ) ) ); - name_check_equal( name, "func_bleh_", 6 ); - names.insert( name ); - } - - names.erase( name_t( "func_bleh_", "1" ) ); - names.erase( name_t( "func_bleh_", "2" ) ); - names.erase( name_t( "func_bleh_", "3" ) ); - names.erase( name_t( "func_bleh_", "4" ) ); - names.erase( name_t( "func_bleh_", "5" ) ); - names.erase( name_t( "func_bleh_", "6" ) ); - - ASSERT_MESSAGE( names.empty(), "test failed!" ); -} -public: -TestUniqueName(){ - test_refcount(); - test_make_unique(); -} -}; - -const TestUniqueName g_testuniquename; - -#endif - - -#endif diff --git a/libs/versionlib.h b/libs/versionlib.h deleted file mode 100644 index 80d98cd..0000000 --- a/libs/versionlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_VERSIONLIB_H ) -#define INCLUDED_VERSIONLIB_H - -#include -#include -#include - -class Version -{ -public: -int major; -int minor; -}; - -inline bool operator<( const Version& version, const Version& other ){ - return version.major < other.major || ( !( other.major < version.major ) && version.minor < other.minor ); -} - -template -TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream, const Version& version ){ - return outputStream << version.major << '.' << version.minor; -} - -/// \brief Returns true if \p version (code) is compatible with \p other (data). -inline bool version_compatible( const Version& version, const Version& other ){ - return version.major == other.major // different major-versions are always incompatible - && !( version.minor < other.minor ); // data minor-version is incompatible if greater than code minor-version -} - -inline int string_range_parse_unsigned_decimal_integer( const char* first, const char* last ){ - int result = 0; - for (; first != last; ++first ) - { - result *= 10; - result += *first - '0'; - } - return result; -} - -inline Version version_parse( const char* versionString ){ - Version version; - const char* endVersion = versionString + strlen( versionString ); - - const char* endMajor = strchr( versionString, '.' ); - if ( endMajor == 0 ) { - endMajor = endVersion; - - version.minor = 0; - } - else - { - const char* endMinor = strchr( endMajor + 1, '.' ); - if ( endMinor == 0 ) { - endMinor = endVersion; - } - version.minor = string_range_parse_unsigned_decimal_integer( endMajor + 1, endMinor ); - } - version.major = string_range_parse_unsigned_decimal_integer( versionString, endMajor ); - - return version; -} - -#endif diff --git a/libs/xml/Makefile b/libs/xml/Makefile deleted file mode 100644 index 9275cbd..0000000 --- a/libs/xml/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) - -LIB_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(XML_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - xmltextags.o - -# binary target -../libxmllib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -xmltextags.o: ixml.h xmlelement.h xmlparser.h xmltextags.cpp xmltextags.h xmlwriter.h - -clean: - -rm -f *.o ../libxmllib.a diff --git a/libs/xml/ixml.h b/libs/xml/ixml.h deleted file mode 100644 index 7b86020..0000000 --- a/libs/xml/ixml.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_IXML_H ) -#define INCLUDED_XML_IXML_H - -#include "itextstream.h" -#include "generic/constant.h" - -class XMLAttrVisitor -{ -public: -virtual void visit( const char* name, const char* value ) = 0; -}; - -class XMLElement -{ -public: -virtual const char* name() const = 0; -virtual const char* attribute( const char* name ) const = 0; -virtual void forEachAttribute( XMLAttrVisitor& visitor ) const = 0; -}; - -class XMLImporter : public TextOutputStream -{ -public: -STRING_CONSTANT( Name, "XMLImporter" ); - -virtual void pushElement( const XMLElement& element ) = 0; -virtual void popElement( const char* name ) = 0; -}; - -class XMLExporter -{ -public: -STRING_CONSTANT( Name, "XMLExporter" ); - -virtual void exportXML( XMLImporter& importer ) = 0; -}; - - -#endif diff --git a/libs/xml/xmlelement.h b/libs/xml/xmlelement.h deleted file mode 100644 index 5bedf55..0000000 --- a/libs/xml/xmlelement.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLELEMENT_H ) -#define INCLUDED_XML_XMLELEMENT_H - -#include "xml/ixml.h" -#include "string/string.h" - -#include - -///\brief All string pointers passed to an instance of this class are not -/// copied and must stay valid for the lifetime of the instance. -class StaticElement : public XMLElement -{ -typedef std::map attrs_t; -public: -StaticElement( const char* name ) - : m_name( name ){ -} -void insertAttribute( const char* name, const char* value ){ - m_attrs.insert( attrs_t::value_type( name, value ) ); -} -const char* name() const { - return m_name; -} -const char* attribute( const char* name ) const { - attrs_t::const_iterator i = m_attrs.find( name ); - if ( i != m_attrs.end() ) { - return i->second; - } - else{ - return ""; - } -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i ) - { - visitor.visit( i->first, i->second ); - } -} -private: -const char* m_name; -attrs_t m_attrs; -}; - -///\brief All string pointers passed to an instance of this class are copied. -class DynamicElement : public XMLElement -{ -typedef std::map attrs_t; -public: -DynamicElement( const char* name ) - : m_name( name ){ -} -void insertAttribute( const char* name, const char* value ){ - m_attrs.insert( attrs_t::value_type( name, value ) ); -} -const char* name() const { - return m_name.c_str(); -} -const char* attribute( const char* name ) const { - attrs_t::const_iterator i = m_attrs.find( name ); - if ( i != m_attrs.end() ) { - return i->second.c_str(); - } - else{ - return ""; - } -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i ) - { - visitor.visit( i->first.c_str(), i->second.c_str() ); - } -} -private: -CopiedString m_name; -attrs_t m_attrs; -}; - -#endif diff --git a/libs/xml/xmlparser.h b/libs/xml/xmlparser.h deleted file mode 100644 index 17bcc68..0000000 --- a/libs/xml/xmlparser.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLPARSER_H ) -#define INCLUDED_XML_XMLPARSER_H - -#include -#include -#include "ixml.h" -#include "libxml/parser.h" -#include "convert.h" - -class TextInputStream; - -class SAXElement : public XMLElement -{ -public: -SAXElement( const char* name, const char** atts ) - : m_name( name ), m_atts( atts ){ -} -const char* name() const { - return m_name; -} -const char* attribute( const char* name ) const { - if ( m_atts != 0 ) { - for ( const char** att = m_atts; *att != 0; att += 2 ) - { - if ( strcmp( *att, name ) == 0 ) { - return *( ++att ); - } - } - } - return ""; -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - if ( m_atts != 0 ) { - for ( const char** att = m_atts; *att != 0; att += 2 ) - { - visitor.visit( *att, *( att + 1 ) ); - } - } -} -private: -const char* m_name; -const char** m_atts; -}; - -#include - -class FormattedVA -{ -public: -const char* m_format; -va_list& m_arguments; -FormattedVA( const char* format, va_list& m_arguments ) - : m_format( format ), m_arguments( m_arguments ){ -} -}; - -class Formatted -{ -public: -const char* m_format; -mutable va_list m_arguments; -Formatted( const char* format, ... ) - : m_format( format ){ - va_start( m_arguments, format ); -} -~Formatted(){ - va_end( m_arguments ); -} -}; - -#ifdef _MSC_VER -#if _MSC_VER < 1400 -#define vsnprintf std::vsnprintf -#endif -#endif - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const FormattedVA& formatted ){ - char buffer[1024]; - ostream.write( buffer, vsnprintf( buffer, 1023, formatted.m_format, formatted.m_arguments ) ); - return ostream; -} - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Formatted& formatted ){ - char buffer[1024]; - ostream.write( buffer, vsnprintf( buffer, 1023, formatted.m_format, formatted.m_arguments ) ); - return ostream; -} - -class XMLSAXImporter -{ -XMLImporter& m_importer; -xmlSAXHandler m_sax; - -static void startElement( void *user_data, const xmlChar *name, const xmlChar **atts ){ - SAXElement element( reinterpret_cast( name ), reinterpret_cast( atts ) ); - reinterpret_cast( user_data )->m_importer.pushElement( element ); -} -static void endElement( void *user_data, const xmlChar *name ){ - reinterpret_cast( user_data )->m_importer.popElement( reinterpret_cast( name ) ); -} -static void characters( void *user_data, const xmlChar *ch, int len ){ - reinterpret_cast( user_data )->m_importer - << StringRange( reinterpret_cast( ch ), reinterpret_cast( ch + len ) ); -} - -static void warning( void *user_data, const char *msg, ... ){ - va_list args; - va_start( args, msg ); - globalErrorStream() << "XML WARNING: " << FormattedVA( msg, args ); - va_end( args ); -} -static void error( void *user_data, const char *msg, ... ){ - va_list args; - va_start( args, msg ); - globalErrorStream() << "XML ERROR: " << FormattedVA( msg, args ); - va_end( args ); -} - -public: -XMLSAXImporter( XMLImporter& importer ) : m_importer( importer ){ - m_sax.internalSubset = 0; - m_sax.isStandalone = 0; - m_sax.hasInternalSubset = 0; - m_sax.hasExternalSubset = 0; - m_sax.resolveEntity = 0; - m_sax.getEntity = 0; - m_sax.entityDecl = 0; - m_sax.notationDecl = 0; - m_sax.attributeDecl = 0; - m_sax.elementDecl = 0; - m_sax.unparsedEntityDecl = 0; - m_sax.setDocumentLocator = 0; - m_sax.startDocument = 0; - m_sax.endDocument = 0; - m_sax.startElement = startElement; - m_sax.endElement = endElement; - m_sax.reference = 0; - m_sax.characters = characters; - m_sax.ignorableWhitespace = 0; - m_sax.processingInstruction = 0; - m_sax.comment = 0; - m_sax.warning = warning; - m_sax.error = error; - m_sax.fatalError = 0; - m_sax.getParameterEntity = 0; - m_sax.cdataBlock = 0; - m_sax.externalSubset = 0; - m_sax.initialized = 1; -} - -xmlSAXHandler* callbacks(){ - return &m_sax; -} -void* context(){ - return this; -} -}; - -class XMLStreamParser : public XMLExporter -{ -enum unnamed0 { BUFSIZE = 1024 }; -public: -XMLStreamParser( TextInputStream& istream ) - : m_istream( istream ){ -} -virtual void exportXML( XMLImporter& importer ){ - bool wellFormed = false; - - char chars[BUFSIZE]; - std::size_t res = m_istream.read( chars, 4 ); - if ( res > 0 ) { - XMLSAXImporter sax( importer ); - - xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt( sax.callbacks(), sax.context(), chars, static_cast( res ), 0 ); - ctxt->replaceEntities = 1; - - while ( ( res = m_istream.read( chars, BUFSIZE ) ) > 0 ) - { - xmlParseChunk( ctxt, chars, static_cast( res ), 0 ); - } - xmlParseChunk( ctxt, chars, 0, 1 ); - - wellFormed = ( ctxt->wellFormed == 1 ); - - xmlFreeParserCtxt( ctxt ); - } - - (void) wellFormed; - //return wellFormed; -} -private: -TextInputStream& m_istream; -}; - - - -#endif diff --git a/libs/xml/xmltextags.cpp b/libs/xml/xmltextags.cpp deleted file mode 100644 index 00f57a0..0000000 --- a/libs/xml/xmltextags.cpp +++ /dev/null @@ -1,592 +0,0 @@ -/* - Copyright (C) 2006, Stefan Greven. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "xmltextags.h" - -#include - -#include "qerplugin.h" -#include "stream/stringstream.h" - -XmlTagBuilder::XmlTagBuilder(){ -} - -XmlTagBuilder::~XmlTagBuilder(){ - // clean up - xmlFreeDoc( doc ); - xmlXPathFreeContext( context ); -} - -bool XmlTagBuilder::CreateXmlDocument(){ - /* Creates an XML file - - returns TRUE if the file was created successfully or FALSE when failed - */ - - xmlTextWriterPtr writer; - - writer = xmlNewTextWriterDoc( &doc, 0 ); - - // begin a new UTF-8 formatted xml document - xmlTextWriterStartDocument( writer, NULL, "UTF-8", NULL ); - - // create the root node with stock and custom elements - xmlTextWriterStartElement( writer, (xmlChar*)"root" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterStartElement( writer, (xmlChar*)"stock" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterEndElement( writer ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterStartElement( writer, (xmlChar*)"custom" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterEndElement( writer ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n" ); - xmlTextWriterEndElement( writer ); - - // end of the xml document - xmlTextWriterEndDocument( writer ); - xmlFreeTextWriter( writer ); - - if ( !doc ) { - return false; - } - else { - context = xmlXPathNewContext( doc ); - return true; - } -} - -bool XmlTagBuilder::OpenXmlDoc( const char* file, const char* savefile ){ - /* Reads a XML document from a file - - returns TRUE if the document was read successfully or FALSE when failed - */ - - if ( savefile ) { - m_savefilename = savefile; - } - else{ - m_savefilename = file; - } - - doc = xmlParseFile( file ); // TODO error checking! - - if ( !doc ) { - return false; - } - else { - context = xmlXPathNewContext( doc ); - return true; - } -} - -bool XmlTagBuilder::SaveXmlDoc( void ){ - return SaveXmlDoc( m_savefilename.c_str() ); -} - -bool XmlTagBuilder::SaveXmlDoc( const char* file ){ - /* Writes the XML document - - returns TRUE if the document was saved successfully or FALSE when saving failed - */ - - xmlSaveNoEmptyTags = 1; - - if ( xmlSaveFile( file, doc ) != -1 ) { - return true; - } - return false; -} - -bool XmlTagBuilder::AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType ){ - /* Adds a shader node - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the node was added successfully or FALSE when failed - */ - - xmlNodeSetPtr nodePtr = NULL; - xmlXPathObjectPtr xpathPtr = NULL; - - switch ( textureType ) - { - case STOCK: - xpathPtr = XpathEval( "/root/stock" ); - break; - case CUSTOM: - xpathPtr = XpathEval( "/root/custom" ); - }; - - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr newnode, newtext; - xmlNodePtr nodeParent = nodePtr->nodeTab[0]; - - // create a new node and set the node attribute (shader path) - switch ( nodeShaderType ) - { - case SHADER: - newnode = xmlNewNode( NULL, (xmlChar*)"shader" ); - break; - case TEXTURE: - newnode = xmlNewNode( NULL, (xmlChar*)"texture" ); - }; - - newnode = xmlDocCopyNode( newnode, doc, 1 ); - xmlSetProp( newnode, (xmlChar*)"path", (xmlChar*)shader ); - xmlNodeSetContent( newnode, (xmlChar*)"\n " ); - - if ( nodePtr->nodeTab[0]->children->next == NULL ) { // there are no shaders yet - // add spaces - newtext = xmlNewText( (xmlChar*)" " ); - xmlAddChild( nodeParent->children, newtext ); - - // add the new node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - else { - // add the node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line and spaces - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::DeleteShaderNode( const char* shader ){ - /* Deletes a shader node - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the node was deleted successfully or FALSE when failed - */ - - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptrContent = nodePtr->nodeTab[0]; - xmlNodePtr ptrWhitespace = nodePtr->nodeTab[0]->prev; - - // delete the node - xmlUnlinkNode( ptrContent ); - xmlFreeNode( ptrContent ); - - // delete leading whitespace node - xmlUnlinkNode( ptrWhitespace ); - xmlFreeNode( ptrWhitespace ); - xmlXPathFreeObject( xpathPtr ); - return true; - } - xmlXPathFreeObject( xpathPtr ); - return false; -} - -bool XmlTagBuilder::CheckShaderTag( const char* shader ){ - /* Checks whether there exists an entry for a shader/texture with at least one tag - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the shader is already stored in the XML tag file and has at least one tag - */ - - // build the XPath expression to search for - char buffer[256]; - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - strcat( buffer, "']" ); - - char* expression = buffer; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::CheckShaderTag( const char* shader, const char* content ){ - /* Checks whether a tag with content already exists - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* content - the node content (a tag name) - - returns TRUE if the tag with content already exists or FALSE if not - */ - - // build the XPath expression to search for - // example expression: "/stock/*[@path='textures/alpha/barb_wire'][child::tag='Alpha']"; - - char buffer[256]; - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - strcat( buffer, "'][child::tag='" ); - strcat( buffer, content ); - strcat( buffer, "']" ); - - char* expression = buffer; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType ){ - /* Adds a tag node to an existing shader/texture node if there's no tag with the same content yet - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* content - the node content (a tag name) - - returns TRUE if the node was added successfully or FALSE when failed - */ - - // build the XPath expression - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { // node was found - xmlNodePtr newnode = xmlNewNode( NULL, (xmlChar*)"tag" ); - xmlNodePtr nodeParent = nodePtr->nodeTab[0]; - newnode = xmlDocCopyNode( newnode, doc, 1 ); - xmlNodeSetContent( newnode, (xmlChar*)content ); - - if ( nodePtr->nodeTab[0]->children->next == NULL ) { // shader node has NO children - // add spaces - xmlNodePtr newtext = xmlNewText( (xmlChar*)" " ); - xmlAddChild( nodeParent->children, newtext ); - - // add new node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line + spaces - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - else { // shader node has children already - the new node will be the first sibling - xmlAddNextSibling( nodeParent->children, newnode ); - xmlNodePtr newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -//int XmlTagBuilder::RenameShaderTag(const char* oldtag, const char* newtag) -int XmlTagBuilder::RenameShaderTag( const char* oldtag, CopiedString newtag ){ - /* Replaces tag node contents - - char* oldtag - the node content that sould be changed - char* newtag - the new node content - - returns the number of renamed shaders - */ - - int num = 0; - - // build the XPath expression - char expression[256]; - strcpy( expression, "/root/*/*[child::tag='" ); - strcat( expression, oldtag ); - strcat( expression, "']/*" ); - - xmlXPathObjectPtr result = xmlXPathEvalExpression( (xmlChar*)expression, context ); - if ( !result ) { - return 0; - } - xmlNodeSetPtr nodePtr = result->nodesetval; - - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - xmlNodePtr ptrContent = nodePtr->nodeTab[i]; - char* content = (char*)xmlNodeGetContent( ptrContent ); - - if ( strcmp( content, oldtag ) == 0 ) { // found a node with old content? - xmlNodeSetContent( ptrContent, (xmlChar*)newtag.c_str() ); - num++; - } - } - - SaveXmlDoc(); - xmlXPathFreeObject( result ); // CHANGED - return num; -} - -bool XmlTagBuilder::DeleteShaderTag( const char* shader, const char* tag ){ - /* Deletes a child node of a shader - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* tag - the tag being deleted - - returns TRUE if the node was deleted successfully or FALSE when failed - */ - - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, TAG ); - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - xmlNodePtr ptrContent = nodePtr->nodeTab[i]; - char* content = (char*)(xmlChar*)xmlNodeGetContent( ptrContent ); - - if ( strcmp( content, tag ) == 0 ) { // find the node - xmlNodePtr ptrWhitespace = nodePtr->nodeTab[i]->prev; - // delete the node - xmlUnlinkNode( ptrContent ); - xmlFreeNode( ptrContent ); - - // delete leading whitespace node - xmlUnlinkNode( ptrWhitespace ); - xmlFreeNode( ptrWhitespace ); - xmlXPathFreeObject( xpathPtr ); - return true; - } - } - } - xmlXPathFreeObject( xpathPtr ); - return false; -} - -bool XmlTagBuilder::DeleteTag( const char* tag ){ - /* Deletes a tag from all shaders - - char* tag - the tag being deleted from all shaders - - returns TRUE if the tag was deleted successfully or FALSE when failed - */ - - char expression[256]; - strcpy( expression, "/root/*/*[child::tag='" ); - strcat( expression, tag ); - strcat( expression, "']" ); - - std::set dellist; - TagSearch( expression, dellist ); - std::set::iterator iter; - - for ( iter = dellist.begin(); iter != dellist.end(); iter++ ) - { - DeleteShaderTag( iter->c_str(), tag ); - } - SaveXmlDoc(); - - return true; -} - -void XmlTagBuilder::GetShaderTags( const char* shader, std::vector& tags ){ - /* Gets the tags from a shader - - char* shader - the name of the shader - - returns a vector containing the tags - */ - - char const *expression; - - if ( shader == NULL ) { // get all tags from all shaders - expression = "/root/*/*/tag"; - } - else { - char buffer[256]; - expression = GetTagsXpathExpression( buffer, shader, TAG ); - } - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - tags.push_back( (CopiedString)(char*)xmlNodeGetContent( nodePtr->nodeTab[i] ) ); - } - } - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::GetUntagged( std::set& shaders ){ - /* Gets all textures and shaders listed in the xml file that don't have any tag - - returns a set containing the shaders (with path) - */ - - char const *expression = "/root/*/*[not(child::tag)]"; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptr; - - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - ptr = nodePtr->nodeTab[i]; - shaders.insert( (char*)xmlGetProp( ptr, (xmlChar*)"path" ) ); - } - } - - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::GetAllTags( std::set& tags ){ - /* Gets a list of all tags that are used (assigned to any shader) - - returns a set containing all used tags - */ - - char const *expression = "/root/*/*/tag"; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - tags.insert( (CopiedString)(char*)xmlNodeGetContent( nodePtr->nodeTab[i] ) ); - } - } - - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::TagSearch( const char* expression, std::set& paths ){ - /* Searches shaders by tags - - char* expression - the XPath expression to search - - returns a set containing the found shaders - */ - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptr; - xmlChar* xmlattrib; - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - ptr = nodePtr->nodeTab[i]; - xmlattrib = xmlGetProp( ptr, (xmlChar*)"path" ); - paths.insert( (CopiedString)(char*)xmlattrib ); - } - } - xmlXPathFreeObject( xpathPtr ); -} diff --git a/libs/xml/xmltextags.h b/libs/xml/xmltextags.h deleted file mode 100644 index 7a1bae6..0000000 --- a/libs/xml/xmltextags.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2006, Stefan Greven. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XMLTEXTAGS_H ) -#define INCLUDED_XMLTEXTAGS_H - -#include -#include -#include - -#include "iscriplib.h" - -#include -#include - -enum NodeTagType -{ - TAG, - EMPTY -}; - -enum NodeShaderType -{ - SHADER, - TEXTURE -}; - -enum TextureType -{ - STOCK, - CUSTOM -}; - -class XmlTagBuilder -{ -private: -CopiedString m_savefilename; -xmlDocPtr doc; -xmlXPathContextPtr context; -xmlNodeSetPtr nodePtr; - -xmlXPathObjectPtr XpathEval( const char* queryString ){ - xmlChar* expression = (xmlChar*)queryString; - xmlXPathObjectPtr result = xmlXPathEvalExpression( expression, context ); - return result; -}; - -char* GetTagsXpathExpression( char* buffer, const char* shader, NodeTagType nodeTagType ){ - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - - switch ( nodeTagType ) - { - case TAG: - strcat( buffer, "']/tag" ); - break; - case EMPTY: - strcat( buffer, "']" ); - }; - - return buffer; -} - -public: -XmlTagBuilder(); -~XmlTagBuilder(); - -bool CreateXmlDocument(); -bool OpenXmlDoc( const char* file, const char* savefile = 0 ); -bool SaveXmlDoc( const char* file ); -bool SaveXmlDoc( void ); -bool AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType ); -bool DeleteShaderNode( const char* shader ); -bool CheckShaderTag( const char* shader ); -bool CheckShaderTag( const char* shader, const char* content ); -bool AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType ); -bool DeleteTag( const char* tag ); -int RenameShaderTag( const char* oldtag, CopiedString newtag ); -bool DeleteShaderTag( const char* shader, const char* tag ); -void GetShaderTags( const char* shader, std::vector& tags ); -void GetUntagged( std::set& shaders ); -void GetAllTags( std::set& tags ); -void TagSearch( const char* expression, std::set& paths ); -}; - -#endif diff --git a/libs/xml/xmlwriter.h b/libs/xml/xmlwriter.h deleted file mode 100644 index c144646..0000000 --- a/libs/xml/xmlwriter.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLWRITER_H ) -#define INCLUDED_XML_XMLWRITER_H - -#include "convert.h" -#include -#include "xml/ixml.h" - -class XMLEntityOutputStream -{ -SingleCharacterOutputStream m_ostream; -public: -XMLEntityOutputStream( TextOutputStream& ostream ) - : m_ostream( ostream ){ -} -void write( const char c ){ - m_ostream.write( c ); -} -void writeEscaped( const char c ){ - switch ( c ) - { - case '<': - write( '&' ); - write( 'l' ); - write( 't' ); - write( ';' ); - break; - case '>': - write( '&' ); - write( 'g' ); - write( 't' ); - write( ';' ); - break; - case '"': - write( '&' ); - write( 'q' ); - write( 'u' ); - write( 'o' ); - write( 't' ); - write( ';' ); - break; - case '&': - write( '&' ); - write( 'a' ); - write( 'm' ); - write( 'p' ); - write( ';' ); - break; - default: - write( c ); - break; - } -} -std::size_t write( const char* buffer, std::size_t length ){ - const char*const end = buffer + length; - for ( const char* p = buffer; p != end; ++p ) - { - writeEscaped( *p ); - } - return length; -} -}; - -template -inline XMLEntityOutputStream& operator<<( XMLEntityOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -class XMLStreamWriter : public XMLImporter, public XMLAttrVisitor -{ -class state_t -{ -public: -enum EState -{ - eStartElement, - eContent, -}; -state_t() - : m_state( eStartElement ) -{ -} -EState m_state; -}; - -XMLEntityOutputStream m_ostream; -std::vector m_elements; - -void write_cdata( const char* buffer, std::size_t length ){ - m_ostream << StringRange( buffer, buffer + length ); -} -void write_string( const char* string ){ - m_ostream << string; -} -void write_quoted_string( const char* string ){ - m_ostream.write( '"' ); - m_ostream << string; - m_ostream.write( '"' ); -} -public: -XMLStreamWriter( TextOutputStream& ostream ) - : m_ostream( ostream ){ - m_elements.push_back( state_t() ); - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '<' ); - m_ostream.write( '?' ); - write_string( "xml" ); - visit( "version", "1.0" ); - m_ostream.write( '?' ); - m_ostream.write( '>' ); -} - -void pushElement( const XMLElement& element ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '>' ); - } - - m_elements.push_back( state_t() ); - - m_ostream.write( '<' ); - write_string( element.name() ); - element.forEachAttribute( *this ); -} -void popElement( const char* name ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_ostream.write( '/' ); - m_ostream.write( '>' ); - m_elements.pop_back(); - } - else - { - m_ostream.write( '<' ); - m_ostream.write( '/' ); - write_string( name ); - m_ostream.write( '>' ); - m_elements.pop_back(); - } -} -std::size_t write( const char* data, std::size_t length ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '>' ); - } - write_cdata( data, length ); - return length; -} - -void visit( const char* name, const char* value ){ - m_ostream.write( ' ' ); - write_string( name ); - m_ostream.write( '=' ); - write_quoted_string( value ); -} -}; - - -#endif diff --git a/plugins/Makefile b/plugins/Makefile deleted file mode 100644 index 87e9306..0000000 --- a/plugins/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -all: - mkdir -p ../build/plugins - cd archivezip && $(MAKE) - cd archivewad && $(MAKE) - cd archivepak && $(MAKE) - cd entity && $(MAKE) - cd image && $(MAKE) - cd imagehl && $(MAKE) - cd iqmmodel && $(MAKE) - cd mapq3 && $(MAKE) - cd model && $(MAKE) - cd matsys && $(MAKE) - cd shaders && $(MAKE) - cd vfspk3 && $(MAKE) - cd brushexport && $(MAKE) - cd prtview && $(MAKE) -clean: - -rm -rf ../build/plugins - cd archivezip && $(MAKE) clean - cd archivewad && $(MAKE) clean - cd archivepak && $(MAKE) clean - cd entity && $(MAKE) clean - cd image && $(MAKE) clean - cd imagehl && $(MAKE) clean - cd iqmmodel && $(MAKE) clean - cd mapq3 && $(MAKE) clean - cd model && $(MAKE) clean - cd shaders && $(MAKE) clean - cd matsys && $(MAKE) clean - cd vfspk3 && $(MAKE) clean - cd brushexport && $(MAKE) clean - cd prtview && $(MAKE) clean diff --git a/plugins/archivepak/Makefile b/plugins/archivepak/Makefile deleted file mode 100644 index 6d91d7e..0000000 --- a/plugins/archivepak/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# WorldSpawn Plugin Makefile - -LIB_EXT=so -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivepak.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libarchivepak.$(LIB_EXT) diff --git a/plugins/archivepak/archive.cpp b/plugins/archivepak/archive.cpp deleted file mode 100644 index ee19333..0000000 --- a/plugins/archivepak/archive.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "cmdlib.h" -#include "bytestreamutils.h" -#include -#include "stream/filestream.h" - -#include "iarchive.h" - -#include "archivelib.h" - - -#include -#include "string/string.h" -#include "fs_filesystem.h" - -inline void buffer_findreplace( char* buffer, char find, char replace ){ - while ( *buffer != '\0' ) - { - if ( *buffer == find ) { - *buffer = replace; - } - ++buffer; - } -} - -#include "pak.h" - -class PakArchive : public Archive -{ -class PakRecord -{ -public: -PakRecord( unsigned int position, unsigned int stream_size ) - : m_position( position ), m_stream_size( stream_size ){ -} -unsigned int m_position; -unsigned int m_stream_size; -}; -typedef GenericFileSystem PakFileSystem; -PakFileSystem m_filesystem; -FileInputStream m_pakfile; -CopiedString m_name; - -public: - -PakArchive( const char* name ) - : m_pakfile( name ), m_name( name ){ - if ( !m_pakfile.failed() ) { - pakheader_t header; - - m_pakfile.read( reinterpret_cast( header.magic ), 4 ); - header.diroffset = istream_read_uint32_le( m_pakfile ); - header.dirsize = istream_read_uint32_le( m_pakfile ); - - if ( strncmp( header.magic, "PACK", 4 ) == 0 ) { - m_pakfile.seek( header.diroffset ); - - for ( unsigned int i = 0; i < header.dirsize; i += sizeof( pakentry_t ) ) - { - pakentry_t entry; - - m_pakfile.read( reinterpret_cast( entry.filename ), 0x38 ); - entry.offset = istream_read_uint32_le( m_pakfile ); - entry.size = istream_read_uint32_le( m_pakfile ); - - buffer_findreplace( entry.filename, '\\', '/' ); - - PakFileSystem::entry_type& file = m_filesystem[entry.filename]; - if ( !file.is_directory() ) { - globalOutputStream() << "Warning: pak archive " << makeQuoted( m_name.c_str() ) << " contains duplicated file: " << makeQuoted( entry.filename ) << "\n"; - } - else - { - file = new PakRecord( entry.offset, entry.size ); - } - } - } - } -} - -~PakArchive(){ - for ( PakFileSystem::iterator i = m_filesystem.begin(); i != m_filesystem.end(); ++i ) - delete i->second.file(); -} - -void release(){ - delete this; -} -ArchiveFile* openFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - if ( i != m_filesystem.end() && !i->second.is_directory() ) { - PakRecord* file = i->second.file(); - return StoredArchiveFile::create( name, m_name.c_str(), file->m_position, file->m_stream_size, file->m_stream_size ); - } - return 0; -} -virtual ArchiveTextFile* openTextFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - if ( i != m_filesystem.end() && !i->second.is_directory() ) { - PakRecord* file = i->second.file(); - return StoredArchiveTextFile::create( name, m_name.c_str(), file->m_position, file->m_stream_size ); - } - return 0; -} -bool containsFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - return i != m_filesystem.end() && !i->second.is_directory(); -} -void forEachFile( VisitorFunc visitor, const char* root ){ - m_filesystem.traverse( visitor, root ); -} -}; - - -Archive* OpenArchive( const char* name ){ - return new PakArchive( name ); -} - -#if 0 - -class TestArchive -{ -public: -TestArchive(){ - Archive* archive = OpenArchive( "c:/quake3/baseq3/pak0.pak" ); - ArchiveFile* file = archive->openFile( "gfx/palette.lmp" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( (InputStream::byte_type*)buffer, 1024 ); - file->release(); - } - archive->release(); -} -}; - -TestArchive g_test; - -#endif - -#if 0 - -class TestArchive -{ -class TestVisitor : public Archive::IVisitor -{ -public: -void visit( const char* name ){ - int bleh = 0; -} -}; -public: -TestArchive(){ - { - Archive* archive = OpenArchive( "" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "NONEXISTANTFILE" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "c:/quake/id1/pak0.pak" ); - ArchiveFile* file = archive->openFile( "gfx/palette.lmp" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( (InputStream::byte_type*)buffer, 1024 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 0 ), "progs/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 0 ), "maps/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "sound/ambience/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->release(); - } -} -}; - -TestArchive g_test; - -#endif diff --git a/plugins/archivepak/archive.h b/plugins/archivepak/archive.h deleted file mode 100644 index 309cef5..0000000 --- a/plugins/archivepak/archive.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class Archive; -Archive* OpenArchive( const char* name ); diff --git a/plugins/archivepak/pak.h b/plugins/archivepak/pak.h deleted file mode 100644 index 2205156..0000000 --- a/plugins/archivepak/pak.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PAK_H ) -#define INCLUDED_PAK_H - -struct pakheader_t -{ - char magic[4]; // Name of the new WAD format ("PACK") - unsigned int diroffset; // Position of WAD directory from start of file - unsigned int dirsize; // Number of entries * 0x40 (64 char) -}; - -struct pakentry_t -{ - char filename[0x38]; // Name of the file, Unix style, with extension, 50 chars, padded with '\0'. - unsigned int offset; // Position of the entry in PACK file - unsigned int size; // Size of the entry in PACK file -}; - -#endif diff --git a/plugins/archivepak/plugin.cpp b/plugins/archivepak/plugin.cpp deleted file mode 100644 index 489af0b..0000000 --- a/plugins/archivepak/plugin.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - -class ArchivePakAPI -{ -_QERArchiveTable m_archivepak; -public: -typedef _QERArchiveTable Type; -STRING_CONSTANT( Name, "pak" ); - -ArchivePakAPI(){ - m_archivepak.m_pfnOpenArchive = &OpenArchive; -} -_QERArchiveTable* getTable(){ - return &m_archivepak; -} -}; - -typedef SingletonModule ArchivePakModule; - -ArchivePakModule g_ArchivePakModule; - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ArchivePakModule.selfRegister(); -} diff --git a/plugins/archivewad/Makefile b/plugins/archivewad/Makefile deleted file mode 100644 index ab561ba..0000000 --- a/plugins/archivewad/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# WorldSpawn Plugin Makefile - -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivewad.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libarchivewad.$(LIB_EXT) diff --git a/plugins/archivewad/archive.cpp b/plugins/archivewad/archive.cpp deleted file mode 100644 index 357f9cd..0000000 --- a/plugins/archivewad/archive.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "bytestreamutils.h" -#include -#include "stream/filestream.h" - -#include "iarchive.h" - -#include "archivelib.h" - - -#include -#include "string/string.h" - -#include "wad.h" - -class WadArchive final : public Archive -{ - class wad_record_t - { - public: - wad_record_t( unsigned int position, unsigned int stream_size, unsigned int file_size ) - : m_position( position ), m_stream_size( stream_size ), m_file_size( file_size ) - {} - unsigned int m_position; - unsigned int m_stream_size; - unsigned int m_file_size; - }; - - enum EWadVersion - { - eNotValid, - eWAD2, - eWAD3, - }; - - typedef std::map files_t; - files_t m_files; - CopiedString m_name; - FileInputStream m_wadfile; - - EWadVersion wad_version( const char* identification ){ - if ( strncmp( identification, "WAD2", 4 ) == 0 ) { - return eWAD2; - } - if ( strncmp( identification, "WAD3", 4 ) == 0 ) { - return eWAD3; - } - return eNotValid; - } - - const char* type_for_version( EWadVersion version ){ - switch ( version ) - { - case eWAD2: - return ".mip"; - case eWAD3: - return ".hlw"; - default: - break; - } - return ""; - } - - int miptex_type_for_version( EWadVersion version ){ - switch ( version ) - { - case eWAD2: - return TYP_MIPTEX; - case eWAD3: - return 67; - default: - break; - } - return -1; - } - -public: - WadArchive( const char* name ) - : m_name( name ), m_wadfile( name ){ - if ( !m_wadfile.failed() ) { - wadinfo_t wadinfo; - istream_read_wadinfo( m_wadfile, wadinfo ); - - EWadVersion version = wad_version( wadinfo.identification ); - int miptexType = miptex_type_for_version( version ); - - if ( version != eNotValid ) { - m_wadfile.seek( wadinfo.infotableofs ); - - for ( int i = 0; i < wadinfo.numlumps; ++i ) - { - char buffer[32]; - lumpinfo_t lumpinfo; - istream_read_lumpinfo( m_wadfile, lumpinfo ); - if ( lumpinfo.type == miptexType ) { - strcpy( buffer, "textures/" ); - strcat( buffer, lumpinfo.name ); - strcat( buffer, type_for_version( version ) ); - m_files.insert( files_t::value_type( buffer, wad_record_t( lumpinfo.filepos, lumpinfo.disksize, lumpinfo.size ) ) ); - } - } - } - } - } - - void release(){ - delete this; - } - ArchiveFile* openFile( const char* name ){ - files_t::iterator i = m_files.find( name ); - if ( i != m_files.end() ) { - return StoredArchiveFile::create( name, m_name.c_str(), i->second.m_position, i->second.m_stream_size, i->second.m_file_size ); - } - return 0; - } - virtual ArchiveTextFile* openTextFile( const char* name ){ - files_t::iterator i = m_files.find( name ); - if ( i != m_files.end() ) { - return StoredArchiveTextFile::create( name, m_name.c_str(), i->second.m_position, i->second.m_stream_size ); - } - return 0; - } - bool containsFile( const char* name ){ - return m_files.find( name ) != m_files.end(); - } - void forEachFile( VisitorFunc visitor, const char* root ){ - if ( root[0] == '\0' ) { - if ( visitor.directory( "textures/", 1 ) ) { - return; - } - } - else if ( strcmp( root, "textures/" ) != 0 ) { - return; - } - - for ( files_t::iterator i = m_files.begin(); i != m_files.end(); ++i ) - visitor.file( i->first.c_str() ); - } -}; - - -Archive* OpenArchive( const char* name ){ - return new WadArchive( name ); -} - -#if 0 - -class TestArchive -{ - class TestVisitor : public Archive::IVisitor - { - public: - void visit( const char* name ){ - int bleh = 0; - } - }; -public: - TestArchive(){ - { - Archive* archive = OpenArchive( "" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "NONEXISTANTFILE" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "c:/quake/id1/quake101.wad" ); - ArchiveFile* file = archive->openFile( "textures/sky1.mip" ); - if ( file != 0 ) { - unsigned char* buffer = new unsigned char[file->size()]; - file->getInputStream().read( (InputStream::byte_type*)buffer, file->size() ); - delete[] buffer; - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "textures/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures/" ); - archive->release(); - } - } -}; - -TestArchive g_test; - -#endif diff --git a/plugins/archivewad/archive.h b/plugins/archivewad/archive.h deleted file mode 100644 index 309cef5..0000000 --- a/plugins/archivewad/archive.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class Archive; -Archive* OpenArchive( const char* name ); diff --git a/plugins/archivewad/plugin.cpp b/plugins/archivewad/plugin.cpp deleted file mode 100644 index 66d0fed..0000000 --- a/plugins/archivewad/plugin.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - -class ArchiveWadAPI -{ - _QERArchiveTable m_archivewad; -public: - typedef _QERArchiveTable Type; - STRING_CONSTANT( Name, "wad" ); - - ArchiveWadAPI(){ - m_archivewad.m_pfnOpenArchive = &OpenArchive; - } - _QERArchiveTable* getTable(){ - return &m_archivewad; - } -}; - -typedef SingletonModule ArchiveWadModule; - -ArchiveWadModule g_ArchiveWadModule; - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ArchiveWadModule.selfRegister(); -} diff --git a/plugins/archivewad/wad.h b/plugins/archivewad/wad.h deleted file mode 100644 index 617900c..0000000 --- a/plugins/archivewad/wad.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WAD_H ) -#define INCLUDED_WAD_H - -#include "bytestreamutils.h" -#include "idatastream.h" - -#define CMP_NONE 0 -#define CMP_LZSS 1 - -#define TYP_NONE 0 -#define TYP_LABEL 1 - -#define TYP_LUMPY 64 // 64 + grab command number -#define TYP_PALETTE 64 -#define TYP_QTEX 65 -#define TYP_QPIC 66 -#define TYP_SOUND 67 -#define TYP_MIPTEX 68 - -typedef struct -{ - char identification[4]; // should be WAD2 or 2DAW - int numlumps; - int infotableofs; -} wadinfo_t; - -typedef struct -{ - int filepos; - int disksize; - int size; // uncompressed - char type; - char compression; - char pad1, pad2; - char name[16]; // must be null terminated -} lumpinfo_t; - -inline void istream_read_wadinfo( InputStream& istream, wadinfo_t& wadinfo ){ - istream.read( reinterpret_cast( wadinfo.identification ), 4 ); - wadinfo.numlumps = istream_read_int32_le( istream ); - wadinfo.infotableofs = istream_read_int32_le( istream ); -} - -inline void istream_read_lumpinfo( InputStream& istream, lumpinfo_t& lumpinfo ){ - lumpinfo.filepos = istream_read_int32_le( istream ); - lumpinfo.disksize = istream_read_int32_le( istream ); - lumpinfo.size = istream_read_int32_le( istream ); - lumpinfo.type = istream_read_byte( istream ); - lumpinfo.compression = istream_read_byte( istream ); - lumpinfo.pad1 = istream_read_byte( istream ); - lumpinfo.pad2 = istream_read_byte( istream ); - istream.read( reinterpret_cast( lumpinfo.name ), 16 ); -} - -#endif diff --git a/plugins/archivezip/Makefile b/plugins/archivezip/Makefile deleted file mode 100644 index 430807c..0000000 --- a/plugins/archivezip/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# WorldSpawn Plugin Makefile - -ZLIB_LDFLAGS=$(shell pkg-config --libs zlib) - -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared $(ZLIB_LDFLAGS) -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivezip.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp zlibstream.h - -clean: - -rm -f *.o ../../build/plugins/libarchivezip.$(LIB_EXT) diff --git a/plugins/archivezip/archive.cpp b/plugins/archivezip/archive.cpp deleted file mode 100644 index d7be70d..0000000 --- a/plugins/archivezip/archive.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "idatastream.h" -#include "cmdlib.h" -#include "bytestreamutils.h" - -#include "modulesystem.h" -#include "iarchive.h" - -#include -#include "stream/filestream.h" -#include "container/array.h" -#include "archivelib.h" -#include "zlibstream.h" - -class DeflatedArchiveFile : public ArchiveFile { -CopiedString m_name; -FileInputStream m_istream; -SubFileInputStream m_substream; -DeflatedInputStream m_zipstream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -DeflatedArchiveFile(const char *name, const char *archiveName, position_type position, size_type stream_size, - size_type file_size) - : m_name(name), m_istream(archiveName), m_substream(m_istream, position, stream_size), - m_zipstream(m_substream), m_size(file_size) -{ -} - -void release() -{ - delete this; -} - -size_type size() const -{ - return m_size; -} - -const char *getName() const -{ - return m_name.c_str(); -} - -InputStream &getInputStream() -{ - return m_zipstream; -} -}; - -class DeflatedArchiveTextFile : public ArchiveTextFile { -CopiedString m_name; -FileInputStream m_istream; -SubFileInputStream m_substream; -DeflatedInputStream m_zipstream; -BinaryToTextInputStream m_textStream; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -DeflatedArchiveTextFile(const char *name, const char *archiveName, position_type position, size_type stream_size) - : m_name(name), m_istream(archiveName), m_substream(m_istream, position, stream_size), - m_zipstream(m_substream), m_textStream(m_zipstream) -{ -} - -void release() -{ - delete this; -} - -TextInputStream &getInputStream() -{ - return m_textStream; -} -}; - -#include "pkzip.h" - -#include -#include "string/string.h" -#include "fs_filesystem.h" - - -class ZipArchive : public Archive { -class ZipRecord { -public: -enum ECompressionMode { - eStored, - eDeflated, -}; - -ZipRecord(unsigned int position, unsigned int compressed_size, unsigned int uncompressed_size, - ECompressionMode mode) - : m_position(position), m_stream_size(compressed_size), m_file_size(uncompressed_size), m_mode(mode) -{ -} - -unsigned int m_position; -unsigned int m_stream_size; -unsigned int m_file_size; -ECompressionMode m_mode; -}; - -typedef GenericFileSystem ZipFileSystem; -ZipFileSystem m_filesystem; -CopiedString m_name; -FileInputStream m_istream; - -bool read_record() -{ - zip_magic magic; - istream_read_zip_magic(m_istream, magic); - if (!(magic == zip_root_dirent_magic)) { - return false; - } - zip_version version_encoder; - istream_read_zip_version(m_istream, version_encoder); - zip_version version_extract; - istream_read_zip_version(m_istream, version_extract); - //unsigned short flags = - istream_read_int16_le(m_istream); - unsigned short compression_mode = istream_read_int16_le(m_istream); - if (compression_mode != Z_DEFLATED && compression_mode != 0) { - return false; - } - zip_dostime dostime; - istream_read_zip_dostime(m_istream, dostime); - //unsigned int crc32 = - istream_read_int32_le(m_istream); - unsigned int compressed_size = istream_read_uint32_le(m_istream); - unsigned int uncompressed_size = istream_read_uint32_le(m_istream); - unsigned int namelength = istream_read_uint16_le(m_istream); - unsigned short extras = istream_read_uint16_le(m_istream); - unsigned short comment = istream_read_uint16_le(m_istream); - //unsigned short diskstart = - istream_read_int16_le(m_istream); - //unsigned short filetype = - istream_read_int16_le(m_istream); - //unsigned int filemode = - istream_read_int32_le(m_istream); - unsigned int position = istream_read_int32_le(m_istream); - - Array filename(namelength + 1); - m_istream.read(reinterpret_cast( filename.data()), namelength); - filename[namelength] = '\0'; - - m_istream.seek(extras + comment, FileInputStream::cur); - - if (path_is_directory(filename.data())) { - m_filesystem[filename.data()] = 0; - } else { - ZipFileSystem::entry_type &file = m_filesystem[filename.data()]; - if (!file.is_directory()) { - globalOutputStream() << "Warning: zip archive " << makeQuoted(m_name.c_str()) - << " contains duplicated file: " << makeQuoted(filename.data()) << "\n"; - } else { - file = new ZipRecord(position, compressed_size, uncompressed_size, - (compression_mode == Z_DEFLATED) ? ZipRecord::eDeflated : ZipRecord::eStored); - } - } - - return true; -} - -bool read_pkzip() -{ - SeekableStream::position_type pos = pkzip_find_disk_trailer(m_istream); - if (pos != 0) { - zip_disk_trailer disk_trailer; - m_istream.seek(pos); - istream_read_zip_disk_trailer(m_istream, disk_trailer); - if (!(disk_trailer.z_magic == zip_disk_trailer_magic)) { - return false; - } - - m_istream.seek(disk_trailer.z_rootseek); - for (unsigned int i = 0; i < disk_trailer.z_entries; ++i) { - if (!read_record()) { - return false; - } - } - return true; - } - return false; -} - -public: -ZipArchive(const char *name) - : m_name(name), m_istream(name) -{ - if (!m_istream.failed()) { - if (!read_pkzip()) { - globalErrorStream() << "ERROR: invalid zip-file " << makeQuoted(name) << '\n'; - } - } -} - -~ZipArchive() -{ - for (ZipFileSystem::iterator i = m_filesystem.begin(); i != m_filesystem.end(); ++i) { - delete i->second.file(); - } -} - -bool failed() -{ - return m_istream.failed(); -} - -void release() -{ - delete this; -} - -ArchiveFile *openFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - if (i != m_filesystem.end() && !i->second.is_directory()) { - ZipRecord *file = i->second.file(); - - m_istream.seek(file->m_position); - zip_file_header file_header; - istream_read_zip_file_header(m_istream, file_header); - if (file_header.z_magic != zip_file_header_magic) { - globalErrorStream() << "error reading zip file " << makeQuoted(m_name.c_str()); - return 0; - } - - switch (file->m_mode) { - case ZipRecord::eStored: - return StoredArchiveFile::create(name, m_name.c_str(), m_istream.tell(), file->m_stream_size, - file->m_file_size); - case ZipRecord::eDeflated: - return new DeflatedArchiveFile(name, m_name.c_str(), m_istream.tell(), file->m_stream_size, - file->m_file_size); - } - } - return 0; -} - -ArchiveTextFile *openTextFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - if (i != m_filesystem.end() && !i->second.is_directory()) { - ZipRecord *file = i->second.file(); - - m_istream.seek(file->m_position); - zip_file_header file_header; - istream_read_zip_file_header(m_istream, file_header); - if (file_header.z_magic != zip_file_header_magic) { - globalErrorStream() << "error reading zip file " << makeQuoted(m_name.c_str()); - return 0; - } - - switch (file->m_mode) { - case ZipRecord::eStored: - return StoredArchiveTextFile::create(name, m_name.c_str(), m_istream.tell(), file->m_stream_size); - case ZipRecord::eDeflated: - return new DeflatedArchiveTextFile(name, m_name.c_str(), m_istream.tell(), file->m_stream_size); - } - } - return 0; -} - -bool containsFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - return i != m_filesystem.end() && !i->second.is_directory(); -} - -void forEachFile(VisitorFunc visitor, const char *root) -{ - m_filesystem.traverse(visitor, root); -} -}; - -Archive *OpenArchive(const char *name) -{ - return new ZipArchive(name); -} - -#if 0 - -class TestZip -{ -class TestVisitor : public Archive::IVisitor -{ -public: -void visit( const char* name ){ - int bleh = 0; -} -}; -public: -TestZip(){ - testzip( "c:/quake3/baseq3/mapmedia.pk3", "textures/radiant/notex.tga" ); -} - -void testzip( const char* name, const char* filename ){ - Archive* archive = OpenArchive( name ); - ArchiveFile* file = archive->openFile( filename ); - if ( file != 0 ) { - unsigned char buffer[4096]; - std::size_t count = file->getInputStream().read( (InputStream::byte_type*)buffer, 4096 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->release(); -} -}; - -TestZip g_TestZip; - -#endif diff --git a/plugins/archivezip/archive.h b/plugins/archivezip/archive.h deleted file mode 100644 index 95f64d9..0000000 --- a/plugins/archivezip/archive.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -Archive *OpenArchive(const char *name); diff --git a/plugins/archivezip/pkzip.h b/plugins/archivezip/pkzip.h deleted file mode 100644 index 296d15f..0000000 --- a/plugins/archivezip/pkzip.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PKZIP_H ) -#define INCLUDED_PKZIP_H - -#include "bytestreamutils.h" -#include "idatastream.h" -#include - -class zip_magic { -public: -bool operator==(const zip_magic &other) const -{ - return m_value[0] == other.m_value[0] - && m_value[1] == other.m_value[1] - && m_value[2] == other.m_value[2] - && m_value[3] == other.m_value[3]; -} - -bool operator!=(const zip_magic &other) const -{ - return !(*this == other); -} - -char m_value[4]; -}; - -inline void istream_read_zip_magic(InputStream &istream, zip_magic &magic) -{ - istream.read(reinterpret_cast( magic.m_value ), 4); -} - -struct zip_version { - char version; - char ostype; -}; - -inline void istream_read_zip_version(InputStream &istream, zip_version &version) -{ - version.version = istream_read_byte(istream); - version.ostype = istream_read_byte(istream); -} - -struct zip_dostime { - unsigned short time; - unsigned short date; -}; - -inline void istream_read_zip_dostime(InputStream &istream, zip_dostime &dostime) -{ - dostime.time = istream_read_int16_le(istream); - dostime.date = istream_read_int16_le(istream); -} - -const zip_magic zip_file_header_magic = {{'P', 'K', 0x03, 0x04}}; - -/* A. Local file header */ -struct zip_file_header { - zip_magic z_magic; /* local file header signature (0x04034b50) */ - zip_version z_extract; /* version needed to extract */ - unsigned short z_flags; /* general purpose bit flag */ - unsigned short z_compr; /* compression method */ - zip_dostime z_dostime; /* last mod file time (dos format) */ - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ - unsigned short z_namlen; /* filename length (null if stdin) */ - unsigned short z_extras; /* extra field length */ - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ -}; - -inline void istream_read_zip_file_header(SeekableInputStream &istream, zip_file_header &file_header) -{ - istream_read_zip_magic(istream, file_header.z_magic); - istream_read_zip_version(istream, file_header.z_extract); - file_header.z_flags = istream_read_uint16_le(istream); - file_header.z_compr = istream_read_uint16_le(istream); - istream_read_zip_dostime(istream, file_header.z_dostime); - file_header.z_crc32 = istream_read_uint32_le(istream); - file_header.z_csize = istream_read_uint32_le(istream); - file_header.z_usize = istream_read_uint32_le(istream); - file_header.z_namlen = istream_read_uint16_le(istream); - file_header.z_extras = istream_read_uint16_le(istream); - istream.seek(file_header.z_namlen + file_header.z_extras, SeekableInputStream::cur); -} - -/* B. data descriptor - * the data descriptor exists only if bit 3 of z_flags is set. It is byte aligned - * and immediately follows the last byte of compressed data. It is only used if - * the output media of the compressor was not seekable, eg. standard output. - */ -const zip_magic zip_file_trailer_magic = {{'P', 'K', 0x07, 0x08}}; - -struct zip_file_trailer { - zip_magic z_magic; - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ -}; - -inline void istream_read_zip_file_trailer(InputStream &istream, zip_file_trailer &file_trailer) -{ - istream_read_zip_magic(istream, file_trailer.z_magic); - file_trailer.z_crc32 = istream_read_uint32_le(istream); - file_trailer.z_csize = istream_read_uint32_le(istream); - file_trailer.z_usize = istream_read_uint32_le(istream); -} - - -/* C. central directory structure: - [file header] . . . end of central dir record - */ - -/* directory file header - * - a single entry including filename, extras and comment may not exceed 64k. - */ - -const zip_magic zip_root_dirent_magic = {{'P', 'K', 0x01, 0x02}}; - -struct zip_root_dirent { - zip_magic z_magic; - zip_version z_encoder; /* version made by */ - zip_version z_extract; /* version need to extract */ - unsigned short z_flags; /* general purpose bit flag */ - unsigned short z_compr; /* compression method */ - zip_dostime z_dostime; /* last mod file time&date (dos format) */ - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ - unsigned short z_namlen; /* filename length (null if stdin) */ - unsigned short z_extras; /* extra field length */ - unsigned short z_comment; /* file comment length */ - unsigned short z_diskstart; /* disk number of start (if spanning zip over multiple disks) */ - unsigned short z_filetype; /* internal file attributes, bit0 = ascii */ - unsigned int z_filemode; /* extrnal file attributes, eg. msdos attrib byte */ - unsigned int z_off; /* relative offset of local file header, seekval if singledisk */ - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ - /* followed by file comment (of variable size) */ -}; - -inline void istream_read_zip_root_dirent(SeekableInputStream &istream, zip_root_dirent &root_dirent) -{ - istream_read_zip_magic(istream, root_dirent.z_magic); - istream_read_zip_version(istream, root_dirent.z_encoder); - istream_read_zip_version(istream, root_dirent.z_extract); - root_dirent.z_flags = istream_read_uint16_le(istream); - root_dirent.z_compr = istream_read_uint16_le(istream); - istream_read_zip_dostime(istream, root_dirent.z_dostime); - root_dirent.z_crc32 = istream_read_uint32_le(istream); - root_dirent.z_csize = istream_read_uint32_le(istream); - root_dirent.z_usize = istream_read_uint32_le(istream); - root_dirent.z_namlen = istream_read_uint16_le(istream); - root_dirent.z_extras = istream_read_uint16_le(istream); - root_dirent.z_comment = istream_read_uint16_le(istream); - root_dirent.z_diskstart = istream_read_uint16_le(istream); - root_dirent.z_filetype = istream_read_uint16_le(istream); - root_dirent.z_filemode = istream_read_uint32_le(istream); - root_dirent.z_off = istream_read_uint32_le(istream); - istream.seek(root_dirent.z_namlen + root_dirent.z_extras + root_dirent.z_comment, SeekableInputStream::cur); -} - -/* end of central dir record */ -const zip_magic zip_disk_trailer_magic = {{'P', 'K', 0x05, 0x06}}; -const unsigned int disk_trailer_length = 22; -struct zip_disk_trailer { - zip_magic z_magic; - unsigned short z_disk; /* number of this disk */ - unsigned short z_finaldisk; /* number of the disk with the start of the central dir */ - unsigned short z_entries; /* total number of entries in the central dir on this disk */ - unsigned short z_finalentries; /* total number of entries in the central dir */ - unsigned int z_rootsize; /* size of the central directory */ - unsigned int z_rootseek; /* offset of start of central directory with respect to * - * the starting disk number */ - unsigned short z_comment; /* zipfile comment length */ - /* followed by zipfile comment (of variable size) */ -}; - -inline void istream_read_zip_disk_trailer(SeekableInputStream &istream, zip_disk_trailer &disk_trailer) -{ - istream_read_zip_magic(istream, disk_trailer.z_magic); - disk_trailer.z_disk = istream_read_uint16_le(istream); - disk_trailer.z_finaldisk = istream_read_uint16_le(istream); - disk_trailer.z_entries = istream_read_uint16_le(istream); - disk_trailer.z_finalentries = istream_read_uint16_le(istream); - disk_trailer.z_rootsize = istream_read_uint32_le(istream); - disk_trailer.z_rootseek = istream_read_uint32_le(istream); - disk_trailer.z_comment = istream_read_uint16_le(istream); - istream.seek(disk_trailer.z_comment, SeekableInputStream::cur); -} - -inline SeekableStream::position_type pkzip_find_disk_trailer(SeekableInputStream &istream) -{ - istream.seek(0, SeekableInputStream::end); - SeekableStream::position_type start_position = istream.tell(); - if (start_position < disk_trailer_length) { - return 0; - } - start_position -= disk_trailer_length; - - zip_magic magic; - istream.seek(start_position); - istream_read_zip_magic(istream, magic); - - if (magic == zip_disk_trailer_magic) { - return start_position; - } else { - const SeekableStream::position_type max_comment = 0x10000; - const SeekableStream::position_type bufshift = 6; - const SeekableStream::position_type bufsize = max_comment >> bufshift; - unsigned char buffer[bufsize]; - - SeekableStream::position_type search_end = (max_comment < start_position) ? start_position - max_comment : 0; - SeekableStream::position_type position = start_position; - while (position != search_end) { - StreamBase::size_type to_read = std::min(bufsize, position - search_end); - position -= to_read; - - istream.seek(position); - StreamBase::size_type size = istream.read(buffer, to_read); - - unsigned char *p = buffer + size; - while (p != buffer) { - --p; - magic.m_value[3] = magic.m_value[2]; - magic.m_value[2] = magic.m_value[1]; - magic.m_value[1] = magic.m_value[0]; - magic.m_value[0] = *p; - if (magic == zip_disk_trailer_magic) { - return position + (p - buffer); - } - } - } - return 0; - } -} - -#endif diff --git a/plugins/archivezip/plugin.cpp b/plugins/archivezip/plugin.cpp deleted file mode 100644 index 8e619d9..0000000 --- a/plugins/archivezip/plugin.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - - -class ArchiveZipAPI { -_QERArchiveTable m_archivezip; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "pk3"); - -ArchiveZipAPI() -{ - m_archivezip.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivezip; -} -}; - -typedef SingletonModule ArchiveZipModule; - -ArchiveZipModule g_ArchiveZipModule; - - -class ArchivePK4API { -_QERArchiveTable m_archivepk4; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "pk4"); - -ArchivePK4API() -{ - m_archivepk4.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivepk4; -} -}; - -typedef SingletonModule ArchivePK4Module; - -ArchivePK4Module g_ArchivePK4Module; - - -class ArchiveDPKAPI { -_QERArchiveTable m_archivedpk; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "dpk"); - -ArchiveDPKAPI() -{ - m_archivedpk.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivedpk; -} -}; - -typedef SingletonModule ArchiveDPKModule; - -ArchiveDPKModule g_ArchiveDPKModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_ArchiveZipModule.selfRegister(); - g_ArchivePK4Module.selfRegister(); - g_ArchiveDPKModule.selfRegister(); -} diff --git a/plugins/archivezip/zlibstream.h b/plugins/archivezip/zlibstream.h deleted file mode 100644 index 3761462..0000000 --- a/plugins/archivezip/zlibstream.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ZLIBSTREAM_H ) -#define INCLUDED_ZLIBSTREAM_H - -#include "zlib.h" -#include "idatastream.h" - -/// \brief A wrapper around an InputStream of data compressed with the zlib deflate algorithm. -/// -/// - Uses z_stream to decompress the data stream on the fly. -/// - Uses a buffer to reduce the number of times the wrapped stream must be read. -class DeflatedInputStream : public InputStream { -InputStream &m_istream; -z_stream m_zipstream; -enum unnamed0 { m_bufsize = 1024 }; -unsigned char m_buffer[m_bufsize]; - -public: -DeflatedInputStream(InputStream &istream) - : m_istream(istream) -{ - m_zipstream.zalloc = 0; - m_zipstream.zfree = 0; - m_zipstream.opaque = 0; - m_zipstream.avail_in = 0; - inflateInit2(&m_zipstream, -MAX_WBITS); -} - -~DeflatedInputStream() -{ - inflateEnd(&m_zipstream); -} - -size_type read(byte_type *buffer, size_type length) -{ - m_zipstream.next_out = buffer; - m_zipstream.avail_out = static_cast( length ); - while (m_zipstream.avail_out != 0) { - if (m_zipstream.avail_in == 0) { - m_zipstream.next_in = m_buffer; - m_zipstream.avail_in = static_cast( m_istream.read(m_buffer, m_bufsize)); - } - if (inflate(&m_zipstream, Z_SYNC_FLUSH) != Z_OK) { - break; - } - } - return length - m_zipstream.avail_out; -} -}; - -#endif diff --git a/plugins/brushexport/Makefile b/plugins/brushexport/Makefile deleted file mode 100644 index 115dbcb..0000000 --- a/plugins/brushexport/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - callbacks.o export.o interface.o plugin.o support.o - -# binary target -../../build/plugins/libbrushexport.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a $(PLUGIN_LDFLAGS) - -# object files -callbacks.o: callbacks.cpp callbacks.h -export.o: export.cpp export.h -interface.o: interface.cpp -plugin.o: plugin.cpp plugin.h -support.o: support.cpp support.h - -clean: - -rm -f *.o ../../build/plugins/libbrushexport.$(LIB_EXT) diff --git a/plugins/brushexport/callbacks.cpp b/plugins/brushexport/callbacks.cpp deleted file mode 100644 index d21ec5a..0000000 --- a/plugins/brushexport/callbacks.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include - -#include "qerplugin.h" -#include "debugging/debugging.h" -#include "support.h" -#include "export.h" - -// stuff from interface.cpp -void DestroyWindow(); - - -namespace callbacks { - -void OnDestroy(ui::Widget w, gpointer data) -{ - DestroyWindow(); -} - -void OnExportClicked(ui::Button button, gpointer user_data) -{ - auto window = ui::Window::from(lookup_widget(button, "w_plugplug2")); - ASSERT_TRUE(window); - const char *cpath = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0, false, false, true); - if (!cpath) { - return; - } - - std::string path(cpath); - - // get ignore list from ui - std::set ignore; - - auto view = ui::TreeView::from(lookup_widget(button, "t_materialist")); - ui::ListStore list = ui::ListStore::from(gtk_tree_view_get_model(view)); - - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first(list, &iter); - while (valid) { - gchar *data; - gtk_tree_model_get(list, &iter, 0, &data, -1); - globalOutputStream() << data << "\n"; - ignore.insert(std::string(data)); - g_free(data); - valid = gtk_tree_model_iter_next(list, &iter); - } - - for (std::set::iterator it(ignore.begin()); it != ignore.end(); ++it) { - globalOutputStream() << it->c_str() << "\n"; - } - - // collapse mode - collapsemode mode = COLLAPSE_NONE; - - auto radio = lookup_widget(button, "r_collapse"); - ASSERT_TRUE(radio); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) { - mode = COLLAPSE_ALL; - } else { - radio = lookup_widget(button, "r_collapsebymaterial"); - ASSERT_TRUE(radio); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) { - mode = COLLAPSE_BY_MATERIAL; - } else { - radio = lookup_widget(button, "r_nocollapse"); - ASSERT_TRUE(radio); - ASSERT_TRUE(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))); - mode = COLLAPSE_NONE; - } - } - - // export materials? - auto toggle = lookup_widget(button, "t_exportmaterials"); - ASSERT_TRUE(toggle); - - bool exportmat = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) { - exportmat = TRUE; - } - - // limit material names? - toggle = lookup_widget(button, "t_limitmatnames"); - ASSERT_TRUE(toggle); - - bool limitMatNames = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) { - limitMatNames = TRUE; - } - - // create objects instead of groups? - toggle = lookup_widget(button, "t_objects"); - ASSERT_TRUE(toggle); - - bool objects = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) { - objects = TRUE; - } - - // export - ExportSelection(ignore, mode, exportmat, path, limitMatNames, objects); -} - -void OnAddMaterial(ui::Button button, gpointer user_data) -{ - auto edit = ui::Entry::from(lookup_widget(button, "ed_materialname")); - ASSERT_TRUE(edit); - - const gchar *name = gtk_entry_get_text(edit); - if (g_utf8_strlen(name, -1) > 0) { - ui::ListStore list = ui::ListStore::from( - gtk_tree_view_get_model(ui::TreeView::from(lookup_widget(button, "t_materialist")))); - list.append(0, name); - gtk_entry_set_text(edit, ""); - } -} - -void OnRemoveMaterial(ui::Button button, gpointer user_data) -{ - ui::TreeView view = ui::TreeView::from(lookup_widget(button, "t_materialist")); - ui::ListStore list = ui::ListStore::from(gtk_tree_view_get_model(view)); - auto sel = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(sel, 0, &iter)) { - gtk_list_store_remove(list, &iter); - } -} - -void OnExportMatClicked(ui::Button button, gpointer user_data) -{ - ui::Widget toggleLimit = lookup_widget(button, "t_limitmatnames"); - ui::Widget toggleObject = lookup_widget(button, "t_objects"); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { - gtk_widget_set_sensitive(toggleLimit, TRUE); - gtk_widget_set_sensitive(toggleObject, TRUE); - } else { - gtk_widget_set_sensitive(toggleLimit, FALSE); - gtk_widget_set_sensitive(toggleObject, FALSE); - } -} - -} // callbacks diff --git a/plugins/brushexport/callbacks.h b/plugins/brushexport/callbacks.h deleted file mode 100644 index c10ef3d..0000000 --- a/plugins/brushexport/callbacks.h +++ /dev/null @@ -1,16 +0,0 @@ - -#include - -namespace callbacks { - -void OnDestroy(ui::Widget, gpointer); - -void OnExportClicked(ui::Button, gpointer); - -void OnAddMaterial(ui::Button, gpointer); - -void OnRemoveMaterial(ui::Button, gpointer); - -void OnExportMatClicked(ui::Button button, gpointer); - -} // callbacks diff --git a/plugins/brushexport/export.cpp b/plugins/brushexport/export.cpp deleted file mode 100644 index f07dc61..0000000 --- a/plugins/brushexport/export.cpp +++ /dev/null @@ -1,367 +0,0 @@ -#include "export.h" -#include "globaldefs.h" -#include "debugging/debugging.h" -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" - -#include - -// this is very evil, but right now there is no better way -#include "../../src/brush.h" - -// for limNames -const int MAX_MATERIAL_NAME = 20; - -/* - Abstract baseclass for modelexporters - the class collects all the data which then gets - exported through the WriteToFile method. - */ -class ExportData { -public: -ExportData(const std::set &ignorelist, collapsemode mode, bool limNames, bool objs); - -virtual ~ExportData(void); - -virtual void BeginBrush(Brush &b); - -virtual void AddBrushFace(Face &f); - -virtual void EndBrush(void); - -virtual bool WriteToFile(const std::string &path, collapsemode mode) const = 0; - -protected: - -// a group of faces -class group { -public: -std::string name; -std::list faces; -}; - -std::list groups; - -private: - -// "textures/common/caulk" -> "caulk" -void GetShaderNameFromShaderPath(const char *path, std::string &name); - -group *current; -collapsemode mode; -const std::set &ignorelist; -}; - -ExportData::ExportData(const std::set &_ignorelist, collapsemode _mode, bool _limNames, bool _objs) - : mode(_mode), - ignorelist(_ignorelist) -{ - current = 0; - - // in this mode, we need just one group - if (mode == COLLAPSE_ALL) { - groups.push_back(group()); - current = &groups.back(); - current->name = "all"; - } -} - -ExportData::~ExportData(void) -{ - -} - -void ExportData::BeginBrush(Brush &b) -{ - // create a new group for each brush - if (mode == COLLAPSE_NONE) { - groups.push_back(group()); - current = &groups.back(); - - StringOutputStream str(256); - str << "Brush" << (const unsigned int) groups.size(); - current->name = str.c_str(); - } -} - -void ExportData::EndBrush(void) -{ - // all faces of this brush were on the ignorelist, discard the emptygroup - if (mode == COLLAPSE_NONE) { - ASSERT_NOTNULL(current); - if (current->faces.empty()) { - groups.pop_back(); - current = 0; - } - } -} - -void ExportData::AddBrushFace(Face &f) -{ - std::string shadername; - GetShaderNameFromShaderPath(f.GetShader(), shadername); - - // ignore faces from ignore list - if (ignorelist.find(shadername) != ignorelist.end()) { - return; - } - - if (mode == COLLAPSE_BY_MATERIAL) { - // find a group for this material - current = 0; - const std::list::iterator end(groups.end()); - for (std::list::iterator it(groups.begin()); it != end; ++it) { - if (it->name == shadername) { - current = &(*it); - } - } - - // no group found, create one - if (!current) { - groups.push_back(group()); - current = &groups.back(); - current->name = shadername; - } - } - - ASSERT_NOTNULL(current); - - // add face to current group - current->faces.push_back(&f); - -#if GDEF_DEBUG - globalOutputStream() << "Added Face to group " << current->name.c_str() << "\n"; -#endif -} - -void ExportData::GetShaderNameFromShaderPath(const char *path, std::string &name) -{ - std::string tmp(path); - - size_t last_slash = tmp.find_last_of("/"); - - if (last_slash != std::string::npos && last_slash == (tmp.length() - 1)) { - name = path; - } else { - name = tmp.substr(last_slash + 1, tmp.length() - last_slash); - } - -#if GDEF_DEBUG - globalOutputStream() << "Last: " << (const unsigned int) last_slash << " " << "length: " - << (const unsigned int) tmp.length() << "Name: " << name.c_str() << "\n"; -#endif -} - -/* - Exporter writing facedata as wavefront object - */ -class ExportDataAsWavefront : public ExportData { -private: -bool expmat; -bool limNames; -bool objs; - -public: -ExportDataAsWavefront(const std::set &_ignorelist, collapsemode _mode, bool _expmat, bool _limNames, - bool _objs) - : ExportData(_ignorelist, _mode, _limNames, _objs) -{ - expmat = _expmat; - limNames = _limNames; - objs = _objs; -} - -bool WriteToFile(const std::string &path, collapsemode mode) const; -}; - -bool ExportDataAsWavefront::WriteToFile(const std::string &path, collapsemode mode) const -{ - std::string objFile = path; - - if (path.compare(path.length() - 4, 4, ".obj") != 0) { - objFile += ".obj"; - } - - std::string mtlFile = objFile.substr(0, objFile.length() - 4) + ".mtl"; - - std::set materials; - - TextFileOutputStream out(objFile.c_str()); - - if (out.failed()) { - globalErrorStream() << "Unable to open file\n"; - return false; - } - - out - << "# Wavefront Objectfile exported with radiants brushexport plugin 3.0 by Thomas 'namespace' Nitschke, spam@codecreator.net\n\n"; - - if (expmat) { - size_t last = mtlFile.find_last_of("//"); - std::string mtllib = mtlFile.substr(last + 1, mtlFile.size() - last).c_str(); - out << "mtllib " << mtllib.c_str() << "\n"; - } - - unsigned int vertex_count = 0; - - const std::list::const_iterator gend(groups.end()); - for (std::list::const_iterator git(groups.begin()); git != gend; ++git) { - typedef std::multimap bm; - bm brushMaterials; - typedef std::pair String_Pair; - - const std::list::const_iterator end(git->faces.end()); - - // submesh starts here - if (objs) { - out << "\no "; - } else { - out << "\ng "; - } - out << git->name.c_str() << "\n"; - - // material - if (expmat && mode == COLLAPSE_ALL) { - out << "usemtl material" << "\n\n"; - materials.insert("material"); - } - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // vertices - for (size_t i = 0; i < w.numpoints; ++i) { - out << "v " << FloatFormat(w[i].vertex.x(), 1, 6) << " " << FloatFormat(w[i].vertex.z(), 1, 6) << " " - << FloatFormat(w[i].vertex.y(), 1, 6) << "\n"; - } - } - out << "\n"; - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // texcoords - for (size_t i = 0; i < w.numpoints; ++i) { - out << "vt " << FloatFormat(w[i].texcoord.x(), 1, 6) << " " << FloatFormat(w[i].texcoord.y(), 1, 6) - << "\n"; - } - } - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // faces - StringOutputStream faceLine(256); - faceLine << "\nf"; - for (size_t i = 0; i < w.numpoints; ++i, ++vertex_count) { - faceLine << " " << vertex_count + 1 << "/" << vertex_count + 1; - } - - if (mode != COLLAPSE_ALL) { - materials.insert((*it)->getShader().getShader()); - brushMaterials.insert(String_Pair((*it)->getShader().getShader(), faceLine.c_str())); - } else { - out << faceLine.c_str(); - } - } - - if (mode != COLLAPSE_ALL) { - std::string lastMat; - std::string mat; - std::string faces; - - for (bm::iterator iter = brushMaterials.begin(); iter != brushMaterials.end(); iter++) { - mat = (*iter).first.c_str(); - faces = (*iter).second.c_str(); - - if (mat != lastMat) { - if (limNames && mat.size() > MAX_MATERIAL_NAME) { - out << "\nusemtl " << mat.substr(mat.size() - MAX_MATERIAL_NAME, mat.size()).c_str(); - } else { - out << "\nusemtl " << mat.c_str(); - } - } - - out << faces.c_str(); - lastMat = mat; - } - } - - out << "\n"; - } - - if (expmat) { - TextFileOutputStream outMtl(mtlFile.c_str()); - if (outMtl.failed()) { - globalErrorStream() << "Unable to open material file\n"; - return false; - } - - outMtl << "# Wavefront material file exported with NetRadiants brushexport plugin.\n"; - outMtl << "# Material Count: " << (const Unsigned) materials.size() << "\n\n"; - for (std::set::const_iterator it(materials.begin()); it != materials.end(); ++it) { - if (limNames && it->size() > MAX_MATERIAL_NAME) { - outMtl << "newmtl " << it->substr(it->size() - MAX_MATERIAL_NAME, it->size()).c_str() << "\n"; - } else { - outMtl << "newmtl " << it->c_str() << "\n"; - } - } - } - - return true; -} - - -class ForEachFace : public BrushVisitor { -public: -ForEachFace(ExportData &_exporter) - : exporter(_exporter) -{ -} - -void visit(Face &face) const -{ - exporter.AddBrushFace(face); -} - -private: -ExportData &exporter; -}; - -class ForEachSelected : public SelectionSystem::Visitor { -public: -ForEachSelected(ExportData &_exporter) - : exporter(_exporter) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *bptr = InstanceTypeCast::cast(instance); - if (bptr) { - Brush &brush(bptr->getBrush()); - - exporter.BeginBrush(brush); - ForEachFace face_vis(exporter); - brush.forEachFace(face_vis); - exporter.EndBrush(); - } -} - -private: -ExportData &exporter; -}; - -bool ExportSelection(const std::set &ignorelist, collapsemode m, bool exmat, const std::string &path, - bool limNames, bool objs) -{ - ExportDataAsWavefront exporter(ignorelist, m, exmat, limNames, objs); - - ForEachSelected vis(exporter); - GlobalSelectionSystem().foreachSelected(vis); - - return exporter.WriteToFile(path, m); -} diff --git a/plugins/brushexport/export.h b/plugins/brushexport/export.h deleted file mode 100644 index 68b3c3f..0000000 --- a/plugins/brushexport/export.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EXPORT_H -#define EXPORT_H - -#include -#include - -enum collapsemode { - COLLAPSE_ALL, - COLLAPSE_BY_MATERIAL, - COLLAPSE_NONE -}; - -bool ExportSelection(const std::set &ignorelist, collapsemode m, bool exmat, const std::string &path, - bool limitMatNames, bool objects); - -#endif diff --git a/plugins/brushexport/interface.cpp b/plugins/brushexport/interface.cpp deleted file mode 100644 index 3988d48..0000000 --- a/plugins/brushexport/interface.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include - -#include "debugging/debugging.h" -#include "callbacks.h" -#include "support.h" - -#define GLADE_HOOKUP_OBJECT(component, widget, name) \ - g_object_set_data_full( G_OBJECT( component ), name, \ - g_object_ref( (void *) widget ), (GDestroyNotify) g_object_unref ) - -#define GLADE_HOOKUP_OBJECT_NO_REF(component, widget, name) \ - g_object_set_data( G_OBJECT( component ), name, (void *) widget ) - -// created by glade -ui::Widget create_w_plugplug2(void) -{ - GSList *r_collapse_group = NULL; - - auto w_plugplug2 = ui::Window(ui::window_type::TOP); - gtk_widget_set_name(w_plugplug2, "w_plugplug2"); - gtk_window_set_title(w_plugplug2, "BrushExport-Plugin 3.0 by namespace"); - gtk_window_set_position(w_plugplug2, GTK_WIN_POS_CENTER); - gtk_window_set_destroy_with_parent(w_plugplug2, TRUE); - - auto vbox1 = ui::VBox(FALSE, 0); - gtk_widget_set_name(vbox1, "vbox1"); - vbox1.show(); - w_plugplug2.add(vbox1); - gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); - - auto hbox2 = ui::HBox(TRUE, 5); - gtk_widget_set_name(hbox2, "hbox2"); - hbox2.show(); - vbox1.pack_start(hbox2, FALSE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(hbox2), 5); - - auto vbox4 = ui::VBox(TRUE, 0); - gtk_widget_set_name(vbox4, "vbox4"); - vbox4.show(); - hbox2.pack_start(vbox4, TRUE, FALSE, 0); - - auto r_collapse = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Collapse mesh")); - gtk_widget_set_name(r_collapse, "r_collapse"); - gtk_widget_set_tooltip_text(r_collapse, "Collapse all brushes into a single group"); - r_collapse.show(); - vbox4.pack_start(r_collapse, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_collapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_collapse)); - - auto r_collapsebymaterial = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Collapse by material")); - gtk_widget_set_name(r_collapsebymaterial, "r_collapsebymaterial"); - gtk_widget_set_tooltip_text(r_collapsebymaterial, "Collapse into groups by material"); - r_collapsebymaterial.show(); - vbox4.pack_start(r_collapsebymaterial, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_collapsebymaterial), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_collapsebymaterial)); - - auto r_nocollapse = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Don't collapse")); - gtk_widget_set_name(r_nocollapse, "r_nocollapse"); - gtk_widget_set_tooltip_text(r_nocollapse, "Every brush is stored in its own group"); - r_nocollapse.show(); - vbox4.pack_start(r_nocollapse, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_nocollapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_nocollapse)); - - auto vbox3 = ui::VBox(FALSE, 0); - gtk_widget_set_name(vbox3, "vbox3"); - vbox3.show(); - hbox2.pack_start(vbox3, FALSE, FALSE, 0); - - auto b_export = ui::Button::from(gtk_button_new_from_stock("gtk-save")); - gtk_widget_set_name(b_export, "b_export"); - b_export.show(); - vbox3.pack_start(b_export, TRUE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(b_export), 5); - - auto b_close = ui::Button::from(gtk_button_new_from_stock("gtk-cancel")); - gtk_widget_set_name(b_close, "b_close"); - b_close.show(); - vbox3.pack_start(b_close, TRUE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(b_close), 5); - - auto vbox2 = ui::VBox(FALSE, 5); - gtk_widget_set_name(vbox2, "vbox2"); - vbox2.show(); - vbox1.pack_start(vbox2, TRUE, TRUE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 2); - - auto label1 = ui::Label("Ignored materials:"); - gtk_widget_set_name(label1, "label1"); - label1.show(); - vbox2.pack_start(label1, FALSE, FALSE, 0); - - auto scrolledwindow1 = ui::ScrolledWindow(ui::New); - gtk_widget_set_name(scrolledwindow1, "scrolledwindow1"); - scrolledwindow1.show(); - vbox2.pack_start(scrolledwindow1, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN); - - auto t_materialist = ui::TreeView(ui::New); - gtk_widget_set_name(t_materialist, "t_materialist"); - t_materialist.show(); - scrolledwindow1.add(t_materialist); - gtk_tree_view_set_headers_visible(t_materialist, FALSE); - gtk_tree_view_set_enable_search(t_materialist, FALSE); - - auto ed_materialname = ui::Entry(ui::New); - gtk_widget_set_name(ed_materialname, "ed_materialname"); - ed_materialname.show(); - vbox2.pack_start(ed_materialname, FALSE, FALSE, 0); - - auto hbox1 = ui::HBox(TRUE, 0); - gtk_widget_set_name(hbox1, "hbox1"); - hbox1.show(); - vbox2.pack_start(hbox1, FALSE, FALSE, 0); - - auto b_addmaterial = ui::Button::from(gtk_button_new_from_stock("gtk-add")); - gtk_widget_set_name(b_addmaterial, "b_addmaterial"); - b_addmaterial.show(); - hbox1.pack_start(b_addmaterial, FALSE, FALSE, 0); - - auto b_removematerial = ui::Button::from(gtk_button_new_from_stock("gtk-remove")); - gtk_widget_set_name(b_removematerial, "b_removematerial"); - b_removematerial.show(); - hbox1.pack_start(b_removematerial, FALSE, FALSE, 0); - - auto t_limitmatnames = ui::Widget::from( - gtk_check_button_new_with_mnemonic("Use short material names (max. 20 chars)")); - gtk_widget_set_name(t_limitmatnames, "t_limitmatnames"); - t_limitmatnames.show(); - vbox2.pack_end(t_limitmatnames, FALSE, FALSE, 0); - - auto t_objects = ui::Widget::from(gtk_check_button_new_with_mnemonic("Create (o)bjects instead of (g)roups")); - gtk_widget_set_name(t_objects, "t_objects"); - t_objects.show(); - vbox2.pack_end(t_objects, FALSE, FALSE, 0); - - auto t_exportmaterials = ui::CheckButton::from( - gtk_check_button_new_with_mnemonic("Create material information (.mtl file)")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_exportmaterials), true); - gtk_widget_set_name(t_exportmaterials, "t_exportmaterials"); - t_exportmaterials.show(); - vbox2.pack_end(t_exportmaterials, FALSE, FALSE, 10); - - using namespace callbacks; - w_plugplug2.connect("destroy", G_CALLBACK(OnDestroy), NULL); - g_signal_connect_swapped(G_OBJECT(b_close), "clicked", G_CALLBACK(OnDestroy), NULL); - - b_export.connect("clicked", G_CALLBACK(OnExportClicked), NULL); - b_addmaterial.connect("clicked", G_CALLBACK(OnAddMaterial), NULL); - b_removematerial.connect("clicked", G_CALLBACK(OnRemoveMaterial), NULL); - t_exportmaterials.connect("clicked", G_CALLBACK(OnExportMatClicked), NULL); - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF(w_plugplug2, w_plugplug2, "w_plugplug2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox1, "vbox1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, hbox2, "hbox2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox4, "vbox4"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_collapse, "r_collapse"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_collapsebymaterial, "r_collapsebymaterial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_nocollapse, "r_nocollapse"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox3, "vbox3"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_export, "b_export"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_close, "b_close"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox2, "vbox2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, label1, "label1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, scrolledwindow1, "scrolledwindow1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_materialist, "t_materialist"); - GLADE_HOOKUP_OBJECT(w_plugplug2, ed_materialname, "ed_materialname"); - GLADE_HOOKUP_OBJECT(w_plugplug2, hbox1, "hbox1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_addmaterial, "b_addmaterial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_removematerial, "b_removematerial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_exportmaterials, "t_exportmaterials"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_limitmatnames, "t_limitmatnames"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_objects, "t_objects"); - - return w_plugplug2; -} - -// global main window, is 0 when not created -ui::Widget g_brushexp_window{ui::null}; - -// spawn plugin window (and make sure it got destroyed first or never created) -void CreateWindow(void) -{ - ASSERT_TRUE(!g_brushexp_window); - - ui::Widget wnd = create_w_plugplug2(); - - // column & renderer - auto col = ui::TreeViewColumn::from(gtk_tree_view_column_new()); - gtk_tree_view_column_set_title(col, "materials"); - auto view = ui::TreeView::from(lookup_widget(wnd, "t_materialist")); - gtk_tree_view_append_column(view, col); - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(view, -1, "", renderer, "text", 0, NULL); - - // list store - auto ignorelist = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - gtk_tree_view_set_model(view, ignorelist); - ignorelist.unref(); - - gtk_widget_show_all(wnd); - g_brushexp_window = wnd; -} - -void DestroyWindow() -{ - ASSERT_TRUE(g_brushexp_window); - ui::Widget(g_brushexp_window).destroy(); - g_brushexp_window = ui::Widget(ui::null); -} - -bool IsWindowOpen() -{ - return g_brushexp_window; -} diff --git a/plugins/brushexport/plugin.cpp b/plugins/brushexport/plugin.cpp deleted file mode 100644 index 950c19e..0000000 --- a/plugins/brushexport/plugin.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (C) 2006, Thomas Nitschke. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "plugin.h" - -#include "iplugin.h" -#include "qerplugin.h" - -#include - -#include "debugging/debugging.h" -#include "string/string.h" -#include "modulesystem/singletonmodule.h" -#include "stream/textfilestream.h" -#include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" - -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "ifilesystem.h" -#include "ifiletypes.h" - -#include "support.h" - -#include "typesystem.h" - -void CreateWindow(void); - -void DestroyWindow(void); - -bool IsWindowOpen(void); - -namespace BrushExport { -ui::Window g_mainwnd{ui::null}; - -const char *init(void *hApp, void *pMainWidget) -{ - g_mainwnd = ui::Window::from(pMainWidget); - ASSERT_TRUE(g_mainwnd); - return ""; -} - -const char *getName() -{ - return "Brush export Plugin"; -} - -const char *getCommandList() -{ - return "About;Export selected as Wavefront OBJ"; -} - -const char *getCommandTitleList() -{ - return ""; -} - -void dispatch(const char *command, float *vMin, float *vMax, bool bSingleBrush) -{ - if (string_equal(command, "About")) { - GlobalRadiant().m_pfnMessageBox(g_mainwnd, "Brushexport plugin v 2.0 by namespace (www.codecreator.net)\n" - "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", - eMB_OK, - eMB_ICONDEFAULT); - } else if (string_equal(command, "Export selected as Wavefront OBJ")) { - if (IsWindowOpen()) { - DestroyWindow(); - } - CreateWindow(); - } -} -} - -class BrushExportDependencies : - public GlobalRadiantModuleRef, - public GlobalFiletypesModuleRef, - public GlobalBrushModuleRef, - public GlobalFileSystemModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalSelectionModuleRef { -public: -BrushExportDependencies(void) - : GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")) -{ -} -}; - -class BrushExportModule : public TypeSystemRef { -_QERPluginTable m_plugin; -public: -typedef _QERPluginTable Type; - -STRING_CONSTANT(Name, "Export Brushes"); - -BrushExportModule() -{ - m_plugin.m_pfnQERPlug_Init = &BrushExport::init; - m_plugin.m_pfnQERPlug_GetName = &BrushExport::getName; - m_plugin.m_pfnQERPlug_GetCommandList = &BrushExport::getCommandList; - m_plugin.m_pfnQERPlug_GetCommandTitleList = &BrushExport::getCommandTitleList; - m_plugin.m_pfnQERPlug_Dispatch = &BrushExport::dispatch; -} - -_QERPluginTable *getTable() -{ - return &m_plugin; -} -}; - -typedef SingletonModule SingletonBrushExportModule; -SingletonBrushExportModule g_BrushExportModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - g_BrushExportModule.selfRegister(); -} diff --git a/plugins/brushexport/plugin.h b/plugins/brushexport/plugin.h deleted file mode 100644 index d924f64..0000000 --- a/plugins/brushexport/plugin.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2006, Thomas Nitschke. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_EXPORT_H ) -#define INCLUDED_BRUSH_EXPORT_H - -#endif diff --git a/plugins/brushexport/support.cpp b/plugins/brushexport/support.cpp deleted file mode 100644 index c10e5b0..0000000 --- a/plugins/brushexport/support.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#include "support.h" - -ui::Widget -lookup_widget(ui::Widget widget, - const gchar *widget_name) -{ - ui::Widget parent{ui::null}; - - for (;;) { - if (GTK_IS_MENU(widget)) { - parent = ui::Widget::from(gtk_menu_get_attach_widget(GTK_MENU(widget))); - } else { - parent = ui::Widget::from(gtk_widget_get_parent(widget)); - } - if (!parent) { - parent = ui::Widget::from(g_object_get_data(G_OBJECT(widget), "GladeParentKey")); - } - if (parent == NULL) { - break; - } - widget = parent; - } - - auto found_widget = ui::Widget::from(g_object_get_data(G_OBJECT(widget), widget_name)); - if (!found_widget) { - g_warning("Widget not found: %s", widget_name); - } - return found_widget; -} diff --git a/plugins/brushexport/support.h b/plugins/brushexport/support.h deleted file mode 100644 index 374ba75..0000000 --- a/plugins/brushexport/support.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * DO NOT EDIT THIS FILE - it is generated by Glade. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -/* - * Public Functions. - */ - -/* - * This function returns a widget in a component created by Glade. - * Call it with the toplevel widget in the component (i.e. a window/dialog), - * or alternatively any widget in the component, and the name of the widget - * you want returned. - */ -ui::Widget lookup_widget(ui::Widget widget, - const gchar *widget_name); diff --git a/plugins/entity/Makefile b/plugins/entity/Makefile deleted file mode 100644 index d6005ec..0000000 --- a/plugins/entity/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - eclassmodel.o \ - entity.o \ - filters.o \ - generic.o \ - group.o \ - light.o \ - miscmodel.o \ - prop_dynamic.o \ - plugin.o \ - skincache.o \ - targetable.o - -# binary target -../../build/plugins/libentity.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -eclassmodel.o: eclassmodel.cpp eclassmodel.h -entity.o: entity.cpp entity.h -filters.o: filters.cpp filters.h -generic.o: generic.cpp generic.h -group.o: group.cpp group.h -light.o: light.cpp light.h -miscmodel.o: miscmodel.cpp miscmodel.h -prop_dynamic.o: prop_dynamic.cpp prop_dynamic.h -plugin.o: plugin.cpp -skincache.o: skincache.cpp skincache.h -targetable.o: targetable.cpp targetable.h - -clean: - -rm -f *.o ../../build/plugins/libentity.$(LIB_EXT) diff --git a/plugins/entity/angle.h b/plugins/entity/angle.h deleted file mode 100644 index 2c9c8c2..0000000 --- a/plugins/entity/angle.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ANGLE_H ) -#define INCLUDED_ANGLE_H - -#include "ientity.h" - -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -const float ANGLEKEY_IDENTITY = 0; - -inline void default_angle(float &angle) -{ - angle = ANGLEKEY_IDENTITY; -} - -inline void normalise_angle(float &angle) -{ - angle = static_cast( float_mod(angle, 360.0)); -} - -inline void read_angle(float &angle, const char *value) -{ - if (!string_parse_float(value, angle)) { - angle = 0; - } else { - normalise_angle(angle); - } -} - -inline void write_angle(float angle, Entity *entity) -{ - if (angle == 0) { - entity->setKeyValue("angle", ""); - } else { - char value[64]; - sprintf(value, "%f", angle); - entity->setKeyValue("angle", value); - } -} - -class AngleKey { -Callback m_angleChanged; -public: -float m_angle; - - -AngleKey(const Callback &angleChanged) - : m_angleChanged(angleChanged), m_angle(ANGLEKEY_IDENTITY) -{ -} - -void angleChanged(const char *value) -{ - read_angle(m_angle, value); - m_angleChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void write(Entity *entity) const -{ - write_angle(m_angle, entity); -} -}; - -inline float angle_rotated(float angle, const Quaternion &rotation) -{ - return matrix4_get_rotation_euler_xyz_degrees( - matrix4_multiplied_by_matrix4( - matrix4_rotation_for_z_degrees(angle), - matrix4_rotation_for_quaternion_quantised(rotation) - ) - ).z(); -} - -#endif diff --git a/plugins/entity/angles.h b/plugins/entity/angles.h deleted file mode 100644 index dca01c2..0000000 --- a/plugins/entity/angles.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ANGLES_H ) -#define INCLUDED_ANGLES_H - -#include "ientity.h" - -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "angle.h" - -const Vector3 ANGLESKEY_IDENTITY = Vector3(0, 0, 0); - -inline void default_angles(Vector3 &angles) -{ - angles = ANGLESKEY_IDENTITY; -} - -inline void normalise_angles(Vector3 &angles) -{ - angles[0] = static_cast( float_mod(angles[0], 360)); - angles[1] = static_cast( float_mod(angles[1], 360)); - angles[2] = static_cast( float_mod(angles[2], 360)); -} - -inline void read_angle(Vector3 &angles, const char *value) -{ - if (!string_parse_float(value, angles[2])) { - default_angles(angles); - } else { - angles[0] = 0; - angles[1] = 0; - normalise_angles(angles); - } -} - -inline void read_angles(Vector3 &angles, const char *value) -{ - if (!string_parse_vector3(value, angles)) { - default_angles(angles); - printf("Failed to read angles!\n"); - } else { - angles = Vector3(angles[2], angles[0], angles[1]); - normalise_angles(angles); - } -} - -inline void write_angles(const Vector3 &angles, Entity *entity) -{ - if (angles[0] == 0 - && angles[1] == 0 - && angles[2] == 0) { - entity->setKeyValue("angles", ""); - } else { - char value[64]; - sprintf(value, "%f %f %f", angles[1], angles[2], angles[0]); - entity->setKeyValue("angles", value); - } -} - -inline Vector3 angles_rotated(const Vector3 &angles, const Quaternion &rotation) -{ - return matrix4_get_rotation_euler_xyz_degrees( - matrix4_multiplied_by_matrix4( - matrix4_rotation_for_euler_xyz_degrees(angles), - matrix4_rotation_for_quaternion_quantised(rotation) - ) - ); -} - -class AnglesKey { -Callback m_anglesChanged; -public: -Vector3 m_angles; - - -AnglesKey(const Callback &anglesChanged) - : m_anglesChanged(anglesChanged), m_angles(ANGLESKEY_IDENTITY) -{ -} - -void angleChanged(const char *value) -{ - read_angle(m_angles, value); - m_anglesChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void anglesChanged(const char *value) -{ - read_angles(m_angles, value); - m_anglesChanged(); -} - -typedef MemberCaller AnglesChangedCaller; - -void write(Entity *entity) const -{ - write_angles(m_angles, entity); -} -}; - - -#endif diff --git a/plugins/entity/colour.h b/plugins/entity/colour.h deleted file mode 100644 index e1e9237..0000000 --- a/plugins/entity/colour.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_COLOUR_H ) -#define INCLUDED_COLOUR_H - -#include "ientity.h" -#include "irender.h" - -#include "math/vector.h" -#include "eclasslib.h" -#include "generic/callback.h" -#include "stringio.h" - -inline void default_colour(Vector3 &colour) -{ - colour = Vector3(1, 1, 1); -} - -inline void read_colour(Vector3 &colour, const char *value) -{ - if (!string_parse_vector3(value, colour)) { - default_colour(colour); - } -} - -inline void read_colour255(Vector3 &colour, const char *value) -{ - if (!string_parse_vector3(value, colour)) { - default_colour(colour); - } else { - colour[0] /= 255; - colour[1] /= 255; - colour[2] /= 255; - } -} - -inline void write_colour(const Vector3 &colour, Entity *entity) -{ - char value[64]; - - sprintf(value, "%f %f %f", colour[0], colour[1], colour[2]); - entity->setKeyValue("_color", value); -} - -class Colour { -Callback m_colourChanged; -Shader *m_state; - -void capture_state() -{ - m_state = colour_capture_state_fill(m_colour); -} - -void release_state() -{ - colour_release_state_fill(m_colour); -} - -public: -Vector3 m_colour; - -Colour(const Callback &colourChanged) - : m_colourChanged(colourChanged) -{ - default_colour(m_colour); - capture_state(); -} - -~Colour() -{ - release_state(); -} - -void colourChanged(const char *value) -{ - release_state(); - read_colour(m_colour, value); - capture_state(); - - m_colourChanged(); -} - -void colour255Changed(const char *value) -{ - release_state(); - read_colour255(m_colour, value); - capture_state(); - - m_colourChanged(); -} - -typedef MemberCaller ColourChangedCaller; -typedef MemberCaller Colour255ChangedCaller; - - -void write(Entity *entity) const -{ - write_colour(m_colour, entity); -} - -Shader *state() const -{ - return m_state; -} -}; - -#endif diff --git a/plugins/entity/curve.h b/plugins/entity/curve.h deleted file mode 100644 index 038771a..0000000 --- a/plugins/entity/curve.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CURVE_H ) -#define INCLUDED_CURVE_H - -#include "ientity.h" -#include "selectable.h" -#include "renderable.h" - -#include - -#include "math/curve.h" -#include "stream/stringstream.h" -#include "signal/signal.h" -#include "selectionlib.h" -#include "render.h" -#include "stringio.h" - -class RenderableCurve : public OpenGLRenderable { -public: -std::vector m_vertices; - -void render(RenderStateFlags state) const -{ - pointvertex_gl_array(&m_vertices.front()); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_vertices.size())); -} -}; - -inline void plotBasisFunction(std::size_t numSegments, int point, int degree) -{ - Knots knots; - KnotVector_openUniform(knots, 4, degree); - - globalOutputStream() << "plotBasisFunction point " << point << " of 4, knot vector:"; - for (Knots::iterator i = knots.begin(); i != knots.end(); ++i) { - globalOutputStream() << " " << *i; - } - globalOutputStream() << "\n"; - globalOutputStream() << "t=0 basis=" << BSpline_basis(knots, point, degree, 0.0) << "\n"; - for (std::size_t i = 1; i < numSegments; ++i) { - double t = (1.0 / double(numSegments)) * double(i); - globalOutputStream() << "t=" << t << " basis=" << BSpline_basis(knots, point, degree, t) << "\n"; - } - globalOutputStream() << "t=1 basis=" << BSpline_basis(knots, point, degree, 1.0) << "\n"; -} - -inline bool ControlPoints_parse(ControlPoints &controlPoints, const char *value) -{ - StringTokeniser tokeniser(value, " "); - - std::size_t size; - if (!string_parse_size(tokeniser.getToken(), size)) { - return false; - } - - if (size < 3) { - return false; - } - controlPoints.resize(size); - - if (!string_equal(tokeniser.getToken(), "(")) { - return false; - } - for (ControlPoints::iterator i = controlPoints.begin(); i != controlPoints.end(); ++i) { - if (!string_parse_float(tokeniser.getToken(), (*i).x()) - || !string_parse_float(tokeniser.getToken(), (*i).y()) - || !string_parse_float(tokeniser.getToken(), (*i).z())) { - return false; - } - } - if (!string_equal(tokeniser.getToken(), ")")) { - return false; - } - return true; -} - -inline void ControlPoints_write(const ControlPoints &controlPoints, StringOutputStream &value) -{ - value << Unsigned(controlPoints.size()) << " ("; - for (ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i) { - value << " " << (*i).x() << " " << (*i).y() << " " << (*i).z() << " "; - } - value << ")"; -} - -inline void -ControlPoint_testSelect(const Vector3 &point, ObservedSelectable &selectable, Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - test.TestPoint(point, best); - if (best.valid()) { - Selector_add(selector, selectable, best); - } -} - -class CurveEditType { -public: -Shader *m_controlsShader; -Shader *m_selectedShader; -}; - -inline void ControlPoints_write(ControlPoints &controlPoints, const char *key, Entity &entity) -{ - StringOutputStream value(256); - if (!controlPoints.empty()) { - ControlPoints_write(controlPoints, value); - } - entity.setKeyValue(key, value.c_str()); -} - -class CurveEdit { -SelectionChangeCallback m_selectionChanged; -ControlPoints &m_controlPoints; -typedef Array Selectables; -Selectables m_selectables; - -RenderablePointVector m_controlsRender; -mutable RenderablePointVector m_selectedRender; - -public: -typedef Static Type; - -CurveEdit(ControlPoints &controlPoints, const SelectionChangeCallback &selectionChanged) : - m_selectionChanged(selectionChanged), - m_controlPoints(controlPoints), - m_controlsRender(GL_POINTS), - m_selectedRender(GL_POINTS) -{ -} - -template -const Functor &forEachSelected(const Functor &functor) -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::iterator p = m_controlPoints.begin(); - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - if ((*i).isSelected()) { - functor(*p); - } - } - return functor; -} - -template -const Functor &forEachSelected(const Functor &functor) const -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::const_iterator p = m_controlPoints.begin(); - for (Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - if ((*i).isSelected()) { - functor(*p); - } - } - return functor; -} - -template -const Functor &forEach(const Functor &functor) const -{ - for (ControlPoints::const_iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i) { - functor(*i); - } - return functor; -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::const_iterator p = m_controlPoints.begin(); - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - ControlPoint_testSelect(*p, *i, selector, test); - } -} - -bool isSelected() const -{ - for (Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i) { - if ((*i).isSelected()) { - return true; - } - } - return false; -} - -void setSelected(bool selected) -{ - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i) { - (*i).setSelected(selected); - } -} - -void write(const char *key, Entity &entity) -{ - ControlPoints_write(m_controlPoints, key, entity); -} - -void transform(const Matrix4 &matrix) -{ - forEachSelected([&](Vector3 &point) { - matrix4_transform_point(matrix, point); - }); -} - -void snapto(float snap) -{ - forEachSelected([&](Vector3 &point) { - vector3_snap(point, snap); - }); -} - -void updateSelected() const -{ - m_selectedRender.clear(); - forEachSelected([&](const Vector3 &point) { - m_selectedRender.push_back(PointVertex(vertex3f_for_vector3(point), colour_selected)); - }); -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(Type::instance().m_controlsShader, Renderer::eWireframeOnly); - renderer.SetState(Type::instance().m_controlsShader, Renderer::eFullMaterials); - renderer.addRenderable(m_controlsRender, localToWorld); -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - updateSelected(); - if (!m_selectedRender.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(Type::instance().m_selectedShader, Renderer::eWireframeOnly); - renderer.SetState(Type::instance().m_selectedShader, Renderer::eFullMaterials); - renderer.addRenderable(m_selectedRender, localToWorld); - } -} - -void curveChanged() -{ - m_selectables.resize(m_controlPoints.size(), m_selectionChanged); - - m_controlsRender.clear(); - m_controlsRender.reserve(m_controlPoints.size()); - forEach([&](const Vector3 &point) { - m_controlsRender.push_back(PointVertex(vertex3f_for_vector3(point), colour_vertex)); - }); - - m_selectedRender.reserve(m_controlPoints.size()); -} - -typedef MemberCaller CurveChangedCaller; -}; - - -const int NURBS_degree = 3; - -class NURBSCurve { -Signal0 m_curveChanged; -Callback m_boundsChanged; -public: -ControlPoints m_controlPoints; -ControlPoints m_controlPointsTransformed; -NURBSWeights m_weights; -Knots m_knots; -RenderableCurve m_renderCurve; -AABB m_bounds; - -NURBSCurve(const Callback &boundsChanged) : m_boundsChanged(boundsChanged) -{ -} - -SignalHandlerId connect(const SignalHandler &curveChanged) -{ - curveChanged(); - return m_curveChanged.connectLast(curveChanged); -} - -void disconnect(SignalHandlerId id) -{ - m_curveChanged.disconnect(id); -} - -void notify() -{ - m_curveChanged(); -} - -void tesselate() -{ - if (!m_controlPointsTransformed.empty()) { - const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16; - m_renderCurve.m_vertices.resize(numSegments + 1); - m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]); - for (std::size_t i = 1; i < numSegments; ++i) { - m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( - NURBS_evaluate(m_controlPointsTransformed, m_weights, m_knots, NURBS_degree, - (1.0 / double(numSegments)) * double(i))); - } - m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( - m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]); - } else { - m_renderCurve.m_vertices.clear(); - } -} - -void curveChanged() -{ - tesselate(); - - m_bounds = AABB(); - for (ControlPoints::iterator i = m_controlPointsTransformed.begin(); - i != m_controlPointsTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_bounds, (*i)); - } - - m_boundsChanged(); - notify(); -} - -bool parseCurve(const char *value) -{ - if (!ControlPoints_parse(m_controlPoints, value)) { - return false; - } - - m_weights.resize(m_controlPoints.size()); - for (NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i) { - (*i) = 1; - } - - KnotVector_openUniform(m_knots, m_controlPoints.size(), NURBS_degree); - - //plotBasisFunction(8, 0, NURBS_degree); - - return true; -} - -void curveChanged(const char *value) -{ - if (string_empty(value) || !parseCurve(value)) { - m_controlPoints.resize(0); - m_knots.resize(0); - m_weights.resize(0); - } - m_controlPointsTransformed = m_controlPoints; - curveChanged(); -} - -typedef MemberCaller CurveChangedCaller; -}; - -class CatmullRomSpline { -Signal0 m_curveChanged; -Callback m_boundsChanged; -public: -ControlPoints m_controlPoints; -ControlPoints m_controlPointsTransformed; -RenderableCurve m_renderCurve; -AABB m_bounds; - -CatmullRomSpline(const Callback &boundsChanged) : m_boundsChanged(boundsChanged) -{ -} - -SignalHandlerId connect(const SignalHandler &curveChanged) -{ - curveChanged(); - return m_curveChanged.connectLast(curveChanged); -} - -void disconnect(SignalHandlerId id) -{ - m_curveChanged.disconnect(id); -} - -void notify() -{ - m_curveChanged(); -} - -void tesselate() -{ - if (!m_controlPointsTransformed.empty()) { - const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16; - m_renderCurve.m_vertices.resize(numSegments + 1); - m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]); - for (std::size_t i = 1; i < numSegments; ++i) { - m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( - CatmullRom_evaluate(m_controlPointsTransformed, (1.0 / double(numSegments)) * double(i))); - } - m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( - m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]); - } else { - m_renderCurve.m_vertices.clear(); - } -} - -bool parseCurve(const char *value) -{ - return ControlPoints_parse(m_controlPoints, value); -} - -void curveChanged() -{ - tesselate(); - - m_bounds = AABB(); - for (ControlPoints::iterator i = m_controlPointsTransformed.begin(); - i != m_controlPointsTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_bounds, (*i)); - } - - m_boundsChanged(); - notify(); -} - -void curveChanged(const char *value) -{ - if (string_empty(value) || !parseCurve(value)) { - m_controlPoints.resize(0); - } - m_controlPointsTransformed = m_controlPoints; - curveChanged(); -} - -typedef MemberCaller CurveChangedCaller; -}; - -const char *const curve_Nurbs = "curve_Nurbs"; -const char *const curve_CatmullRomSpline = "curve_CatmullRomSpline"; - - -#endif diff --git a/plugins/entity/doom3group.cpp b/plugins/entity/doom3group.cpp deleted file mode 100644 index a5d8912..0000000 --- a/plugins/entity/doom3group.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any Doom3 entity which does not have a fixed size specified in its entity-definition (e.g. func_static). -/// -/// This entity behaves as a group only when the "model" key is empty or is the same as the "name" key. Otherwise it behaves as a model. -/// When behaving as a group, the "origin" key is the translation to be applied to all brushes (not patches) grouped under this entity. -/// When behaving as a model, the "origin", "angle" and "rotation" keys directly control the entity's local-to-parent transform. -/// When either the "curve_Nurbs" or "curve_CatmullRomSpline" keys define a curve, the curve is rendered and can be edited. - -#include "doom3group.h" - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" -#include "modelskin.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "stream/stringstream.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angle.h" -#include "rotation.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "curve.h" -#include "modelskinkey.h" - -#include "entity.h" - -inline void -PointVertexArray_testSelect(PointVertex *first, std::size_t count, SelectionTest &test, SelectionIntersection &best) -{ - test.TestLineStrip( - VertexPointer( - reinterpret_cast( &first->vertex ), - sizeof(PointVertex) - ), - IndexPointer::index_type(count), - best - ); -} - -class Doom3Group : - public Bounded, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -TraversableNodeSet m_traverse; -MatrixTransform m_transform; - -SingletonModel m_model; -OriginKey m_originKey; -Vector3 m_origin; - -RotationKey m_rotationKey; -Float9 m_rotation; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -TraversableObserverPairRelay m_traverseObservers; -Doom3GroupOrigin m_funcStaticOrigin; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; -mutable Vector3 m_name_origin; -ModelSkinKey m_skin; - -public: -NURBSCurve m_curveNURBS; -SignalHandlerId m_curveNURBSChanged; -CatmullRomSpline m_curveCatmullRom; -SignalHandlerId m_curveCatmullRomChanged; -private: -mutable AABB m_curveBounds; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -CopiedString m_name; -CopiedString m_modelKey; -bool m_isModel; - -scene::Traversable *m_traversable; - -void construct() -{ - default_rotation(m_rotation); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", Doom3Group::ModelChangedCaller(*this)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", RotationKey::AngleChangedCaller(m_rotationKey)); - m_keyObservers.insert("rotation", RotationKey::RotationChangedCaller(m_rotationKey)); - m_keyObservers.insert("name", NameChangedCaller(*this)); - m_keyObservers.insert(curve_Nurbs, NURBSCurve::CurveChangedCaller(m_curveNURBS)); - m_keyObservers.insert(curve_CatmullRomSpline, CatmullRomSpline::CurveChangedCaller(m_curveCatmullRom)); - m_keyObservers.insert("skin", ModelSkinKey::SkinChangedCaller(m_skin)); - - m_traverseObservers.attach(m_funcStaticOrigin); - m_isModel = false; - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - attachTraverse(); - - m_entity.attach(m_keyObservers); -} - -void destroy() -{ - m_entity.detach(m_keyObservers); - - if (isModel()) { - detachModel(); - } else { - detachTraverse(); - } - - m_traverseObservers.detach(m_funcStaticOrigin); -} - -void attachModel() -{ - m_traversable = &m_model.getTraversable(); - m_model.attach(&m_traverseObservers); -} - -void detachModel() -{ - m_traversable = 0; - m_model.detach(&m_traverseObservers); -} - -void attachTraverse() -{ - m_traversable = &m_traverse; - m_traverse.attach(&m_traverseObservers); -} - -void detachTraverse() -{ - m_traversable = 0; - m_traverse.detach(&m_traverseObservers); -} - -bool isModel() const -{ - return m_isModel; -} - -void setIsModel(bool newValue) -{ - if (newValue && !m_isModel) { - detachTraverse(); - attachModel(); - - m_nameKeys.setKeyIsName(Static::instance().m_keyIsName); - m_model.modelChanged(m_modelKey.c_str()); - } else if (!newValue && m_isModel) { - detachModel(); - attachTraverse(); - - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - } - m_isModel = newValue; - updateTransform(); -} - -void updateIsModel() -{ - setIsModel(!string_equal(m_modelKey.c_str(), m_name.c_str())); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void nameChanged(const char *value) -{ - m_name = value; - updateIsModel(); -} - -typedef MemberCaller NameChangedCaller; - -void modelChanged(const char *value) -{ - m_modelKey = value; - updateIsModel(); - if (isModel()) { - m_model.modelChanged(value); - } else { - m_model.modelChanged(""); - } -} - -typedef MemberCaller ModelChangedCaller; - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - if (isModel()) { - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - matrix4_multiply_by_matrix4(m_transform.localToParent(), rotation_toMatrix(m_rotation)); - } - m_transformChanged(); - if (!isModel()) { - m_funcStaticOrigin.originChanged(); - } -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void rotationChanged() -{ - rotation_assign(m_rotation, m_rotationKey.m_rotation); - updateTransform(); -} - -typedef MemberCaller RotationChangedCaller; - -void skinChanged() -{ - if (isModel()) { - scene::Node *node = m_model.getNode(); - if (node != 0) { - Node_modelSkinChanged(*node); - } - } -} - -typedef MemberCaller SkinChangedCaller; - -public: -Doom3Group(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, m_name_origin), - m_name_origin(g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) -{ - construct(); -} - -Doom3Group(const Doom3Group &other, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) -{ - construct(); -} - -~Doom3Group() -{ - destroy(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); - - m_funcStaticOrigin.enable(); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_funcStaticOrigin.disable(); - - m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return *m_traversable; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -ModelSkin &getModelSkin() -{ - return m_skin.get(); -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.attach(*observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.detach(*observer); -} - -const AABB &localAABB() const -{ - m_curveBounds = m_curveNURBS.m_bounds; - aabb_extend_by_aabb_safe(m_curveBounds, m_curveCatmullRom.m_bounds); - return m_curveBounds; -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (isModel() && selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); - - if (!m_curveNURBS.m_renderCurve.m_vertices.empty()) { - renderer.addRenderable(m_curveNURBS.m_renderCurve, localToWorld); - } - if (!m_curveCatmullRom.m_renderCurve.m_vertices.empty()) { - renderer.addRenderable(m_curveCatmullRom.m_renderCurve, localToWorld); - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected, - const AABB &childBounds) const -{ - renderSolid(renderer, volume, localToWorld, selected); - - if (g_showNames) { - // draw models as usual - if (!isModel()) { - // don't draw the name for worldspawn - if (!strcmp(m_entity.getEntityClass().name(), "worldspawn")) { - return; - } - - // place name in the middle of the "children cloud" - m_name_origin = childBounds.origin; - } - - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void testSelect(Selector &selector, SelectionTest &test, SelectionIntersection &best) -{ - PointVertexArray_testSelect(&m_curveNURBS.m_renderCurve.m_vertices[0], - m_curveNURBS.m_renderCurve.m_vertices.size(), test, best); - PointVertexArray_testSelect(&m_curveCatmullRom.m_renderCurve.m_vertices[0], - m_curveCatmullRom.m_renderCurve.m_vertices.size(), test, best); -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - rotation_rotate(m_rotation, rotation); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - rotation_assign(m_rotation, m_rotationKey.m_rotation); - m_curveNURBS.m_controlPointsTransformed = m_curveNURBS.m_controlPoints; - m_curveCatmullRom.m_controlPointsTransformed = m_curveCatmullRom.m_controlPoints; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - rotation_assign(m_rotationKey.m_rotation, m_rotation); - m_rotationKey.write(&m_entity); - m_curveNURBS.m_controlPoints = m_curveNURBS.m_controlPointsTransformed; - ControlPoints_write(m_curveNURBS.m_controlPoints, curve_Nurbs, m_entity); - m_curveCatmullRom.m_controlPoints = m_curveCatmullRom.m_controlPointsTransformed; - ControlPoints_write(m_curveCatmullRom.m_controlPoints, curve_CatmullRomSpline, m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); - m_curveNURBS.curveChanged(); - m_curveCatmullRom.curveChanged(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class Doom3GroupInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Doom3Group &m_contained; -CurveEdit m_curveNURBS; -CurveEdit m_curveCatmullRom; -mutable AABB m_aabb_component; -public: - -typedef LazyStatic StaticTypeCasts; - - -Bounded &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "Doom3GroupInstance"); - -Doom3GroupInstance(const scene::Path &path, scene::Instance *parent, Doom3Group &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(Doom3Group::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained), - m_curveNURBS(m_contained.m_curveNURBS.m_controlPointsTransformed, SelectionChangedComponentCaller(*this)), - m_curveCatmullRom(m_contained.m_curveCatmullRom.m_controlPointsTransformed, - SelectionChangedComponentCaller(*this)) -{ - m_contained.instanceAttach(Instance::path()); - m_contained.m_curveNURBSChanged = m_contained.m_curveNURBS.connect(CurveEdit::CurveChangedCaller(m_curveNURBS)); - m_contained.m_curveCatmullRomChanged = m_contained.m_curveCatmullRom.connect( - CurveEdit::CurveChangedCaller(m_curveCatmullRom)); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~Doom3GroupInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.m_curveCatmullRom.disconnect(m_contained.m_curveCatmullRomChanged); - m_contained.m_curveNURBS.disconnect(m_contained.m_curveNURBSChanged); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); - - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), - Instance::childBounds()); - - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) { - m_curveNURBS.renderComponents(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponents(renderer, volume, localToWorld()); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld()); - SelectionIntersection best; - - m_contained.testSelect(selector, test, best); - - if (best.valid()) { - Selector_add(selector, getSelectable(), best); - } -} - -bool isSelectedComponents() const -{ - return m_curveNURBS.isSelected() || m_curveCatmullRom.isSelected(); -} - -void setSelectedComponents(bool selected, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - m_curveNURBS.setSelected(selected); - m_curveCatmullRom.setSelected(selected); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - test.BeginMesh(localToWorld()); - m_curveNURBS.testSelect(selector, test); - m_curveCatmullRom.testSelect(selector, test); - } -} - -void transformComponents(const Matrix4 &matrix) -{ - if (m_curveNURBS.isSelected()) { - m_curveNURBS.transform(matrix); - } - if (m_curveCatmullRom.isSelected()) { - m_curveCatmullRom.transform(matrix); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - m_curveNURBS.forEachSelected([&](const Vector3 &point) { - aabb_extend_by_point_safe(m_aabb_component, point); - }); - m_curveCatmullRom.forEachSelected([&](const Vector3 &point) { - aabb_extend_by_point_safe(m_aabb_component, point); - }); - return m_aabb_component; -} - -void snapComponents(float snap) -{ - if (m_curveNURBS.isSelected()) { - m_curveNURBS.snapto(snap); - m_curveNURBS.write(curve_Nurbs, m_contained.getEntity()); - } - if (m_curveCatmullRom.isSelected()) { - m_curveCatmullRom.snapto(snap); - m_curveCatmullRom.write(curve_CatmullRomSpline, m_contained.getEntity()); - } -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } else { - transformComponents(calculateTransform()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void selectionChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectionChangedComponentCaller; -}; - -class Doom3GroupNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Doom3Group m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -ModelSkin &get(NullType) -{ - return m_contained.getModelSkin(); -} - -Doom3GroupNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -Doom3GroupNode(const Doom3GroupNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~Doom3GroupNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new Doom3GroupNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new Doom3GroupInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -void Doom3Group_construct() -{ - CurveEdit::Type::instance().m_controlsShader = GlobalShaderCache().capture("$POINT"); - CurveEdit::Type::instance().m_selectedShader = GlobalShaderCache().capture("$SELPOINT"); -} - -void Doom3Group_destroy() -{ - GlobalShaderCache().release("$SELPOINT"); - GlobalShaderCache().release("$POINT"); -} - -scene::Node &New_Doom3Group(EntityClass *eclass) -{ - return (new Doom3GroupNode(eclass))->node(); -} diff --git a/plugins/entity/doom3group.h b/plugins/entity/doom3group.h deleted file mode 100644 index a5e0cd2..0000000 --- a/plugins/entity/doom3group.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STATIC_H ) -#define INCLUDED_STATIC_H - -namespace scene { -class Node; -} -class EntityClass; - -void Doom3Group_construct(); - -void Doom3Group_destroy(); - -scene::Node &New_Doom3Group(EntityClass *eclass); - -#endif diff --git a/plugins/entity/eclassmodel.cpp b/plugins/entity/eclassmodel.cpp deleted file mode 100644 index 0e40ae1..0000000 --- a/plugins/entity/eclassmodel.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which has a fixed size specified in its entity-definition and displays a model (e.g. ammo_bfg). -/// -/// This entity displays the model specified in its entity-definition. -/// The "origin" and "angle" keys directly control the entity's local-to-parent transform. -/// The "rotation" key directly controls the entity's local-to-parent transform for Doom3 only. - -#include "eclassmodel.h" - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "rotation.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "modelskinkey.h" - -#include "entity.h" - -class EclassModel : - public Snappable { -MatrixTransform m_transform; -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -RotationKey m_rotationKey; -Float9 m_rotation; -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; -ModelSkinKey m_skin; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - default_rotation(m_rotation); - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - matrix4_multiply_by_matrix4(m_transform.localToParent(), matrix4_rotation_for_euler_xyz_degrees(m_angles)); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void rotationChanged() -{ - rotation_assign(m_rotation, m_rotationKey.m_rotation); - updateTransform(); -} - -typedef MemberCaller RotationChangedCaller; - -void skinChanged() -{ - scene::Node *node = m_model.getNode(); - if (node != 0) { - Node_modelSkinChanged(*node); - } -} - -typedef MemberCaller SkinChangedCaller; - -public: - -EclassModel(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -EclassModel(const EclassModel &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - m_model.modelChanged(m_entity.getEntityClass().modelpath()); - m_skin.skinChanged(m_entity.getEntityClass().skin()); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_skin.skinChanged(""); - m_model.modelChanged(""); - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -ModelSkin &getModelSkin() -{ - return m_skin.get(); -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - if (g_gameType == eGameTypeDoom3) { - rotation_rotate(m_rotation, rotation); - } else { - m_angles = angles_rotated(m_angles, rotation); - } -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - if (g_gameType == eGameTypeDoom3) { - rotation_assign(m_rotation, m_rotationKey.m_rotation); - } else { - m_angles = m_anglesKey.m_angles; - } -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - if (g_gameType == eGameTypeDoom3) { - rotation_assign(m_rotationKey.m_rotation, m_rotation); - m_rotationKey.write(&m_entity); - } else { - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - } -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class EclassModelInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -EclassModel &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "EclassModelInstance"); - -EclassModelInstance(const scene::Path &path, scene::Instance *parent, EclassModel &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(EclassModel::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained) -{ - m_contained.instanceAttach(Instance::path()); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~EclassModelInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class EclassModelNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -EclassModel m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -ModelSkin &get(NullType) -{ - return m_contained.getModelSkin(); -} - -EclassModelNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -EclassModelNode(const EclassModelNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~EclassModelNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Node &clone() const -{ - return (new EclassModelNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new EclassModelInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_EclassModel(EntityClass *eclass) -{ - return (new EclassModelNode(eclass))->node(); -} diff --git a/plugins/entity/eclassmodel.h b/plugins/entity/eclassmodel.h deleted file mode 100644 index ebf9da2..0000000 --- a/plugins/entity/eclassmodel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASSMODEL_H ) -#define INCLUDED_ECLASSMODEL_H - -namespace scene { -class Node; -} -class EntityClass; - -scene::Node &New_EclassModel(EntityClass *eclass); - -#include "entity.h" - -#endif diff --git a/plugins/entity/entity.cpp b/plugins/entity/entity.cpp deleted file mode 100644 index 8d2a035..0000000 --- a/plugins/entity/entity.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entity.h" - -#include "ifilter.h" -#include "selectable.h" -#include "namespace.h" - -#include "scenelib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "pivot.h" - -#include "targetable.h" -#include "uniquenames.h" -#include "namekeys.h" -#include "stream/stringstream.h" -#include "filters.h" - - -#include "miscmodel.h" -#include "prop_dynamic.h" -#include "light.h" -#include "group.h" -#include "eclassmodel.h" -#include "generic.h" -#include "doom3group.h" - - -EGameType g_gameType; - -inline scene::Node &entity_for_eclass(EntityClass *eclass) -{ - if ( classname_equal(eclass->name(), "prop_dynamic" ) ) { - return New_PropDynamic(eclass); - } else if ( classname_equal(eclass->name(), "prop_static" ) ) { - return New_PropStatic(eclass); - } else if ( classname_equal(eclass->name(), "prop_physics" ) ) { - return New_PropStatic(eclass); - } else if (classname_equal(eclass->name(), "light") - || classname_equal(eclass->name(), "lightJunior")) { - return New_Light(eclass); - } else if (classname_equal(eclass->name(), "env_sound") - || classname_equal(eclass->name(), "lightJunior")) { - return New_Light(eclass); - } - - if (!eclass->fixedsize) { - /*if (g_gameType == eGameTypeDoom3) { - return New_Doom3Group(eclass); - } else {*/ - return New_Group(eclass); - /*}*/ - } else if (!string_empty(eclass->modelpath())) { - return New_EclassModel(eclass); - } else { - return New_GenericEntity(eclass); - } -} - -void Entity_setName(Entity &entity, const char *name) -{ - entity.setKeyValue("name", name); -} - -typedef ReferenceCaller EntitySetNameCaller; - -inline Namespaced *Node_getNamespaced(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline scene::Node &node_for_eclass(EntityClass *eclass) -{ - scene::Node &node = entity_for_eclass(eclass); - Node_getEntity(node)->setKeyValue("classname", eclass->name()); - - /*if (string_not_empty(eclass->name()) - && !string_equal(eclass->name(), "worldspawn") - && !string_equal(eclass->name(), "UNKNOWN_CLASS")) { - char buffer[1024]; - strcpy(buffer, eclass->name()); - strcat(buffer, "_1"); - GlobalNamespace().makeUnique(buffer, EntitySetNameCaller(*Node_getEntity(node))); - }*/ - - Namespaced *namespaced = Node_getNamespaced(node); - if (namespaced != 0) { - namespaced->setNamespace(GlobalNamespace()); - } - - return node; -} - -EntityCreator::KeyValueChangedFunc EntityKeyValues::m_entityKeyValueChanged = 0; -EntityCreator::KeyValueChangedFunc KeyValue::m_entityKeyValueChanged = 0; -Counter *EntityKeyValues::m_counter = 0; - -bool g_showNames = false; -bool g_showAngles = false; -bool g_newLightDraw = true; -bool g_lightRadii = true; - -class ConnectEntities { -public: -Entity *m_e1; -Entity *m_e2; -int m_index; - -ConnectEntities(Entity *e1, Entity *e2, int index) : m_e1(e1), m_e2(e2), m_index(index) -{ -} - -const char *keyname() -{ - StringOutputStream key(16); - if (m_index <= 0) { - return "target"; - } - if (m_index == 1) { - return "killtarget"; - } - key << "target" << m_index; - return key.c_str(); -} - -void connect(const char *name) -{ - m_e1->setKeyValue(keyname(), name); - m_e2->setKeyValue("targetname", name); -} - -typedef MemberCaller ConnectCaller; -}; - -inline Entity *ScenePath_getEntity(const scene::Path &path) -{ - Entity *entity = Node_getEntity(path.top()); - if (entity == 0) { - entity = Node_getEntity(path.parent()); - } - return entity; -} - -class Quake3EntityCreator : public EntityCreator { -public: -scene::Node &createEntity(EntityClass *eclass) -{ - return node_for_eclass(eclass); -} - -void setKeyValueChangedFunc(KeyValueChangedFunc func) -{ - EntityKeyValues::setKeyValueChangedFunc(func); -} - -void setCounter(Counter *counter) -{ - EntityKeyValues::setCounter(counter); -} - -void connectEntities(const scene::Path &path, const scene::Path &targetPath, int index) -{ - Entity *e1 = ScenePath_getEntity(path); - Entity *e2 = ScenePath_getEntity(targetPath); - - if (e1 == 0 || e2 == 0) { - globalErrorStream() << "entityConnectSelected: both of the selected instances must be an entity\n"; - return; - } - - if (e1 == e2) { - globalErrorStream() - << "entityConnectSelected: the selected instances must not both be from the same entity\n"; - return; - } - - - UndoableCommand undo("entityConnectSelected"); - - if (g_gameType == eGameTypeDoom3) { - StringOutputStream key(16); - if (index >= 0) { - key << "target"; - if (index != 0) { - key << index; - } - e1->setKeyValue(key.c_str(), e2->getKeyValue("name")); - key.clear(); - } else { - for (unsigned int i = 0;; ++i) { - key << "target"; - if (i != 0) { - key << i; - } - const char *value = e1->getKeyValue(key.c_str()); - if (string_empty(value)) { - e1->setKeyValue(key.c_str(), e2->getKeyValue("name")); - break; - } - key.clear(); - } - } - } else { - ConnectEntities connector(e1, e2, index); - const char *value = e2->getKeyValue("targetname"); - if (!string_empty(value)) { - connector.connect(value); - } else { - const char *type = e2->getKeyValue("classname"); - if (string_empty(type)) { - type = "t"; - } - StringOutputStream key(64); - key << type << "1"; - GlobalNamespace().makeUnique(key.c_str(), ConnectEntities::ConnectCaller(connector)); - } - } - - SceneChangeNotify(); -} - -void setLightRadii(bool lightRadii) -{ - g_lightRadii = lightRadii; -} - -bool getLightRadii() const -{ - return g_lightRadii; -} - -void setShowNames(bool showNames) -{ - g_showNames = showNames; -} - -bool getShowNames() -{ - return g_showNames; -} - -void setShowAngles(bool showAngles) -{ - g_showAngles = showAngles; -} - -bool getShowAngles() -{ - return g_showAngles; -} - -void printStatistics() const -{ - StringPool_analyse(EntityKeyValues::getPool()); -} -}; - -Quake3EntityCreator g_Quake3EntityCreator; - -EntityCreator &GetEntityCreator() -{ - return g_Quake3EntityCreator; -} - - -class filter_entity_classname : public EntityFilter { -const char *m_classname; -public: -filter_entity_classname(const char *classname) : m_classname(classname) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), m_classname); -} -}; - -class filter_entity_classgroup : public EntityFilter { -const char *m_classgroup; -std::size_t m_length; -public: -filter_entity_classgroup(const char *classgroup) : m_classgroup(classgroup), m_length(string_length(m_classgroup)) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal_n(entity.getKeyValue("classname"), m_classgroup, m_length); -} -}; - -/* this is such a bad hack because radiant sucks and I ran out of time */ -class filter_entity_classtwo : public EntityFilter { -const char *m_classname1; -const char *m_classname2; -public: -filter_entity_classtwo(const char *classname1, const char *classname2) : m_classname1(classname1), m_classname2(classname2) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), m_classname1) || string_equal(entity.getKeyValue("classname"), m_classname2); -} -}; - -filter_entity_classtwo g_filter_entity_world("worldspawn", "func_group"); -filter_entity_classname g_filter_entity_func_group("func_group"); -filter_entity_classtwo g_filter_entity_details("func_detail", "func_detail_illusionary"); -filter_entity_classname g_filter_entity_light("light"); -filter_entity_classname g_filter_entity_prop_static("prop_static"); -filter_entity_classname g_filter_entity_prop_dynamic("prop_dynamic"); -filter_entity_classgroup g_filter_entity_trigger("trigger_"); -filter_entity_classgroup g_filter_entity_path("path_"); - -class filter_entity_doom3model : public EntityFilter { -public: -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), "func_static") - && !string_equal(entity.getKeyValue("model"), entity.getKeyValue("name")); -} -}; - -filter_entity_doom3model g_filter_entity_doom3model; - - -void Entity_InitFilters() -{ - add_entity_filter(g_filter_entity_world, EXCLUDE_WORLD); - add_entity_filter(g_filter_entity_func_group, EXCLUDE_GROUP); - add_entity_filter(g_filter_entity_details, EXCLUDE_DETAILS); - add_entity_filter(g_filter_entity_trigger, EXCLUDE_TRIGGERS); - add_entity_filter(g_filter_entity_prop_static, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_prop_dynamic, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_doom3model, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_light, EXCLUDE_LIGHTS); - add_entity_filter(g_filter_entity_path, EXCLUDE_PATHS); - add_entity_filter(g_filter_entity_world, EXCLUDE_ENT, true); -} - - -#include "preferencesystem.h" - -void Entity_Construct(EGameType gameType) -{ - g_gameType = gameType; - - Static::instance().m_keyIsName = keyIsNameQuake3; - Static::instance().m_nameKey = "targetname"; - - - GlobalPreferenceSystem().registerPreference("SI_ShowNames", make_property_string(g_showNames)); - GlobalPreferenceSystem().registerPreference("SI_ShowAngles", make_property_string(g_showAngles)); - GlobalPreferenceSystem().registerPreference("NewLightStyle", make_property_string(g_newLightDraw)); - GlobalPreferenceSystem().registerPreference("LightRadiuses", make_property_string(g_lightRadii)); - - Entity_InitFilters(); - Light_Construct(); - PropStatic_construct(); - PropDynamic_construct(); - /* Doom3Group_construct();*/ - - RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture("$PIVOT"); - - GlobalShaderCache().attachRenderable(StaticRenderableConnectionLines::instance()); -} - -void Entity_Destroy() -{ - GlobalShaderCache().detachRenderable(StaticRenderableConnectionLines::instance()); - - GlobalShaderCache().release("$PIVOT"); - - /*Doom3Group_destroy();*/ - PropStatic_destroy(); - PropDynamic_destroy(); - Light_Destroy(); -} diff --git a/plugins/entity/entity.h b/plugins/entity/entity.h deleted file mode 100644 index a1fe3eb..0000000 --- a/plugins/entity/entity.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITY_H ) -#define INCLUDED_ENTITY_H - -class EntityCreator; - -EntityCreator &GetEntityCreator(); - -enum EGameType { - eGameTypeQuake3, - eGameTypeRTCW, - eGameTypeDoom3, -}; - -extern EGameType g_gameType; - -class FilterSystem; - -void Entity_Construct(EGameType gameType = eGameTypeQuake3); - -void Entity_Destroy(); - -extern bool g_showNames; -extern bool g_showAngles; -extern bool g_newLightDraw; -extern bool g_lightRadii; - -#endif diff --git a/plugins/entity/filters.cpp b/plugins/entity/filters.cpp deleted file mode 100644 index 3453fe5..0000000 --- a/plugins/entity/filters.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filters.h" - -#include "ifilter.h" - -#include - -class EntityFilterWrapper : public Filter { -bool m_active; -bool m_invert; -EntityFilter &m_filter; -public: -EntityFilterWrapper(EntityFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Entity &entity) -{ - return m_invert ^ m_filter.filter(entity); -} -}; - - -typedef std::list EntityFilters; -EntityFilters g_entityFilters; - -void add_entity_filter(EntityFilter &filter, int mask, bool invert) -{ - g_entityFilters.push_back(EntityFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_entityFilters.back(), mask); -} - -bool entity_filtered(Entity &entity) -{ - for (EntityFilters::iterator i = g_entityFilters.begin(); i != g_entityFilters.end(); ++i) { - if ((*i).active() && (*i).filter(entity)) { - return true; - } - } - return false; -} diff --git a/plugins/entity/filters.h b/plugins/entity/filters.h deleted file mode 100644 index 7be17b2..0000000 --- a/plugins/entity/filters.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FILTERS_H ) -#define INCLUDED_FILTERS_H - -#include "ifilter.h" - -#include "generic/callback.h" -#include "scenelib.h" - -class Entity; - -class EntityFilter { -public: -virtual bool filter(const Entity &entity) const = 0; -}; - -bool entity_filtered(Entity &entity); - -void add_entity_filter(EntityFilter &filter, int mask, bool invert = false); - -class ClassnameFilter : public Filterable { -scene::Node &m_node; -public: -Entity &m_entity; - -ClassnameFilter(Entity &entity, scene::Node &node) : m_node(node), m_entity(entity) -{ -} - -~ClassnameFilter() -{ -} - -void instanceAttach() -{ - GlobalFilterSystem().registerFilterable(*this); -} - -void instanceDetach() -{ - GlobalFilterSystem().unregisterFilterable(*this); -} - -void updateFiltered() -{ - if (entity_filtered(m_entity)) { - m_node.enable(scene::Node::eFiltered); - } else { - m_node.disable(scene::Node::eFiltered); - } -} - -void classnameChanged(const char *value) -{ - updateFiltered(); -} - -typedef MemberCaller ClassnameChangedCaller; -}; - -#endif diff --git a/plugins/entity/generic.cpp b/plugins/entity/generic.cpp deleted file mode 100644 index a7fd902..0000000 --- a/plugins/entity/generic.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which has a fixed size specified in its entity-definition and does not display a model (e.g. info_player_start). -/// -/// This entity displays an axis-aligned bounding box of the size and colour specified in its entity-definition. -/// The "origin" key directly controls the entity's local-to-parent transform. -/// An arrow is drawn to visualise the "angle" key. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "math/line.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "rotation.h" - -#include "entity.h" - - -class RenderableArrow : public OpenGLRenderable { -const Vector3 &m_origin; -const Vector3 &m_angles; - -public: -RenderableArrow(const Vector3 &origin, const Vector3 &angles) - : m_origin(origin), m_angles(angles) -{ -} - -void render(RenderStateFlags state) const -{ - Matrix4 mat = matrix4_rotation_for_euler_xyz_degrees(m_angles); - arrow_draw(m_origin, matrix4_transformed_direction(mat, Vector3(1, 0, 0)), - matrix4_transformed_direction(mat, Vector3(0, 1, 0)), - matrix4_transformed_direction(mat, Vector3(0, 0, 1))); -} -}; - -inline void read_aabb(AABB &aabb, const EntityClass &eclass) -{ - aabb = aabb_for_minmax(eclass.mins, eclass.maxs); -} - - -class GenericEntity : - public Cullable, - public Bounded, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; - -AABB m_aabb_local; - -RenderableArrow m_arrow; -RenderableSolidAABB m_aabb_solid; -RenderableWireframeAABB m_aabb_wire; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - read_aabb(m_aabb_local, m_entity.getEntityClass()); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; -public: - -GenericEntity(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_arrow(m_aabb_local.origin, m_angles), - m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -GenericEntity(const GenericEntity &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_arrow(m_aabb_local.origin, m_angles), - m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(localAABB(), localToWorld); -} - -void renderArrow(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (g_showAngles) { - renderer.addRenderable(m_arrow, localToWorld); - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials); - renderer.addRenderable(m_aabb_solid, localToWorld); - renderArrow(renderer, volume, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (string_equal(m_entity.getKeyValue("classname"), "worldspawn")) { - /* todo: handle colors differently for worldspawn brushes */ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - } else { - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - } - - renderer.addRenderable(m_aabb_wire, localToWorld); - renderArrow(renderer, volume, localToWorld); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_local, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class GenericEntityInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -GenericEntity &m_contained; -mutable AABB m_bounds; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_contained; -} - -Cullable &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "GenericEntityInstance"); - -GenericEntityInstance(const scene::Path &path, scene::Instance *parent, GenericEntity &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(GenericEntity::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained) -{ - m_contained.instanceAttach(Instance::path()); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~GenericEntityInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_contained.testSelect(selector, test, Instance::localToWorld()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class GenericEntityNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -InstanceSet m_instances; - -scene::Node m_node; -GenericEntity m_contained; - -public: -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -GenericEntityNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ -} - -GenericEntityNode(const GenericEntityNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new GenericEntityNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new GenericEntityInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_GenericEntity(EntityClass *eclass) -{ - return (new GenericEntityNode(eclass))->node(); -} diff --git a/plugins/entity/generic.h b/plugins/entity/generic.h deleted file mode 100644 index 1a04b95..0000000 --- a/plugins/entity/generic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_H ) -#define INCLUDED_GENERIC_H - -scene::Node &New_GenericEntity(EntityClass *eclass); - -#endif diff --git a/plugins/entity/group.cpp b/plugins/entity/group.cpp deleted file mode 100644 index 8760cca..0000000 --- a/plugins/entity/group.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which does not have a fixed size specified in its entity-definition (except misc_model). -/// -/// This entity behaves as a group, i.e. it contains brushes. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -/// The "origin" key directly controls the entity's local-to-parent transform. - -class Group { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; -TraversableNodeSet m_traverse; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; - -OriginKey m_originKey; -Vector3 m_origin; - -RenderableNamedEntity m_renderName; -mutable Vector3 m_name_origin; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); -} - -public: -Group(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_renderName(m_named, m_name_origin), - m_name_origin(g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -Group(const Group &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverse.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverse.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, - const AABB &childBounds) const -{ - renderSolid(renderer, volume, localToWorld); - - if (g_showNames) { - // don't draw the name for worldspawn - if (!strcmp(m_entity.getEntityClass().name(), "worldspawn")) { - return; - } - - // place name in the middle of the "children cloud" - m_name_origin = childBounds.origin; - - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -#if 0 -class TransformableSetTranslation -{ -Translation m_value; -public: -TransformableSetTranslation( const Translation& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setTranslation( m_value ); -} -}; - -class TransformableSetRotation -{ -Rotation m_value; -public: -TransformableSetRotation( const Rotation& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setRotation( m_value ); -} -}; - -class TransformableSetScale -{ -Scale m_value; -public: -TransformableSetScale( const Scale& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setScale( m_value ); -} -}; - -class TransformableSetType -{ -TransformModifierType m_value; -public: -TransformableSetType( const TransformModifierType& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setType( m_value ); -} -}; - -class TransformableFreezeTransform -{ -TransformModifierType m_value; -public: -void operator()( Transformable& transformable ) const { - transformable.freezeTransform(); -} -}; - -template -inline void Scene_forEachChildTransformable( const Functor& functor, const scene::Path& path ){ - GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply >( functor ), path ); -} -#endif - -class GroupInstance : - public TargetableInstance, - public TransformModifier, -#if 0 - public Transformable, -#endif - public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); -#if 0 - InstanceStaticCast::install( m_casts ); -#endif -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Group &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -GroupInstance(const scene::Path &path, scene::Instance *parent, Group &group) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), group.getEntity(), *this), - TransformModifier(Group::TransformChangedCaller(group), ApplyTransformCaller(*this)), - m_contained(group) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~GroupInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), Instance::childBounds()); -} - -STRING_CONSTANT(Name, "GroupInstance"); - -#if 0 -void setType( TransformModifierType type ){ - Scene_forEachChildTransformable( TransformableSetType( type ), Instance::path() ); -} -void setTranslation( const Translation& value ){ - Scene_forEachChildTransformable( TransformableSetTranslation( value ), Instance::path() ); -} -void setRotation( const Rotation& value ){ - Scene_forEachChildTransformable( TransformableSetRotation( value ), Instance::path() ); -} -void setScale( const Scale& value ){ - Scene_forEachChildTransformable( TransformableSetScale( value ), Instance::path() ); -} -void freezeTransform(){ - Scene_forEachChildTransformable( TransformableFreezeTransform(), Instance::path() ); -} - -void evaluateTransform(){ -} -#endif - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class GroupNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Group m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -GroupNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -GroupNode(const GroupNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~GroupNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new GroupNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new GroupInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_Group(EntityClass *eclass) -{ - return (new GroupNode(eclass))->node(); -} diff --git a/plugins/entity/group.h b/plugins/entity/group.h deleted file mode 100644 index c8c8353..0000000 --- a/plugins/entity/group.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GROUP_H ) -#define INCLUDED_GROUP_H - -scene::Node &New_Group(EntityClass *eclass); - -#endif diff --git a/plugins/entity/keyobservers.h b/plugins/entity/keyobservers.h deleted file mode 100644 index 5767674..0000000 --- a/plugins/entity/keyobservers.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_KEYOBSERVERS_H ) -#define INCLUDED_KEYOBSERVERS_H - -#include "entitylib.h" -#include - -class KeyObserverMap : public Entity::Observer { -typedef std::multimap KeyObservers; -KeyObservers m_keyObservers; -public: -void insert(const char *key, const KeyObserver &observer) -{ - m_keyObservers.insert(KeyObservers::value_type(key, observer)); -} - -void insert(const char *key, EntityKeyValue &value) -{ - for (KeyObservers::const_iterator i = m_keyObservers.find(key); - i != m_keyObservers.end() && string_equal((*i).first, key); ++i) { - value.attach((*i).second); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - for (KeyObservers::const_iterator i = m_keyObservers.find(key); - i != m_keyObservers.end() && string_equal((*i).first, key); ++i) { - value.detach((*i).second); - } -} -}; - -#endif diff --git a/plugins/entity/light.cpp b/plugins/entity/light.cpp deleted file mode 100644 index f177d5b..0000000 --- a/plugins/entity/light.cpp +++ /dev/null @@ -1,1680 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any light entity (e.g. light). -/// -/// This entity dislays a special 'light' model. -/// The "origin" key directly controls the position of the light model in local space. -/// The "_color" key controls the colour of the light model. -/// The "light" key is visualised with a sphere representing the approximate coverage of the light (except Doom3). -/// Doom3 special behaviour: -/// The entity behaves as a group. -/// The "origin" key is the translation to be applied to all brushes (not patches) grouped under this entity. -/// The "light_center" and "light_radius" keys are visualised with a point and a box when the light is selected. -/// The "rotation" key directly controls the orientation of the light bounding box in local space. -/// The "light_origin" key controls the position of the light independently of the "origin" key if it is specified. -/// The "light_rotation" key duplicates the behaviour of the "rotation" key if it is specified. This appears to be an unfinished feature in Doom3. - -#include "light.h" - -#include - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "render.h" -#include "stringio.h" -#include "traverselib.h" -#include "dragplanes.h" - -#include "targetable.h" -#include "origin.h" -#include "colour.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "rotation.h" - -#include "entity.h" - -extern bool g_newLightDraw; - - -void sphere_draw_fill(const Vector3 &origin, float radius, int sides) -{ - if (radius <= 0) { - return; - } - - const double dt = c_2pi / static_cast( sides ); - const double dp = c_pi / static_cast( sides ); - - glBegin(GL_TRIANGLES); - for (int i = 0; i <= sides - 1; ++i) { - for (int j = 0; j <= sides - 2; ++j) { - const double t = i * dt; - const double p = (j * dp) - (c_pi / 2.0); - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - - { - const double p = (sides - 1) * dp - (c_pi / 2.0); - for (int i = 0; i <= sides - 1; ++i) { - const double t = i * dt; - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - glEnd(); -} - -void sphere_draw_wire(const Vector3 &origin, float radius, int sides) -{ - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - static_cast( origin[0] + radius * dc ), - static_cast( origin[1] + radius * ds ), - origin[2] - ); - } - - glEnd(); - } - - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - static_cast( origin[0] + radius * dc ), - origin[1], - static_cast( origin[2] + radius * ds ) - ); - } - - glEnd(); - } - - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - origin[0], - static_cast( origin[1] + radius * dc ), - static_cast( origin[2] + radius * ds ) - ); - } - - glEnd(); - } -} - -void light_draw_box_lines(const Vector3 &origin, const Vector3 points[8]) -{ - //draw lines from the center of the bbox to the corners - glBegin(GL_LINES); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[1])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[5])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[2])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[6])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[0])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[4])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[3])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[7])); - - glEnd(); -} - -void light_draw_radius_wire(const Vector3 &origin, const float envelope[3]) -{ - if (envelope[0] > 0) { - sphere_draw_wire(origin, envelope[0], 24); - } - if (envelope[1] > 0) { - sphere_draw_wire(origin, envelope[1], 24); - } - if (envelope[2] > 0) { - sphere_draw_wire(origin, envelope[2], 24); - } -} - -void light_draw_radius_fill(const Vector3 &origin, const float envelope[3]) -{ - if (envelope[0] > 0) { - sphere_draw_fill(origin, envelope[0], 16); - } - if (envelope[1] > 0) { - sphere_draw_fill(origin, envelope[1], 16); - } - if (envelope[2] > 0) { - sphere_draw_fill(origin, envelope[2], 16); - } -} - -void light_vertices(const AABB &aabb_light, Vector3 points[6]) -{ - Vector3 max(vector3_added(aabb_light.origin, aabb_light.extents)); - Vector3 min(vector3_subtracted(aabb_light.origin, aabb_light.extents)); - Vector3 mid(aabb_light.origin); - - // top, bottom, middle-up, middle-right, middle-down, middle-left - points[0] = Vector3(mid[0], mid[1], max[2]); - points[1] = Vector3(mid[0], mid[1], min[2]); - points[2] = Vector3(mid[0], max[1], mid[2]); - points[3] = Vector3(max[0], mid[1], mid[2]); - points[4] = Vector3(mid[0], min[1], mid[2]); - points[5] = Vector3(min[0], mid[1], mid[2]); -} - -void light_draw(const AABB &aabb_light, RenderStateFlags state) -{ - Vector3 points[6]; - light_vertices(aabb_light, points); - - typedef unsigned int index_t; - const index_t indices[24] = { - 0, 2, 3, - 0, 3, 4, - 0, 4, 5, - 0, 5, 2, - 1, 2, 5, - 1, 5, 4, - 1, 4, 3, - 1, 3, 2 - }; - - glVertexPointer(3, GL_FLOAT, 0, points); - glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(index_t), RenderIndexTypeID, indices); -} - -// These variables are tweakable on the q3map2 console, setting to q3map2 -// default here as there is no way to find out what the user actually uses -// right now. Maybe move them to worldspawn? -float fPointScale = 7500.f; -float fLinearScale = 1.f / 8000.f; - -float light_radius_linear(float fIntensity, float fFalloffTolerance) -{ - return ((fIntensity * fPointScale * fLinearScale) - fFalloffTolerance); -} - -float light_radius(float fIntensity, float fFalloffTolerance) -{ - return sqrt(fIntensity * fPointScale / fFalloffTolerance); -} - -bool spawnflags_linear(int flags) -{ - return (flags & 1); -} - -class LightRadii { -public: -float m_radii[3]; - -private: -float m_primaryIntensity; -float m_secondaryIntensity; -int m_flags; -float m_fade; -float m_scale; - -void calculateRadii() -{ - float intensity = 300.0f; - - if (m_primaryIntensity != 0.0f) { - intensity = m_primaryIntensity; - } else if (m_secondaryIntensity != 0.0f) { - intensity = m_secondaryIntensity; - } - - if (m_scale) { - intensity = m_scale * 0.5f; - m_radii[0] = light_radius(intensity, 1.0f); - m_radii[1] = light_radius(intensity, 48.0f); - m_radii[2] = light_radius(intensity, 255.0f); - } else { - if (spawnflags_linear(m_flags)) { - m_radii[0] = light_radius_linear(intensity, 1.0f) / m_fade; - m_radii[1] = light_radius_linear(intensity, 48.0f) / m_fade; - m_radii[2] = light_radius_linear(intensity, 255.0f) / m_fade; - } else { - m_radii[0] = light_radius(intensity, 1.0f); - m_radii[1] = light_radius(intensity, 48.0f); - m_radii[2] = light_radius(intensity, 255.0f); - } - } -} - -public: -LightRadii() : m_primaryIntensity(0), m_secondaryIntensity(0), m_flags(0), m_fade(1), m_scale(1) -{ -} - - -void primaryIntensityChanged(const char *value) -{ - m_primaryIntensity = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller PrimaryIntensityChangedCaller; - -void secondaryIntensityChanged(const char *value) -{ - m_secondaryIntensity = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller SecondaryIntensityChangedCaller; - -void scaleChanged(const char *value) -{ - m_scale = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller ScaleChangedCaller; - -void fadeChanged(const char *value) -{ - m_fade = string_read_float(value); - if (m_fade <= 0.0f) { - m_fade = 1.0f; - } - calculateRadii(); -} - -typedef MemberCaller FadeChangedCaller; - -void flagsChanged(const char *value) -{ - m_flags = string_read_int(value); - calculateRadii(); -} - -typedef MemberCaller FlagsChangedCaller; -}; - -class LightRadius { -public: -Vector3 m_defaultRadius; -Vector3 m_radius; -Vector3 m_radiusTransformed; -Vector3 m_center; -Callback m_changed; -bool m_useCenterKey; - -LightRadius(const char *defaultRadius) : m_defaultRadius(300, 300, 300), m_center(0, 0, 0), - m_useCenterKey(false) -{ - if (!string_parse_vector3(defaultRadius, m_defaultRadius)) { - globalErrorStream() << "LightRadius: failed to parse default light radius\n"; - } - m_radius = m_defaultRadius; -} - -void lightRadiusChanged(const char *value) -{ - if (!string_parse_vector3(value, m_radius)) { - m_radius = m_defaultRadius; - } - m_radiusTransformed = m_radius; - m_changed(); - SceneChangeNotify(); -} - -typedef MemberCaller LightRadiusChangedCaller; - -void lightCenterChanged(const char *value) -{ - m_useCenterKey = string_parse_vector3(value, m_center); - if (!m_useCenterKey) { - m_center = Vector3(0, 0, 0); - } - SceneChangeNotify(); -} - -typedef MemberCaller LightCenterChangedCaller; -}; - -class RenderLightRadiiWire : public OpenGLRenderable { -LightRadii &m_radii; -const Vector3 &m_origin; -public: -RenderLightRadiiWire(LightRadii &radii, const Vector3 &origin) : m_radii(radii), m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - light_draw_radius_wire(m_origin, m_radii.m_radii); -} -}; - -class RenderLightRadiiFill : public OpenGLRenderable { -LightRadii &m_radii; -const Vector3 &m_origin; -public: -static Shader *m_state; - -RenderLightRadiiFill(LightRadii &radii, const Vector3 &origin) : m_radii(radii), m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - light_draw_radius_fill(m_origin, m_radii.m_radii); -} -}; - -class RenderLightRadiiBox : public OpenGLRenderable { -const Vector3 &m_origin; -public: -mutable Vector3 m_points[8]; -static Shader *m_state; - -RenderLightRadiiBox(const Vector3 &origin) : m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - //draw the bounding box of light based on light_radius key - if ((state & RENDER_FILL) != 0) { - aabb_draw_flatshade(m_points); - } else { - aabb_draw_wire(m_points); - } - -#if 1 //disable if you dont want lines going from the center of the light bbox to the corners - light_draw_box_lines(m_origin, m_points); -#endif -} -}; - -Shader *RenderLightRadiiFill::m_state = 0; - -class RenderLightCenter : public OpenGLRenderable { -const Vector3 &m_center; -EntityClass &m_eclass; -public: -static Shader *m_state; - -RenderLightCenter(const Vector3 ¢er, EntityClass &eclass) : m_center(center), m_eclass(eclass) -{ -} - -void render(RenderStateFlags state) const -{ - glBegin(GL_POINTS); - glColor3fv(vector3_to_array(m_eclass.color)); - glVertex3fv(vector3_to_array(m_center)); - glEnd(); -} -}; - -Shader *RenderLightCenter::m_state = 0; - -class RenderLightProjection : public OpenGLRenderable { -const Matrix4 &m_projection; -public: - -RenderLightProjection(const Matrix4 &projection) : m_projection(projection) -{ -} - -void render(RenderStateFlags state) const -{ - Matrix4 unproject(matrix4_full_inverse(m_projection)); - Vector3 points[8]; - aabb_corners(AABB(Vector3(0.5f, 0.5f, 0.5f), Vector3(0.5f, 0.5f, 0.5f)), points); - points[0] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[0], 1))); - points[1] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[1], 1))); - points[2] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[2], 1))); - points[3] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[3], 1))); - points[4] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[4], 1))); - points[5] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[5], 1))); - points[6] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[6], 1))); - points[7] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[7], 1))); -// Vector4 test1 = matrix4_transformed_vector4( unproject, Vector4( 0.5f, 0.5f, 0.5f, 1 ) ); -// Vector3 test2 = vector4_projected( test1 ); - aabb_draw_wire(points); -} -}; - -inline void default_extents(Vector3 &extents) -{ - extents = Vector3(8, 8, 8); -} - -class ShaderRef { -CopiedString m_name; -Shader *m_shader; - -void capture() -{ - m_shader = GlobalShaderCache().capture(m_name.c_str()); -} - -void release() -{ - GlobalShaderCache().release(m_name.c_str()); -} - -public: -ShaderRef() -{ - capture(); -} - -~ShaderRef() -{ - release(); -} - -void setName(const char *name) -{ - release(); - m_name = name; - capture(); -} - -Shader *get() const -{ - return m_shader; -} -}; - -class LightShader { -ShaderRef m_shader; - -void setDefault() -{ - m_shader.setName(m_defaultShader); -} - -public: -static const char *m_defaultShader; - -LightShader() -{ - setDefault(); -} - -void valueChanged(const char *value) -{ - if (string_empty(value)) { - setDefault(); - } else { - m_shader.setName(value); - } - SceneChangeNotify(); -} - -typedef MemberCaller ValueChangedCaller; - -Shader *get() const -{ - return m_shader.get(); -} -}; - -const char *LightShader::m_defaultShader = ""; - -inline const BasicVector4 &plane3_to_vector4(const Plane3 &self) -{ - return reinterpret_cast &>( self ); -} - -inline BasicVector4 &plane3_to_vector4(Plane3 &self) -{ - return reinterpret_cast &>( self ); -} - -inline Matrix4 matrix4_from_planes(const Plane3 &left, const Plane3 &right, const Plane3 &bottom, const Plane3 &top, - const Plane3 &front, const Plane3 &back) -{ - return Matrix4( - (right.a - left.a) / 2, - (top.a - bottom.a) / 2, - (back.a - front.a) / 2, - right.a - (right.a - left.a) / 2, - (right.b - left.b) / 2, - (top.b - bottom.b) / 2, - (back.b - front.b) / 2, - right.b - (right.b - left.b) / 2, - (right.c - left.c) / 2, - (top.c - bottom.c) / 2, - (back.c - front.c) / 2, - right.c - (right.c - left.c) / 2, - (right.d - left.d) / 2, - (top.d - bottom.d) / 2, - (back.d - front.d) / 2, - right.d - (right.d - left.d) / 2 - ); -} - -class Light : - public OpenGLRenderable, - public Cullable, - public Bounded, - public Editable, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -TraversableNodeSet m_traverse; -IdentityTransform m_transform; - -OriginKey m_originKey; -RotationKey m_rotationKey; -Float9 m_rotation; -Colour m_colour; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -TraversableObserverPairRelay m_traverseObservers; - -LightRadii m_radii; -LightRadius m_radius; - -RenderLightRadiiWire m_radii_wire; -RenderLightRadiiFill m_radii_fill; -RenderLightRadiiBox m_radii_box; -RenderLightCenter m_render_center; -RenderableNamedEntity m_renderName; - -Vector3 m_lightOrigin; -bool m_useLightOrigin; -Float9 m_lightRotation; -bool m_useLightRotation; - -Vector3 m_lightTarget; -bool m_useLightTarget; -Vector3 m_lightUp; -bool m_useLightUp; -Vector3 m_lightRight; -bool m_useLightRight; -Vector3 m_lightStart; -bool m_useLightStart; -Vector3 m_lightEnd; -bool m_useLightEnd; - -mutable AABB m_doom3AABB; -mutable Matrix4 m_doom3Rotation; -mutable Matrix4 m_doom3Projection; -mutable Frustum m_doom3Frustum; -mutable bool m_doom3ProjectionChanged; - -RenderLightProjection m_renderProjection; - -LightShader m_shader; - -AABB m_aabb_light; - -Callback m_transformChanged; -Callback m_boundsChanged; -Callback m_evaluateTransform; - -void construct() -{ - default_rotation(m_rotation); - m_aabb_light.origin = Vector3(0, 0, 0); - default_extents(m_aabb_light.extents); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("_color", Colour::ColourChangedCaller(m_colour)); - m_keyObservers.insert("_color255", Colour::Colour255ChangedCaller(m_colour)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("_light", LightRadii::PrimaryIntensityChangedCaller(m_radii)); - m_keyObservers.insert("light", LightRadii::SecondaryIntensityChangedCaller(m_radii)); - m_keyObservers.insert("fade", LightRadii::FadeChangedCaller(m_radii)); - m_keyObservers.insert("radius", LightRadii::ScaleChangedCaller(m_radii)); - m_keyObservers.insert("scale", LightRadii::ScaleChangedCaller(m_radii)); - m_keyObservers.insert("spawnflags", LightRadii::FlagsChangedCaller(m_radii)); - -} - -void destroy() -{ - -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateOrigin() -{ - m_boundsChanged(); - m_radius.m_changed(); - GlobalSelectionSystem().pivotChanged(); -} - -void originChanged() -{ - m_aabb_light.origin = m_useLightOrigin ? m_lightOrigin : m_originKey.m_origin; - updateOrigin(); -} - -typedef MemberCaller OriginChangedCaller; - -void lightOriginChanged(const char *value) -{ - m_useLightOrigin = !string_empty(value); - if (m_useLightOrigin) { - read_origin(m_lightOrigin, value); - } - originChanged(); -} - -typedef MemberCaller LightOriginChangedCaller; - -void lightTargetChanged(const char *value) -{ - m_useLightTarget = !string_empty(value); - if (m_useLightTarget) { - read_origin(m_lightTarget, value); - } - projectionChanged(); -} - -typedef MemberCaller LightTargetChangedCaller; - -void lightUpChanged(const char *value) -{ - m_useLightUp = !string_empty(value); - if (m_useLightUp) { - read_origin(m_lightUp, value); - } - projectionChanged(); -} - -typedef MemberCaller LightUpChangedCaller; - -void lightRightChanged(const char *value) -{ - m_useLightRight = !string_empty(value); - if (m_useLightRight) { - read_origin(m_lightRight, value); - } - projectionChanged(); -} - -typedef MemberCaller LightRightChangedCaller; - -void lightStartChanged(const char *value) -{ - m_useLightStart = !string_empty(value); - if (m_useLightStart) { - read_origin(m_lightStart, value); - } - projectionChanged(); -} - -typedef MemberCaller LightStartChangedCaller; - -void lightEndChanged(const char *value) -{ - m_useLightEnd = !string_empty(value); - if (m_useLightEnd) { - read_origin(m_lightEnd, value); - } - projectionChanged(); -} - -typedef MemberCaller LightEndChangedCaller; - -void writeLightOrigin() -{ - write_origin(m_lightOrigin, &m_entity, "light_origin"); -} - -void updateLightRadiiBox() const -{ - const Matrix4 &rotation = rotation_toMatrix(m_rotation); - aabb_corners(AABB(Vector3(0, 0, 0), m_radius.m_radiusTransformed), m_radii_box.m_points); - matrix4_transform_point(rotation, m_radii_box.m_points[0]); - vector3_add(m_radii_box.m_points[0], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[1]); - vector3_add(m_radii_box.m_points[1], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[2]); - vector3_add(m_radii_box.m_points[2], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[3]); - vector3_add(m_radii_box.m_points[3], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[4]); - vector3_add(m_radii_box.m_points[4], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[5]); - vector3_add(m_radii_box.m_points[5], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[6]); - vector3_add(m_radii_box.m_points[6], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[7]); - vector3_add(m_radii_box.m_points[7], m_aabb_light.origin); -} - -void rotationChanged() -{ - rotation_assign(m_rotation, m_useLightRotation ? m_lightRotation : m_rotationKey.m_rotation); - GlobalSelectionSystem().pivotChanged(); -} - -typedef MemberCaller RotationChangedCaller; - -void lightRotationChanged(const char *value) -{ - m_useLightRotation = !string_empty(value); - if (m_useLightRotation) { - read_rotation(m_lightRotation, value); - } - rotationChanged(); -} - -typedef MemberCaller LightRotationChangedCaller; - -public: - -Light(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_rotationKey(RotationChangedCaller(*this)), - m_colour(Callback()), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")), - m_radii_wire(m_radii, m_aabb_light.origin), - m_radii_fill(m_radii, m_aabb_light.origin), - m_radii_box(m_aabb_light.origin), - m_render_center(m_radius.m_center, m_entity.getEntityClass()), - m_renderName(m_named, m_aabb_light.origin), - m_useLightOrigin(false), - m_useLightRotation(false), - m_renderProjection(m_doom3Projection), - m_transformChanged(transformChanged), - m_boundsChanged(boundsChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -Light(const Light &other, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_rotationKey(RotationChangedCaller(*this)), - m_colour(Callback()), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")), - m_radii_wire(m_radii, m_aabb_light.origin), - m_radii_fill(m_radii, m_aabb_light.origin), - m_radii_box(m_aabb_light.origin), - m_render_center(m_radius.m_center, m_entity.getEntityClass()), - m_renderName(m_named, m_aabb_light.origin), - m_useLightOrigin(false), - m_useLightRotation(false), - m_renderProjection(m_doom3Projection), - m_transformChanged(transformChanged), - m_boundsChanged(boundsChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -~Light() -{ - destroy(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.attach(*observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.detach(*observer); -} - -void render(RenderStateFlags state) const -{ - if (!g_newLightDraw) { - aabb_draw(m_aabb_light, state); - } else { - light_draw(m_aabb_light, state); - } -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(m_aabb_light, localToWorld); -} - -// cache -const AABB &localAABB() const -{ - return m_aabb_light; -} - - -mutable Matrix4 m_projectionOrientation; - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_colour.state(), Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); - - if (selected && g_lightRadii && string_empty(m_entity.getKeyValue("target"))) { - if (renderer.getStyle() == Renderer::eFullMaterials) { - renderer.SetState(RenderLightRadiiFill::m_state, Renderer::eFullMaterials); - renderer.Highlight(Renderer::ePrimitive, false); - renderer.addRenderable(m_radii_fill, localToWorld); - } else { - renderer.addRenderable(m_radii_wire, localToWorld); - } - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_light, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -void translate(const Vector3 &translation) -{ - m_aabb_light.origin = origin_translated(m_aabb_light.origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - rotation_rotate(m_rotation, rotation); -} - -void snapto(float snap) -{ - if (m_useLightOrigin) { - m_lightOrigin = origin_snapped(m_lightOrigin, snap); - writeLightOrigin(); - } else { - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); - } -} - -void setLightRadius(const AABB &aabb) -{ - m_aabb_light.origin = aabb.origin; - m_radius.m_radiusTransformed = aabb.extents; -} - -void transformLightRadius(const Matrix4 &transform) -{ - matrix4_transform_point(transform, m_aabb_light.origin); -} - -void revertTransform() -{ - m_aabb_light.origin = m_useLightOrigin ? m_lightOrigin : m_originKey.m_origin; - rotation_assign(m_rotation, m_useLightRotation ? m_lightRotation : m_rotationKey.m_rotation); - m_radius.m_radiusTransformed = m_radius.m_radius; -} - -void freezeTransform() -{ - if (m_useLightOrigin) { - m_lightOrigin = m_aabb_light.origin; - writeLightOrigin(); - } else { - m_originKey.m_origin = m_aabb_light.origin; - m_originKey.write(&m_entity); - } -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateOrigin(); -} - -typedef MemberCaller TransformChangedCaller; - -mutable Matrix4 m_localPivot; - -const Matrix4 &getLocalPivot() const -{ - m_localPivot = rotation_toMatrix(m_rotation); - vector4_to_vector3(m_localPivot.t()) = m_aabb_light.origin; - return m_localPivot; -} - -void setLightChangedCallback(const Callback &callback) -{ - m_radius.m_changed = callback; -} - -const AABB &aabb() const -{ - m_doom3AABB = AABB(m_aabb_light.origin, m_radius.m_radiusTransformed); - return m_doom3AABB; -} - -bool testAABB(const AABB &other) const -{ - if (isProjected()) { - Matrix4 transform = rotation(); - vector4_to_vector3(transform.t()) = localAABB().origin; - projection(); - Frustum frustum(frustum_transformed(m_doom3Frustum, transform)); - return frustum_test_aabb(frustum, other) != c_volumeOutside; - } - // test against an AABB which contains the rotated bounds of this light. - const AABB &bounds = aabb(); - return aabb_intersects_aabb(other, AABB( - bounds.origin, - Vector3( - static_cast( fabs(m_rotation[0] * bounds.extents[0]) - + fabs(m_rotation[3] * bounds.extents[1]) - + fabs(m_rotation[6] * bounds.extents[2])), - static_cast( fabs(m_rotation[1] * bounds.extents[0]) - + fabs(m_rotation[4] * bounds.extents[1]) - + fabs(m_rotation[7] * bounds.extents[2])), - static_cast( fabs(m_rotation[2] * bounds.extents[0]) - + fabs(m_rotation[5] * bounds.extents[1]) - + fabs(m_rotation[8] * bounds.extents[2])) - ) - )); -} - -const Matrix4 &rotation() const -{ - m_doom3Rotation = rotation_toMatrix(m_rotation); - return m_doom3Rotation; -} - -const Vector3 &offset() const -{ - return m_radius.m_center; -} - -const Vector3 &colour() const -{ - return m_colour.m_colour; -} - -bool isProjected() const -{ - return m_useLightTarget && m_useLightUp && m_useLightRight; -} - -void projectionChanged() -{ - m_doom3ProjectionChanged = true; - m_radius.m_changed(); - SceneChangeNotify(); -} - -const Matrix4 &projection() const -{ - if (!m_doom3ProjectionChanged) { - return m_doom3Projection; - } - m_doom3ProjectionChanged = false; - m_doom3Projection = g_matrix4_identity; - matrix4_translate_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 0)); - matrix4_scale_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 1)); - -#if 0 - Vector3 right = vector3_cross( m_lightUp, vector3_normalised( m_lightTarget ) ); - Vector3 up = vector3_cross( vector3_normalised( m_lightTarget ), m_lightRight ); - Vector3 target = m_lightTarget; - Matrix4 test( - -right.x(), -right.y(), -right.z(), 0, - -up.x(), -up.y(), -up.z(), 0, - -target.x(), -target.y(), -target.z(), 0, - 0, 0, 0, 1 - ); - Matrix4 frustum = matrix4_frustum( -0.01, 0.01, -0.01, 0.01, 0.01, 1.0 ); - test = matrix4_full_inverse( test ); - matrix4_premultiply_by_matrix4( test, frustum ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#elif 0 - const float nearFar = 1 / 49.5f; - Vector3 right = vector3_cross( m_lightUp, vector3_normalised( m_lightTarget + m_lightRight ) ); - Vector3 up = vector3_cross( vector3_normalised( m_lightTarget + m_lightUp ), m_lightRight ); - Vector3 target = vector3_negated( m_lightTarget * ( 1 + nearFar ) ); - float scale = -1 / vector3_length( m_lightTarget ); - Matrix4 test( - -inverse( right.x() ), -inverse( up.x() ), -inverse( target.x() ), 0, - -inverse( right.y() ), -inverse( up.y() ), -inverse( target.y() ), 0, - -inverse( right.z() ), -inverse( up.z() ), -inverse( target.z() ), scale, - 0, 0, -nearFar, 0 - ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#elif 0 - Vector3 leftA( m_lightTarget - m_lightRight ); - Vector3 leftB( m_lightRight + m_lightUp ); - Plane3 left( vector3_normalised( vector3_cross( leftA, leftB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 rightA( m_lightTarget + m_lightRight ); - Vector3 rightB( vector3_cross( rightA, m_lightTarget ) ); - Plane3 right( vector3_normalised( vector3_cross( rightA, rightB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 bottomA( m_lightTarget - m_lightUp ); - Vector3 bottomB( vector3_cross( bottomA, m_lightTarget ) ); - Plane3 bottom( vector3_normalised( vector3_cross( bottomA, bottomB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 topA( m_lightTarget + m_lightUp ); - Vector3 topB( vector3_cross( topA, m_lightTarget ) ); - Plane3 top( vector3_normalised( vector3_cross( topA, topB ) ) * ( 1.0 / 128 ), 0 ); - Plane3 front( vector3_normalised( m_lightTarget ) * ( 1.0 / 128 ), 1 ); - Plane3 back( vector3_normalised( vector3_negated( m_lightTarget ) ) * ( 1.0 / 128 ), 0 ); - Matrix4 test( matrix4_from_planes( plane3_flipped( left ), plane3_flipped( right ), plane3_flipped( bottom ), plane3_flipped( top ), plane3_flipped( front ), plane3_flipped( back ) ) ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#else - - Plane3 lightProject[4]; - - Vector3 start = m_useLightStart && m_useLightEnd ? m_lightStart : vector3_normalised(m_lightTarget); - Vector3 stop = m_useLightStart && m_useLightEnd ? m_lightEnd : m_lightTarget; - - float rLen = vector3_length(m_lightRight); - Vector3 right = vector3_divided(m_lightRight, rLen); - float uLen = vector3_length(m_lightUp); - Vector3 up = vector3_divided(m_lightUp, uLen); - Vector3 normal = vector3_normalised(vector3_cross(up, right)); - - float dist = vector3_dot(m_lightTarget, normal); - if (dist < 0) { - dist = -dist; - normal = vector3_negated(normal); - } - - right *= (0.5f * dist) / rLen; - up *= -(0.5f * dist) / uLen; - - lightProject[2] = Plane3(normal, 0); - lightProject[0] = Plane3(right, 0); - lightProject[1] = Plane3(up, 0); - - // now offset to center - Vector4 targetGlobal(m_lightTarget, 1); - { - float a = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[0])); - float b = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[2])); - float ofs = 0.5f - a / b; - plane3_to_vector4(lightProject[0]) += plane3_to_vector4(lightProject[2]) * ofs; - } - { - float a = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[1])); - float b = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[2])); - float ofs = 0.5f - a / b; - plane3_to_vector4(lightProject[1]) += plane3_to_vector4(lightProject[2]) * ofs; - } - - // set the falloff vector - Vector3 falloff = stop - start; - float length = vector3_length(falloff); - falloff = vector3_divided(falloff, length); - if (length <= 0) { - length = 1; - } - falloff *= (1.0f / length); - lightProject[3] = Plane3(falloff, -vector3_dot(start, falloff)); - - // we want the planes of s=0, s=q, t=0, and t=q - m_doom3Frustum.left = lightProject[0]; - m_doom3Frustum.bottom = lightProject[1]; - m_doom3Frustum.right = Plane3(lightProject[2].normal() - lightProject[0].normal(), - lightProject[2].dist() - lightProject[0].dist()); - m_doom3Frustum.top = Plane3(lightProject[2].normal() - lightProject[1].normal(), - lightProject[2].dist() - lightProject[1].dist()); - - // we want the planes of s=0 and s=1 for front and rear clipping planes - m_doom3Frustum.front = lightProject[3]; - - m_doom3Frustum.back = lightProject[3]; - m_doom3Frustum.back.dist() -= 1.0f; - m_doom3Frustum.back = plane3_flipped(m_doom3Frustum.back); - - Matrix4 test(matrix4_from_planes(m_doom3Frustum.left, m_doom3Frustum.right, m_doom3Frustum.bottom, - m_doom3Frustum.top, m_doom3Frustum.front, m_doom3Frustum.back)); - matrix4_multiply_by_matrix4(m_doom3Projection, test); - - m_doom3Frustum.left = plane3_normalised(m_doom3Frustum.left); - m_doom3Frustum.right = plane3_normalised(m_doom3Frustum.right); - m_doom3Frustum.bottom = plane3_normalised(m_doom3Frustum.bottom); - m_doom3Frustum.top = plane3_normalised(m_doom3Frustum.top); - m_doom3Frustum.back = plane3_normalised(m_doom3Frustum.back); - m_doom3Frustum.front = plane3_normalised(m_doom3Frustum.front); -#endif - //matrix4_scale_by_vec3(m_doom3Projection, Vector3(1.0 / 128, 1.0 / 128, 1.0 / 128)); - return m_doom3Projection; -} - -Shader *getShader() const -{ - return m_shader.get(); -} -}; - -class LightInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable, - public RendererLight, - public PlaneSelectable, - public ComponentSelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - //InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Light &m_contained; -DragPlanes m_dragPlanes; // dragplanes for lightresizing using mousedrag -public: -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "LightInstance"); - -LightInstance(const scene::Path &path, scene::Instance *parent, Light &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(Light::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained), - m_dragPlanes(SelectedChangedComponentCaller(*this)) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~LightInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_contained.testSelect(selector, test, Instance::localToWorld()); -} - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - m_dragPlanes.selectPlanes(m_contained.aabb(), selector, test, selectedPlaneCallback, rotation()); -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - m_dragPlanes.selectReversedPlanes(m_contained.aabb(), selector, selectedPlanes, rotation()); -} - -bool isSelectedComponents() const -{ - return m_dragPlanes.isSelected(); -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eFace) { - m_dragPlanes.setSelected(false); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ -} - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } else { - //globalOutputStream() << getTranslation() << "\n"; - - m_dragPlanes.m_bounds = m_contained.aabb(); - m_contained.setLightRadius(m_dragPlanes.evaluateResize(getTranslation(), rotation())); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void lightChanged() -{ - GlobalShaderCache().changed(*this); -} - -typedef MemberCaller LightChangedCaller; - -Shader *getShader() const -{ - return m_contained.getShader(); -} - -const AABB &aabb() const -{ - return m_contained.aabb(); -} - -bool testAABB(const AABB &other) const -{ - return m_contained.testAABB(other); -} - -const Matrix4 &rotation() const -{ - return m_contained.rotation(); -} - -const Vector3 &offset() const -{ - return m_contained.offset(); -} - -const Vector3 &colour() const -{ - return m_contained.colour(); -} - -bool isProjected() const -{ - return m_contained.isProjected(); -} - -const Matrix4 &projection() const -{ - return m_contained.projection(); -} -}; - -class LightNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Light m_contained; - -void construct() -{ -} - -void destroy() -{ - -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Editable &get(NullType) -{ - return m_contained; -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -LightNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -LightNode(const LightNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~LightNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new LightNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new LightInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -void Light_Construct() -{ - RenderLightRadiiFill::m_state = GlobalShaderCache().capture("$Q3MAP2_LIGHT_SPHERE"); - RenderLightCenter::m_state = GlobalShaderCache().capture("$BIGPOINT"); -} - -void Light_Destroy() -{ - GlobalShaderCache().release("$Q3MAP2_LIGHT_SPHERE"); - GlobalShaderCache().release("$BIGPOINT"); -} - -scene::Node &New_Light(EntityClass *eclass) -{ - return (new LightNode(eclass))->node(); -} diff --git a/plugins/entity/light.h b/plugins/entity/light.h deleted file mode 100644 index 81d9ff6..0000000 --- a/plugins/entity/light.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_LIGHT_H ) -#define INCLUDED_LIGHT_H - -namespace scene { -class Node; -} -class EntityClass; - -scene::Node &New_Light(EntityClass *eclass); - -void Light_Construct(); - -void Light_Destroy(); - -#endif diff --git a/plugins/entity/miscmodel.cpp b/plugins/entity/miscmodel.cpp deleted file mode 100644 index 7d69bad..0000000 --- a/plugins/entity/miscmodel.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents the Quake3 misc_model entity. -/// -/// This entity displays the model specified in its "model" key. -/// The "origin", "angles" and "modelscale*" keys directly control the entity's local-to-parent transform. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "render.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -class PropStatic : - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -ScaleKey m_scaleKey; -Vector3 m_scale; - -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("modelscale", ScaleKey::UniformScaleChangedCaller(m_scaleKey)); - m_keyObservers.insert("modelscale_vec", ScaleKey::ScaleChangedCaller(m_scaleKey)); -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_transform_by_euler_xyz_degrees(m_transform.localToParent(), m_origin, m_angles, m_scale); - m_transformChanged(); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void scaleChanged() -{ - m_scale = m_scaleKey.m_scale; - updateTransform(); -} - -typedef MemberCaller ScaleChangedCaller; -public: - -PropStatic(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -PropStatic(const PropStatic &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void scale(const Vector3 &scaling) -{ - m_scale = scale_scaled(m_scale, scaling); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; - m_scale = m_scaleKey.m_scale; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - m_scaleKey.m_scale = m_scale; - m_scaleKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class PropStaticInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PropStatic &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "PropStaticInstance"); - -PropStaticInstance(const scene::Path &path, scene::Instance *parent, PropStatic &miscmodel) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this), - TransformModifier(PropStatic::TransformChangedCaller(miscmodel), ApplyTransformCaller(*this)), - m_contained(miscmodel) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~PropStaticInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - m_contained.scale(getScale()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class PropStaticNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PropStatic m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -PropStaticNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -PropStaticNode(const PropStaticNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~PropStaticNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new PropStaticNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PropStaticInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_PropStatic(EntityClass *eclass) -{ - return (new PropStaticNode(eclass))->node(); -} - -void PropStatic_construct() -{ -} - -void PropStatic_destroy() -{ -} diff --git a/plugins/entity/miscmodel.h b/plugins/entity/miscmodel.h deleted file mode 100644 index 7b0befe..0000000 --- a/plugins/entity/miscmodel.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MISCMODEL_H ) -#define INCLUDED_MISCMODEL_H - -scene::Node &New_PropStatic(EntityClass *eclass); - -void PropStatic_construct(); - -void PropStatic_destroy(); - -#endif diff --git a/plugins/entity/model.h b/plugins/entity/model.h deleted file mode 100644 index 114cad9..0000000 --- a/plugins/entity/model.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -#include "entitylib.h" -#include "traverselib.h" -#include "generic/callback.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "moduleobserver.h" - -class EModel : public ModuleObserver { -ResourceReference m_resource; -scene::Traversable &m_traverse; -scene::Node *m_node; -Callback m_modelChanged; - -public: -EModel(scene::Traversable &traversable, const Callback &modelChanged) - : m_resource(""), m_traverse(traversable), m_node(0), m_modelChanged(modelChanged) -{ - m_resource.attach(*this); -} - -~EModel() -{ - m_resource.detach(*this); -} - -void realise() -{ - m_resource.get()->load(); - m_node = m_resource.get()->getNode(); - if (m_node != 0) { - m_traverse.insert(*m_node); - } -} - -void unrealise() -{ - if (m_node != 0) { - m_traverse.erase(*m_node); - } -} - -void modelChanged(const char *value) -{ - StringOutputStream cleaned(string_length(value)); - cleaned << PathCleaned(value); - m_resource.detach(*this); - m_resource.setName(cleaned.c_str()); - m_resource.attach(*this); - m_modelChanged(); -} - -typedef MemberCaller ModelChangedCaller; - -const char *getName() const -{ - return m_resource.getName(); -} - -scene::Node *getNode() const -{ - return m_node; -} -}; - -class SingletonModel { -TraversableNode m_traverse; -EModel m_model; -public: -SingletonModel() - : m_model(m_traverse, Callback()) -{ -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverse.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverse.detach(observer); -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -void modelChanged(const char *value) -{ - m_model.modelChanged(value); -} - -typedef MemberCaller ModelChangedCaller; - -scene::Node *getNode() const -{ - return m_model.getNode(); -} -}; - -#endif diff --git a/plugins/entity/modelskinkey.h b/plugins/entity/modelskinkey.h deleted file mode 100644 index c995ac4..0000000 --- a/plugins/entity/modelskinkey.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODELSKINKEY_H ) -#define INCLUDED_MODELSKINKEY_H - -#include "modelskin.h" - -#include "os/path.h" -#include "stream/stringstream.h" -#include "moduleobserver.h" -#include "entitylib.h" -#include "traverselib.h" - -inline void parseTextureName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension -} - -class ModelSkinKey : public ModuleObserver { -CopiedString m_name; -ModelSkin *m_skin; -Callback m_skinChangedCallback; - -ModelSkinKey(const ModelSkinKey &); - -ModelSkinKey operator=(const ModelSkinKey &); - -void construct() -{ - m_skin = &GlobalModelSkinCache().capture(m_name.c_str()); - m_skin->attach(*this); -} - -void destroy() -{ - m_skin->detach(*this); - GlobalModelSkinCache().release(m_name.c_str()); -} - -public: -ModelSkinKey(const Callback &skinChangedCallback) : m_skinChangedCallback(skinChangedCallback) -{ - construct(); -} - -~ModelSkinKey() -{ - destroy(); -} - -ModelSkin &get() const -{ - return *m_skin; -} - -void skinChanged(const char *value) -{ - destroy(); - parseTextureName(m_name, value); - construct(); -} - -typedef MemberCaller SkinChangedCaller; - -void realise() -{ - m_skinChangedCallback(); -} - -void unrealise() -{ -} -}; - -class InstanceSkinChanged : public scene::Instantiable::Visitor { -public: -void visit(scene::Instance &instance) const -{ - //\todo don't do this for instances that are not children of the entity setting the skin - SkinnedModel *skinned = InstanceTypeCast::cast(instance); - if (skinned != 0) { - skinned->skinChanged(); - } -} -}; - -inline void Node_modelSkinChanged(scene::Node &node) -{ - scene::Instantiable *instantiable = Node_getInstantiable(node); - ASSERT_NOTNULL(instantiable); - instantiable->forEachInstance(InstanceSkinChanged()); -} - -#endif diff --git a/plugins/entity/namedentity.h b/plugins/entity/namedentity.h deleted file mode 100644 index d3f6c0d..0000000 --- a/plugins/entity/namedentity.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_NAMEDENTITY_H ) -#define INCLUDED_NAMEDENTITY_H - -#include "entitylib.h" -#include "eclasslib.h" -#include "generic/callback.h" -#include "nameable.h" - -#include - -class NameCallbackSet { -typedef std::set NameCallbacks; -NameCallbacks m_callbacks; -public: -void insert(const NameCallback &callback) -{ - m_callbacks.insert(callback); -} - -void erase(const NameCallback &callback) -{ - m_callbacks.erase(callback); -} - -void changed(const char *name) const -{ - for (NameCallbacks::const_iterator i = m_callbacks.begin(); i != m_callbacks.end(); ++i) { - (*i)(name); - } -} -}; - -class NamedEntity : public Nameable { -EntityKeyValues &m_entity; -NameCallbackSet m_changed; -CopiedString m_name; -public: -NamedEntity(EntityKeyValues &entity) : m_entity(entity) -{ -} - -const char *name() const -{ - if (string_empty(m_name.c_str())) { - return m_entity.getEntityClass().name(); - } - return m_name.c_str(); -} - -void attach(const NameCallback &callback) -{ - m_changed.insert(callback); -} - -void detach(const NameCallback &callback) -{ - m_changed.erase(callback); -} - -void identifierChanged(const char *value) -{ - if (string_empty(value)) { - m_changed.changed(m_entity.getEntityClass().name()); - } else { - m_changed.changed(value); - } - m_name = value; -} - -typedef MemberCaller IdentifierChangedCaller; -}; - -class RenderableNamedEntity : public OpenGLRenderable { -const NamedEntity &m_named; -const Vector3 &m_position; -public: -RenderableNamedEntity(const NamedEntity &named, const Vector3 &position) - : m_named(named), m_position(position) -{ -} - -void render(RenderStateFlags state) const -{ - glRasterPos3fv(vector3_to_array(m_position)); - GlobalOpenGL().drawString(m_named.name()); -} -}; - - -#endif diff --git a/plugins/entity/namekeys.h b/plugins/entity/namekeys.h deleted file mode 100644 index f113338..0000000 --- a/plugins/entity/namekeys.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_NAMEKEYS_H ) -#define INCLUDED_NAMEKEYS_H - -#include -#include -#include "generic/static.h" -#include "entitylib.h" -#include "namespace.h" - -inline bool string_is_integer(const char *string) -{ - strtol(string, const_cast( &string ), 10); - return *string == '\0'; -} - -typedef bool ( *KeyIsNameFunc )(const char *key); - -class KeyIsName { -public: -KeyIsNameFunc m_keyIsName; -const char *m_nameKey; - -KeyIsName() -{ -} -}; - - -typedef MemberCaller KeyValueAssignCaller; -typedef MemberCaller KeyValueAttachCaller; -typedef MemberCaller KeyValueDetachCaller; - -class NameKeys : public Entity::Observer, public Namespaced { -Namespace *m_namespace; -EntityKeyValues &m_entity; -KeyIsNameFunc m_keyIsName; - -NameKeys(const NameKeys &other); - -NameKeys &operator=(const NameKeys &other); - -typedef std::map KeyValues; -KeyValues m_keyValues; - -void insertName(const char *key, EntityKeyValue &value) -{ - if (m_namespace != 0 && m_keyIsName(key)) { - //globalOutputStream() << "insert " << key << "\n"; - m_namespace->attach(KeyValueAssignCaller(value), KeyValueAttachCaller(value)); - } -} - -void eraseName(const char *key, EntityKeyValue &value) -{ - if (m_namespace != 0 && m_keyIsName(key)) { - //globalOutputStream() << "erase " << key << "\n"; - m_namespace->detach(KeyValueAssignCaller(value), KeyValueDetachCaller(value)); - } -} - -void insertAll() -{ - for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) { - insertName((*i).first.c_str(), *(*i).second); - } -} - -void eraseAll() -{ - for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) { - eraseName((*i).first.c_str(), *(*i).second); - } -} - -public: -NameKeys(EntityKeyValues &entity) : m_namespace(0), m_entity(entity), - m_keyIsName(Static::instance().m_keyIsName) -{ - m_entity.attach(*this); -} - -~NameKeys() -{ - m_entity.detach(*this); -} - -void setNamespace(Namespace &space) -{ - eraseAll(); - m_namespace = &space; - insertAll(); -} - -void setKeyIsName(KeyIsNameFunc keyIsName) -{ - eraseAll(); - m_keyIsName = keyIsName; - insertAll(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - m_keyValues.insert(KeyValues::value_type(key, &value)); - insertName(key, value); -} - -void erase(const char *key, EntityKeyValue &value) -{ - eraseName(key, value); - m_keyValues.erase(key); -} -}; - -inline bool keyIsNameDoom3(const char *key) -{ - return string_equal(key, "target") - || (string_equal_n(key, "target", 6) && string_is_integer(key + 6)) - || string_equal(key, "name"); -} - -inline bool keyIsNameDoom3Doom3Group(const char *key) -{ - return keyIsNameDoom3(key) - || string_equal(key, "model"); -} - -inline bool keyIsNameQuake3(const char *key) -{ - return string_equal(key, "target") - || string_equal(key, "targetname") - || string_equal(key, "killtarget") - || (string_equal_n(key, "target", 6) && string_is_integer(key + 6)); // Nexuiz -} - -#endif diff --git a/plugins/entity/origin.h b/plugins/entity/origin.h deleted file mode 100644 index 2ac5522..0000000 --- a/plugins/entity/origin.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ORIGIN_H ) -#define INCLUDED_ORIGIN_H - -#include "ientity.h" - -#include "math/matrix.h" -#include "generic/callback.h" -#include "stringio.h" - -const Vector3 ORIGINKEY_IDENTITY = Vector3(0, 0, 0); - -inline void default_origin(Vector3 &origin) -{ - origin = ORIGINKEY_IDENTITY; -} - -inline void read_origin(Vector3 &origin, const char *value) -{ - if (!string_parse_vector3(value, origin)) { - default_origin(origin); - } -} - -inline void write_origin(const Vector3 &origin, Entity *entity, const char *key) -{ - char value[64]; - sprintf(value, "%f %f %f", origin[0], origin[1], origin[2]); - entity->setKeyValue(key, value); -} - -inline Vector3 origin_translated(const Vector3 &origin, const Vector3 &translation) -{ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translation_for_vec3(origin), - matrix4_translation_for_vec3(translation) - ) - ); -} - -inline Vector3 origin_snapped(const Vector3 &origin, float snap) -{ - return vector3_snapped(origin, snap); -} - -class OriginKey { -Callback m_originChanged; -public: -Vector3 m_origin; - - -OriginKey(const Callback &originChanged) - : m_originChanged(originChanged), m_origin(ORIGINKEY_IDENTITY) -{ -} - -void originChanged(const char *value) -{ - read_origin(m_origin, value); - m_originChanged(); -} - -typedef MemberCaller OriginChangedCaller; - - -void write(Entity *entity) const -{ - write_origin(m_origin, entity, "origin"); -} -}; - - -#include "scenelib.h" - -inline BrushDoom3 *Node_getBrushDoom3(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline void BrushDoom3_setDoom3GroupOrigin(scene::Node &node, const Vector3 &origin) -{ - BrushDoom3 *brush = Node_getBrushDoom3(node); - if (brush != 0) { - brush->setDoom3GroupOrigin(origin); - } -} - -class SetDoom3GroupOriginWalker : public scene::Traversable::Walker { -const Vector3 &m_origin; -public: -SetDoom3GroupOriginWalker(const Vector3 &origin) : m_origin(origin) -{ -} - -bool pre(scene::Node &node) const -{ - BrushDoom3_setDoom3GroupOrigin(node, m_origin); - return true; -} -}; - -class Doom3GroupOrigin : public scene::Traversable::Observer { -scene::Traversable &m_set; -const Vector3 &m_origin; -bool m_enabled; - -public: -Doom3GroupOrigin(scene::Traversable &set, const Vector3 &origin) : m_set(set), m_origin(origin), m_enabled(false) -{ -} - -void enable() -{ - m_enabled = true; - originChanged(); -} - -void disable() -{ - m_enabled = false; -} - -void originChanged() -{ - if (m_enabled) { - m_set.traverse(SetDoom3GroupOriginWalker(m_origin)); - } -} - -void insert(scene::Node &node) -{ - if (m_enabled) { - BrushDoom3_setDoom3GroupOrigin(node, m_origin); - } -} - -void erase(scene::Node &node) -{ - if (m_enabled) { - BrushDoom3_setDoom3GroupOrigin(node, Vector3(0, 0, 0)); - } -} -}; - - -#endif diff --git a/plugins/entity/plugin.cpp b/plugins/entity/plugin.cpp deleted file mode 100644 index 3da9088..0000000 --- a/plugins/entity/plugin.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "ientity.h" -#include "iundo.h" -#include "ieclass.h" -#include "igl.h" -#include "ireference.h" -#include "ifilter.h" -#include "preferencesystem.h" -#include "qerplugin.h" -#include "namespace.h" -#include "modelskin.h" - -#include "typesystem.h" - -#include "entity.h" -#include "skincache.h" - -#include "modulesystem/singletonmodule.h" - -class EntityDependencies : - public GlobalRadiantModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalReferenceModuleRef, - public GlobalFilterModuleRef, - public GlobalPreferenceSystemModuleRef, - public GlobalNamespaceModuleRef, - public GlobalModelSkinCacheModuleRef { -}; - -class EntityQ3API : public TypeSystemRef { -EntityCreator *m_entityq3; -public: -typedef EntityCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -EntityQ3API() -{ - Entity_Construct(); - - m_entityq3 = &GetEntityCreator(); - - GlobalReferenceCache().setEntityCreator(*m_entityq3); -} - -~EntityQ3API() -{ - Entity_Destroy(); -} - -EntityCreator *getTable() -{ - return m_entityq3; -} -}; - -typedef SingletonModule EntityQ3Module; - -EntityQ3Module g_EntityQ3Module; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_EntityQ3Module.selfRegister(); - Doom3ModelSkinCacheModule_selfRegister(server); -} diff --git a/plugins/entity/prop_dynamic.cpp b/plugins/entity/prop_dynamic.cpp deleted file mode 100644 index 3bcde39..0000000 --- a/plugins/entity/prop_dynamic.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "render.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -class PropDynamic : - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -ScaleKey m_scaleKey; -Vector3 m_scale; - -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("modelscale", ScaleKey::UniformScaleChangedCaller(m_scaleKey)); - m_keyObservers.insert("modelscale_vec", ScaleKey::ScaleChangedCaller(m_scaleKey)); -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_transform_by_euler_xyz_degrees(m_transform.localToParent(), m_origin, m_angles, m_scale); - m_transformChanged(); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void scaleChanged() -{ - m_scale = m_scaleKey.m_scale; - updateTransform(); -} - -typedef MemberCaller ScaleChangedCaller; -public: - -PropDynamic(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -PropDynamic(const PropDynamic &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void scale(const Vector3 &scaling) -{ - m_scale = scale_scaled(m_scale, scaling); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; - m_scale = m_scaleKey.m_scale; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - m_scaleKey.m_scale = m_scale; - m_scaleKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class PropDynamicInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PropDynamic &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "PropDynamicInstance"); - -PropDynamicInstance(const scene::Path &path, scene::Instance *parent, PropDynamic &miscmodel) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this), - TransformModifier(PropDynamic::TransformChangedCaller(miscmodel), ApplyTransformCaller(*this)), - m_contained(miscmodel) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~PropDynamicInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - m_contained.scale(getScale()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class PropDynamicNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PropDynamic m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -PropDynamicNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -PropDynamicNode(const PropDynamicNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~PropDynamicNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new PropDynamicNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PropDynamicInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_PropDynamic(EntityClass *eclass) -{ - return (new PropDynamicNode(eclass))->node(); -} - -void PropDynamic_construct() -{ -} - -void PropDynamic_destroy() -{ -} diff --git a/plugins/entity/prop_dynamic.h b/plugins/entity/prop_dynamic.h deleted file mode 100644 index 56d30f5..0000000 --- a/plugins/entity/prop_dynamic.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PROPDYNAMIC_H ) -#define INCLUDED_PROPDYNAMIC_H - -scene::Node &New_PropDynamic(EntityClass *eclass); - -void PropDynamic_construct(); - -void PropDynamic_destroy(); - -#endif diff --git a/plugins/entity/rotation.h b/plugins/entity/rotation.h deleted file mode 100644 index 50aa953..0000000 --- a/plugins/entity/rotation.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ROTATION_H ) -#define INCLUDED_ROTATION_H - -#include "ientity.h" - -#include "stream/stringstream.h" -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "angle.h" - -typedef float Float9[9]; - -inline void default_rotation(Float9 rotation) -{ - rotation[0] = 1; - rotation[1] = 0; - rotation[2] = 0; - rotation[3] = 0; - rotation[4] = 1; - rotation[5] = 0; - rotation[6] = 0; - rotation[7] = 0; - rotation[8] = 1; -} - -inline void write_rotation(const Float9 rotation, Entity *entity, const char *key = "rotation") -{ - if (rotation[0] == 1 - && rotation[1] == 0 - && rotation[2] == 0 - && rotation[3] == 0 - && rotation[4] == 1 - && rotation[5] == 0 - && rotation[6] == 0 - && rotation[7] == 0 - && rotation[8] == 1) { - entity->setKeyValue(key, ""); - } else { - StringOutputStream value(256); - value << rotation[0] << ' ' - << rotation[1] << ' ' - << rotation[2] << ' ' - << rotation[3] << ' ' - << rotation[4] << ' ' - << rotation[5] << ' ' - << rotation[6] << ' ' - << rotation[7] << ' ' - << rotation[8]; - entity->setKeyValue(key, value.c_str()); - } -} - -inline void read_rotation(Float9 rotation, const char *value) -{ - if (!string_parse_vector(value, rotation, rotation + 9)) { - default_rotation(rotation); - } -} - -inline Matrix4 rotation_toMatrix(const Float9 rotation) -{ - return Matrix4( - rotation[0], - rotation[1], - rotation[2], - 0, - rotation[3], - rotation[4], - rotation[5], - 0, - rotation[6], - rotation[7], - rotation[8], - 0, - 0, - 0, - 0, - 1 - ); -} - -inline void rotation_fromMatrix(Float9 rotation, const Matrix4 &matrix) -{ - rotation[0] = matrix.xx(); - rotation[1] = matrix.xy(); - rotation[2] = matrix.xz(); - rotation[3] = matrix.yx(); - rotation[4] = matrix.yy(); - rotation[5] = matrix.yz(); - rotation[6] = matrix.zx(); - rotation[7] = matrix.zy(); - rotation[8] = matrix.zz(); -} - -inline void rotation_assign(Float9 rotation, const Float9 other) -{ - rotation[0] = other[0]; - rotation[1] = other[1]; - rotation[2] = other[2]; - rotation[3] = other[3]; - rotation[4] = other[4]; - rotation[5] = other[5]; - rotation[6] = other[6]; - rotation[7] = other[7]; - rotation[8] = other[8]; -} - -inline void rotation_rotate(Float9 rotation, const Quaternion &rotate) -{ - rotation_fromMatrix(rotation, - matrix4_multiplied_by_matrix4( - rotation_toMatrix(rotation), - matrix4_rotation_for_quaternion_quantised(rotate) - ) - ); -} - -inline void read_angle(Float9 rotation, const char *value) -{ - float angle; - if (!string_parse_float(value, angle)) { - default_rotation(rotation); - } else { - rotation_fromMatrix(rotation, matrix4_rotation_for_z_degrees(angle)); - } -} - -class RotationKey { -Callback m_rotationChanged; -public: -Float9 m_rotation; - - -RotationKey(const Callback &rotationChanged) - : m_rotationChanged(rotationChanged) -{ - default_rotation(m_rotation); -} - -void angleChanged(const char *value) -{ - read_angle(m_rotation, value); - m_rotationChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void rotationChanged(const char *value) -{ - read_rotation(m_rotation, value); - m_rotationChanged(); -} - -typedef MemberCaller RotationChangedCaller; - -void write(Entity *entity) const -{ - Vector3 euler = matrix4_get_rotation_euler_xyz_degrees(rotation_toMatrix(m_rotation)); - if (euler[0] == 0 && euler[1] == 0) { - entity->setKeyValue("rotation", ""); - write_angle(euler[2], entity); - } else { - entity->setKeyValue("angle", ""); - write_rotation(m_rotation, entity); - } -} -}; - -#endif diff --git a/plugins/entity/scale.h b/plugins/entity/scale.h deleted file mode 100644 index 6f79b47..0000000 --- a/plugins/entity/scale.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCALE_H ) -#define INCLUDED_SCALE_H - -#include "ientity.h" - -#include "math/matrix.h" -#include "generic/callback.h" -#include "stringio.h" - -const Vector3 SCALEKEY_IDENTITY = Vector3(1, 1, 1); - -inline void default_scale(Vector3 &scale) -{ - scale = SCALEKEY_IDENTITY; -} - -inline void read_scale(Vector3 &scalevec, const char *value) -{ - float scale; - if (!string_parse_float(value, scale) - || scale == 0) { - default_scale(scalevec); - } else { - scalevec = Vector3(scale, scale, scale); - } -} - -inline void read_scalevec(Vector3 &scale, const char *value) -{ - if (!string_parse_vector3(value, scale) - || scale[0] == 0 - || scale[1] == 0 - || scale[2] == 0) { - default_scale(scale); - } -} - -inline void write_scale(const Vector3 &scale, Entity *entity) -{ - if (scale[0] == 1 && scale[1] == 1 && scale[2] == 1) { - entity->setKeyValue("modelscale", ""); - entity->setKeyValue("modelscale_vec", ""); - } else { - char value[64]; - - if (scale[0] == scale[1] && scale[0] == scale[2]) { - sprintf(value, "%f", scale[0]); - entity->setKeyValue("modelscale_vec", ""); - entity->setKeyValue("modelscale", value); - } else { - sprintf(value, "%f %f %f", scale[0], scale[1], scale[2]); - entity->setKeyValue("modelscale", ""); - entity->setKeyValue("modelscale_vec", value); - } - } -} - -inline Vector3 scale_scaled(const Vector3 &scale, const Vector3 &scaling) -{ - return matrix4_get_scale_vec3( - matrix4_multiplied_by_matrix4( - matrix4_scale_for_vec3(scale), - matrix4_scale_for_vec3(scaling) - ) - ); -} - - -class ScaleKey { -Callback m_scaleChanged; -public: -Vector3 m_scale; - - -ScaleKey(const Callback &scaleChanged) - : m_scaleChanged(scaleChanged), m_scale(SCALEKEY_IDENTITY) -{ -} - -void uniformScaleChanged(const char *value) -{ - read_scale(m_scale, value); - m_scaleChanged(); -} - -typedef MemberCaller UniformScaleChangedCaller; - -void scaleChanged(const char *value) -{ - read_scalevec(m_scale, value); - m_scaleChanged(); -} - -typedef MemberCaller ScaleChangedCaller; - -void write(Entity *entity) const -{ - write_scale(m_scale, entity); -} -}; - - -#endif diff --git a/plugins/entity/skincache.cpp b/plugins/entity/skincache.cpp deleted file mode 100644 index 5ee747f..0000000 --- a/plugins/entity/skincache.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "skincache.h" - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "iarchive.h" -#include "modelskin.h" - -#include - -#include "stream/stringstream.h" -#include "generic/callback.h" -#include "container/cache.h" -#include "container/hashfunc.h" -#include "os/path.h" -#include "moduleobservers.h" -#include "modulesystem/singletonmodule.h" -#include "stringio.h" - -void parseShaderName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = cleaned.c_str(); -} - -class Doom3ModelSkin { -typedef std::map Remaps; -Remaps m_remaps; -public: -bool parseTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - if (token == 0) { - return false; - } - if (string_equal(token, "}")) { - tokeniser.nextLine(); - return true; - } else if (string_equal(token, "model")) { - //const char* model = - tokeniser.getToken(); - } else { - CopiedString from, to; - parseShaderName(from, token); - - tokeniser.nextLine(); // hack to handle badly formed skins - - parseShaderName(to, tokeniser.getToken()); - - if (!string_equal(from.c_str(), to.c_str())) { - m_remaps.insert(Remaps::value_type(from, to)); - } - } - tokeniser.nextLine(); - } -} - -const char *getRemap(const char *name) const -{ - Remaps::const_iterator i = m_remaps.find(name); - if (i != m_remaps.end()) { - return (*i).second.c_str(); - } - return ""; -} - -void forEachRemap(const SkinRemapCallback &callback) const -{ - for (Remaps::const_iterator i = m_remaps.begin(); i != m_remaps.end(); ++i) { - callback(SkinRemap((*i).first.c_str(), (*i).second.c_str())); - } -} -}; - -class GlobalSkins { -public: -typedef std::map SkinMap; -SkinMap m_skins; -Doom3ModelSkin g_nullSkin; - -Doom3ModelSkin &getSkin(const char *name) -{ - SkinMap::iterator i = m_skins.find(name); - if (i != m_skins.end()) { - return (*i).second; - } - - return g_nullSkin; -} - -bool parseTokens(Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - if (token == 0) { - // end of token stream - return true; - } - if (!string_equal(token, "skin")) { - Tokeniser_unexpectedError(tokeniser, token, "skin"); - return false; - } - const char *other = tokeniser.getToken(); - if (other == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#string"); - return false; - } - CopiedString name; - parseShaderName(name, other); - Doom3ModelSkin &skin = m_skins[name]; - RETURN_FALSE_IF_FAIL(skin.parseTokens(tokeniser)); - } -} - -void parseFile(const char *name) -{ - StringOutputStream relativeName(64); - relativeName << "skins/" << name; - ArchiveTextFile *file = GlobalFileSystem().openTextFile(relativeName.c_str()); - if (file != 0) { - globalOutputStream() << "parsing skins from " << makeQuoted(name) << "\n"; - { - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(file->getInputStream()); - parseTokens(tokeniser); - tokeniser.release(); - } - file->release(); - } else { - globalErrorStream() << "failed to open " << makeQuoted(name) << "\n"; - } -} - -typedef MemberCaller ParseFileCaller; - -void construct() -{ - GlobalFileSystem().forEachFile("skins/", "skin", ParseFileCaller(*this)); -} - -void destroy() -{ - m_skins.clear(); -} - -void realise() -{ - construct(); -} - -void unrealise() -{ - destroy(); -} -}; - -GlobalSkins g_skins; - - -class Doom3ModelSkinCacheElement : public ModelSkin { -ModuleObservers m_observers; -Doom3ModelSkin *m_skin; -public: -Doom3ModelSkinCacheElement() : m_skin(0) -{ -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); - if (realised()) { - observer.realise(); - } -} - -void detach(ModuleObserver &observer) -{ - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); -} - -bool realised() const -{ - return m_skin != 0; -} - -void realise(const char *name) -{ - ASSERT_MESSAGE(!realised(), "Doom3ModelSkinCacheElement::realise: already realised"); - m_skin = &g_skins.getSkin(name); - m_observers.realise(); -} - -void unrealise() -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::unrealise: not realised"); - m_observers.unrealise(); - m_skin = 0; -} - -const char *getRemap(const char *name) const -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::getRemap: not realised"); - return m_skin->getRemap(name); -} - -void forEachRemap(const SkinRemapCallback &callback) const -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::forEachRemap: not realised"); - m_skin->forEachRemap(callback); -} -}; - -class Doom3ModelSkinCache : public ModelSkinCache, public ModuleObserver { -class CreateDoom3ModelSkin { -Doom3ModelSkinCache &m_cache; -public: -explicit CreateDoom3ModelSkin(Doom3ModelSkinCache &cache) - : m_cache(cache) -{ -} - -Doom3ModelSkinCacheElement *construct(const CopiedString &name) -{ - Doom3ModelSkinCacheElement *skin = new Doom3ModelSkinCacheElement; - if (m_cache.realised()) { - skin->realise(name.c_str()); - } - return skin; -} - -void destroy(Doom3ModelSkinCacheElement *skin) -{ - if (m_cache.realised()) { - skin->unrealise(); - } - delete skin; -} -}; - -typedef HashedCache, CreateDoom3ModelSkin> Cache; -Cache m_cache; -bool m_realised; - -public: -typedef ModelSkinCache Type; - -STRING_CONSTANT(Name, "*"); - -ModelSkinCache *getTable() -{ - return this; -} - -Doom3ModelSkinCache() : m_cache(CreateDoom3ModelSkin(*this)), m_realised(false) -{ - GlobalFileSystem().attach(*this); -} - -~Doom3ModelSkinCache() -{ - GlobalFileSystem().detach(*this); -} - -ModelSkin &capture(const char *name) -{ - return *m_cache.capture(name); -} - -void release(const char *name) -{ - m_cache.release(name); -} - -bool realised() const -{ - return m_realised; -} - -void realise() -{ - g_skins.realise(); - m_realised = true; - for (Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i) { - (*i).value->realise((*i).key.c_str()); - } -} - -void unrealise() -{ - m_realised = false; - for (Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i) { - (*i).value->unrealise(); - } - g_skins.unrealise(); -} -}; - -class Doom3ModelSkinCacheDependencies : public GlobalFileSystemModuleRef, public GlobalScripLibModuleRef { -}; - -typedef SingletonModule Doom3ModelSkinCacheModule; - -Doom3ModelSkinCacheModule g_Doom3ModelSkinCacheModule; - -void Doom3ModelSkinCacheModule_selfRegister(ModuleServer &server) -{ - g_Doom3ModelSkinCacheModule.selfRegister(); -} diff --git a/plugins/entity/skincache.h b/plugins/entity/skincache.h deleted file mode 100644 index 7970843..0000000 --- a/plugins/entity/skincache.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SKINCACHE_H ) -#define INCLUDED_SKINCACHE_H - -class ModuleServer; - -void Doom3ModelSkinCacheModule_selfRegister(ModuleServer &server); - -#endif diff --git a/plugins/entity/targetable.cpp b/plugins/entity/targetable.cpp deleted file mode 100644 index 16d2bcd..0000000 --- a/plugins/entity/targetable.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "targetable.h" - -typedef std::map targetnames_t; - -const char *g_targetable_nameKey = "targetname"; - -targetnames_t g_targetnames; - -targetables_t *getTargetables(const char *targetname) -{ - if (targetname[0] == '\0') { - return 0; - } - return &g_targetnames[targetname]; -} - -Shader *RenderableTargetingEntity::m_state; diff --git a/plugins/entity/targetable.h b/plugins/entity/targetable.h deleted file mode 100644 index d6df314..0000000 --- a/plugins/entity/targetable.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TARGETABLE_H ) -#define INCLUDED_TARGETABLE_H - -#include -#include - -#include "cullable.h" -#include "renderable.h" - -#include "math/line.h" -#include "render.h" -#include "generic/callback.h" -#include "selectionlib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "stringio.h" - -class Targetable { -public: -virtual const Vector3 &world_position() const = 0; -}; - -typedef std::set targetables_t; - -extern const char *g_targetable_nameKey; - -targetables_t *getTargetables(const char *targetname); - -class EntityConnectionLine : public OpenGLRenderable { -public: -Vector3 start; -Vector3 end; - -void render(RenderStateFlags state) const -{ - float s1[2], s2[2]; - Vector3 dir(vector3_subtracted(end, start)); - double len = vector3_length(dir); - vector3_scale(dir, 8.0 * (1.0 / len)); - s1[0] = dir[0] - dir[1]; - s1[1] = dir[0] + dir[1]; - s2[0] = dir[0] + dir[1]; - s2[1] = -dir[0] + dir[1]; - - glBegin(GL_LINES); - - glVertex3fv(vector3_to_array(start)); - glVertex3fv(vector3_to_array(end)); - - len *= 0.0625; // half / 8 - - Vector3 arrow(start); - for (unsigned int i = 0, count = (len < 32) ? 1 : static_cast( len * 0.0625 ); i < count; i++) { - vector3_add(arrow, vector3_scaled(dir, (len < 32) ? len : 32)); - glVertex3fv(vector3_to_array(arrow)); - glVertex3f(arrow[0] + s1[0], arrow[1] + s1[1], arrow[2] + dir[2]); - glVertex3fv(vector3_to_array(arrow)); - glVertex3f(arrow[0] + s2[0], arrow[1] + s2[1], arrow[2] + dir[2]); - } - - glEnd(); -} -}; - -class TargetedEntity { -Targetable &m_targetable; -targetables_t *m_targets; - -void construct() -{ - if (m_targets != 0) { - m_targets->insert(&m_targetable); - } -} - -void destroy() -{ - if (m_targets != 0) { - m_targets->erase(&m_targetable); - } -} - -public: -TargetedEntity(Targetable &targetable) - : m_targetable(targetable), m_targets(getTargetables("")) -{ - construct(); -} - -~TargetedEntity() -{ - destroy(); -} - -void targetnameChanged(const char *name) -{ - destroy(); - m_targets = getTargetables(name); - construct(); -} - -typedef MemberCaller TargetnameChangedCaller; -}; - - -class TargetingEntity { -targetables_t *m_targets; -public: -TargetingEntity() : - m_targets(getTargetables("")) -{ -} - -void targetChanged(const char *target) -{ - m_targets = getTargetables(target); -} - -typedef MemberCaller TargetChangedCaller; - -typedef targetables_t::iterator iterator; - -iterator begin() const -{ - if (m_targets == 0) { - return iterator(); - } - return m_targets->begin(); -} - -iterator end() const -{ - if (m_targets == 0) { - return iterator(); - } - return m_targets->end(); -} - -size_t size() const -{ - if (m_targets == 0) { - return 0; - } - return m_targets->size(); -} - -bool empty() const -{ - return m_targets == 0 || m_targets->empty(); -} -}; - - -template -void TargetingEntity_forEach(const TargetingEntity &targets, const Functor &functor) -{ - for (TargetingEntity::iterator i = targets.begin(); i != targets.end(); ++i) { - functor((*i)->world_position()); - } -} - -typedef std::map TargetingEntities; - -template -void TargetingEntities_forEach(const TargetingEntities &targetingEntities, const Functor &functor) -{ - for (TargetingEntities::const_iterator i = targetingEntities.begin(); i != targetingEntities.end(); ++i) { - TargetingEntity_forEach((*i).second, functor); - } -} - -class TargetLinesPushBack { -RenderablePointVector &m_targetLines; -const Vector3 &m_worldPosition; -const VolumeTest &m_volume; -public: -TargetLinesPushBack(RenderablePointVector &targetLines, const Vector3 &worldPosition, const VolumeTest &volume) : - m_targetLines(targetLines), m_worldPosition(worldPosition), m_volume(volume) -{ -} - -void operator()(const Vector3 &worldPosition) const -{ - if (m_volume.TestLine(segment_for_startend(m_worldPosition, worldPosition))) { - m_targetLines.push_back(PointVertex(reinterpret_cast( m_worldPosition ))); - m_targetLines.push_back(PointVertex(reinterpret_cast( worldPosition ))); - } -} -}; - -class TargetKeys : public Entity::Observer { -TargetingEntities m_targetingEntities; -Callback m_targetsChanged; - -bool readTargetKey(const char *key, std::size_t &index) -{ - if (string_equal_n(key, "target", 6)) { - index = 0; - if (string_empty(key + 6) || string_parse_size(key + 6, index)) { - return true; - } - } - if (string_equal(key, "killtarget")) { - index = -1; - return true; - } - return false; -} - -public: -void setTargetsChanged(const Callback &targetsChanged) -{ - m_targetsChanged = targetsChanged; -} - -void targetsChanged() -{ - m_targetsChanged(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - std::size_t index; - if (readTargetKey(key, index)) { - TargetingEntities::iterator i = m_targetingEntities.insert( - TargetingEntities::value_type(index, TargetingEntity())).first; - value.attach(TargetingEntity::TargetChangedCaller((*i).second)); - targetsChanged(); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - std::size_t index; - if (readTargetKey(key, index)) { - TargetingEntities::iterator i = m_targetingEntities.find(index); - value.detach(TargetingEntity::TargetChangedCaller((*i).second)); - m_targetingEntities.erase(i); - targetsChanged(); - } -} - -const TargetingEntities &get() const -{ - return m_targetingEntities; -} -}; - - -class RenderableTargetingEntity { -TargetingEntity &m_targets; -mutable RenderablePointVector m_target_lines; -public: -static Shader *m_state; - -RenderableTargetingEntity(TargetingEntity &targets) - : m_targets(targets), m_target_lines(GL_LINES) -{ -} - -void compile(const VolumeTest &volume, const Vector3 &world_position) const -{ - m_target_lines.clear(); - m_target_lines.reserve(m_targets.size() * 2); - TargetingEntity_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume)); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Vector3 &world_position) const -{ - if (!m_targets.empty()) { - compile(volume, world_position); - if (!m_target_lines.empty()) { - renderer.addRenderable(m_target_lines, g_matrix4_identity); - } - } -} -}; - -class RenderableTargetingEntities { -const TargetingEntities &m_targets; -mutable RenderablePointVector m_target_lines; -public: -static Shader *m_state; - -RenderableTargetingEntities(const TargetingEntities &targets) - : m_targets(targets), m_target_lines(GL_LINES) -{ -} - -void compile(const VolumeTest &volume, const Vector3 &world_position) const -{ - m_target_lines.clear(); - TargetingEntities_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume)); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Vector3 &world_position) const -{ - if (!m_targets.empty()) { - compile(volume, world_position); - if (!m_target_lines.empty()) { - renderer.addRenderable(m_target_lines, g_matrix4_identity); - } - } -} -}; - - -class TargetableInstance : - public SelectableInstance, - public Targetable, - public Entity::Observer { -mutable Vertex3f m_position; -EntityKeyValues &m_entity; -TargetKeys m_targeting; -TargetedEntity m_targeted; -RenderableTargetingEntities m_renderable; -public: - -TargetableInstance( - const scene::Path &path, - scene::Instance *parent, - void *instance, - InstanceTypeCastTable &casts, - EntityKeyValues &entity, - Targetable &targetable - ) : - SelectableInstance(path, parent, instance, casts), - m_entity(entity), - m_targeted(targetable), - m_renderable(m_targeting.get()) -{ - m_entity.attach(*this); - m_entity.attach(m_targeting); -} - -~TargetableInstance() -{ - m_entity.detach(m_targeting); - m_entity.detach(*this); -} - -void setTargetsChanged(const Callback &targetsChanged) -{ - m_targeting.setTargetsChanged(targetsChanged); -} - -void targetsChanged() -{ - m_targeting.targetsChanged(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - if (string_equal(key, g_targetable_nameKey)) { - value.attach(TargetedEntity::TargetnameChangedCaller(m_targeted)); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - if (string_equal(key, g_targetable_nameKey)) { - value.detach(TargetedEntity::TargetnameChangedCaller(m_targeted)); - } -} - -const Vector3 &world_position() const -{ -#if 1 - const AABB &bounds = Instance::worldAABB(); - if (aabb_valid(bounds)) { - return bounds.origin; - } -#else - const AABB& childBounds = Instance::childBounds(); - if ( aabb_valid( childBounds ) ) { - return childBounds.origin; - } -#endif - return vector4_to_vector3(localToWorld().t()); -} - -void render(Renderer &renderer, const VolumeTest &volume) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); - m_renderable.render(renderer, volume, world_position()); -} - -const TargetingEntities &getTargeting() const -{ - return m_targeting.get(); -} -}; - - -class RenderableConnectionLines : public Renderable { -typedef std::set TargetableInstances; -TargetableInstances m_instances; -public: -void attach(TargetableInstance &instance) -{ - ASSERT_MESSAGE(m_instances.find(&instance) == m_instances.end(), "cannot attach instance"); - m_instances.insert(&instance); -} - -void detach(TargetableInstance &instance) -{ - ASSERT_MESSAGE(m_instances.find(&instance) != m_instances.end(), "cannot detach instance"); - m_instances.erase(&instance); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - for (TargetableInstances::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) { - if ((*i)->path().top().get().visible()) { - (*i)->render(renderer, volume); - } - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} -}; - -typedef Static StaticRenderableConnectionLines; - -#endif diff --git a/plugins/image/Makefile b/plugins/image/Makefile deleted file mode 100644 index 7b8c863..0000000 --- a/plugins/image/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) -JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(JPEG_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) $(JPEG_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - bmp.o dds.o image.o jpeg.o ktx.o pcx.o tga.o - -# binary target -../../build/plugins/libimage.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libddslib.a ../../libs/libetclib.a $(PLUGIN_LDFLAGS) - -# object files -bmp.o: bmp.cpp bmp.h -dds.o: dds.cpp dds.h -image.o: image.cpp -jpeg.o: jpeg.cpp jpeg.h -ktx.o: ktx.cpp ktx.h -pcx.o: pcx.cpp pcx.h -tga.o: tga.cpp tga.h - -clean: - -rm -f *.o ../../build/plugins/libimage.$(LIB_EXT) diff --git a/plugins/image/bmp.cpp b/plugins/image/bmp.cpp deleted file mode 100644 index a89bb63..0000000 --- a/plugins/image/bmp.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "bmp.h" - -#include "ifilesystem.h" - -typedef unsigned char byte; - -#include "imagelib.h" -#include "bytestreamutils.h" - - -typedef unsigned char PaletteEntry[4]; -typedef struct { - char id[2]; - unsigned long fileSize; - unsigned long reserved0; - unsigned long bitmapDataOffset; - unsigned long bitmapHeaderSize; - unsigned long width; - unsigned long height; - unsigned short planes; - unsigned short bitsPerPixel; - unsigned long compression; - unsigned long bitmapDataSize; - unsigned long hRes; - unsigned long vRes; - unsigned long colors; - unsigned long importantColors; - PaletteEntry palette[256]; -} BMPHeader_t; - -class ReadPixel8 { -PaletteEntry *m_palette; -public: -ReadPixel8(PaletteEntry *palette) : m_palette(palette) -{ -} - -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte palIndex; - inputStream.read(&palIndex, 1); - *pixbuf++ = m_palette[palIndex][2]; - *pixbuf++ = m_palette[palIndex][1]; - *pixbuf++ = m_palette[palIndex][0]; - *pixbuf++ = 0xff; -} -}; - -class ReadPixel16 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - unsigned short shortPixel; - inputStream.read(reinterpret_cast( &shortPixel ), sizeof(unsigned short)); //!\todo Is this endian safe? - *pixbuf++ = static_cast( shortPixel & (31 << 10)) >> 7; - *pixbuf++ = static_cast( shortPixel & (31 << 5)) >> 2; - *pixbuf++ = static_cast( shortPixel & (31)) << 3; - *pixbuf++ = 0xff; -} -}; - -class ReadPixel24 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte bgr[3]; - inputStream.read(bgr, 3); - *pixbuf++ = bgr[2]; - *pixbuf++ = bgr[1]; - *pixbuf++ = bgr[0]; - *pixbuf++ = 255; -} -}; - -class ReadPixel32 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte bgra[4]; - inputStream.read(bgra, 4); - *pixbuf++ = bgra[2]; - *pixbuf++ = bgra[1]; - *pixbuf++ = bgra[0]; - *pixbuf++ = bgra[3]; -} -}; - -template -void ReadBMP(PointerInputStream &inputStream, byte *bmpRGBA, int rows, int columns, ReadPixel readPixel) -{ - for (int row = rows - 1; row >= 0; row--) { - byte *pixbuf = bmpRGBA + row * columns * 4; - - for (int column = 0; column < columns; column++) { - readPixel(inputStream, pixbuf); - } - } -} - -Image *LoadBMPBuff(PointerInputStream &inputStream, std::size_t length) -{ - BMPHeader_t bmpHeader; - inputStream.read(reinterpret_cast( bmpHeader.id ), 2); - bmpHeader.fileSize = istream_read_uint32_le(inputStream); - bmpHeader.reserved0 = istream_read_uint32_le(inputStream); - bmpHeader.bitmapDataOffset = istream_read_uint32_le(inputStream); - bmpHeader.bitmapHeaderSize = istream_read_uint32_le(inputStream); - bmpHeader.width = istream_read_uint32_le(inputStream); - bmpHeader.height = istream_read_uint32_le(inputStream); - bmpHeader.planes = istream_read_uint16_le(inputStream); - bmpHeader.bitsPerPixel = istream_read_uint16_le(inputStream); - bmpHeader.compression = istream_read_uint32_le(inputStream); - bmpHeader.bitmapDataSize = istream_read_uint32_le(inputStream); - bmpHeader.hRes = istream_read_uint32_le(inputStream); - bmpHeader.vRes = istream_read_uint32_le(inputStream); - bmpHeader.colors = istream_read_uint32_le(inputStream); - bmpHeader.importantColors = istream_read_uint32_le(inputStream); - - if (bmpHeader.bitsPerPixel == 8) { - int paletteSize = bmpHeader.colors * 4; - inputStream.read(reinterpret_cast( bmpHeader.palette ), paletteSize); - } - - if (bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M') { - globalErrorStream() << "LoadBMP: only Windows-style BMP files supported\n"; - return 0; - } - if (bmpHeader.fileSize != length) { - globalErrorStream() << "LoadBMP: header size does not match file size (" << Unsigned(bmpHeader.fileSize) - << " vs. " << Unsigned(length) << ")\n"; - return 0; - } - if (bmpHeader.compression != 0) { - globalErrorStream() << "LoadBMP: only uncompressed BMP files supported\n"; - return 0; - } - if (bmpHeader.bitsPerPixel < 8) { - globalErrorStream() << "LoadBMP: monochrome and 4-bit BMP files not supported\n"; - return 0; - } - - int columns = bmpHeader.width; - int rows = bmpHeader.height; - if (rows < 0) { - rows = -rows; - } - - RGBAImage *image = new RGBAImage(columns, rows); - - switch (bmpHeader.bitsPerPixel) { - case 8: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel8(bmpHeader.palette)); - break; - case 16: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel16()); - break; - case 24: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel24()); - break; - case 32: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel32()); - break; - default: - globalErrorStream() << "LoadBMP: illegal pixel_size '" << bmpHeader.bitsPerPixel << "'\n"; - image->release(); - return 0; - } - return image; -} - -Image *LoadBMP(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - PointerInputStream inputStream(buffer.buffer); - return LoadBMPBuff(inputStream, buffer.length); -} diff --git a/plugins/image/bmp.h b/plugins/image/bmp.h deleted file mode 100644 index 043c289..0000000 --- a/plugins/image/bmp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_BMP_H ) -#define INCLUDED_BMP_H - -class Image; - -class ArchiveFile; - -Image *LoadBMP(ArchiveFile &file); - -#endif diff --git a/plugins/image/dds.cpp b/plugins/image/dds.cpp deleted file mode 100644 index 09d3649..0000000 --- a/plugins/image/dds.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dds.h" - -#include - -#include "ifilesystem.h" -#include "iarchive.h" -#include "idatastream.h" - -#include "ddslib.h" -#include "imagelib.h" - -Image *LoadDDSBuff(const byte *buffer) -{ - int width, height; - ddsPF_t pixelFormat; - if (DDSGetInfo(reinterpret_cast( const_cast( buffer )), &width, &height, &pixelFormat) == - -1) { - return 0; - } - - RGBAImage *image = new RGBAImage(width, height); - - if (DDSDecompress(reinterpret_cast( const_cast( buffer )), image->getRGBAPixels()) == -1) { - image->release(); - return 0; - } - return image; -} - -Image *LoadDDS(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadDDSBuff(buffer.buffer); -} diff --git a/plugins/image/dds.h b/plugins/image/dds.h deleted file mode 100644 index 5e65831..0000000 --- a/plugins/image/dds.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DDS_H ) -#define INCLUDED_DDS_H - -class Image; - -class ArchiveFile; - -Image *LoadDDS(ArchiveFile &file); - -#endif diff --git a/plugins/image/image.cpp b/plugins/image/image.cpp deleted file mode 100644 index 9458c5b..0000000 --- a/plugins/image/image.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ifilesystem.h" -#include "iimage.h" - -#include "jpeg.h" -#include "tga.h" -#include "bmp.h" -#include "pcx.h" -#include "dds.h" -#include "ktx.h" - - -#include "modulesystem/singletonmodule.h" - -class ImageDependencies : public GlobalFileSystemModuleRef { -}; - -class ImageTGAAPI { -_QERPlugImageTable m_imagetga; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "tga"); - -ImageTGAAPI() -{ - m_imagetga.loadImage = LoadTGA; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagetga; -} -}; - -typedef SingletonModule ImageTGAModule; - -ImageTGAModule g_ImageTGAModule; - - -class ImageJPGAPI { -_QERPlugImageTable m_imagejpg; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "jpg"); - -ImageJPGAPI() -{ - m_imagejpg.loadImage = LoadJPG; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagejpg; -} -}; - -typedef SingletonModule ImageJPGModule; - -ImageJPGModule g_ImageJPGModule; - - -class ImageBMPAPI { -_QERPlugImageTable m_imagebmp; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "bmp"); - -ImageBMPAPI() -{ - m_imagebmp.loadImage = LoadBMP; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagebmp; -} -}; - -typedef SingletonModule ImageBMPModule; - -ImageBMPModule g_ImageBMPModule; - - -class ImagePCXAPI { -_QERPlugImageTable m_imagepcx; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "pcx"); - -ImagePCXAPI() -{ - m_imagepcx.loadImage = LoadPCX32; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagepcx; -} -}; - -typedef SingletonModule ImagePCXModule; - -ImagePCXModule g_ImagePCXModule; - - -class ImageDDSAPI { -_QERPlugImageTable m_imagedds; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "dds"); - -ImageDDSAPI() -{ - m_imagedds.loadImage = LoadDDS; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagedds; -} -}; - -typedef SingletonModule ImageDDSModule; - -ImageDDSModule g_ImageDDSModule; - - -class ImageKTXAPI { -_QERPlugImageTable m_imagektx; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "ktx"); - -ImageKTXAPI() -{ - m_imagektx.loadImage = LoadKTX; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagektx; -} -}; - -typedef SingletonModule ImageKTXModule; - -ImageKTXModule g_ImageKTXModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_ImageTGAModule.selfRegister(); - g_ImageJPGModule.selfRegister(); - g_ImageBMPModule.selfRegister(); - g_ImagePCXModule.selfRegister(); - g_ImageDDSModule.selfRegister(); - g_ImageKTXModule.selfRegister(); -} diff --git a/plugins/image/jpeg.cpp b/plugins/image/jpeg.cpp deleted file mode 100644 index a91fa5e..0000000 --- a/plugins/image/jpeg.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Functions to load JPEG files from a buffer, based on jdatasrc.c -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "jpeg.h" - -#include -#include -#include -#include - -extern "C" { -#include -#include -} - -#include "ifilesystem.h" - -#include "imagelib.h" - -typedef unsigned char byte; - -/* Expanded data source object for stdio input */ - -typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - int src_size; - JOCTET *src_buffer; - - JOCTET *buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ -} my_source_mgr; - -typedef my_source_mgr *my_src_ptr; - -const int INPUT_BUF_SIZE = 4096; /* choose an efficiently fread'able size */ - - -/* - * Initialize source --- called by jpeg_read_header - * before any data is actually read. - */ - -static void my_init_source(j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; -} - - -/* - * Fill the input buffer --- called whenever buffer is emptied. - * - * In typical applications, this should read fresh data into the buffer - * (ignoring the current state of next_input_byte & bytes_in_buffer), - * reset the pointer & count to the start of the buffer, and return TRUE - * indicating that the buffer has been reloaded. It is not necessary to - * fill the buffer entirely, only to obtain at least one more byte. - * - * There is no such thing as an EOF return. If the end of the file has been - * reached, the routine has a choice of ERREXIT() or inserting fake data into - * the buffer. In most cases, generating a warning message and inserting a - * fake EOI marker is the best course of action --- this will allow the - * decompressor to output however much of the image is there. However, - * the resulting error message is misleading if the real problem is an empty - * input file, so we handle that case specially. - * - * In applications that need to be able to suspend compression due to input - * not being available yet, a FALSE return indicates that no more data can be - * obtained right now, but more may be forthcoming later. In this situation, - * the decompressor will return to its caller (with an indication of the - * number of scanlines it has read, if any). The application should resume - * decompression after it has loaded more data into the input buffer. Note - * that there are substantial restrictions on the use of suspension --- see - * the documentation. - * - * When suspending, the decompressor will back up to a convenient restart point - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point must be rescanned after resumption, so move it to - * the front of the buffer rather than discarding it. - */ - -static boolean my_fill_input_buffer(j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - size_t nbytes; - - if (src->src_size > INPUT_BUF_SIZE) { - nbytes = INPUT_BUF_SIZE; - } else { - nbytes = src->src_size; - } - - memcpy(src->buffer, src->src_buffer, nbytes); - src->src_buffer += nbytes; - src->src_size -= nbytes; - - if (nbytes <= 0) { - if (src->start_of_file) { /* Treat empty input file as fatal error */ - ERREXIT(cinfo, JERR_INPUT_EMPTY); - } - WARNMS(cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (JOCTET) 0xFF; - src->buffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; -} - - -/* - * Skip data --- used to skip over a potentially large amount of - * uninteresting data (such as an APPn marker). - * - * Writers of suspendable-input applications must note that skip_input_data - * is not granted the right to give a suspension return. If the skip extends - * beyond the data currently in the buffer, the buffer can be marked empty so - * that the next read will cause a fill_input_buffer call that can suspend. - * Arranging for additional bytes to be discarded before reloading the input - * buffer is the application writer's problem. - */ - -static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* Just a dumb implementation for now. Could use fseek() except - * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) { - while (num_bytes > (long) src->pub.bytes_in_buffer) { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) my_fill_input_buffer(cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - - -/* - * An additional method that can be provided by data source modules is the - * resync_to_restart method for error recovery in the presence of RST markers. - * For the moment, this source module just uses the default resync method - * provided by the JPEG library. That method assumes that no backtracking - * is possible. - */ - - -/* - * Terminate source --- called by jpeg_finish_decompress - * after all data has been read. Often a no-op. - * - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding - * application must deal with any cleanup that should happen even - * for error exit. - */ - -static void my_term_source(j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. - */ - -static void jpeg_buffer_src(j_decompress_ptr cinfo, void *buffer, int bufsize) -{ - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * sizeof(JOCTET)); - } - - src = (my_src_ptr) cinfo->src; - src->pub.init_source = my_init_source; - src->pub.fill_input_buffer = my_fill_input_buffer; - src->pub.skip_input_data = my_skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = my_term_source; - src->src_buffer = (JOCTET *) buffer; - src->src_size = bufsize; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ -} - -// ============================================================================= - -static char errormsg[JMSG_LENGTH_MAX]; - -typedef struct my_jpeg_error_mgr { - struct jpeg_error_mgr pub; // "public" fields - jmp_buf setjmp_buffer; // for return to caller -} bt_jpeg_error_mgr; - -static void my_jpeg_error_exit(j_common_ptr cinfo) -{ - my_jpeg_error_mgr *myerr = (bt_jpeg_error_mgr *) cinfo->err; - - (*cinfo->err->format_message)(cinfo, errormsg); - - longjmp(myerr->setjmp_buffer, 1); -} - -// stash a scanline -static void j_putRGBScanline(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iRed, iBlu, iGrn; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - iRed = *(jpegline + count * 3 + 0); - iGrn = *(jpegline + count * 3 + 1); - iBlu = *(jpegline + count * 3 + 2); - - oRed = outBuf + offset + count * 4 + 0; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iRed; - *oGrn = iGrn; - *oBlu = iBlu; - *oAlp = 255; - } -} - -// stash a scanline -static void j_putRGBAScanline(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iRed, iBlu, iGrn, iAlp; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - iRed = *(jpegline + count * 4 + 0); - iGrn = *(jpegline + count * 4 + 1); - iBlu = *(jpegline + count * 4 + 2); - iAlp = *(jpegline + count * 4 + 3); - - oRed = outBuf + offset + count * 4 + 0; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iRed; - *oGrn = iGrn; - *oBlu = iBlu; - - //!\todo fix jpeglib, it leaves alpha channel uninitialised -#if 1 - (void) iAlp; - *oAlp = 255; -#else - *oAlp = iAlp; -#endif - } -} - -// stash a gray scanline -static void j_putGrayScanlineToRGB(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iGray; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - // get our grayscale value - iGray = *(jpegline + count); - - oRed = outBuf + offset + count * 4; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iGray; - *oGrn = iGray; - *oBlu = iGray; - *oAlp = 255; - } -} - -static Image *LoadJPGBuff_(const void *src_buffer, int src_size) -{ - struct jpeg_decompress_struct cinfo; - struct my_jpeg_error_mgr jerr; - - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_jpeg_error_exit; - - if (setjmp(jerr.setjmp_buffer)) { //< TODO: use c++ exceptions instead of setjmp/longjmp to handle errors - globalErrorStream() << "WARNING: JPEG library error: " << errormsg << "\n"; - jpeg_destroy_decompress(&cinfo); - return 0; - } - - jpeg_create_decompress(&cinfo); - jpeg_buffer_src(&cinfo, const_cast( src_buffer ), src_size); - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - int row_stride = cinfo.output_width * cinfo.output_components; - - RGBAImage *image = new RGBAImage(cinfo.output_width, cinfo.output_height); - - JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - while (cinfo.output_scanline < cinfo.output_height) { - jpeg_read_scanlines(&cinfo, buffer, 1); - - if (cinfo.out_color_components == 4) { - j_putRGBAScanline(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } else if (cinfo.out_color_components == 3) { - j_putRGBScanline(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } else if (cinfo.out_color_components == 1) { - j_putGrayScanlineToRGB(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - return image; -} - -Image *LoadJPG(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadJPGBuff_(buffer.buffer, static_cast( buffer.length )); -} diff --git a/plugins/image/jpeg.h b/plugins/image/jpeg.h deleted file mode 100644 index 2295297..0000000 --- a/plugins/image/jpeg.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined ( INCLUDED_JPEG_H ) -#define INCLUDED_JPEG_H - -class Image; - -class ArchiveFile; - -Image *LoadJPG(ArchiveFile &file); - -#endif diff --git a/plugins/image/ktx.cpp b/plugins/image/ktx.cpp deleted file mode 100644 index 0692bc8..0000000 --- a/plugins/image/ktx.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - Copyright (C) 2015, SiPlus, Chasseur de bots. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ktx.h" - -#include - -#include "bytestreamutils.h" -#include "etclib.h" -#include "ifilesystem.h" -#include "imagelib.h" - - -const int KTX_TYPE_UNSIGNED_BYTE = 0x1401; -const int KTX_TYPE_UNSIGNED_SHORT_4_4_4_4 = 0x8033; -const int KTX_TYPE_UNSIGNED_SHORT_5_5_5_1 = 0x8034; -const int KTX_TYPE_UNSIGNED_SHORT_5_6_5 = 0x8363; - -const int KTX_FORMAT_ALPHA = 0x1906; -const int KTX_FORMAT_RGB = 0x1907; -const int KTX_FORMAT_RGBA = 0x1908; -const int KTX_FORMAT_LUMINANCE = 0x1909; -const int KTX_FORMAT_LUMINANCE_ALPHA = 0x190A; -const int KTX_FORMAT_BGR = 0x80E0; -const int KTX_FORMAT_BGRA = 0x80E1; - -const int KTX_FORMAT_ETC1_RGB8 = 0x8D64; - -class KTX_Decoder { -public: -virtual ~KTX_Decoder() = default; - -virtual void Decode(PointerInputStream &istream, byte *out) = 0; - -virtual unsigned int GetPixelSize() = 0; -}; - -class KTX_Decoder_A8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - out[0] = out[1] = out[2] = 0; - out[3] = istream_read_byte(istream); -} - -virtual unsigned int GetPixelSize() -{ - return 1; -} -}; - -class KTX_Decoder_RGB8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - istream.read(out, 3); - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 3; -} -}; - -class KTX_Decoder_RGBA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - istream.read(out, 4); -} - -virtual unsigned int GetPixelSize() -{ - return 4; -} -}; - -class KTX_Decoder_L8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte l = istream_read_byte(istream); - out[0] = out[1] = out[2] = l; - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 1; -} -}; - -class KTX_Decoder_LA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte la[2]; - istream.read(la, 2); - out[0] = out[1] = out[2] = la[0]; - out[3] = la[1]; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_BGR8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte bgr[3]; - istream.read(bgr, 3); - out[0] = bgr[2]; - out[1] = bgr[1]; - out[2] = bgr[0]; - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 3; -} -}; - -class KTX_Decoder_BGRA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte bgra[4]; - istream.read(bgra, 4); - out[0] = bgra[2]; - out[1] = bgra[1]; - out[2] = bgra[0]; - out[3] = bgra[3]; -} - -virtual unsigned int GetPixelSize() -{ - return 4; -} -}; - -class KTX_Decoder_RGBA4 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGBA4(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgba; - if (m_bigEndian) { - rgba = istream_read_uint16_be(istream); - } else { - rgba = istream_read_uint16_le(istream); - } - int r = (rgba >> 12) & 0xf; - int g = (rgba >> 8) & 0xf; - int b = (rgba >> 4) & 0xf; - int a = rgba & 0xf; - out[0] = (r << 4) | r; - out[1] = (g << 4) | g; - out[2] = (b << 4) | b; - out[3] = (a << 4) | a; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_RGBA5 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGBA5(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgba; - if (m_bigEndian) { - rgba = istream_read_uint16_be(istream); - } else { - rgba = istream_read_uint16_le(istream); - } - int r = (rgba >> 11) & 0x1f; - int g = (rgba >> 6) & 0x1f; - int b = (rgba >> 1) & 0x1f; - out[0] = (r << 3) | (r >> 2); - out[1] = (g << 3) | (g >> 2); - out[2] = (b << 3) | (b >> 2); - out[3] = (rgba & 1) * 255; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_RGB5 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGB5(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgb; - if (m_bigEndian) { - rgb = istream_read_uint16_be(istream); - } else { - rgb = istream_read_uint16_le(istream); - } - int r = (rgb >> 11) & 0x1f; - int g = (rgb >> 5) & 0x3f; - int b = rgb & 0x1f; - out[0] = (r << 3) | (r >> 2); - out[1] = (g << 2) | (g >> 4); - out[2] = (b << 3) | (b >> 2); - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -static void KTX_DecodeETC1(PointerInputStream &istream, Image &image) -{ - unsigned int width = image.getWidth(), height = image.getHeight(); - unsigned int stride = width * 4; - byte *pixbuf = image.getRGBAPixels(); - byte etc[8], rgba[64]; - - for (unsigned int y = 0; y < height; y += 4, pixbuf += stride * 4) { - unsigned int blockrows = height - y; - if (blockrows > 4) { - blockrows = 4; - } - - byte *p = pixbuf; - for (unsigned int x = 0; x < width; x += 4, p += 16) { - istream.read(etc, 8); - ETC_DecodeETC1Block(etc, rgba, qtrue); - - unsigned int blockrowsize = width - x; - if (blockrowsize > 4) { - blockrowsize = 4; - } - blockrowsize *= 4; - for (unsigned int blockrow = 0; blockrow < blockrows; blockrow++) { - memcpy(p + blockrow * stride, rgba + blockrow * 16, blockrowsize); - } - } - } -} - -Image *LoadKTXBuff(PointerInputStream &istream) -{ - byte identifier[12]; - istream.read(identifier, 12); - if (memcmp(identifier, "\xABKTX 11\xBB\r\n\x1A\n", 12)) { - globalErrorStream() << "LoadKTX: Image has the wrong identifier\n"; - return 0; - } - - bool bigEndian = (istream_read_uint32_le(istream) == 0x01020304); - - unsigned int type; - if (bigEndian) { - type = istream_read_uint32_be(istream); - } else { - type = istream_read_uint32_le(istream); - } - - // For compressed textures, the format is in glInternalFormat. - // For uncompressed textures, it's in glBaseInternalFormat. - istream.seek((type ? 3 : 2) * sizeof(uint32_t)); - unsigned int format; - if (bigEndian) { - format = istream_read_uint32_be(istream); - } else { - format = istream_read_uint32_le(istream); - } - if (!type) { - istream.seek(sizeof(uint32_t)); - } - - unsigned int width, height; - if (bigEndian) { - width = istream_read_uint32_be(istream); - height = istream_read_uint32_be(istream); - } else { - width = istream_read_uint32_le(istream); - height = istream_read_uint32_le(istream); - } - if (!width) { - globalErrorStream() << "LoadKTX: Image has zero width\n"; - return 0; - } - if (!height) { - height = 1; - } - - // Skip the key/values and load the first 2D image in the texture. - // Since KTXorientation is only a hint and has no effect on the texture data and coordinates, it must be ignored. - istream.seek(4 * sizeof(uint32_t)); - unsigned int bytesOfKeyValueData; - if (bigEndian) { - bytesOfKeyValueData = istream_read_uint32_be(istream); - } else { - bytesOfKeyValueData = istream_read_uint32_le(istream); - } - istream.seek(bytesOfKeyValueData + sizeof(uint32_t)); - - RGBAImage *image = new RGBAImage(width, height); - - if (type) { - KTX_Decoder *decoder = NULL; - switch (type) { - case KTX_TYPE_UNSIGNED_BYTE: - switch (format) { - case KTX_FORMAT_ALPHA: - decoder = new KTX_Decoder_A8(); - break; - case KTX_FORMAT_RGB: - decoder = new KTX_Decoder_RGB8(); - break; - case KTX_FORMAT_RGBA: - decoder = new KTX_Decoder_RGBA8(); - break; - case KTX_FORMAT_LUMINANCE: - decoder = new KTX_Decoder_L8(); - break; - case KTX_FORMAT_LUMINANCE_ALPHA: - decoder = new KTX_Decoder_LA8(); - break; - case KTX_FORMAT_BGR: - decoder = new KTX_Decoder_BGR8(); - break; - case KTX_FORMAT_BGRA: - decoder = new KTX_Decoder_BGRA8(); - break; - } - break; - case KTX_TYPE_UNSIGNED_SHORT_4_4_4_4: - if (format == KTX_FORMAT_RGBA) { - decoder = new KTX_Decoder_RGBA4(bigEndian); - } - break; - case KTX_TYPE_UNSIGNED_SHORT_5_5_5_1: - if (format == KTX_FORMAT_RGBA) { - decoder = new KTX_Decoder_RGBA5(bigEndian); - } - break; - case KTX_TYPE_UNSIGNED_SHORT_5_6_5: - if (format == KTX_FORMAT_RGB) { - decoder = new KTX_Decoder_RGB5(bigEndian); - } - break; - } - - if (!decoder) { - globalErrorStream() << "LoadKTX: Image has an unsupported pixel type " << type << " or format " << format - << "\n"; - image->release(); - return 0; - } - - unsigned int inRowLength = width * decoder->GetPixelSize(); - unsigned int inPadding = ((inRowLength + 3) & ~3) - inRowLength; - byte *out = image->getRGBAPixels(); - for (unsigned int y = 0; y < height; y++) { - for (unsigned int x = 0; x < width; x++, out += 4) { - decoder->Decode(istream, out); - } - - if (inPadding) { - istream.seek(inPadding); - } - } - - delete decoder; - } else { - switch (format) { - case KTX_FORMAT_ETC1_RGB8: - KTX_DecodeETC1(istream, *image); - break; - default: - globalErrorStream() << "LoadKTX: Image has an unsupported compressed format " << format << "\n"; - image->release(); - return 0; - } - } - - return image; -} - -Image *LoadKTX(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - PointerInputStream istream(buffer.buffer); - return LoadKTXBuff(istream); -} diff --git a/plugins/image/ktx.h b/plugins/image/ktx.h deleted file mode 100644 index f9b0553..0000000 --- a/plugins/image/ktx.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2015, SiPlus, Chasseur de bots. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_KTX_H ) -#define INCLUDED_KTX_H - -class Image; - -class ArchiveFile; - -Image *LoadKTX(ArchiveFile &file); - -#endif diff --git a/plugins/image/pcx.cpp b/plugins/image/pcx.cpp deleted file mode 100644 index 99646f3..0000000 --- a/plugins/image/pcx.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pcx.h" - -#include "ifilesystem.h" - -typedef unsigned char byte; - -#include - -#include "imagelib.h" -#include "bytestreamutils.h" - -/* - ================================================================= - - PCX LOADING - - ================================================================= - */ - -typedef struct { - unsigned char manufacturer; - unsigned char version; - unsigned char encoding; - unsigned char bits_per_pixel; - unsigned short xmin, ymin, xmax, ymax; - unsigned short hres, vres; - unsigned char palette[48]; - unsigned char reserved; - unsigned char color_planes; - unsigned short bytes_per_line; - unsigned short palette_type; - unsigned char filler[58]; - unsigned char data; // unbounded -} pcx_t; - -/* - ============== - LoadPCX - ============== - */ - -struct PCXRLEPacket { - byte data; - int length; -}; - -inline void ByteStream_readPCXRLEPacket(PointerInputStream &inputStream, PCXRLEPacket &packet) -{ - byte d; - inputStream.read(&d, 1); - if ((d & 0xC0) == 0xC0) { - packet.length = d & 0x3F; - inputStream.read(&packet.data, 1); - } else { - packet.length = 1; - packet.data = d; - } -} - -void LoadPCXBuff(byte *buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height) -{ - *pic = 0; - - pcx_t pcx; - int x, y, lsize; - byte *out, *pix; - - /* parse the PCX file */ - - PointerInputStream inputStream(buffer); - - pcx.manufacturer = istream_read_byte(inputStream); - pcx.version = istream_read_byte(inputStream); - pcx.encoding = istream_read_byte(inputStream); - pcx.bits_per_pixel = istream_read_byte(inputStream); - pcx.xmin = istream_read_int16_le(inputStream); - pcx.ymin = istream_read_int16_le(inputStream); - pcx.xmax = istream_read_int16_le(inputStream); - pcx.ymax = istream_read_int16_le(inputStream); - pcx.hres = istream_read_int16_le(inputStream); - pcx.vres = istream_read_int16_le(inputStream); - inputStream.read(pcx.palette, 48); - pcx.reserved = istream_read_byte(inputStream); - pcx.color_planes = istream_read_byte(inputStream); - pcx.bytes_per_line = istream_read_int16_le(inputStream); - pcx.palette_type = istream_read_int16_le(inputStream); - inputStream.read(pcx.filler, 58); - - - if (pcx.manufacturer != 0x0a - || pcx.version != 5 - || pcx.encoding != 1 - || pcx.bits_per_pixel != 8) { - return; - } - - if (width) { - *width = pcx.xmax + 1; - } - if (height) { - *height = pcx.ymax + 1; - } - - if (!pic) { - return; - } - - out = (byte *) malloc((pcx.ymax + 1) * (pcx.xmax + 1)); - - *pic = out; - pix = out; - - /* RR2DO2: pcx fix */ - lsize = pcx.color_planes * pcx.bytes_per_line; - - /* go scanline by scanline */ - for (y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1) { - /* do a scanline */ - for (x = 0; x <= pcx.xmax;) { - /* RR2DO2 */ - PCXRLEPacket packet; - ByteStream_readPCXRLEPacket(inputStream, packet); - - while (packet.length-- > 0) { - pix[x++] = packet.data; - } - } - - /* RR2DO2: discard any other data */ - PCXRLEPacket packet; - while (x < lsize) { - ByteStream_readPCXRLEPacket(inputStream, packet); - x++; - } - while (packet.length-- > 0) { - x++; - } - } - - /* validity check */ - if (std::size_t(inputStream.get() - buffer) > len) { - *pic = 0; - } - - if (palette) { - *palette = (byte *) malloc(768); - memcpy(*palette, buffer + len - 768, 768); - } -} - -/* - ============== - LoadPCX32 - ============== - */ -Image *LoadPCX32Buff(byte *buffer, std::size_t length) -{ - byte *palette; - byte *pic8; - int i, c, p, width, height; - byte *pic32; - - LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height); - if (!pic8) { - return 0; - } - - RGBAImage *image = new RGBAImage(width, height); - c = (width) * (height); - pic32 = image->getRGBAPixels(); - for (i = 0; i < c; i++) { - p = pic8[i]; - pic32[0] = palette[p * 3]; - pic32[1] = palette[p * 3 + 1]; - pic32[2] = palette[p * 3 + 2]; - pic32[3] = 255; - pic32 += 4; - } - - free(pic8); - free(palette); - - return image; -} - -Image *LoadPCX32(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadPCX32Buff(buffer.buffer, buffer.length); -} diff --git a/plugins/image/pcx.h b/plugins/image/pcx.h deleted file mode 100644 index 81f10e4..0000000 --- a/plugins/image/pcx.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_PCX_H ) -#define INCLUDED_PCX_H - -class Image; - -class ArchiveFile; - -Image *LoadPCX32(ArchiveFile &file); - -#endif diff --git a/plugins/image/tga.cpp b/plugins/image/tga.cpp deleted file mode 100644 index 7aa85bd..0000000 --- a/plugins/image/tga.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "tga.h" - -#include "ifilesystem.h" -#include "iarchive.h" -#include "idatastream.h" - -typedef unsigned char byte; - -#include - -#include "generic/bitfield.h" -#include "imagelib.h" -#include "bytestreamutils.h" - -// represents x,y origin of tga image being decoded -class Flip00 {}; // no flip -class Flip01 {}; // vertical flip only -class Flip10 {}; // horizontal flip only -class Flip11 {}; // both - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip00 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = end; row != image.pixels; row -= image.width) { - for (RGBAPixel *pixel = row - image.width; pixel != row; ++pixel) { - decode(istream, *pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip01 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = image.pixels; row != end; row += image.width) { - for (RGBAPixel *pixel = row; pixel != row + image.width; ++pixel) { - decode(istream, *pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip10 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = end; row != image.pixels; row -= image.width) { - for (RGBAPixel *pixel = row; pixel != row - image.width;) { - decode(istream, *--pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip11 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = image.pixels; row != end; row += image.width) { - for (RGBAPixel *pixel = row + image.width; pixel != row;) { - decode(istream, *--pixel); - } - } -} - -inline void istream_read_gray(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - pixel.red = pixel.green = pixel.blue; - pixel.alpha = 0xff; -} - -inline void istream_read_rgb(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - istream.read(&pixel.green, 1); - istream.read(&pixel.red, 1); - pixel.alpha = 0xff; -} - -inline void istream_read_rgba(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - istream.read(&pixel.green, 1); - istream.read(&pixel.red, 1); - istream.read(&pixel.alpha, 1); -} - -class TargaDecodeGrayPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_gray(istream, pixel); -} -}; - -template -void targa_decode_grayscale(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeGrayPixel decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_rgb(istream, pixel); -} -}; - -template -void targa_decode_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBPixel decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBAPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_rgba(istream, pixel); -} -}; - -template -void targa_decode_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBAPixel decode; - image_decode(istream, decode, image, flip); -} - -typedef byte TargaPacket; -typedef byte TargaPacketSize; - -inline void targa_packet_read_istream(TargaPacket &packet, PointerInputStream &istream) -{ - istream.read(&packet, 1); -} - -inline bool targa_packet_is_rle(const TargaPacket &packet) -{ - return (packet & 0x80) != 0; -} - -inline TargaPacketSize targa_packet_size(const TargaPacket &packet) -{ - return 1 + (packet & 0x7f); -} - - -class TargaDecodeGrayPixelRLE { -TargaPacketSize m_packetSize; -RGBAPixel m_pixel; -TargaPacket m_packet; -public: -TargaDecodeGrayPixelRLE() : m_packetSize(0) -{ -} - -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - if (m_packetSize == 0) { - targa_packet_read_istream(m_packet, istream); - m_packetSize = targa_packet_size(m_packet); - - if (targa_packet_is_rle(m_packet)) { - istream_read_gray(istream, m_pixel); - } - } - - if (targa_packet_is_rle(m_packet)) { - pixel = m_pixel; - } else { - istream_read_gray(istream, pixel); - } - - --m_packetSize; -} -}; - -template -void targa_decode_rle_grayscale(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeGrayPixelRLE decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBPixelRLE { -TargaPacketSize m_packetSize; -RGBAPixel m_pixel; -TargaPacket m_packet; -public: -TargaDecodeRGBPixelRLE() : m_packetSize(0) -{ -} - -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - if (m_packetSize == 0) { - targa_packet_read_istream(m_packet, istream); - m_packetSize = targa_packet_size(m_packet); - - if (targa_packet_is_rle(m_packet)) { - istream_read_rgb(istream, m_pixel); - } - } - - if (targa_packet_is_rle(m_packet)) { - pixel = m_pixel; - } else { - istream_read_rgb(istream, pixel); - } - - --m_packetSize; -} -}; - -template -void targa_decode_rle_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBPixelRLE decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBAPixelRLE { -TargaPacketSize m_packetSize; -RGBAPixel m_pixel; -TargaPacket m_packet; -public: -TargaDecodeRGBAPixelRLE() : m_packetSize(0) -{ -} - -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - if (m_packetSize == 0) { - targa_packet_read_istream(m_packet, istream); - m_packetSize = targa_packet_size(m_packet); - - if (targa_packet_is_rle(m_packet)) { - istream_read_rgba(istream, m_pixel); - } - } - - if (targa_packet_is_rle(m_packet)) { - pixel = m_pixel; - } else { - istream_read_rgba(istream, pixel); - } - - --m_packetSize; -} -}; - -template -void targa_decode_rle_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBAPixelRLE decode; - image_decode(istream, decode, image, flip); -} - -struct TargaHeader { - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -}; - -inline void targa_header_read_istream(TargaHeader &targa_header, PointerInputStream &istream) -{ - targa_header.id_length = istream_read_byte(istream); - targa_header.colormap_type = istream_read_byte(istream); - targa_header.image_type = istream_read_byte(istream); - - targa_header.colormap_index = istream_read_int16_le(istream); - targa_header.colormap_length = istream_read_int16_le(istream); - targa_header.colormap_size = istream_read_byte(istream); - targa_header.x_origin = istream_read_int16_le(istream); - targa_header.y_origin = istream_read_int16_le(istream); - targa_header.width = istream_read_int16_le(istream); - targa_header.height = istream_read_int16_le(istream); - targa_header.pixel_size = istream_read_byte(istream); - targa_header.attributes = istream_read_byte(istream); - - if (targa_header.id_length != 0) { - istream.seek(targa_header.id_length); // skip TARGA image comment - } -} - -template -class ScopeDelete { -Type *m_value; - -ScopeDelete(const ScopeDelete &); - -ScopeDelete &operator=(const ScopeDelete &); - -public: -ScopeDelete(Type *value) : m_value(value) -{ -} - -~ScopeDelete() -{ - delete m_value; -} - -Type *get_pointer() const -{ - return m_value; -} -}; - -template -Image *Targa_decodeImageData(const TargaHeader &targa_header, PointerInputStream &istream, const Flip &flip) -{ - RGBAImage *image = new RGBAImage(targa_header.width, targa_header.height); - - if (targa_header.image_type == 2 || targa_header.image_type == 3) { - switch (targa_header.pixel_size) { - case 8: - targa_decode_grayscale(istream, *image, flip); - break; - case 24: - targa_decode_rgb(istream, *image, flip); - break; - case 32: - targa_decode_rgba(istream, *image, flip); - break; - default: - globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n"; - image->release(); - return 0; - } - } else if (targa_header.image_type == 10 || targa_header.image_type == 11) { - switch (targa_header.pixel_size) { - case 8: - targa_decode_rle_grayscale(istream, *image, flip); - break; - case 24: - targa_decode_rle_rgb(istream, *image, flip); - break; - case 32: - targa_decode_rle_rgba(istream, *image, flip); - break; - default: - globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n"; - image->release(); - return 0; - } - } - - return image; -} - -const unsigned int TGA_FLIP_HORIZONTAL = 0x10; -const unsigned int TGA_FLIP_VERTICAL = 0x20; - -Image *LoadTGABuff(const byte *buffer) -{ - PointerInputStream istream(buffer); - TargaHeader targa_header; - - targa_header_read_istream(targa_header, istream); - - if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 && - targa_header.image_type != 11) { - globalErrorStream() << "LoadTGA: TGA type " << targa_header.image_type << " not supported\n"; - globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), 10 (RGB), and 11 (gray) TGA images supported\n"; - return 0; - } - - if (targa_header.colormap_type != 0) { - globalErrorStream() << "LoadTGA: colormaps not supported\n"; - return 0; - } - - if (((targa_header.image_type == 2 || targa_header.image_type == 10) && targa_header.pixel_size != 32 && - targa_header.pixel_size != 24) || - ((targa_header.image_type == 3 || targa_header.image_type == 11) && targa_header.pixel_size != 8)) { - globalErrorStream() << "LoadTGA: Only 32, 24 or 8 bit images supported\n"; - return 0; - } - - if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip00()); - } - if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip01()); - } - if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip10()); - } - if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip11()); - } - - // unreachable - return 0; -} - -Image *LoadTGA(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadTGABuff(buffer.buffer); -} diff --git a/plugins/image/tga.h b/plugins/image/tga.h deleted file mode 100644 index 226a997..0000000 --- a/plugins/image/tga.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TGA_H ) -#define INCLUDED_TGA_H - -class Image; - -class ArchiveFile; - -Image *LoadTGA(ArchiveFile &file); - -#endif diff --git a/plugins/imagehl/Makefile b/plugins/imagehl/Makefile deleted file mode 100644 index a8738fb..0000000 --- a/plugins/imagehl/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - hlw.o imagehl.o mip.o sprite.o - -# binary target -../../build/plugins/libimagehl.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a $(PLUGIN_LDFLAGS) - -# object files -hlw.o: hlw.cpp hlw.h -imagehl.o: imagehl.cpp -mip.o: mip.cpp mip.h -sprite.o: sprite.cpp sprite.h - -clean: - -rm -f *.o ../../build/plugins/libimagehl.$(LIB_EXT) diff --git a/plugins/imagehl/hlw.cpp b/plugins/imagehl/hlw.cpp deleted file mode 100644 index 7327554..0000000 --- a/plugins/imagehl/hlw.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// by Hydra - hydra@hydras-world.com -// -// HLW = Half-Life-WAD, I don't know if the actual in data in the WAD files -// has it's own name, so I'm just calling the individal textures .HLW files :) -// -// Thanks to the guys that made Wally for releasing an example WAD loader. -// without it this would not have been possible. - -#include "hlw.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" - - -/* - ============================================================================ - - HLW IMAGE - - HalfLife WAD files contain files that look like this: - - Mip section - First mip - Mip header - First mip (width * height) - Second mip (width * height / 4) - Third mip (width * height / 16) - Fourth mip (width * height / 64) - Palette size (WORD) - Palette (Palette size * 3) - Padding (WORD) - - ============================================================================ - */ - -#define GET_MIP_DATA_SIZE( WIDTH, HEIGHT ) ( sizeof( WAD3_MIP ) + ( WIDTH * HEIGHT ) + ( WIDTH * HEIGHT / 4 ) + ( WIDTH * HEIGHT / 16 ) + ( WIDTH * HEIGHT / 64 ) ) - -typedef struct -{ - char name[16]; - unsigned int width, height; - unsigned int offsets[4]; // four mip maps stored -} WAD3_MIP, *LPWAD3_MIP; - -/* - ========================================================= - - HLW LOADING - - Hydra: this code isn't bullet proof and probably won't - like corrupt WAD files, but it works for now. - - TODO: make it more robust. - ========================================================= - */ - -/* - ============= - LoadHLW - ============= - */ - -Image* LoadHLWBuff( byte* buffer ){ - byte *buf_p; - unsigned long mipdatasize; - int columns, rows; - byte *pixbuf; - int row, column; - byte *palette; - LPWAD3_MIP lpMip; - unsigned char red, green, blue, alphabyte; - - lpMip = (LPWAD3_MIP)buffer; //!\todo Make endian-safe. - - mipdatasize = GET_MIP_DATA_SIZE( lpMip->width,lpMip->height ); - - palette = buffer + mipdatasize + 2; - - buf_p = buffer + lpMip->offsets[0]; - - columns = lpMip->width; - rows = lpMip->height; - - RGBAImage* image = new RGBAImage( columns, rows ); - - for ( row = 0; row < rows; row++ ) - { - pixbuf = image->getRGBAPixels() + row * columns * 4; - - for ( column = 0; column < columns; column++ ) - { - int palIndex; - - palIndex = *buf_p++; - - red = *( palette + ( palIndex * 3 ) ); - green = *( palette + ( palIndex * 3 ) + 1 ); - blue = *( palette + ( palIndex * 3 ) + 2 ); - - // HalfLife engine makes pixels that are BLUE transparent. - // So show them that way in the editor. - if ( blue == 0xff && red == 0x00 && green == 0x00 ) { - alphabyte = 0x00; - blue = 0x00; // don't set the resulting pixel to blue - } - else - { - alphabyte = 0xff; - } - - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - - *pixbuf++ = alphabyte; - } - } - - return image; -} - -Image* LoadHLW( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadHLWBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/hlw.h b/plugins/imagehl/hlw.h deleted file mode 100644 index 3313823..0000000 --- a/plugins/imagehl/hlw.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_HLW_H ) -#define INCLUDED_HLW_H - -class Image; -class ArchiveFile; - -Image* LoadHLW( ArchiveFile& file ); - -#endif diff --git a/plugins/imagehl/imagehl.cpp b/plugins/imagehl/imagehl.cpp deleted file mode 100644 index dfdf98b..0000000 --- a/plugins/imagehl/imagehl.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging/debugging.h" -#include "ifilesystem.h" -#include "iimage.h" - -#include "hlw.h" -#include "mip.h" -#include "sprite.h" - -#include "modulesystem/singletonmodule.h" - - -class ImageDependencies : public GlobalFileSystemModuleRef -{ -}; - -class ImageHLWAPI -{ -_QERPlugImageTable m_imagehlw; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "hlw" ); - -ImageHLWAPI(){ - m_imagehlw.loadImage = LoadHLW; -} -_QERPlugImageTable* getTable(){ - return &m_imagehlw; -} -}; - -typedef SingletonModule ImageHLWModule; - -ImageHLWModule g_ImageHLWModule; - - -class ImageMipAPI -{ -_QERPlugImageTable m_imagemip; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "mip" ); - -ImageMipAPI(){ - m_imagemip.loadImage = LoadMIP; -} -_QERPlugImageTable* getTable(){ - return &m_imagemip; -} -}; - -typedef SingletonModule ImageMipModule; - -ImageMipModule g_ImageMipModule; - - -class ImageSpriteAPI -{ -_QERPlugImageTable m_imagesprite; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "spr" ); - -ImageSpriteAPI(){ - m_imagesprite.loadImage = LoadIDSP; -} -_QERPlugImageTable* getTable(){ - return &m_imagesprite; -} -}; - -typedef SingletonModule ImageSpriteModule; - -ImageSpriteModule g_ImageSpriteModule; - - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ImageHLWModule.selfRegister(); - g_ImageMipModule.selfRegister(); - g_ImageSpriteModule.selfRegister(); -} diff --git a/plugins/imagehl/imagehl.txt b/plugins/imagehl/imagehl.txt deleted file mode 100644 index e442e64..0000000 --- a/plugins/imagehl/imagehl.txt +++ /dev/null @@ -1,30 +0,0 @@ -ImageHL -======= - -Coding by Dominic Clifton - Hydra - hydra@hydras-world.com - -What is it ? ------------- - -This GTKRadiant 1.2+ plugin handles the loading of textures from .WAD files. -I'll refer to these textures as .HLW files, even though they don't have any -extension when they're stored in the .WAD file itself. - -You need a VFS plugin to go with this plugin that can open and read .WAD files -My VFSWAD plugin does just this. - -Developer Notes ---------------- - -The project file will copy the compiled DLL file and this .TXT file to -"$(HLRADIANTDIR)modules" so make sure you have that environment variable -defined. - -For my GTKRadiant 1.2 HalfLife game pack files I use the directory: -"E:\games\HalfLife\Tools\GTKR12N". Under which there are the directories -"modules" and "plugins" - -Credits -------- -Thanks to the guys that made Wally for releasing an example WAD loader. -without it this would not have been possible. diff --git a/plugins/imagehl/mip.cpp b/plugins/imagehl/mip.cpp deleted file mode 100644 index a9d5a71..0000000 --- a/plugins/imagehl/mip.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mip.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" -#include "bytestreamutils.h" - -/* - ============================================================================ - - MIP IMAGE - - Quake WAD files contain miptex files that look like this: - - Mip section - First mip - Mip header - First mip (width * height) - Second mip (width * height / 4) - Third mip (width * height / 16) - Fourth mip (width * height / 64) - - ============================================================================ - */ - -#define GET_MIP_DATA_SIZE( WIDTH, HEIGHT ) ( sizeof( WAD3_MIP ) + ( WIDTH * HEIGHT ) + ( WIDTH * HEIGHT / 4 ) + ( WIDTH * HEIGHT / 16 ) + ( WIDTH * HEIGHT / 64 ) ) - -const int MIP_NAME_LENGTH = 16; -const int MIP_MIPMAP_COUNT = 4; -typedef struct -{ - char name[MIP_NAME_LENGTH]; - unsigned int width, height; - unsigned int offsets[MIP_MIPMAP_COUNT]; // four mip maps stored -} WAD3_MIP, *LPWAD3_MIP; - -static const byte quakepalette[768] = -{ - 0x00,0x00,0x00, 0x0f,0x0f,0x0f, 0x1f,0x1f,0x1f, 0x2f,0x2f,0x2f, - 0x3f,0x3f,0x3f, 0x4b,0x4b,0x4b, 0x5b,0x5b,0x5b, 0x6b,0x6b,0x6b, - 0x7b,0x7b,0x7b, 0x8b,0x8b,0x8b, 0x9b,0x9b,0x9b, 0xab,0xab,0xab, - 0xbb,0xbb,0xbb, 0xcb,0xcb,0xcb, 0xdb,0xdb,0xdb, 0xeb,0xeb,0xeb, - 0x0f,0x0b,0x07, 0x17,0x0f,0x0b, 0x1f,0x17,0x0b, 0x27,0x1b,0x0f, - 0x2f,0x23,0x13, 0x37,0x2b,0x17, 0x3f,0x2f,0x17, 0x4b,0x37,0x1b, - 0x53,0x3b,0x1b, 0x5b,0x43,0x1f, 0x63,0x4b,0x1f, 0x6b,0x53,0x1f, - 0x73,0x57,0x1f, 0x7b,0x5f,0x23, 0x83,0x67,0x23, 0x8f,0x6f,0x23, - 0x0b,0x0b,0x0f, 0x13,0x13,0x1b, 0x1b,0x1b,0x27, 0x27,0x27,0x33, - 0x2f,0x2f,0x3f, 0x37,0x37,0x4b, 0x3f,0x3f,0x57, 0x47,0x47,0x67, - 0x4f,0x4f,0x73, 0x5b,0x5b,0x7f, 0x63,0x63,0x8b, 0x6b,0x6b,0x97, - 0x73,0x73,0xa3, 0x7b,0x7b,0xaf, 0x83,0x83,0xbb, 0x8b,0x8b,0xcb, - 0x00,0x00,0x00, 0x07,0x07,0x00, 0x0b,0x0b,0x00, 0x13,0x13,0x00, - 0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2b,0x2b,0x07, 0x2f,0x2f,0x07, - 0x37,0x37,0x07, 0x3f,0x3f,0x07, 0x47,0x47,0x07, 0x4b,0x4b,0x0b, - 0x53,0x53,0x0b, 0x5b,0x5b,0x0b, 0x63,0x63,0x0b, 0x6b,0x6b,0x0f, - 0x07,0x00,0x00, 0x0f,0x00,0x00, 0x17,0x00,0x00, 0x1f,0x00,0x00, - 0x27,0x00,0x00, 0x2f,0x00,0x00, 0x37,0x00,0x00, 0x3f,0x00,0x00, - 0x47,0x00,0x00, 0x4f,0x00,0x00, 0x57,0x00,0x00, 0x5f,0x00,0x00, - 0x67,0x00,0x00, 0x6f,0x00,0x00, 0x77,0x00,0x00, 0x7f,0x00,0x00, - 0x13,0x13,0x00, 0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2f,0x2b,0x00, - 0x37,0x2f,0x00, 0x43,0x37,0x00, 0x4b,0x3b,0x07, 0x57,0x43,0x07, - 0x5f,0x47,0x07, 0x6b,0x4b,0x0b, 0x77,0x53,0x0f, 0x83,0x57,0x13, - 0x8b,0x5b,0x13, 0x97,0x5f,0x1b, 0xa3,0x63,0x1f, 0xaf,0x67,0x23, - 0x23,0x13,0x07, 0x2f,0x17,0x0b, 0x3b,0x1f,0x0f, 0x4b,0x23,0x13, - 0x57,0x2b,0x17, 0x63,0x2f,0x1f, 0x73,0x37,0x23, 0x7f,0x3b,0x2b, - 0x8f,0x43,0x33, 0x9f,0x4f,0x33, 0xaf,0x63,0x2f, 0xbf,0x77,0x2f, - 0xcf,0x8f,0x2b, 0xdf,0xab,0x27, 0xef,0xcb,0x1f, 0xff,0xf3,0x1b, - 0x0b,0x07,0x00, 0x1b,0x13,0x00, 0x2b,0x23,0x0f, 0x37,0x2b,0x13, - 0x47,0x33,0x1b, 0x53,0x37,0x23, 0x63,0x3f,0x2b, 0x6f,0x47,0x33, - 0x7f,0x53,0x3f, 0x8b,0x5f,0x47, 0x9b,0x6b,0x53, 0xa7,0x7b,0x5f, - 0xb7,0x87,0x6b, 0xc3,0x93,0x7b, 0xd3,0xa3,0x8b, 0xe3,0xb3,0x97, - 0xab,0x8b,0xa3, 0x9f,0x7f,0x97, 0x93,0x73,0x87, 0x8b,0x67,0x7b, - 0x7f,0x5b,0x6f, 0x77,0x53,0x63, 0x6b,0x4b,0x57, 0x5f,0x3f,0x4b, - 0x57,0x37,0x43, 0x4b,0x2f,0x37, 0x43,0x27,0x2f, 0x37,0x1f,0x23, - 0x2b,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07, - 0xbb,0x73,0x9f, 0xaf,0x6b,0x8f, 0xa3,0x5f,0x83, 0x97,0x57,0x77, - 0x8b,0x4f,0x6b, 0x7f,0x4b,0x5f, 0x73,0x43,0x53, 0x6b,0x3b,0x4b, - 0x5f,0x33,0x3f, 0x53,0x2b,0x37, 0x47,0x23,0x2b, 0x3b,0x1f,0x23, - 0x2f,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07, - 0xdb,0xc3,0xbb, 0xcb,0xb3,0xa7, 0xbf,0xa3,0x9b, 0xaf,0x97,0x8b, - 0xa3,0x87,0x7b, 0x97,0x7b,0x6f, 0x87,0x6f,0x5f, 0x7b,0x63,0x53, - 0x6b,0x57,0x47, 0x5f,0x4b,0x3b, 0x53,0x3f,0x33, 0x43,0x33,0x27, - 0x37,0x2b,0x1f, 0x27,0x1f,0x17, 0x1b,0x13,0x0f, 0x0f,0x0b,0x07, - 0x6f,0x83,0x7b, 0x67,0x7b,0x6f, 0x5f,0x73,0x67, 0x57,0x6b,0x5f, - 0x4f,0x63,0x57, 0x47,0x5b,0x4f, 0x3f,0x53,0x47, 0x37,0x4b,0x3f, - 0x2f,0x43,0x37, 0x2b,0x3b,0x2f, 0x23,0x33,0x27, 0x1f,0x2b,0x1f, - 0x17,0x23,0x17, 0x0f,0x1b,0x13, 0x0b,0x13,0x0b, 0x07,0x0b,0x07, - 0xff,0xf3,0x1b, 0xef,0xdf,0x17, 0xdb,0xcb,0x13, 0xcb,0xb7,0x0f, - 0xbb,0xa7,0x0f, 0xab,0x97,0x0b, 0x9b,0x83,0x07, 0x8b,0x73,0x07, - 0x7b,0x63,0x07, 0x6b,0x53,0x00, 0x5b,0x47,0x00, 0x4b,0x37,0x00, - 0x3b,0x2b,0x00, 0x2b,0x1f,0x00, 0x1b,0x0f,0x00, 0x0b,0x07,0x00, - 0x00,0x00,0xff, 0x0b,0x0b,0xef, 0x13,0x13,0xdf, 0x1b,0x1b,0xcf, - 0x23,0x23,0xbf, 0x2b,0x2b,0xaf, 0x2f,0x2f,0x9f, 0x2f,0x2f,0x8f, - 0x2f,0x2f,0x7f, 0x2f,0x2f,0x6f, 0x2f,0x2f,0x5f, 0x2b,0x2b,0x4f, - 0x23,0x23,0x3f, 0x1b,0x1b,0x2f, 0x13,0x13,0x1f, 0x0b,0x0b,0x0f, - 0x2b,0x00,0x00, 0x3b,0x00,0x00, 0x4b,0x07,0x00, 0x5f,0x07,0x00, - 0x6f,0x0f,0x00, 0x7f,0x17,0x07, 0x93,0x1f,0x07, 0xa3,0x27,0x0b, - 0xb7,0x33,0x0f, 0xc3,0x4b,0x1b, 0xcf,0x63,0x2b, 0xdb,0x7f,0x3b, - 0xe3,0x97,0x4f, 0xe7,0xab,0x5f, 0xef,0xbf,0x77, 0xf7,0xd3,0x8b, - 0xa7,0x7b,0x3b, 0xb7,0x9b,0x37, 0xc7,0xc3,0x37, 0xe7,0xe3,0x57, - 0x7f,0xbf,0xff, 0xab,0xe7,0xff, 0xd7,0xff,0xff, 0x67,0x00,0x00, - 0x8b,0x00,0x00, 0xb3,0x00,0x00, 0xd7,0x00,0x00, 0xff,0x00,0x00, - 0xff,0xf3,0x93, 0xff,0xf7,0xc7, 0xff,0xff,0xff, 0x9f,0x5b,0x53 -}; - -/* - ============= - LoadMIP - ============= - */ - -Image* LoadMIPBuff( byte* buffer ){ - byte *buf_p; - int palettelength; - int columns, rows, numPixels; - byte *pixbuf; - int i; - byte *loadedpalette; - const byte *palette; - - loadedpalette = 0; - - PointerInputStream inputStream( buffer ); - - inputStream.seek( MIP_NAME_LENGTH ); - columns = istream_read_int32_le( inputStream ); - rows = istream_read_int32_le( inputStream ); - int offset = istream_read_int32_le( inputStream ); - - if ( std::size_t( columns ) > 65536 && std::size_t( rows ) > 65536 ) { - return 0; - } - -// unsigned long mipdatasize = GET_MIP_DATA_SIZE( columns, rows ); - - palettelength = vfsLoadFile( "gfx/palette.lmp", (void **) &loadedpalette ); - if ( palettelength == 768 ) { - palette = loadedpalette; - } - else - { - loadedpalette = 0; - palette = quakepalette; - } - - buf_p = buffer + offset; - - numPixels = columns * rows; - - RGBAImage* image = new RGBAImage( columns, rows ); - - //Sys_Printf("lpMip->width = %i, lpMip->height = %i, lpMip->offsets[0] = %i, lpMip->offsets[1] = %i, lpMip->offsets[2] = %i, lpMip->offsets[3] = %i, numPixels = %i\n", lpMip->width, lpMip->height, lpMip->offsets[0], lpMip->offsets[1], lpMip->offsets[2], lpMip->offsets[3], numPixels); - //for (i = 0; i < sizeof(*lpMip); i++) - // Sys_Printf("%02x", (int) ((unsigned char *)lpMip)[i]); - - pixbuf = image->getRGBAPixels(); - - for ( i = 0; i < numPixels; i++ ) - { - int palIndex = *buf_p++; - *pixbuf++ = palette[palIndex * 3]; - *pixbuf++ = palette[palIndex * 3 + 1]; - *pixbuf++ = palette[palIndex * 3 + 2]; - *pixbuf++ = 0xff; - } - - if ( loadedpalette != 0 ) { - vfsFreeFile( loadedpalette ); - } - - return image; -} - -Image* LoadMIP( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadMIPBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/mip.h b/plugins/imagehl/mip.h deleted file mode 100644 index ea11d8f..0000000 --- a/plugins/imagehl/mip.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_MIP_H ) -#define INCLUDED_MIP_H - -class Image; -class ArchiveFile; - -Image* LoadMIP( ArchiveFile& file ); - -#endif diff --git a/plugins/imagehl/sprite.cpp b/plugins/imagehl/sprite.cpp deleted file mode 100644 index 195d952..0000000 --- a/plugins/imagehl/sprite.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// by Hydra - hydra@hydras-world.com - -#include "sprite.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" - -/* - ============================================================================ - - IDSP IMAGE (.spr files) - - Some code copied straight from the Q1 source, also used the HalfLife SDK as - a reference. - - ============================================================================ - */ - -typedef enum {ST_SYNC = 0, ST_RAND } synctype_t; -typedef enum { SPR_SINGLE = 0, SPR_GROUP } spriteframetype_t; - -typedef struct dspriteheader_s { - int ident; - int version; -} dspriteheader_t; - -// Quake1 -typedef struct { - int type; - float boundingradius; - int width; - int height; - int numframes; - float beamlength; - synctype_t synctype; -} dspritev1_t; - -// Halflife -typedef struct { - int type; - int texFormat; - float boundingradius; - int width; - int height; - int numframes; - float beamlength; - synctype_t synctype; -} dspritev2_t; - -typedef struct { - int origin[2]; - int width; - int height; -} dspriteframe_t; - -typedef struct { - short type; -} dspriteframetype_t; - -/* - typedef struct { - byte rgb[256][3]; - } dpalette_t; - */ - -const int IDSPRITEHEADER = ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' ); -// little-endian "IDSP" - -/* - ============= - LoadIDSP - ============= - */ - -Image* LoadIDSPBuff( byte *buffer ){ - byte *buf_p; - int columns, rows; - byte *pixbuf; - - int row, column; - byte *palette; - unsigned char red, green, blue, alphabyte; - - dspriteheader_t *header; - dspritev1_t *pinv1; - dspritev2_t *pinv2; - dspriteframetype_t *pframetype; - int version; - int numframes; - dspriteframe_t *spriteframe; - - header = (dspriteheader_t *)buffer; - - if ( header->ident != IDSPRITEHEADER ) { - globalErrorStream() << "WARNING: IDSP file has wrong header\n"; - return 0; - } - - version = header->version; - if ( version != 1 && version != 2 ) { - globalErrorStream() << "WARNING: IDSP file has wrong version number " - "(" << version << " should be 1 or 2)\n"; - return 0; - } - - // initialise variables depending on the sprite version. - switch ( version ) - { - case 1: - pinv1 = (dspritev1_t *)( header + 1 ); - numframes = pinv1->numframes; - columns = pinv1->width; - rows = pinv1->height; - pframetype = (dspriteframetype_t *)( pinv1 + 1 ); - break; - case 2: - pinv2 = (dspritev2_t *)( header + 1 ); - numframes = pinv2->numframes; - columns = pinv2->width; - rows = pinv2->height; - pframetype = (dspriteframetype_t *)( pinv2 + 1 ); - break; - default: - globalErrorStream() << "WARNING: IDSP file has unsupported version\n"; - return 0; - } - if ( numframes > 1 ) { - globalErrorStream() << "WARNING: IDSP file has multiple frames, only the first frame will be used.\n"; - } - - // palette = buffer+mipdatasize+2; - // buf_p = buffer+lpMip->offsets[0]; - - RGBAImage* image = new RGBAImage( columns, rows ); - -#ifdef DEBUG - frametype = spriteframetype_t( pframetype->type ); - if ( frametype == SPR_SINGLE ) { - globalOutputStream() << "Single Frame\n"; - } - else if ( frametype == SPR_GROUP ) { - globalOutputStream() << "Group of Frames\n"; - } - else - { - globalOutputStream() << "Bleh!\n"; // <-- we always get this, wtf! - } -#endif - - palette = (byte *)( pframetype + 1 ); - spriteframe = (dspriteframe_t *)( palette + ( 256 * 3 ) + 4 ); // what are those 4 extra bytes ? what's missing ? - buf_p = (byte *)( spriteframe + 1 ); - - for ( row = 0; row < rows; row++ ) - { - pixbuf = image->getRGBAPixels() + row * columns * 4; - - for ( column = 0; column < columns; column++ ) - { - int palIndex; - - palIndex = *buf_p++; - - red = *( palette + ( palIndex * 3 ) ); - green = *( palette + ( palIndex * 3 ) + 1 ); - blue = *( palette + ( palIndex * 3 ) + 2 ); - - // HalfLife engine makes pixels that are BLUE transparent. (RGB = 0x0000FF) - // So show them that way in the editor. - if ( blue == 0xff && red == 0x00 && green == 0x00 ) { - alphabyte = 0xff; //FIXME: backwards? (so sprite models to render correctly) - blue = 0x00; // don't set the resulting pixel to blue - } - else - { - alphabyte = 0x00; //FIXME: backwards? (so sprite models to render correctly) - } - - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - - *pixbuf++ = alphabyte; - } - } - - return image; -} - -Image* LoadIDSP( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadIDSPBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/sprite.h b/plugins/imagehl/sprite.h deleted file mode 100644 index d6635d9..0000000 --- a/plugins/imagehl/sprite.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SPRITE_H ) -#define INCLUDED_SPRITE_H - -class Image; -class ArchiveFile; - -Image* LoadIDSP( ArchiveFile& file ); - -#endif diff --git a/plugins/iqmmodel/Makefile b/plugins/iqmmodel/Makefile deleted file mode 100644 index 3a0d957..0000000 --- a/plugins/iqmmodel/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - iqm.o plugin.o - -# binary target -../../build/plugins/libiqmmodel.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -iqm.o: iqm.cpp iqm.h -plugin.o: plugin.cpp plugin.h - -clean: - -rm -f *.o ../../build/plugins/libiqmmodel.$(LIB_EXT) diff --git a/plugins/iqmmodel/iqm.cpp b/plugins/iqmmodel/iqm.cpp deleted file mode 100644 index 79ec6ac..0000000 --- a/plugins/iqmmodel/iqm.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - Copyright (C) 2010-2014 COR Entertainment, LLC. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iqm.h" - -#include "ifilesystem.h" -#include "imodel.h" - -#include "imagelib.h" -#include "bytestreamutils.h" - -#include "../md3model/model.h" - -typedef unsigned char byte; - -/* - ======================================================================== - - .IQM triangle model file format - - ======================================================================== - */ - -typedef struct { - float s; - float t; -} iqmSt_t; - -void istream_read_iqmSt( PointerInputStream &inputStream, iqmSt_t &st ){ - st.s = istream_read_float32_le( inputStream ); - st.t = istream_read_float32_le( inputStream ); -} - -typedef struct { - unsigned int indices[3]; -} iqmTriangle_t; - -void istream_read_iqmTriangle( PointerInputStream &inputStream, iqmTriangle_t &triangle ){ - triangle.indices[0] = istream_read_int32_le( inputStream ); - triangle.indices[1] = istream_read_int32_le( inputStream ); - triangle.indices[2] = istream_read_int32_le( inputStream ); -} - -typedef struct { - float v[3]; -} iqmPos_t; - -void istream_read_iqmPos( PointerInputStream &inputStream, iqmPos_t &iqmPos ){ - iqmPos.v[0] = istream_read_float32_le( inputStream ); - iqmPos.v[1] = istream_read_float32_le( inputStream ); - iqmPos.v[2] = istream_read_float32_le( inputStream ); -} - -const int IQM_POSITION = 0; -const int IQM_TEXCOORD = 1; -const int IQM_NORMAL = 2; -const int IQM_TANGENT = 3; -const int IQM_BLENDINDEXES = 4; -const int IQM_BLENDWEIGHTS = 5; -const int IQM_COLOR = 6; -const int IQM_CUSTOM = 0x10; - -const int IQM_BYTE = 0; -const int IQM_UBYTE = 1; -const int IQM_SHORT = 2; -const int IQM_USHORT = 3; -const int IQM_INT = 4; -const int IQM_UINT = 5; -const int IQM_HALF = 6; -const int IQM_FLOAT = 7; -const int IQM_DOUBLE = 8; - -// animflags -const int IQM_LOOP = 1; - -typedef struct iqmHeader_s { - byte id[16]; - unsigned int version; - unsigned int filesize; - unsigned int flags; - unsigned int num_text, ofs_text; - unsigned int num_meshes, ofs_meshes; - unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays; - unsigned int num_triangles, ofs_triangles, ofs_neighbors; - unsigned int num_joints, ofs_joints; - unsigned int num_poses, ofs_poses; - unsigned int num_anims, ofs_anims; - unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds; - unsigned int num_comment, ofs_comment; - unsigned int num_extensions, ofs_extensions; -} iqmHeader_t; - -void istream_read_iqmHeader( PointerInputStream &inputStream, iqmHeader_t &header ){ - inputStream.read( header.id, 16 ); -#define READINT( x ) header.x = istream_read_int32_le( inputStream ); - READINT( version ) - READINT( filesize ) - READINT( flags ) - READINT( num_text ) - READINT( ofs_text ) - READINT( num_meshes ) - READINT( ofs_meshes ) - READINT( num_vertexarrays ) - READINT( num_vertexes ) - READINT( ofs_vertexarrays ) - READINT( num_triangles ) - READINT( ofs_triangles ) - READINT( ofs_neighbors ) - READINT( num_joints ) - READINT( ofs_joints ) - READINT( num_frames ) - READINT( num_framechannels ) - READINT( ofs_frames ) - READINT( ofs_bounds ) - READINT( num_comment ) - READINT( ofs_comment ) - READINT( num_extensions ) - READINT( ofs_extensions ) -#undef READINT -} - -typedef struct iqmmesh_s { - unsigned int name; - unsigned int material; - unsigned int first_vertex; - unsigned int num_vertexes; - unsigned int first_triangle; - unsigned int num_triangles; -} iqmmesh_t; - -void istream_read_iqmMesh( PointerInputStream &inputStream, iqmmesh_t &iqmmesh ){ -#define READUINT( x ) iqmmesh.x = istream_read_uint32_le( inputStream ); - READUINT( name ) - READUINT( material ) - READUINT( first_vertex ) - READUINT( num_vertexes ) - READUINT( first_triangle ) - READUINT( num_triangles ) -#undef READUINT -} - -typedef struct iqmvertexarray_s { - unsigned int type; - unsigned int flags; - unsigned int format; - unsigned int size; - unsigned int offset; -} iqmvertexarray_t; - -void istream_read_iqmVertexarray( PointerInputStream &inputStream, iqmvertexarray_t &vertexarray ){ -#define READINT( x ) vertexarray.x = istream_read_int32_le( inputStream ); - READINT( type ) - READINT( flags ) - READINT( format ) - READINT( size ) - READINT( offset ) -#undef READINT -} - -ArbitraryMeshVertex IQMVertex_construct( const iqmPos_t *pos, const iqmPos_t *norm, const iqmSt_t *st ){ - return ArbitraryMeshVertex( - Vertex3f( pos->v[0], pos->v[1], pos->v[2] ), - Normal3f( norm->v[0], norm->v[1], norm->v[2] ), - TexCoord2f( st->s, st->t ) - ); -} - -void IQMSurface_read( Model &model, const byte *buffer, ArchiveFile &file ){ - iqmHeader_t header; - { - PointerInputStream inputStream( buffer ); - istream_read_iqmHeader( inputStream, header ); - } - - int ofs_position = -1, ofs_st = -1, ofs_normal = -1; - PointerInputStream vaStream( buffer + header.ofs_vertexarrays ); - for ( unsigned int i = 0; i < header.num_vertexarrays; i++ ) { - iqmvertexarray_t va; - istream_read_iqmVertexarray( vaStream, va ); - - switch ( va.type ) { - case IQM_POSITION: - if ( va.format == IQM_FLOAT && va.size == 3 ) { - ofs_position = va.offset; - } - break; - case IQM_TEXCOORD: - if ( va.format == IQM_FLOAT && va.size == 2 ) { - ofs_st = va.offset; - } - break; - case IQM_NORMAL: - if ( va.format == IQM_FLOAT && va.size == 3 ) { - ofs_normal = va.offset; - } - break; - } - } - - PointerInputStream posStream( buffer + ofs_position ); - Array iqmPos( header.num_vertexes ); - for ( Array::iterator i = iqmPos.begin(); i != iqmPos.end(); ++i ) { - istream_read_iqmPos( posStream, *i ); - } - - PointerInputStream normStream( buffer + ofs_normal ); - Array iqmNorm( header.num_vertexes ); - for ( Array::iterator i = iqmNorm.begin(); i != iqmNorm.end(); ++i ) { - istream_read_iqmPos( normStream, *i ); - } - - Array iqmSt( header.num_vertexes ); - PointerInputStream stStream( buffer + ofs_st ); - for ( Array::iterator i = iqmSt.begin(); i != iqmSt.end(); ++i ) { - istream_read_iqmSt( stStream, *i ); - } - - PointerInputStream iqmMesh( buffer + header.ofs_meshes ); - for ( unsigned int m = 0; m < header.num_meshes; m++ ) { - Surface &surface = model.newSurface(); - - iqmmesh_t iqmmesh; - istream_read_iqmMesh( iqmMesh, iqmmesh ); - - bool material_found = false; - // if not malformed data neither missing string - if ( iqmmesh.material <= header.num_text && iqmmesh.material > 0 ) { - char *material; - material = (char*) buffer + header.ofs_text + iqmmesh.material; - - if ( material[0] != '\0' ) { - surface.setShader( material ); - material_found = true; - } - } - - if ( !material_found ) { - // empty string will trigger "textures/shader/notex" on display - surface.setShader( "" ); - } - - UniqueVertexBuffer inserter( surface.vertices() ); - inserter.reserve( iqmmesh.num_vertexes ); - - surface.indices().reserve( iqmmesh.num_vertexes ); - - unsigned int triangle_offset = header.ofs_triangles + iqmmesh.first_triangle * sizeof( iqmTriangle_t ); - PointerInputStream triangleStream( buffer + triangle_offset ); - for ( unsigned int i = 0; i < iqmmesh.num_triangles; ++i ) { - iqmTriangle_t triangle; - istream_read_iqmTriangle( triangleStream, triangle ); - for ( int j = 0; j < 3; j++ ) { - surface.indices().insert( inserter.insert( IQMVertex_construct( - &iqmPos[triangle.indices[j]], - &iqmNorm[triangle.indices[j]], - &iqmSt[triangle.indices[j]] ) ) ); - } - } - - surface.updateAABB(); - } -} - -void IQMModel_read( Model &model, const byte *buffer, ArchiveFile &file ){ - IQMSurface_read( model, buffer, file ); - model.updateAABB(); -} - -scene::Node &IQMModel_new( const byte *buffer, ArchiveFile &file ){ - ModelNode *modelNode = new ModelNode(); - IQMModel_read( modelNode->model(), buffer, file ); - return modelNode->node(); -} - -scene::Node &IQMModel_default(){ - ModelNode *modelNode = new ModelNode(); - Model_constructNull( modelNode->model() ); - return modelNode->node(); -} - -scene::Node &IQMModel_fromBuffer( unsigned char *buffer, ArchiveFile &file ){ - if ( memcmp( buffer, "INTERQUAKEMODEL", 16 ) ) { - globalErrorStream() << "IQM read error: incorrect ident\n"; - return IQMModel_default(); - } - else { - return IQMModel_new( buffer, file ); - } -} - -scene::Node &loadIQMModel( ArchiveFile &file ){ - ScopedArchiveBuffer buffer( file ); - return IQMModel_fromBuffer( buffer.buffer, file ); -} diff --git a/plugins/iqmmodel/iqm.h b/plugins/iqmmodel/iqm.h deleted file mode 100644 index 8f48f3b..0000000 --- a/plugins/iqmmodel/iqm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_IQM_H ) -#define INCLUDED_IQM_H - -namespace scene { class Node; } -class ArchiveFile; - -scene::Node &loadIQMModel( ArchiveFile &file ); - - -#endif diff --git a/plugins/iqmmodel/plugin.cpp b/plugins/iqmmodel/plugin.cpp deleted file mode 100644 index 79f2288..0000000 --- a/plugins/iqmmodel/plugin.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugin.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iimage.h" -#include "imodel.h" -#include "igl.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "ifiletypes.h" -#include "iscriplib.h" - -#include "modulesystem/singletonmodule.h" -#include "typesystem.h" - -#include "iqm.h" - - -class IQMModelLoader : public ModelLoader { -public: -scene::Node &loadModel( ArchiveFile &file ){ - return loadIQMModel( file ); -} -}; - -/* InterQuake Model Format */ -class ModelDependencies : - public GlobalFileSystemModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalFiletypesModuleRef { -}; - -class ModelIQMAPI : public TypeSystemRef { -IQMModelLoader m_modeliqm; -public: -typedef ModelLoader Type; - -STRING_CONSTANT( Name, "iqm" ); - -ModelIQMAPI(){ - GlobalFiletypesModule::getTable().addType( Type::Name(), Name(), filetype_t( "InterQuake Models", "*.iqm" ) ); -} - -ModelLoader *getTable(){ - return &m_modeliqm; -} -}; -typedef SingletonModule ModelIQMModule; -ModelIQMModule g_ModelIQMModule; - -/* Vera Visions Model Format */ -class ModelVVMAPI : public TypeSystemRef { -IQMModelLoader m_modeliqm; -public: -typedef ModelLoader Type; - -STRING_CONSTANT( Name, "vvm" ); - -ModelVVMAPI(){ - GlobalFiletypesModule::getTable().addType( Type::Name(), Name(), filetype_t( "Vera Visions Model", "*.vvm" ) ); -} - -ModelLoader *getTable(){ - return &m_modeliqm; -} -}; -typedef SingletonModule ModelVVMModule; -ModelVVMModule g_ModelVVMModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules( ModuleServer &server ){ - initialiseModule( server ); - - g_ModelIQMModule.selfRegister(); - g_ModelVVMModule.selfRegister(); -} diff --git a/plugins/iqmmodel/plugin.h b/plugins/iqmmodel/plugin.h deleted file mode 100644 index c6bfe6c..0000000 --- a/plugins/iqmmodel/plugin.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SAMPLE_H ) -#define INCLUDED_SAMPLE_H - -#endif diff --git a/plugins/mapq3/Makefile b/plugins/mapq3/Makefile deleted file mode 100644 index 6c41a79..0000000 --- a/plugins/mapq3/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - parse.o plugin.o write.o - -# binary target -../../build/plugins/libmapq3.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -parse.o: parse.cpp parse.h -plugin.o: plugin.cpp -write.o: write.cpp write.h - -clean: - -rm -f *.o ../../build/plugins/libmapq3.$(LIB_EXT) diff --git a/plugins/mapq3/parse.cpp b/plugins/mapq3/parse.cpp deleted file mode 100644 index e40951e..0000000 --- a/plugins/mapq3/parse.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parse.h" - -#include - -#include "ientity.h" -#include "ibrush.h" -#include "ipatch.h" -#include "ieclass.h" -#include "iscriplib.h" -#include "scenelib.h" -#include "string/string.h" -#include "stringio.h" -#include "eclasslib.h" - -inline MapImporter *Node_getMapImporter(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - - -typedef std::list > KeyValues; - -NodeSmartReference g_nullNode(NewNullNode()); - - -NodeSmartReference Entity_create(EntityCreator &entityTable, EntityClass *entityClass, const KeyValues &keyValues) -{ - scene::Node &entity(entityTable.createEntity(entityClass)); - for (KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) { - Node_getEntity(entity)->setKeyValue((*i).first.c_str(), (*i).second.c_str()); - } - return NodeSmartReference(entity); -} - -NodeSmartReference -Entity_parseTokens(Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser, int index) -{ - NodeSmartReference entity(g_nullNode); - KeyValues keyValues; - const char *classname = ""; - - int count_primitives = 0; - while (1) { - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#entity-token"); - return g_nullNode; - } - if (!strcmp(token, "}")) { // end entity - if (entity == g_nullNode) { - // entity does not have brushes - entity = Entity_create(entityTable, GlobalEntityClassManager().findOrInsert(classname, false), - keyValues); - } - return entity; - } else if (!strcmp(token, "{")) { // begin primitive - if (entity == g_nullNode) { - // entity has brushes - entity = Entity_create(entityTable, GlobalEntityClassManager().findOrInsert(classname, true), - keyValues); - } - - tokeniser.nextLine(); - - NodeSmartReference primitive(parser.parsePrimitive(tokeniser)); - if (primitive == g_nullNode || !Node_getMapImporter(primitive)->importTokens(tokeniser)) { - globalErrorStream() << "brush " << count_primitives << ": parse error\n"; - return g_nullNode; - } - - scene::Traversable *traversable = Node_getTraversable(entity); - if (Node_getEntity(entity)->isContainer() && traversable != 0) { - traversable->insert(primitive); - } else { - globalErrorStream() << "entity " << index << ": type " << classname << ": discarding brush " - << count_primitives << "\n"; - } - ++count_primitives; - } else // epair - { - CopiedString key(token); - token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#epair-value"); - return g_nullNode; - } - keyValues.push_back(KeyValues::value_type(key, token)); - if (string_equal(key.c_str(), "classname")) { - classname = keyValues.back().second.c_str(); - } - } - } - // unreachable code - return g_nullNode; -} - -void Map_Read(scene::Node &root, Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser) -{ - int count_entities = 0; - for (;;) { - tokeniser.nextLine(); - if (!tokeniser.getToken()) { // { or 0 - break; - } - - NodeSmartReference entity(Entity_parseTokens(tokeniser, entityTable, parser, count_entities)); - - if (entity == g_nullNode) { - globalErrorStream() << "entity " << count_entities << ": parse error\n"; - return; - } - - Node_getTraversable(root)->insert(entity); - - ++count_entities; - } -} diff --git a/plugins/mapq3/parse.h b/plugins/mapq3/parse.h deleted file mode 100644 index 81b6357..0000000 --- a/plugins/mapq3/parse.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PARSE_H ) -#define INCLUDED_PARSE_H - -#include "imap.h" - -class BrushCreator; - -class PatchCreator; - -class PrimitiveParser { -public: -virtual scene::Node &parsePrimitive(Tokeniser &tokeniser) const = 0; -}; - -void Map_Read(scene::Node &root, Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser); - -namespace scene { -class Node; -} - -#include "generic/referencecounted.h" - -typedef SmartReference > NodeSmartReference; - -extern NodeSmartReference g_nullNode; - -#endif diff --git a/plugins/mapq3/plugin.cpp b/plugins/mapq3/plugin.cpp deleted file mode 100644 index ce1e71b..0000000 --- a/plugins/mapq3/plugin.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iscriplib.h" -#include "ibrush.h" -#include "ipatch.h" -#include "ifiletypes.h" -#include "ieclass.h" -#include "qerplugin.h" - -#include "scenelib.h" -#include "string/string.h" -#include "stringio.h" -#include "generic/constant.h" - -#include "modulesystem/singletonmodule.h" - -#include "parse.h" -#include "write.h" - -class MapDependencies : - public GlobalRadiantModuleRef, - public GlobalBrushModuleRef, - public GlobalPatchModuleRef, - public GlobalFiletypesModuleRef, - public GlobalScripLibModuleRef, - public GlobalEntityClassManagerModuleRef, - public GlobalSceneGraphModuleRef { -public: -MapDependencies() : - GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")), - GlobalPatchModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("patchtypes")), - GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")) -{ -} -}; - -class MapQ3API : public TypeSystemRef, public MapFormat, public PrimitiveParser { -mutable bool detectedFormat; -public: -typedef MapFormat Type; - -STRING_CONSTANT(Name, "worldspawn"); - -MapQ3API() -{ - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn maps", "*.map", true, true, true)); - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn region", "*.reg", true, true, true)); - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn compiled maps", "*.bsp", false, true, false)); -} - -MapFormat *getTable() -{ - return this; -} - -scene::Node &parsePrimitive(Tokeniser &tokeniser) const -{ - const char *primitive = tokeniser.getToken(); - if (primitive != 0) { - if (string_equal(primitive, "patchDef2") || string_equal(primitive, "patchDef2WS")) { - return GlobalPatchModule::getTable().createPatch(false, false); - } if (string_equal(primitive, "patchDef3") || string_equal(primitive, "patchDef3WS")) { - return GlobalPatchModule::getTable().createPatch(true, false); - } if (string_equal(primitive, "patchDefWS")) { - return GlobalPatchModule::getTable().createPatch(false, true); - } - - if (!detectedFormat) - { - EBrushType fmt; - if (string_equal(primitive, "brushDef")) - fmt = eBrushTypeQuake3BP; - else if (string_equal(primitive, "(")) - { - if (1) //tokeniser.getLine - fmt = eBrushTypeQuake3Valve; - else - fmt = eBrushTypeQuake3; - } - if (fmt != GlobalBrushModule::getTable().getBrushType()) - GlobalBrushModule::getTable().setBrushType(fmt); - } - - switch(GlobalBrushModule::getTable().getBrushType()) - { - default: - tokeniser.ungetToken(); // ( - case eBrushTypeQuake3BP: - return GlobalBrushModule::getTable().createBrush(); - } - } - - Tokeniser_unexpectedError(tokeniser, primitive, "#quake3-primitive"); - return g_nullNode; -} - -void readGraph(scene::Node &root, TextInputStream &inputStream, EntityCreator &entityTable) const -{ - detectedFormat = false; - wrongFormat = false; - Tokeniser &tokeniser = GlobalScripLibModule::getTable().m_pfnNewSimpleTokeniser(inputStream); - Map_Read(root, tokeniser, entityTable, *this); - tokeniser.release(); -} - -void writeGraph(scene::Node &root, GraphTraversalFunc traverse, TextOutputStream &outputStream) const -{ - TokenWriter &writer = GlobalScripLibModule::getTable().m_pfnNewSimpleTokenWriter(outputStream); - Map_Write(root, traverse, writer, false); - writer.release(); -} -}; - -typedef SingletonModule MapQ3Module; - -MapQ3Module g_MapQ3Module; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_MapQ3Module.selfRegister(); -} diff --git a/plugins/mapq3/write.cpp b/plugins/mapq3/write.cpp deleted file mode 100644 index aa94776..0000000 --- a/plugins/mapq3/write.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "write.h" - -#include "ientity.h" -#include "iscriplib.h" -#include "scenelib.h" - -inline MapExporter *Node_getMapExporter(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - - -static std::size_t g_count_entities; -static std::size_t g_count_brushes; - - -void Entity_ExportTokens(const Entity &entity, TokenWriter &writer) -{ - g_count_brushes = 0; - - class WriteKeyValue : public Entity::Visitor { - TokenWriter &m_writer; -public: - WriteKeyValue(TokenWriter &writer) - : m_writer(writer) - { - } - - void visit(const char *key, const char *value) - { - /* cut anything after # including the symbol itself */ - if (!strncmp(key, "On", 2)) { - StringTokeniser st(key, "#"); - m_writer.writeString(st.getToken()); - } else { - m_writer.writeString(key); - } - - m_writer.writeString(value); - m_writer.nextLine(); - } - - } visitor(writer); - - entity.forEachKeyValue(visitor); -} - -class WriteTokensWalker : public scene::Traversable::Walker { -mutable Stack m_stack; -TokenWriter &m_writer; -bool m_ignorePatches; -public: -WriteTokensWalker(TokenWriter &writer, bool ignorePatches) - : m_writer(writer), m_ignorePatches(ignorePatches) -{ -} - -bool pre(scene::Node &node) const -{ - m_stack.push(false); - - Entity *entity = Node_getEntity(node); - if (entity != 0) { - m_writer.writeToken("//"); - m_writer.writeToken("entity"); - m_writer.writeUnsigned(g_count_entities++); - m_writer.nextLine(); - - m_writer.writeToken("{"); - m_writer.nextLine(); - m_stack.top() = true; - - Entity_ExportTokens(*entity, m_writer); - } else { - MapExporter *exporter = Node_getMapExporter(node); - if (exporter != 0 - && !(m_ignorePatches && Node_isPatch(node))) { - m_writer.writeToken("//"); - m_writer.writeToken("brush"); - m_writer.writeUnsigned(g_count_brushes++); - m_writer.nextLine(); - - exporter->exportTokens(m_writer); - } - } - - return true; -} - -void post(scene::Node &node) const -{ - if (m_stack.top()) { - m_writer.writeToken("}"); - m_writer.nextLine(); - } - m_stack.pop(); -} -}; - -void Map_Write(scene::Node &root, GraphTraversalFunc traverse, TokenWriter &writer, bool ignorePatches) -{ - g_count_entities = 0; - traverse(root, WriteTokensWalker(writer, ignorePatches)); -} diff --git a/plugins/mapq3/write.h b/plugins/mapq3/write.h deleted file mode 100644 index 0fbfce0..0000000 --- a/plugins/mapq3/write.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WRITE_H ) -#define INCLUDED_WRITE_H - -#include "imap.h" - -void Map_Write(scene::Node &root, GraphTraversalFunc traverse, TokenWriter &writer, bool ignorePatches); - -#endif diff --git a/plugins/matsys/Makefile b/plugins/matsys/Makefile deleted file mode 100644 index 9fd0fd8..0000000 --- a/plugins/matsys/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - shaders.o plugin.o - -# binary target -../../build/plugins/libmatsys.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -shaders.o: shaders.cpp shaders.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libmatsys.$(LIB_EXT) diff --git a/plugins/matsys/plugin.cpp b/plugins/matsys/plugin.cpp deleted file mode 100644 index 12fedab..0000000 --- a/plugins/matsys/plugin.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ishaders.h" -#include "ifilesystem.h" -#include "itextures.h" -#include "iscriplib.h" -#include "qerplugin.h" - -#include "string/string.h" -#include "modulesystem/singletonmodule.h" -#include "shaders.h" - -class ShadersDependencies : - public GlobalFileSystemModuleRef, - public GlobalTexturesModuleRef, - public GlobalScripLibModuleRef, - public GlobalRadiantModuleRef { -ImageModuleRef m_bitmapModule; -public: -ShadersDependencies() : - m_bitmapModule("tga") -{ -} - -ImageModuleRef &getBitmapModule() -{ - return m_bitmapModule; -} -}; - -class MaterialAPI { -ShaderSystem *m_shadersq3; -public: -typedef ShaderSystem Type; - -STRING_CONSTANT(Name, "mat"); - -MaterialAPI(ShadersDependencies &dependencies) -{ - g_shadersExtension = "mat"; - g_shadersDirectory = "textures/"; - g_enableDefaultShaders = false; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersq3 = &GetShaderSystem(); -} - -~MaterialAPI() -{ - Shaders_Destroy(); -} - -ShaderSystem *getTable() -{ - return m_shadersq3; -} -}; - -typedef SingletonModule > MaterialModule; -MaterialModule g_MaterialModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - g_MaterialModule.selfRegister(); -} diff --git a/plugins/matsys/shaders.cpp b/plugins/matsys/shaders.cpp deleted file mode 100644 index 5b9d65c..0000000 --- a/plugins/matsys/shaders.cpp +++ /dev/null @@ -1,1578 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Shaders Manager Plugin -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "shaders.h" -#include "globaldefs.h" - -#include -#include -#include -#include - -#include "ifilesystem.h" -#include "ishaders.h" -#include "iscriplib.h" -#include "itextures.h" -#include "qerplugin.h" -#include "irender.h" - -#include - -#include "debugging/debugging.h" -#include "string/pooledstring.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "generic/referencecounted.h" -#include "stream/memstream.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "os/dir.h" -#include "os/file.h" -#include "stringio.h" -#include "shaderlib.h" -#include "texturelib.h" -#include "cmdlib.h" -#include "moduleobservers.h" -#include "archivelib.h" -#include "imagelib.h" - -const char *g_shadersExtension = ""; -const char *g_shadersDirectory = ""; -bool g_enableDefaultShaders = true; -bool g_useShaderList = true; -_QERPlugImageTable *g_bitmapModule = 0; -const char *g_texturePrefix = "textures/"; - -void ActiveShaders_IteratorBegin(); -bool ActiveShaders_IteratorAtEnd(); -IShader *ActiveShaders_IteratorCurrent(); -void ActiveShaders_IteratorIncrement(); -Callback g_ActiveShadersChangedNotify; -void FreeShaders(); -void LoadShaderFile(const char *filename); -qtexture_t *Texture_ForName(const char *filename); - -/*! - NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX: - SHADER_NOT_FOUND means we didn't find the raw texture or the shader for this - SHADER_NOTEX means we recognize this as a shader script, but we are missing the texture to represent it - this was in the initial design of the shader code since early GtkRadiant alpha, and got sort of foxed in 1.2 and put back in - */ -Image *loadBitmap(void *environment, const char *name) -{ - DirectoryArchiveFile file(name, name); - if (!file.failed()) { - return g_bitmapModule->loadImage(file); - } - return 0; -} - -inline byte *getPixel(byte *pixels, int width, int height, int x, int y) -{ - return pixels + (((((y + height) % height) * width) + ((x + width) % width)) * 4); -} - -class KernelElement { -public: -int x, y; -float w; -}; - -Image &convertHeightmapToNormalmap(Image &heightmap, float scale) -{ - int w = heightmap.getWidth(); - int h = heightmap.getHeight(); - - Image &normalmap = *(new RGBAImage(heightmap.getWidth(), heightmap.getHeight())); - - byte *in = heightmap.getRGBAPixels(); - byte *out = normalmap.getRGBAPixels(); - - #if 1 - // no filtering - const int kernelSize = 2; - KernelElement kernel_du[kernelSize] = { - {-1, 0, -0.5f}, - {1, 0, 0.5f} - }; - KernelElement kernel_dv[kernelSize] = { - {0, 1, 0.5f}, - {0, -1, -0.5f} - }; - #else - // 3x3 Prewitt - const int kernelSize = 6; - KernelElement kernel_du[kernelSize] = { - {-1, 1,-1.0f }, - {-1, 0,-1.0f }, - {-1,-1,-1.0f }, - { 1, 1, 1.0f }, - { 1, 0, 1.0f }, - { 1,-1, 1.0f } - }; - KernelElement kernel_dv[kernelSize] = { - {-1, 1, 1.0f }, - { 0, 1, 1.0f }, - { 1, 1, 1.0f }, - {-1,-1,-1.0f }, - { 0,-1,-1.0f }, - { 1,-1,-1.0f } - }; - #endif - - int x, y = 0; - while (y < h) { - x = 0; - while (x < w) { - float du = 0; - for (KernelElement *i = kernel_du; i != kernel_du + kernelSize; ++i) { - du += (getPixel(in, w, h, x + (*i).x, y + (*i).y)[0] / 255.0) * (*i).w; - } - float dv = 0; - for (KernelElement *i = kernel_dv; i != kernel_dv + kernelSize; ++i) { - dv += (getPixel(in, w, h, x + (*i).x, y + (*i).y)[0] / 255.0) * (*i).w; - } - - float nx = -du * scale; - float ny = -dv * scale; - float nz = 1.0; - - // Normalize - float norm = 1.0 / sqrt(nx * nx + ny * ny + nz * nz); - out[0] = float_to_integer(((nx * norm) + 1) * 127.5); - out[1] = float_to_integer(((ny * norm) + 1) * 127.5); - out[2] = float_to_integer(((nz * norm) + 1) * 127.5); - out[3] = 255; - - x++; - out += 4; - } - - y++; - } - - return normalmap; -} - -Image *loadHeightmap(void *environment, const char *name) -{ - Image *heightmap = GlobalTexturesCache().loadImage(name); - if (heightmap != 0) { - Image &normalmap = convertHeightmapToNormalmap(*heightmap, *reinterpret_cast( environment )); - heightmap->release(); - return &normalmap; - } - return 0; -} - -Image *loadSpecial(void *environment, const char *name) -{ - if (*name == '_') { // special image - StringOutputStream bitmapName(256); - bitmapName << GlobalRadiant().getAppPath() << "bitmaps/" << name + 1 << ".tga"; - Image *image = loadBitmap(environment, bitmapName.c_str()); - if (image != 0) { - return image; - } - } - return GlobalTexturesCache().loadImage(name); -} - -class ShaderPoolContext { -}; - -typedef Static ShaderPool; -typedef PooledString ShaderString; -typedef ShaderString ShaderVariable; -typedef ShaderString ShaderValue; -typedef CopiedString TextureExpression; - -// clean a texture name to the qtexture_t name format we use internally -// NOTE: case sensitivity: the engine is case sensitive. we store the shader name with case information and save with case -// information as well. but we assume there won't be any case conflict and so when doing lookups based on shader name, -// we compare as case insensitive. That is Radiant is case insensitive, but knows that the engine is case sensitive. -//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present -template -void parseTextureName(StringType &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = CopiedString( - StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str()))).c_str(); // remove extension -} - -bool Tokeniser_parseTextureName(Tokeniser &tokeniser, TextureExpression &name) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#texture-name"); - return false; - } - parseTextureName(name, token); - return true; -} - -bool Tokeniser_parseShaderName(Tokeniser &tokeniser, CopiedString &name) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#shader-name"); - return false; - } - parseTextureName(name, token); - return true; -} - -bool Tokeniser_parseString(Tokeniser &tokeniser, ShaderString &string) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#string"); - return false; - } - string = token; - return true; -} - -typedef std::list ShaderParameters; -typedef std::list ShaderArguments; -typedef std::pair BlendFuncExpression; - -class ShaderTemplate { -std::size_t m_refcount; -CopiedString m_Name; -CopiedString m_WadName; -public: - -ShaderParameters m_params; -TextureExpression m_textureName; -TextureExpression m_diffuse; -TextureExpression m_bump; -ShaderValue m_heightmapScale; -TextureExpression m_specular; -TextureExpression m_lightFalloffImage; - -int m_nFlags; -float m_fTrans; -int m_iPolygonOffset; - -// alphafunc stuff -IShader::EAlphaFunc m_AlphaFunc; -float m_AlphaRef; -// cull stuff -IShader::ECull m_Cull; - -ShaderTemplate() : - m_refcount(0) -{ - m_nFlags = 0; - m_fTrans = 1.0f; -} - -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - ASSERT_MESSAGE(m_refcount != 0, "shader reference-count going below zero"); - if (--m_refcount == 0) { - delete this; - } -} - -std::size_t refcount() -{ - return m_refcount; -} - -const char *getName() const -{ - return m_Name.c_str(); -} - -void setName(const char *name) -{ - m_Name = name; -} -// ----------------------------------------- - -bool parseMaterial(Tokeniser &tokeniser); -bool parseTemplate(Tokeniser &tokeniser); - - -void CreateDefault(const char *name) -{ - /*if (g_enableDefaultShaders) { - m_textureName = name; - } else { - m_textureName = ""; - }*/ - setName(name); -} - -class MapLayerTemplate { -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -public: -MapLayerTemplate(const TextureExpression &texture, const BlendFuncExpression &blendFunc, bool clampToBorder, - const ShaderValue &alphaTest) : - m_texture(texture), - m_blendFunc(blendFunc), - m_clampToBorder(false), - m_alphaTest(alphaTest) -{ -} - -const TextureExpression &texture() const -{ - return m_texture; -} - -const BlendFuncExpression &blendFunc() const -{ - return m_blendFunc; -} - -bool clampToBorder() const -{ - return m_clampToBorder; -} - -const ShaderValue &alphaTest() const -{ - return m_alphaTest; -} -}; - -typedef std::vector MapLayers; -MapLayers m_layers; -}; - -enum LayerTypeId { - LAYER_NONE, - LAYER_BLEND, - LAYER_DIFFUSEMAP, - LAYER_BUMPMAP, - LAYER_SPECULARMAP -}; - -class LayerTemplate { -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -ShaderValue m_heightmapScale; - -LayerTemplate() : m_type(LAYER_NONE), m_blendFunc("GL_ONE", "GL_ZERO"), m_clampToBorder(false), m_alphaTest("-1"), - m_heightmapScale("0") -{ -} -}; - -bool parseShaderParameters(Tokeniser &tokeniser, ShaderParameters ¶ms) -{ - Tokeniser_parseToken(tokeniser, "("); - for (;;) { - const char *param = tokeniser.getToken(); - if (string_equal(param, ")")) { - break; - } - params.push_back(param); - const char *comma = tokeniser.getToken(); - if (string_equal(comma, ")")) { - break; - } - if (!string_equal(comma, ",")) { - Tokeniser_unexpectedError(tokeniser, comma, ","); - return false; - } - } - return true; -} - -bool ShaderTemplate::parseTemplate(Tokeniser &tokeniser) -{ - m_Name = tokeniser.getToken(); - if (!parseShaderParameters(tokeniser, m_params)) { - globalErrorStream() << "shader template: " << makeQuoted(m_Name.c_str()) << ": parameter parse failed\n"; - return false; - } - - return parseMaterial(tokeniser); -} - -typedef SmartPointer ShaderTemplatePointer; -typedef std::map ShaderTemplateMap; - -ShaderTemplateMap g_shaders; -ShaderTemplateMap g_shaderTemplates; - -ShaderTemplate *findTemplate(const char *name) -{ - ShaderTemplateMap::iterator i = g_shaderTemplates.find(name); - if (i != g_shaderTemplates.end()) { - return (*i).second.get(); - } - return 0; -} - -class ShaderDefinition { -public: -ShaderDefinition(ShaderTemplate *shaderTemplate, const ShaderArguments &args, const char *filename) - : shaderTemplate(shaderTemplate), args(args), filename(filename) -{ -} - -ShaderTemplate *shaderTemplate; -ShaderArguments args; -const char *filename; -}; - -typedef std::map ShaderDefinitionMap; -ShaderDefinitionMap g_shaderDefinitions; - -bool parseTemplateInstance(Tokeniser &tokeniser, const char *filename) -{ - CopiedString name; - RETURN_FALSE_IF_FAIL(Tokeniser_parseShaderName(tokeniser, name)); - const char *templateName = tokeniser.getToken(); - ShaderTemplate *shaderTemplate = findTemplate(templateName); - if (shaderTemplate == 0) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) << ": shader template not found: " - << makeQuoted(templateName) << "\n"; - } - - ShaderArguments args; - if (!parseShaderParameters(tokeniser, args)) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) << ": argument parse failed\n"; - return false; - } - - if (shaderTemplate != 0) { - if (!g_shaderDefinitions.insert( - ShaderDefinitionMap::value_type(name, ShaderDefinition(shaderTemplate, args, filename))).second) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) - << ": already exists, second definition ignored\n"; - } - } - return true; -} - -const char *evaluateShaderValue(const char *value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - ShaderArguments::const_iterator j = args.begin(); - for (ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j) { - const char *other = (*i).c_str(); - if (string_equal(value, other)) { - return (*j).c_str(); - } - } - return value; -} - -///\todo BlendFunc parsing -BlendFunc -evaluateBlendFunc(const BlendFuncExpression &blendFunc, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - return BlendFunc(BLEND_ONE, BLEND_ZERO); -} - -qtexture_t* evaluateTexture( const TextureExpression& texture, const ShaderParameters& params, const ShaderArguments& args, const LoadImageCallback& loader = GlobalTexturesCache().defaultLoader() ){ - StringOutputStream result( 64 ); - const char* expression = texture.c_str(); - const char* end = expression + string_length( expression ); - if ( !string_empty( expression ) ) { - for (;; ) - { - const char* best = end; - const char* bestParam = 0; - const char* bestArg = 0; - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* found = strstr( expression, ( *i ).c_str() ); - if ( found != 0 && found < best ) { - best = found; - bestParam = ( *i ).c_str(); - bestArg = ( *j ).c_str(); - } - } - if ( best != end ) { - result << StringRange( expression, best ); - result << PathCleaned( bestArg ); - expression = best + string_length( bestParam ); - } - else - { - break; - } - } - result << expression; - } - return GlobalTexturesCache().capture( loader, result.c_str() ); -} - -float evaluateFloat(const ShaderValue &value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - const char *result = evaluateShaderValue(value.c_str(), params, args); - float f = 0.0f; - if (!string_parse_float(result, f)) { - globalErrorStream() << "parsing float value failed: " << makeQuoted(result) << "\n"; - } - return f; -} - -BlendFactor evaluateBlendFactor(const ShaderValue &value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - const char *result = evaluateShaderValue(value.c_str(), params, args); - - if (string_equal_nocase(result, "gl_zero")) { - return BLEND_ZERO; - } - if (string_equal_nocase(result, "gl_one")) { - return BLEND_ONE; - } - if (string_equal_nocase(result, "gl_src_color")) { - return BLEND_SRC_COLOUR; - } - if (string_equal_nocase(result, "gl_one_minus_src_color")) { - return BLEND_ONE_MINUS_SRC_COLOUR; - } - if (string_equal_nocase(result, "gl_src_alpha")) { - return BLEND_SRC_ALPHA; - } - if (string_equal_nocase(result, "gl_one_minus_src_alpha")) { - return BLEND_ONE_MINUS_SRC_ALPHA; - } - if (string_equal_nocase(result, "gl_dst_color")) { - return BLEND_DST_COLOUR; - } - if (string_equal_nocase(result, "gl_one_minus_dst_color")) { - return BLEND_ONE_MINUS_DST_COLOUR; - } - if (string_equal_nocase(result, "gl_dst_alpha")) { - return BLEND_DST_ALPHA; - } - if (string_equal_nocase(result, "gl_one_minus_dst_alpha")) { - return BLEND_ONE_MINUS_DST_ALPHA; - } - if (string_equal_nocase(result, "gl_src_alpha_saturate")) { - return BLEND_SRC_ALPHA_SATURATE; - } - - globalErrorStream() << "parsing blend-factor value failed: " << makeQuoted(result) << "\n"; - return BLEND_ZERO; -} - -class CShader : public IShader { -std::size_t m_refcount; -const ShaderTemplate &m_template; -const ShaderArguments &m_args; -const char *m_filename; -// name is shader-name, otherwise texture-name (if not a real shader) -CopiedString m_Name; -CopiedString m_WadName; -qtexture_t *m_pTexture; -qtexture_t *m_notfound; -qtexture_t *m_pDiffuse; -float m_heightmapScale; -qtexture_t *m_pBump; -qtexture_t *m_pSpecular; -qtexture_t *m_pLightFalloffImage; -BlendFunc m_blendFunc; -bool m_bInUse; - -public: -CShader(const ShaderDefinition &definition) : - m_refcount(0), - m_template(*definition.shaderTemplate), - m_args(definition.args), - m_filename(definition.filename), - m_blendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA), - m_bInUse(false) -{ - m_pTexture = 0; - m_pDiffuse = 0; - m_pBump = 0; - m_pSpecular = 0; - m_notfound = 0; - realise(); -} - -virtual ~CShader() -{ - unrealise(); - - ASSERT_MESSAGE(m_refcount == 0, "deleting active shader"); -} - -// IShaders implementation ----------------- -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - ASSERT_MESSAGE(m_refcount != 0, "shader reference-count going below zero"); - if (--m_refcount == 0) { - delete this; - } -} - -std::size_t refcount() -{ - return m_refcount; -} - -// get/set the qtexture_t* Radiant uses to represent this shader object -qtexture_t *getTexture() const -{ - return m_pTexture; -} - -qtexture_t *getDiffuse() const -{ - return m_pDiffuse; -} - -qtexture_t *getBump() const -{ - return m_pBump; -} - -qtexture_t *getSpecular() const -{ - return m_pSpecular; -} - -// get shader name -const char *getName() const -{ - return m_Name.c_str(); -} - -const char* getWadName() const -{ - return m_WadName.c_str(); -} - - -bool IsInUse() const -{ - return m_bInUse; -} - -void SetInUse(bool bInUse) -{ - m_bInUse = bInUse; - g_ActiveShadersChangedNotify(); -} - -// get the shader flags -int getFlags() const -{ - return m_template.m_nFlags; -} - -// get the transparency value -float getTrans() const -{ - return m_template.m_fTrans; -} - -int getPolygonOffset() const -{ - return m_template.m_iPolygonOffset; -} - -// test if it's a true shader, or a default shader created to wrap around a texture -bool IsDefault() const -{ - return string_empty(m_filename); -} - -// get the alphaFunc -void getAlphaFunc(EAlphaFunc *func, float *ref) -{ - *func = m_template.m_AlphaFunc; - *ref = m_template.m_AlphaRef; -}; - -BlendFunc getBlendFunc() const -{ - return m_blendFunc; -} - -// get the cull type -ECull getCull() -{ - return m_template.m_Cull; -}; - -// get shader file name (ie the file where this one is defined) -const char *getShaderFileName() const -{ - return m_filename; -} -// ----------------------------------------- - -void realise() -{ - m_pTexture = evaluateTexture(m_template.m_textureName, m_template.m_params, m_args); - - if (m_pTexture->texture_number == 0) { - m_notfound = m_pTexture; - { - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" << (IsDefault() ? "notex.tga" : "shadernotex.tga"); - m_pTexture = GlobalTexturesCache().capture(LoadImageCallback(0, loadBitmap), name.c_str()); - } - } -} - -void unrealise() -{ - GlobalTexturesCache().release(m_pTexture); - - if (m_notfound != 0) { - GlobalTexturesCache().release(m_notfound); - } -} - -// set shader name -void setName(const char *name) -{ - m_Name = name; -} - -void setWadName( const char* name ) -{ - m_WadName = name; -} - -class MapLayer : public ShaderLayer { -qtexture_t *m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -public: -MapLayer(qtexture_t *texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest) : - m_texture(texture), - m_blendFunc(blendFunc), - m_clampToBorder(false), - m_alphaTest(alphaTest) -{ -} - -qtexture_t *texture() const -{ - return m_texture; -} - -BlendFunc blendFunc() const -{ - return m_blendFunc; -} - -bool clampToBorder() const -{ - return m_clampToBorder; -} - -float alphaTest() const -{ - return m_alphaTest; -} -}; - -static MapLayer evaluateLayer(const ShaderTemplate::MapLayerTemplate &layerTemplate, const ShaderParameters ¶ms, - const ShaderArguments &args) -{ - return MapLayer( - evaluateTexture(layerTemplate.texture(), params, args), - evaluateBlendFunc(layerTemplate.blendFunc(), params, args), - layerTemplate.clampToBorder(), - evaluateFloat(layerTemplate.alphaTest(), params, args) - ); -} - -typedef std::vector MapLayers; -MapLayers m_layers; - -const ShaderLayer *firstLayer() const -{ - if (m_layers.empty()) { - return 0; - } - return &m_layers.front(); -} - -void forEachLayer(const ShaderLayerCallback &callback) const -{ - for (MapLayers::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) { - callback(*i); - } -} - -qtexture_t *lightFalloffImage() const -{ - if (!string_empty(m_template.m_lightFalloffImage.c_str())) { - return m_pLightFalloffImage; - } - return 0; -} -}; - -typedef SmartPointer ShaderPointer; -typedef std::map shaders_t; -shaders_t g_ActiveShaders; -static shaders_t::iterator g_ActiveShadersIterator; - -void ActiveShaders_IteratorBegin() -{ - g_ActiveShadersIterator = g_ActiveShaders.begin(); -} - -bool ActiveShaders_IteratorAtEnd() -{ - return g_ActiveShadersIterator == g_ActiveShaders.end(); -} - -IShader *ActiveShaders_IteratorCurrent() -{ - return static_cast( g_ActiveShadersIterator->second ); -} - -void ActiveShaders_IteratorIncrement() -{ - ++g_ActiveShadersIterator; -} - -void debug_check_shaders(shaders_t &shaders) -{ - for (shaders_t::iterator i = shaders.begin(); i != shaders.end(); ++i) { - ASSERT_MESSAGE(i->second->refcount() == 1, "orphan shader still referenced"); - } -} - -// will free all GL binded qtextures and shaders -// NOTE: doesn't make much sense out of Radiant exit or called during a reload -void FreeShaders() -{ - // reload shaders - // empty the actives shaders list - debug_check_shaders(g_ActiveShaders); - g_ActiveShaders.clear(); - g_shaders.clear(); - g_shaderTemplates.clear(); - g_shaderDefinitions.clear(); - g_ActiveShadersChangedNotify(); -} - -bool ShaderTemplate::parseMaterial(Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - - // we need to read until we hit a balanced } - int depth = 0; - for (;;) { - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - - if (token == 0) { - return false; - } - - if (string_equal(token, "{")) { - ++depth; - continue; - } else if (string_equal(token, "}")) { - --depth; - if (depth < 0) { // underflow - return false; - } - if (depth == 0) { // end of shader - break; - } - - continue; - } - - if (depth == 1) { - if (string_equal_nocase(token, "qer_nocarve")) { - m_nFlags |= QER_NOCARVE; - } else if (string_equal_nocase(token, "polygonoffset")) { - if (Tokeniser_getInteger(tokeniser, m_iPolygonOffset) == false) { - m_iPolygonOffset = 1; - } - m_nFlags |= QER_POLYOFS; - } else if (string_equal_nocase(token, "qer_trans")) { - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, m_fTrans)); - m_nFlags |= QER_TRANS; - } else if (string_equal_nocase(token, "qer_editorimage") || string_equal_nocase(token, "diffusemap")) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, m_textureName)); - } else if (string_equal_nocase(token, "qer_alphafunc")) { - const char *alphafunc = tokeniser.getToken(); - - if (alphafunc == 0) { - Tokeniser_unexpectedError(tokeniser, alphafunc, "#alphafunc"); - return false; - } - - if (string_equal_nocase(alphafunc, "equal")) { - m_AlphaFunc = IShader::eEqual; - } else if (string_equal_nocase(alphafunc, "greater")) { - m_AlphaFunc = IShader::eGreater; - } else if (string_equal_nocase(alphafunc, "less")) { - m_AlphaFunc = IShader::eLess; - } else if (string_equal_nocase(alphafunc, "gequal")) { - m_AlphaFunc = IShader::eGEqual; - } else if (string_equal_nocase(alphafunc, "lequal")) { - m_AlphaFunc = IShader::eLEqual; - } else { - m_AlphaFunc = IShader::eAlways; - } - - m_nFlags |= QER_ALPHATEST; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, m_AlphaRef)); - } else if (string_equal_nocase(token, "cull")) { - const char *cull = tokeniser.getToken(); - - if (cull == 0) { - Tokeniser_unexpectedError(tokeniser, cull, "#cull"); - return false; - } - - if (string_equal_nocase(cull, "none") - || string_equal_nocase(cull, "twosided") - || string_equal_nocase(cull, "disable")) { - m_Cull = IShader::eCullNone; - } else if (string_equal_nocase(cull, "back") - || string_equal_nocase(cull, "backside") - || string_equal_nocase(cull, "backsided")) { - m_Cull = IShader::eCullBack; - } else { - m_Cull = IShader::eCullBack; - } - - m_nFlags |= QER_CULL; - } else if (string_equal_nocase(token, "surfaceparm")) { - const char *surfaceparm = tokeniser.getToken(); - - if (surfaceparm == 0) { - Tokeniser_unexpectedError(tokeniser, surfaceparm, "#surfaceparm"); - return false; - } - - if (string_equal_nocase(surfaceparm, "fog")) { - m_nFlags |= QER_FOG; - if (m_fTrans == 1.0f) { // has not been explicitly set by qer_trans - m_fTrans = 0.35f; - } - } else if (string_equal_nocase(surfaceparm, "nodraw")) { - m_nFlags |= QER_NODRAW; - } else if (string_equal_nocase(surfaceparm, "nonsolid")) { - m_nFlags |= QER_NONSOLID; - } else if (string_equal_nocase(surfaceparm, "water")) { - m_nFlags |= QER_WATER; - } else if (string_equal_nocase(surfaceparm, "lava")) { - m_nFlags |= QER_LAVA; - } else if (string_equal_nocase(surfaceparm, "areaportal")) { - m_nFlags |= QER_AREAPORTAL; - } else if (string_equal_nocase(surfaceparm, "playerclip")) { - m_nFlags |= QER_CLIP; - } else if (string_equal_nocase(surfaceparm, "botclip")) { - m_nFlags |= QER_BOTCLIP; - } - } - } - } - - return true; -} - -class Layer { -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -float m_heightmapScale; - -Layer() : m_type(LAYER_NONE), m_blendFunc(BLEND_ONE, BLEND_ZERO), m_clampToBorder(false), m_alphaTest(-1), - m_heightmapScale(0) -{ -} -}; - -std::list g_shaderFilenames; - -#if defined(WIN64) || defined(WIN32) -char * -strndup (const char *s, size_t n) -{ - char *result; - size_t len = strlen (s); - - if (n < len) - len = n; - - result = (char *) malloc (len + 1); - - if (!result) - return 0; - - result[len] = '\0'; - return (char *) memcpy (result, s, len); -} -#endif - -char* m_substring(const char* str, size_t begin, size_t len) -{ - if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len)) { - return 0; - } - - return strndup(str + begin, len); -} - -void ParseShaderFile(Tokeniser &tokeniser, const char *filename) -{ - g_shaderFilenames.push_back(filename); - filename = g_shaderFilenames.back().c_str(); - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - - if (token == 0) { - break; - } - - if (string_equal(token, "table")) { - if (tokeniser.getToken() == 0) { - Tokeniser_unexpectedError(tokeniser, 0, "#table-name"); - return; - } - if (!Tokeniser_parseToken(tokeniser, "{")) { - return; - } - for (;;) { - const char *option = tokeniser.getToken(); - if (string_equal(option, "{")) { - for (;;) { - const char *value = tokeniser.getToken(); - if (string_equal(value, "}")) { - break; - } - } - - if (!Tokeniser_parseToken(tokeniser, "}")) { - return; - } - break; - } - } - } else { - if (string_equal(token, "guide")) { - parseTemplateInstance(tokeniser, filename); - } else { - if (!string_equal(token, "material") - && !string_equal(token, "particle") - && !string_equal(token, "skin")) { - tokeniser.ungetToken(); - } - // first token should be the path + name.. (from base) - ShaderTemplatePointer shaderTemplate(new ShaderTemplate()); - shaderTemplate->setName( m_substring( filename, 0, strlen( filename) - 4 ) ); // EUKARA - - g_shaders.insert(ShaderTemplateMap::value_type(shaderTemplate->getName(), shaderTemplate)); - - bool result = shaderTemplate->parseMaterial(tokeniser); - if (result) { - // do we already have this shader? - if (!g_shaderDefinitions.insert(ShaderDefinitionMap::value_type(shaderTemplate->getName(), - ShaderDefinition( - shaderTemplate.get(), - ShaderArguments(), - filename))).second) { - #if GDEF_DEBUG - globalOutputStream() << "WARNING: shader " << shaderTemplate->getName() - << " is already in memory, definition in " << filename << " ignored.\n"; - #endif - } - } else { - globalErrorStream() << "Error parsing material " << shaderTemplate->getName() << "\n"; - return; - } - } - } - } -} - -void parseGuideFile(Tokeniser &tokeniser, const char *filename) -{ - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - - if (token == 0) { - break; - } - - if (string_equal(token, "guide")) { - // first token should be the path + name.. (from base) - ShaderTemplatePointer shaderTemplate(new ShaderTemplate); - shaderTemplate->parseTemplate(tokeniser); - if (!g_shaderTemplates.insert( - ShaderTemplateMap::value_type(shaderTemplate->getName(), shaderTemplate)).second) { - globalErrorStream() << "guide " << makeQuoted(shaderTemplate->getName()) - << ": already defined, second definition ignored\n"; - } - } else if (string_equal(token, "inlineGuide")) { - // skip entire inlineGuide definition - std::size_t depth = 0; - for (;;) { - tokeniser.nextLine(); - token = tokeniser.getToken(); - if (string_equal(token, "{")) { - ++depth; - } else if (string_equal(token, "}")) { - if (--depth == 0) { - break; - } - } - } - } - } -} - -void LoadShaderFile(const char *filename) -{ - ArchiveTextFile *file = GlobalFileSystem().openTextFile(filename); - - if (file != 0) { - // we probably only want to output when errors happen - //globalOutputStream() << "Parsing material " << filename << "\n"; - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(file->getInputStream()); - ParseShaderFile(tokeniser, filename); - tokeniser.release(); - file->release(); - } else { - globalOutputStream() << "Unable to read material " << filename << "\n"; - } -} - -void loadGuideFile(const char *filename) -{ - StringOutputStream fullname(256); - fullname << "guides/" << filename; - ArchiveTextFile *file = GlobalFileSystem().openTextFile(fullname.c_str()); - - if (file != 0) { - globalOutputStream() << "Parsing guide file " << fullname.c_str() << "\n"; - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(file->getInputStream()); - parseGuideFile(tokeniser, fullname.c_str()); - tokeniser.release(); - file->release(); - } else { - globalOutputStream() << "Unable to read guide file " << fullname.c_str() << "\n"; - } -} - -CShader* Try_Shader_ForName( const char* name ){ - { - shaders_t::iterator i = g_ActiveShaders.find( name ); - if ( i != g_ActiveShaders.end() ) { - return ( *i ).second; - } - } - // active shader was not found - - // find matching shader definition - ShaderDefinitionMap::iterator i = g_shaderDefinitions.find( name ); - if ( i == g_shaderDefinitions.end() ) { - // shader definition was not found - - // create new shader definition from default shader template - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->CreateDefault( name ); - g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - i = g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate.get(), ShaderArguments(), "" ) ) ).first; - } - - // create shader from existing definition - ShaderPointer pShader( new CShader( ( *i ).second ) ); - pShader->setName( name ); - g_ActiveShaders.insert( shaders_t::value_type( name, pShader ) ); - g_ActiveShadersChangedNotify(); - return pShader; -} - -IShader *Shader_ForName(const char *name) -{ - ASSERT_NOTNULL(name); - - IShader *pShader = Try_Shader_ForName(name); - pShader->IncRef(); - return pShader; -} - - -// the list of scripts/*.shader files we need to work with -// those are listed in shaderlist file -GSList *l_shaderfiles = 0; - -GSList *Shaders_getShaderFileList() -{ - return l_shaderfiles; -} - -/* - ================== - DumpUnreferencedShaders - usefull function: dumps the list of .shader files that are not referenced to the console - ================== - */ -void IfFound_dumpUnreferencedShader(bool &bFound, const char *filename) -{ - bool listed = false; - - for (GSList *sh = l_shaderfiles; sh != 0; sh = g_slist_next(sh)) { - if (!strcmp((char *) sh->data, filename)) { - listed = true; - break; - } - } - - if (!listed) { - if (!bFound) { - bFound = true; - globalOutputStream() << "Following shader files are not referenced in any shaderlist.txt:\n"; - } - globalOutputStream() << "\t" << filename << "\n"; - } -} - -typedef ReferenceCaller IfFoundDumpUnreferencedShaderCaller; - -void DumpUnreferencedShaders() -{ - bool bFound = false; - GlobalFileSystem().forEachFile(g_shadersDirectory, g_shadersExtension, IfFoundDumpUnreferencedShaderCaller(bFound)); -} - -void ShaderList_addShaderFile(const char *dirstring) -{ - bool found = false; - - for (GSList *tmp = l_shaderfiles; tmp != 0; tmp = tmp->next) { - if (string_equal_nocase(dirstring, (char *) tmp->data)) { - found = true; - globalOutputStream() << "duplicate entry \"" << (char *) tmp->data << "\" in shaderlist.txt\n"; - break; - } - } - - if (!found) { - l_shaderfiles = g_slist_append(l_shaderfiles, strdup(dirstring)); - } -} - -/* - ================== - BuildShaderList - build a CStringList of shader names - ================== - */ -void BuildShaderList(TextInputStream &shaderlist) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(shaderlist); - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - StringOutputStream shaderFile(64); - while (token != 0) { - // each token should be a shader filename - shaderFile << token << "." << g_shadersExtension; - ShaderList_addShaderFile(shaderFile.c_str()); - tokeniser.nextLine(); - token = tokeniser.getToken(); - shaderFile.clear(); - } - tokeniser.release(); -} - -void FreeShaderList() -{ - while (l_shaderfiles != 0) { - free(l_shaderfiles->data); - l_shaderfiles = g_slist_remove(l_shaderfiles, l_shaderfiles->data); - } -} - -void ShaderList_addFromArchive(const char *archivename) -{ - const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue("shaderpath"); - if (string_empty(shaderpath)) { - return; - } - - StringOutputStream shaderlist(256); - shaderlist << DirectoryCleaned(shaderpath) << "shaderlist.txt"; - - Archive *archive = GlobalFileSystem().getArchive(archivename, false); - if (archive) { - ArchiveTextFile *file = archive->openTextFile(shaderlist.c_str()); - if (file) { - globalOutputStream() << "Found shaderlist.txt in " << archivename << "\n"; - BuildShaderList(file->getInputStream()); - file->release(); - } - } -} - -#include "stream/filestream.h" - -bool -shaderlist_findOrInstall(const char *enginePath, const char *toolsPath, const char *shaderPath, const char *gamename) -{ - StringOutputStream absShaderList(256); - absShaderList << enginePath << gamename << '/' << shaderPath << "shaderlist.txt"; - if (file_exists(absShaderList.c_str())) { - return true; - } - { - StringOutputStream directory(256); - directory << enginePath << gamename << '/' << shaderPath; - if (!file_exists(directory.c_str()) && !Q_mkdir(directory.c_str())) { - return false; - } - } - { - StringOutputStream defaultShaderList(256); - defaultShaderList << toolsPath << gamename << '/' << "default_shaderlist.txt"; - if (file_exists(defaultShaderList.c_str())) { - return file_copy(defaultShaderList.c_str(), absShaderList.c_str()); - } - } - return false; -} - -void Shaders_Load() -{ - /*if (QUAKE4) { - GlobalFileSystem().forEachFile("guides/", "guide", makeCallbackF(loadGuideFile), 0); - }*/ - - const char *shaderPath = GlobalRadiant().getGameDescriptionKeyValue("shaderpath"); - if (!string_empty(shaderPath)) { - StringOutputStream path(256); - path << DirectoryCleaned(shaderPath); - - if (g_useShaderList) { - // preload shader files that have been listed in shaderlist.txt - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - const char *gamename = GlobalRadiant().getGameName(); - const char *enginePath = GlobalRadiant().getEnginePath(); - const char *toolsPath = GlobalRadiant().getGameToolsPath(); - bool isMod = !string_equal(basegame, gamename); - - if (!isMod || !shaderlist_findOrInstall(enginePath, toolsPath, path.c_str(), gamename)) { - gamename = basegame; - shaderlist_findOrInstall(enginePath, toolsPath, path.c_str(), gamename); - } - - GlobalFileSystem().forEachArchive(makeCallbackF(ShaderList_addFromArchive), false, true); - DumpUnreferencedShaders(); - } else { - GlobalFileSystem().forEachFile(path.c_str(), g_shadersExtension, makeCallbackF(ShaderList_addShaderFile), 0); - } - - GSList *lst = l_shaderfiles; - StringOutputStream shadername(256); - while (lst) { - shadername << path.c_str() << reinterpret_cast( lst->data ); - LoadShaderFile(shadername.c_str()); - shadername.clear(); - lst = lst->next; - } - } - - //StringPool_analyse(ShaderPool::instance()); -} - -void Shaders_Free() -{ - FreeShaders(); - FreeShaderList(); - g_shaderFilenames.clear(); -} - -ModuleObservers g_observers; - -// wait until filesystem and is realised before loading anything -std::size_t g_shaders_unrealised = 1; -bool Shaders_realised() -{ - return g_shaders_unrealised == 0; -} - -void Shaders_Realise() -{ - if (--g_shaders_unrealised == 0) { - Shaders_Load(); - g_observers.realise(); - } -} - -void Shaders_Unrealise() -{ - if (++g_shaders_unrealised == 1) { - g_observers.unrealise(); - Shaders_Free(); - } -} - -void Shaders_Refresh() -{ - Shaders_Unrealise(); - Shaders_Realise(); -} - -class MaterialSystem : public ShaderSystem, public ModuleObserver { -public: -void realise() -{ - Shaders_Realise(); -} - -void unrealise() -{ - Shaders_Unrealise(); -} - -void refresh() -{ - Shaders_Refresh(); -} - -IShader *getShaderForName(const char *name) -{ - return Shader_ForName(name); -} - -void foreachShaderName(const ShaderNameCallback &callback) -{ - for (ShaderDefinitionMap::const_iterator i = g_shaderDefinitions.begin(); i != g_shaderDefinitions.end(); ++i) { - callback((*i).first.c_str()); - } -} - -void beginActiveShadersIterator() -{ - ActiveShaders_IteratorBegin(); -} - -bool endActiveShadersIterator() -{ - return ActiveShaders_IteratorAtEnd(); -} - -IShader *dereferenceActiveShadersIterator() -{ - return ActiveShaders_IteratorCurrent(); -} - -void incrementActiveShadersIterator() -{ - ActiveShaders_IteratorIncrement(); -} - -void setActiveShadersChangedNotify(const Callback ¬ify) -{ - g_ActiveShadersChangedNotify = notify; -} - -void attach(ModuleObserver &observer) -{ - g_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - g_observers.detach(observer); -} - -void setLightingEnabled(bool enabled) -{ - -} - -const char *getTexturePrefix() const -{ - return g_texturePrefix; -} -}; - -MaterialSystem g_MaterialSystem; - -ShaderSystem &GetShaderSystem() -{ - return g_MaterialSystem; -} - -void Shaders_Construct() -{ - GlobalFileSystem().attach(g_MaterialSystem); -} - -void Shaders_Destroy() -{ - GlobalFileSystem().detach(g_MaterialSystem); - - if (Shaders_realised()) { - Shaders_Free(); - } -} diff --git a/plugins/matsys/shaders.h b/plugins/matsys/shaders.h deleted file mode 100644 index 4c9859a..0000000 --- a/plugins/matsys/shaders.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H -void Shaders_Construct(); -void Shaders_Destroy(); -class ShaderSystem; -ShaderSystem &GetShaderSystem(); -extern const char *g_shadersExtension; -extern const char *g_shadersDirectory; -extern bool g_enableDefaultShaders; -extern bool g_useShaderList; -struct _QERPlugImageTable; -extern _QERPlugImageTable *g_bitmapModule; -#endif diff --git a/plugins/md3model/model.h b/plugins/md3model/model.h deleted file mode 100644 index 14c7de1..0000000 --- a/plugins/md3model/model.h +++ /dev/null @@ -1,634 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -#include "globaldefs.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "modelskin.h" - -#include "math/frustum.h" -#include "string/string.h" -#include "generic/static.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "scenelib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "render.h" - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -inline VertexPointer vertexpointer_arbitrarymeshvertex(const ArbitraryMeshVertex *array) -{ - return VertexPointer(VertexPointer::pointer(&array->vertex), sizeof(ArbitraryMeshVertex)); -} - -inline void parseTextureName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension -} - -// generic renderable triangle surface -class Surface : - public OpenGLRenderable { -public: -typedef VertexBuffer vertices_t; -typedef IndexBuffer indices_t; -private: - -AABB m_aabb_local; -CopiedString m_shader; -Shader *m_state; - -vertices_t m_vertices; -indices_t m_indices; - -void CaptureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void ReleaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -public: - -Surface() - : m_shader(""), m_state(0) -{ - CaptureShader(); -} - -~Surface() -{ - ReleaseShader(); -} - -vertices_t &vertices() -{ - return m_vertices; -} - -indices_t &indices() -{ - return m_indices; -} - -void setShader(const char *name) -{ - ReleaseShader(); - parseTextureName(m_shader, name); - CaptureShader(); -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -Shader *getState() const -{ - return m_state; -} - -void updateAABB() -{ - m_aabb_local = AABB(); - for (vertices_t::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, reinterpret_cast((*i).vertex )); - } - - - for (Surface::indices_t::iterator i = m_indices.begin(); i != m_indices.end(); i += 3) { - ArbitraryMeshVertex &a = m_vertices[*(i + 0)]; - ArbitraryMeshVertex &b = m_vertices[*(i + 1)]; - ArbitraryMeshVertex &c = m_vertices[*(i + 2)]; - - ArbitraryMeshTriangle_sumTangents(a, b, c); - } - - for (Surface::vertices_t::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - vector3_normalise(reinterpret_cast((*i).tangent )); - vector3_normalise(reinterpret_cast((*i).bitangent )); - } -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_BUMP) != 0) { - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } - } else { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - } - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->vertex); - glDrawElements(GL_TRIANGLES, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data()); - -#if 0 - glBegin(GL_LINES); - - for (VertexBuffer::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - Vector3 normal = vector3_added(vertex3f_to_vector3((*i).vertex), - vector3_scaled(normal3f_to_vector3((*i).normal), 8)); - glVertex3fv(vertex3f_to_array((*i).vertex)); - glVertex3fv(vector3_to_array(normal)); - } - glEnd(); -#endif -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const Matrix4 &localToWorld, Shader *state) const -{ - renderer.SetState(state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - render(renderer, localToWorld, m_state); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - test.TestTriangles( - vertexpointer_arbitrarymeshvertex(m_vertices.data()), - IndexPointer(m_indices.data(), IndexPointer::index_type(m_indices.size())), - best - ); - if (best.valid()) { - selector.addIntersection(best); - } -} -}; - -// generic model node -class Model : - public Cullable, - public Bounded { -typedef std::vector surfaces_t; -surfaces_t m_surfaces; - -AABB m_aabb_local; -public: -Callback m_lightsChanged; - -~Model() -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - delete *i; - } -} - -typedef surfaces_t::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_surfaces.begin(); -} - -const_iterator end() const -{ - return m_surfaces.end(); -} - -std::size_t size() const -{ - return m_surfaces.size(); -} - -Surface &newSurface() -{ - m_surfaces.push_back(new Surface); - return *m_surfaces.back(); -} - -void updateAABB() -{ - m_aabb_local = AABB(); - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - aabb_extend_by_aabb_safe(m_aabb_local, (*i)->localAABB()); - } -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -virtual const AABB &localAABB() const -{ - return m_aabb_local; -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(test.getVolume(), localToWorld) != c_volumeOutside) { - (*i)->testSelect(selector, test, localToWorld); - } - } -} -}; - -inline void Surface_addLight(const Surface &surface, VectorLightList &lights, const Matrix4 &localToWorld, - const RendererLight &light) -{ - if (light.testAABB(aabb_for_oriented_aabb(surface.localAABB(), localToWorld))) { - lights.addLight(light); - } -} - -class ModelInstance : - public scene::Instance, - public Renderable, - public SelectionTestable, - public LightCullable, - public SkinnedModel { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Model &m_model; - -const LightList *m_lightList; -typedef Array SurfaceLightLists; -SurfaceLightLists m_surfaceLightLists; - -class Remap { -public: -CopiedString first; -Shader *second; - -Remap() : second(0) -{ -} -}; - -typedef Array SurfaceRemaps; -SurfaceRemaps m_skins; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_model; -} - -Cullable &get(NullType) -{ - return m_model; -} - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -void constructRemaps() -{ - ModelSkin *skin = NodeTypeCast::cast(path().parent()); - if (skin != 0 && skin->realised()) { - SurfaceRemaps::iterator j = m_skins.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i, ++j) { - const char *remap = skin->getRemap((*i)->getShader()); - if (!string_empty(remap)) { - (*j).first = remap; - (*j).second = GlobalShaderCache().capture(remap); - } else { - (*j).second = 0; - } - } - SceneChangeNotify(); - } -} - -void destroyRemaps() -{ - for (SurfaceRemaps::iterator i = m_skins.begin(); i != m_skins.end(); ++i) { - if ((*i).second != 0) { - GlobalShaderCache().release((*i).first.c_str()); - (*i).second = 0; - } - } -} - -void skinChanged() -{ - ASSERT_MESSAGE(m_skins.size() == m_model.size(), "ERROR"); - destroyRemaps(); - constructRemaps(); -} - -ModelInstance(const scene::Path &path, scene::Instance *parent, Model &model) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_model(model), - m_surfaceLightLists(m_model.size()), - m_skins(m_model.size()) -{ - m_lightList = &GlobalShaderCache().attach(*this); - m_model.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); - - constructRemaps(); -} - -~ModelInstance() -{ - destroyRemaps(); - - Instance::setTransformChangedCallback(Callback()); - - m_model.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - SurfaceLightLists::const_iterator j = m_surfaceLightLists.begin(); - SurfaceRemaps::const_iterator k = m_skins.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i, ++j, ++k) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - renderer.setLights(*j); - (*i)->render(renderer, localToWorld, (*k).second != 0 ? (*k).second : (*i)->getState()); - } - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_lightList->evaluateLights(); - - render(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_model.testSelect(selector, test, Instance::localToWorld()); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - SurfaceLightLists::iterator j = m_surfaceLightLists.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i) { - Surface_addLight(*(*i), *j++, localToWorld, light); - } -} - -void clearLights() -{ - for (SurfaceLightLists::iterator i = m_surfaceLightLists.begin(); i != m_surfaceLightLists.end(); ++i) { - (*i).clear(); - } -} -}; - -class ModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Model m_model; -public: - -typedef LazyStatic StaticTypeCasts; - -ModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -Model &model() -{ - return m_model; -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new ModelInstance(path, parent, m_model); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -inline void -Surface_constructQuad(Surface &surface, const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, - const Vector3 &normal) -{ - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(a), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topleft) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(b), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topright) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(c), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botright) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(d), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botleft) - ) - ); -} - -inline void Model_constructNull(Model &model) -{ - Surface &surface = model.newSurface(); - - AABB aabb(Vector3(0, 0, 0), Vector3(8, 8, 8)); - - Vector3 points[8]; - aabb_corners(aabb, points); - - surface.vertices().reserve(24); - - Surface_constructQuad(surface, points[2], points[1], points[5], points[6], aabb_normals[0]); - Surface_constructQuad(surface, points[1], points[0], points[4], points[5], aabb_normals[1]); - Surface_constructQuad(surface, points[0], points[1], points[2], points[3], aabb_normals[2]); - Surface_constructQuad(surface, points[0], points[3], points[7], points[4], aabb_normals[3]); - Surface_constructQuad(surface, points[3], points[2], points[6], points[7], aabb_normals[4]); - Surface_constructQuad(surface, points[7], points[6], points[5], points[4], aabb_normals[5]); - - surface.indices().reserve(36); - - RenderIndex indices[36] = { - 0, 1, 2, 0, 2, 3, - 4, 5, 6, 4, 6, 7, - 8, 9, 10, 8, 10, 11, - 12, 13, 14, 12, 14, 15, - 16, 17, 18, 16, 18, 19, - 20, 21, 22, 10, 22, 23, - }; - - for (RenderIndex *i = indices; i != indices + (sizeof(indices) / sizeof(RenderIndex)); ++i) { - surface.indices().insert(*i); - } - - surface.setShader(""); - - surface.updateAABB(); - - model.updateAABB(); -} - -#endif diff --git a/plugins/model/Makefile b/plugins/model/Makefile deleted file mode 100644 index bae6d1b..0000000 --- a/plugins/model/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - model.o plugin.o - -# binary target -../../build/plugins/libmodel.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libpicomodel.a $(PLUGIN_LDFLAGS) - -# object files -model.o: model.cpp model.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libmodel.$(LIB_EXT) \ No newline at end of file diff --git a/plugins/model/bitmaps/model_reload_entity.bmp b/plugins/model/bitmaps/model_reload_entity.bmp deleted file mode 100644 index 800a0dfe79835b00f9c6a0c27240ca23c87825cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308 zcmZvWK@NZ*3O3Zt3U_lI9h=RDiQ`>&?YKZyP7PGNLqrQ_W HYM!J5T+jt+ diff --git a/plugins/model/bitmaps/picomodel.bmp b/plugins/model/bitmaps/picomodel.bmp deleted file mode 100644 index 0d9c88e071f2d3e0f046fbee0350fb611c745119..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192660 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
2Af9YDRoPX5d44{qku}iphSy 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%0Df$FSswf%4 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

({RX16-Zk;7E4z5eH!R-~8q``QpF)%fGO} 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 diff --git a/plugins/model/model.cpp b/plugins/model/model.cpp deleted file mode 100644 index 036c508..0000000 --- a/plugins/model/model.cpp +++ /dev/null @@ -1,1025 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "model.h" -#include "globaldefs.h" - -#include "picomodel.h" - -#include "iarchive.h" -#include "idatastream.h" -#include "imodel.h" -#include "modelskin.h" - -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" - -#include "math/frustum.h" -#include "string/string.h" -#include "generic/static.h" -#include "shaderlib.h" -#include "scenelib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "render.h" - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -class PicoSurface : - public OpenGLRenderable { -AABB m_aabb_local; -CopiedString m_shader; -Shader *m_state; - -Array m_vertices; -Array m_indices; - -public: - -PicoSurface() -{ - constructNull(); - CaptureShader(); -} - -PicoSurface(picoSurface_t *surface) -{ - CopyPicoSurface(surface); - CaptureShader(); -} - -~PicoSurface() -{ - ReleaseShader(); -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_BUMP) != 0) { - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } - } else { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - } - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->vertex); - glDrawElements(GL_TRIANGLES, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data()); - -#if 0 - GLfloat modelview[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, modelview); // I know this is slow as hell, but hey - we're in _DEBUG - Matrix4 modelview_inv( - modelview[0], modelview[1], modelview[2], modelview[3], - modelview[4], modelview[5], modelview[6], modelview[7], - modelview[8], modelview[9], modelview[10], modelview[11], - modelview[12], modelview[13], modelview[14], modelview[15]); - matrix4_full_invert(modelview_inv); - Matrix4 modelview_inv_transposed = matrix4_transposed(modelview_inv); - - glBegin(GL_LINES); - - for (Array::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - Vector3 normal = normal3f_to_vector3((*i).normal); - normal = matrix4_transformed_direction(modelview_inv, vector3_normalised( - matrix4_transformed_direction(modelview_inv_transposed, normal))); // do some magic - Vector3 normalTransformed = vector3_added(vertex3f_to_vector3((*i).vertex), vector3_scaled(normal, 8)); - glVertex3fv(vertex3f_to_array((*i).vertex)); - glVertex3fv(vector3_to_array(normalTransformed)); - } - glEnd(); -#endif -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const Matrix4 &localToWorld, Shader *state) const -{ - renderer.SetState(state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - render(renderer, localToWorld, m_state); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - testSelect(test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -Shader *getState() const -{ - return m_state; -} - -private: - -void CaptureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void ReleaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -void UpdateAABB() -{ - m_aabb_local = AABB(); - for (std::size_t i = 0; i < m_vertices.size(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, reinterpret_cast( m_vertices[i].vertex )); - } - - - for (Array::iterator i = m_indices.begin(); i != m_indices.end(); i += 3) { - ArbitraryMeshVertex &a = m_vertices[*(i + 0)]; - ArbitraryMeshVertex &b = m_vertices[*(i + 1)]; - ArbitraryMeshVertex &c = m_vertices[*(i + 2)]; - - ArbitraryMeshTriangle_sumTangents(a, b, c); - } - - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - vector3_normalise(reinterpret_cast((*i).tangent )); - vector3_normalise(reinterpret_cast((*i).bitangent )); - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestTriangles( - VertexPointer(VertexPointer::pointer(&m_vertices.data()->vertex), sizeof(ArbitraryMeshVertex)), - IndexPointer(m_indices.data(), IndexPointer::index_type(m_indices.size())), - best - ); -} - -void CopyPicoSurface(picoSurface_t *surface) -{ - picoShader_t *shader = PicoGetSurfaceShader(surface); - if (shader == 0) { - m_shader = ""; - } else { - m_shader = PicoGetShaderName(shader); - } - - m_vertices.resize(PicoGetSurfaceNumVertexes(surface)); - m_indices.resize(PicoGetSurfaceNumIndexes(surface)); - - for (std::size_t i = 0; i < m_vertices.size(); ++i) { - picoVec_t *xyz = PicoGetSurfaceXYZ(surface, int(i)); - m_vertices[i].vertex = vertex3f_from_array(xyz); - - picoVec_t *normal = PicoGetSurfaceNormal(surface, int(i)); - m_vertices[i].normal = normal3f_from_array(normal); - - picoVec_t *st = PicoGetSurfaceST(surface, 0, int(i)); - m_vertices[i].texcoord = TexCoord2f(st[0], st[1]); - -#if 0 - picoVec_t* color = PicoGetSurfaceColor( surface, 0, int(i) ); - m_vertices[i].colour = Colour4b( color[0], color[1], color[2], color[3] ); -#endif - } - - picoIndex_t *indexes = PicoGetSurfaceIndexes(surface, 0); - for (std::size_t j = 0; j < m_indices.size(); ++j) { - m_indices[j] = indexes[j]; - } - - UpdateAABB(); -} - -void constructQuad(std::size_t index, const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, - const Vector3 &normal) -{ - m_vertices[index * 4 + 0] = ArbitraryMeshVertex( - vertex3f_for_vector3(a), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topleft) - ); - m_vertices[index * 4 + 1] = ArbitraryMeshVertex( - vertex3f_for_vector3(b), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topright) - ); - m_vertices[index * 4 + 2] = ArbitraryMeshVertex( - vertex3f_for_vector3(c), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botright) - ); - m_vertices[index * 4 + 3] = ArbitraryMeshVertex( - vertex3f_for_vector3(d), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botleft) - ); -} - -void constructNull() -{ - AABB aabb(Vector3(0, 0, 0), Vector3(8, 8, 8)); - - Vector3 points[8]; - aabb_corners(aabb, points); - - m_vertices.resize(24); - - constructQuad(0, points[2], points[1], points[5], points[6], aabb_normals[0]); - constructQuad(1, points[1], points[0], points[4], points[5], aabb_normals[1]); - constructQuad(2, points[0], points[1], points[2], points[3], aabb_normals[2]); - constructQuad(3, points[0], points[3], points[7], points[4], aabb_normals[3]); - constructQuad(4, points[3], points[2], points[6], points[7], aabb_normals[4]); - constructQuad(5, points[7], points[6], points[5], points[4], aabb_normals[5]); - - m_indices.resize(36); - - RenderIndex indices[36] = { - 0, 1, 2, 0, 2, 3, - 4, 5, 6, 4, 6, 7, - 8, 9, 10, 8, 10, 11, - 12, 13, 14, 12, 14, 15, - 16, 17, 18, 16, 18, 19, - 20, 21, 22, 10, 22, 23, - }; - - - Array::iterator j = m_indices.begin(); - for (RenderIndex *i = indices; i != indices + (sizeof(indices) / sizeof(RenderIndex)); ++i) { - *j++ = *i; - } - - m_shader = ""; - - UpdateAABB(); -} -}; - - -typedef std::pair PicoModelKey; - - -class PicoModel : - public Cullable, - public Bounded { -typedef std::vector surfaces_t; -surfaces_t m_surfaces; - -AABB m_aabb_local; -public: -Callback m_lightsChanged; - -PicoModel() -{ - constructNull(); -} - -PicoModel(picoModel_t *model) -{ - CopyPicoModel(model); -} - -~PicoModel() -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - delete *i; - } -} - -typedef surfaces_t::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_surfaces.begin(); -} - -const_iterator end() const -{ - return m_surfaces.end(); -} - -std::size_t size() const -{ - return m_surfaces.size(); -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -virtual const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, - std::vector states) const -{ - for (surfaces_t::const_iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - (*i)->render(renderer, localToWorld, states[i - m_surfaces.begin()]); - } - } -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(test.getVolume(), localToWorld) != c_volumeOutside) { - (*i)->testSelect(selector, test, localToWorld); - } - } -} - -private: -void CopyPicoModel(picoModel_t *model) -{ - m_aabb_local = AABB(); - - /* each surface on the model will become a new map drawsurface */ - int numSurfaces = PicoGetModelNumSurfaces(model); - //% SYs_FPrintf( SYS_VRB, "Model %s has %d surfaces\n", name, numSurfaces ); - for (int s = 0; s < numSurfaces; ++s) { - /* get surface */ - picoSurface_t *surface = PicoGetModelSurface(model, s); - if (surface == 0) { - continue; - } - - /* only handle triangle surfaces initially (fixme: support patches) */ - if (PicoGetSurfaceType(surface) != PICO_TRIANGLES) { - continue; - } - - /* fix the surface's normals */ - PicoFixSurfaceNormals(surface); - - PicoSurface *picosurface = new PicoSurface(surface); - aabb_extend_by_aabb_safe(m_aabb_local, picosurface->localAABB()); - m_surfaces.push_back(picosurface); - } -} - -void constructNull() -{ - PicoSurface *picosurface = new PicoSurface(); - m_aabb_local = picosurface->localAABB(); - m_surfaces.push_back(picosurface); -} -}; - -inline void -Surface_addLight(PicoSurface &surface, VectorLightList &lights, const Matrix4 &localToWorld, const RendererLight &light) -{ - if (light.testAABB(aabb_for_oriented_aabb(surface.localAABB(), localToWorld))) { - lights.addLight(light); - } -} - -class PicoModelInstance : - public scene::Instance, - public Renderable, - public SelectionTestable, - public LightCullable, - public SkinnedModel { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PicoModel &m_picomodel; - -const LightList *m_lightList; -typedef Array SurfaceLightLists; -SurfaceLightLists m_surfaceLightLists; - -class Remap { -public: -CopiedString first; -Shader *second; - -Remap() : second(0) -{ -} -}; - -typedef Array SurfaceRemaps; -SurfaceRemaps m_skins; - -PicoModelInstance(const PicoModelInstance &); - -PicoModelInstance operator=(const PicoModelInstance &); - -public: -typedef LazyStatic StaticTypeCasts; - -void *m_test; - -Bounded &get(NullType) -{ - return m_picomodel; -} - -Cullable &get(NullType) -{ - return m_picomodel; -} - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -void constructRemaps() -{ - ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR"); - ModelSkin *skin = NodeTypeCast::cast(path().parent()); - if (skin != 0 && skin->realised()) { - SurfaceRemaps::iterator j = m_skins.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j) { - const char *remap = skin->getRemap((*i)->getShader()); - if (!string_empty(remap)) { - (*j).first = remap; - (*j).second = GlobalShaderCache().capture(remap); - } else { - (*j).second = 0; - } - } - SceneChangeNotify(); - } -} - -void destroyRemaps() -{ - ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR"); - for (SurfaceRemaps::iterator i = m_skins.begin(); i != m_skins.end(); ++i) { - if ((*i).second != 0) { - GlobalShaderCache().release((*i).first.c_str()); - (*i).second = 0; - } - } -} - -void skinChanged() -{ - destroyRemaps(); - constructRemaps(); -} - -PicoModelInstance(const scene::Path &path, scene::Instance *parent, PicoModel &picomodel) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_picomodel(picomodel), - m_surfaceLightLists(m_picomodel.size()), - m_skins(m_picomodel.size()) -{ - m_lightList = &GlobalShaderCache().attach(*this); - m_picomodel.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); - - constructRemaps(); -} - -~PicoModelInstance() -{ - destroyRemaps(); - - Instance::setTransformChangedCallback(Callback()); - - m_picomodel.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - SurfaceLightLists::const_iterator j = m_surfaceLightLists.begin(); - SurfaceRemaps::const_iterator k = m_skins.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j, ++k) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - renderer.setLights(*j); - (*i)->render(renderer, localToWorld, (*k).second != 0 ? (*k).second : (*i)->getState()); - } - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_lightList->evaluateLights(); - - render(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_picomodel.testSelect(selector, test, Instance::localToWorld()); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - SurfaceLightLists::iterator j = m_surfaceLightLists.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i) { - Surface_addLight(*(*i), *j++, localToWorld, light); - } -} - -void clearLights() -{ - for (SurfaceLightLists::iterator i = m_surfaceLightLists.begin(); i != m_surfaceLightLists.end(); ++i) { - (*i).clear(); - } -} -}; - -class PicoModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PicoModel m_picomodel; - -public: -typedef LazyStatic StaticTypeCasts; - -PicoModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -PicoModelNode(picoModel_t *model) : m_node(this, this, StaticTypeCasts::instance().get()), m_picomodel(model) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PicoModelInstance(path, parent, m_picomodel); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -#if 0 - -template -class create_new -{ -public: -static Type* construct( const Key& key ){ - return new Type( key ); -} -static void destroy( Type* value ){ - delete value; -} -}; - -template > -class cache_element : public creation_policy -{ -public: -inline cache_element() : m_count( 0 ), m_value( 0 ) { -} -inline ~cache_element(){ - ASSERT_MESSAGE( m_count == 0, "destroyed a reference before it was released\n" ); - if ( m_count > 0 ) { - destroy(); - } -} -inline Type* capture( const Key& key ){ - if ( ++m_count == 1 ) { - construct( key ); - } - return m_value; -} -inline void release(){ - ASSERT_MESSAGE( !empty(), "failed to release reference - not found in cache\n" ); - if ( --m_count == 0 ) { - destroy(); - } -} -inline bool empty(){ - return m_count == 0; -} -inline void refresh( const Key& key ){ - m_value->refresh( key ); -} -private: -inline void construct( const Key& key ){ - m_value = creation_policy::construct( key ); -} -inline void destroy(){ - creation_policy::destroy( m_value ); -} - -std::size_t m_count; -Type* m_value; -}; - -class create_picomodel -{ -typedef PicoModelKey key_type; -typedef PicoModel value_type; -public: -static value_type* construct( const key_type& key ){ - picoModel_t* picomodel = PicoLoadModel( const_cast( key.first.c_str() ), key.second ); - value_type* value = new value_type( picomodel ); - PicoFreeModel( picomodel ); - return value; -} -static void destroy( value_type* value ){ - delete value; -} -}; - -#include - -class ModelCache -{ -typedef PicoModel value_type; - -public: -typedef PicoModelKey key_type; -typedef cache_element elem_type; -typedef std::map cache_type; - -value_type* capture( const key_type& key ){ - return m_cache[key].capture( key ); -} -void release( const key_type& key ){ - m_cache[key].release(); -} - -private: -cache_type m_cache; -}; - -ModelCache g_model_cache; - - - -typedef struct remap_s { - char m_remapbuff[64 + 1024]; - char *original; - char *remap; -} remap_t; - -class RemapWrapper : - public Cullable, - public Bounded -{ -public: -RemapWrapper( const char* name ){ - parse_namestr( name ); - - m_model = g_model_cache.capture( ModelCache::key_type( m_name, m_frame ) ); - - construct_shaders(); -} -virtual ~RemapWrapper(){ - g_model_cache.release( ModelCache::key_type( m_name, m_frame ) ); - - for ( shaders_t::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i ) - { - GlobalShaderCache().release( ( *i ).c_str() ); - } - - for ( remaps_t::iterator j = m_remaps.begin(); j != m_remaps.end(); ++j ) - { - delete ( *j ); - } -} - -VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const { - return m_model->intersectVolume( test, localToWorld ); -} - -virtual const AABB& localAABB() const { - return m_model->localAABB(); -} - -void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { - m_model->render( renderer, volume, localToWorld, m_states ); -} - -void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){ - m_model->testSelect( selector, test, localToWorld ); -} - -private: -void add_remap( const char *remap ){ - const char *ch; - remap_t *pRemap; - - ch = remap; - - while ( *ch && *ch != ';' ) - ch++; - - if ( *ch == '\0' ) { - // bad remap - globalErrorStream() << "WARNING: Shader _remap key found in a model entity without a ; character\n"; - } - else { - pRemap = new remap_t; - - strncpy( pRemap->m_remapbuff, remap, sizeof( pRemap->m_remapbuff ) ); - - pRemap->m_remapbuff[ch - remap] = '\0'; - - pRemap->original = pRemap->m_remapbuff; - pRemap->remap = pRemap->m_remapbuff + ( ch - remap ) + 1; - - m_remaps.push_back( pRemap ); - } -} - -void parse_namestr( const char *name ){ - const char *ptr, *s; - bool hasName, hasFrame; - - hasName = hasFrame = false; - - m_frame = 0; - - for ( s = ptr = name; ; ++ptr ) - { - if ( !hasName && ( *ptr == ':' || *ptr == '\0' ) ) { - // model name - hasName = true; - m_name = CopiedString( s, ptr ); - s = ptr + 1; - } - else if ( *ptr == '?' || *ptr == '\0' ) { - // model frame - hasFrame = true; - m_frame = atoi( CopiedString( s, ptr ).c_str() ); - s = ptr + 1; - } - else if ( *ptr == '&' || *ptr == '\0' ) { - // a remap - add_remap( CopiedString( s, ptr ).c_str() ); - s = ptr + 1; - } - - if ( *ptr == '\0' ) { - break; - } - } -} - -void construct_shaders(){ - const char* global_shader = shader_for_remap( "*" ); - - m_shaders.reserve( m_model->size() ); - m_states.reserve( m_model->size() ); - for ( PicoModel::iterator i = m_model->begin(); i != m_model->end(); ++i ) - { - const char* shader = shader_for_remap( ( *i )->getShader() ); - m_shaders.push_back( - ( shader[0] != '\0' ) - ? shader - : ( global_shader[0] != '\0' ) - ? global_shader - : ( *i )->getShader() ); - m_states.push_back( GlobalShaderCache().capture( m_shaders.back().c_str() ) ); - } -} - -inline const char* shader_for_remap( const char* remap ){ - for ( remaps_t::iterator i = m_remaps.begin(); i != m_remaps.end(); ++i ) - { - if ( shader_equal( remap, ( *i )->original ) ) { - return ( *i )->remap; - } - } - return ""; -} - -CopiedString m_name; -int m_frame; -PicoModel* m_model; - -typedef std::vector remaps_t; -remaps_t m_remaps; -typedef std::vector shaders_t; -shaders_t m_shaders; -typedef std::vector states_t; -states_t m_states; -}; - -class RemapWrapperInstance : public scene::Instance, public Renderable, public SelectionTestable -{ -RemapWrapper& m_remapwrapper; -public: -RemapWrapperInstance( const scene::Path& path, scene::Instance* parent, RemapWrapper& remapwrapper ) : Instance( path, parent ), m_remapwrapper( remapwrapper ){ - scene::Instance::m_cullable = &m_remapwrapper; - scene::Instance::m_render = this; - scene::Instance::m_select = this; -} - -void renderSolid( Renderer& renderer, const VolumeTest& volume ) const { - m_remapwrapper.render( renderer, volume, Instance::localToWorld() ); -} -void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const { - renderSolid( renderer, volume ); -} - -void testSelect( Selector& selector, SelectionTest& test ){ - m_remapwrapper.testSelect( selector, test, Instance::localToWorld() ); -} -}; - -class RemapWrapperNode : public scene::Node::Symbiot, public scene::Instantiable -{ -scene::Node m_node; -typedef RemapWrapperInstance instance_type; -InstanceSet m_instances; -RemapWrapper m_remapwrapper; -public: -RemapWrapperNode( const char* name ) : m_node( this ), m_remapwrapper( name ){ - m_node.m_instance = this; -} - -void release(){ - delete this; -} -scene::Node& node(){ - return m_node; -} - -scene::Instance* create( const scene::Path& path, scene::Instance* parent ){ - return new instance_type( path, parent, m_remapwrapper ); -} -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - m_instances.forEachInstance( visitor ); -} -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - m_instances.insert( observer, path, instance ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - return m_instances.erase( observer, path ); -} -}; - -scene::Node& LoadRemapModel( const char* name ){ - return ( new RemapWrapperNode( name ) )->node(); -} - -#endif - - -size_t picoInputStreamReam(void *inputStream, unsigned char *buffer, size_t length) -{ - return reinterpret_cast( inputStream )->read(buffer, length); -} - -scene::Node &loadPicoModel(const picoModule_t *module, ArchiveFile &file) -{ - picoModel_t *model = PicoModuleLoadModelStream(module, &file.getInputStream(), picoInputStreamReam, file.size(), 0, - file.getName()); - PicoModelNode *modelNode = new PicoModelNode(model); - PicoFreeModel(model); - return modelNode->node(); -} diff --git a/plugins/model/model.h b/plugins/model/model.h deleted file mode 100644 index b0145f5..0000000 --- a/plugins/model/model.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -namespace scene { class Node; } -class ArchiveFile; - -typedef struct picoModule_s picoModule_t; - -scene::Node &loadPicoModel(const picoModule_t *module, ArchiveFile &file); - -#endif diff --git a/plugins/model/plugin.cpp b/plugins/model/plugin.cpp deleted file mode 100644 index df619d0..0000000 --- a/plugins/model/plugin.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "picomodel.h" - -typedef unsigned char byte; - -#include -#include -#include - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iimage.h" -#include "imodel.h" -#include "igl.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "ifiletypes.h" - -#include "modulesystem/singletonmodule.h" -#include "stream/textstream.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "typesystem.h" - -#include "model.h" - -void PicoPrintFunc(int level, const char *str) -{ - if (str == 0) { - return; - } - switch (level) { - case PICO_NORMAL: - globalOutputStream() << str << "\n"; - break; - - case PICO_VERBOSE: - //globalOutputStream() << "PICO_VERBOSE: " << str << "\n"; - break; - - case PICO_WARNING: - globalErrorStream() << "PICO_WARNING: " << str << "\n"; - break; - - case PICO_ERROR: - globalErrorStream() << "PICO_ERROR: " << str << "\n"; - break; - - case PICO_FATAL: - globalErrorStream() << "PICO_FATAL: " << str << "\n"; - break; - } -} - -void PicoLoadFileFunc(const char *name, byte **buffer, int *bufSize) -{ - *bufSize = vfsLoadFile(name, (void **) buffer); -} - -void PicoFreeFileFunc(void *file) -{ - vfsFreeFile(file); -} - -void pico_initialise() -{ - PicoInit(); - PicoSetMallocFunc(malloc); - PicoSetFreeFunc(free); - PicoSetPrintFunc(PicoPrintFunc); - PicoSetLoadFileFunc(PicoLoadFileFunc); - PicoSetFreeFileFunc(PicoFreeFileFunc); -} - - -class PicoModelLoader : public ModelLoader { -const picoModule_t *m_module; -public: -PicoModelLoader(const picoModule_t *module) : m_module(module) -{ -} - -scene::Node &loadModel(ArchiveFile &file) -{ - return loadPicoModel(m_module, file); -} -}; - -class ModelPicoDependencies : - public GlobalFileSystemModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalFiletypesModuleRef { -}; - -class ModelPicoAPI : public TypeSystemRef { -PicoModelLoader m_modelLoader; -public: -typedef ModelLoader Type; - -ModelPicoAPI(const char *extension, const picoModule_t *module) : - m_modelLoader(module) -{ - StringOutputStream filter(128); - filter << "*." << extension; - GlobalFiletypesModule::getTable().addType(Type::Name(), extension, - filetype_t(module->displayName, filter.c_str())); -} - -ModelLoader *getTable() -{ - return &m_modelLoader; -} -}; - -class PicoModelAPIConstructor { -CopiedString m_extension; -const picoModule_t *m_module; -public: -PicoModelAPIConstructor(const char *extension, const picoModule_t *module) : - m_extension(extension), m_module(module) -{ -} - -const char *getName() -{ - return m_extension.c_str(); -} - -ModelPicoAPI *constructAPI(ModelPicoDependencies &dependencies) -{ - return new ModelPicoAPI(m_extension.c_str(), m_module); -} - -void destroyAPI(ModelPicoAPI *api) -{ - delete api; -} -}; - - -typedef SingletonModule PicoModelModule; -typedef std::list PicoModelModules; -PicoModelModules g_PicoModelModules; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - pico_initialise(); - - const picoModule_t **modules = PicoModuleList(0); - while (*modules != 0) { - const picoModule_t *module = *modules++; - if (module->canload && module->load) { - for (char *const *ext = module->defaultExts; *ext != 0; ++ext) { - g_PicoModelModules.push_back(PicoModelModule(PicoModelAPIConstructor(*ext, module))); - g_PicoModelModules.back().selfRegister(); - } - } - } -} diff --git a/plugins/prtview/AboutDialog.cpp b/plugins/prtview/AboutDialog.cpp deleted file mode 100644 index ef37d98..0000000 --- a/plugins/prtview/AboutDialog.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "AboutDialog.h" -#include -#include -#include -#include "gtkutil/pointer.h" - -#include "prtview.h" -#include "ConfigDialog.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -void DoAboutDlg() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "About Portal Viewer"); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto hbox = ui::HBox(FALSE, 10); - hbox.show(); - dlg.add(hbox); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); - - char const *label_text = "Version 1.000\n\n" - "Gtk port by Leonardo Zide\nleo@lokigames.com\n\n" - "Written by Geoffrey DeWan\ngdewan@prairienet.org\n\n" - "Built against WorldSpawn\n" - __DATE__; - auto label = ui::Label(label_text); - label.show(); - hbox.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); - - auto vbox = ui::VBox(FALSE, 0); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - auto button = ui::Button("OK"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - gtk_grab_remove(dlg); - dlg.destroy(); -} - - -///////////////////////////////////////////////////////////////////////////// -// CAboutDialog message handlers diff --git a/plugins/prtview/AboutDialog.h b/plugins/prtview/AboutDialog.h deleted file mode 100644 index b46fa93..0000000 --- a/plugins/prtview/AboutDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_ABOUTDIALOG_H ) -#define INCLUDED_ABOUTDIALOG_H - -void DoAboutDlg(); - -#endif diff --git a/plugins/prtview/ConfigDialog.cpp b/plugins/prtview/ConfigDialog.cpp deleted file mode 100644 index 73b2ce8..0000000 --- a/plugins/prtview/ConfigDialog.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ConfigDialog.h" -#include -#include -#include -#include "gtkutil/pointer.h" - -#include "iscenegraph.h" - -#include "prtview.h" -#include "portals.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -// ============================================================================= -// Color selection dialog - -static int DoColor(PackedColour *c) -{ - GdkColor clr; - int loop = 1, ret = IDCANCEL; - - clr.red = (guint16) (GetRValue(*c) * (65535 / 255)); - clr.blue = (guint16) (GetGValue(*c) * (65535 / 255)); - clr.green = (guint16) (GetBValue(*c) * (65535 / 255)); - - auto dlg = ui::Widget::from(gtk_color_selection_dialog_new("Choose Color")); - gtk_color_selection_set_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL); - - GtkWidget *ok_button, *cancel_button; - g_object_get(dlg, "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr); - - ui::Widget::from(ok_button).connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - ui::Widget::from(cancel_button).connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDCANCEL)); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - dlg.show(); - gtk_grab_add(dlg); - - while (loop) { - gtk_main_iteration(); - } - - gtk_color_selection_get_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - - gtk_grab_remove(dlg); - dlg.destroy(); - - if (ret == IDOK) { - *c = RGB(clr.red / (65535 / 255), clr.green / (65535 / 255), clr.blue / (65535 / 255)); - } - - return ret; -} - -static void Set2DText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Line Width = %6.3f", portals.width_2d * 0.5f); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void Set3DText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Line Width = %6.3f", portals.width_3d * 0.5f); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void Set3DTransText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Polygon transparency = %d%%", (int) portals.trans_3d); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void SetClipText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Cubic clip range = %d", (int) portals.clip_range * 64); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void OnScroll2d(ui::Adjustment adj, gpointer data) -{ - portals.width_2d = static_cast( gtk_adjustment_get_value(adj)); - Set2DText(ui::Widget::from(data)); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnScroll3d(ui::Adjustment adj, gpointer data) -{ - portals.width_3d = static_cast( gtk_adjustment_get_value(adj)); - Set3DText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnScrollTrans(ui::Adjustment adj, gpointer data) -{ - portals.trans_3d = static_cast( gtk_adjustment_get_value(adj)); - Set3DTransText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnScrollClip(ui::Adjustment adj, gpointer data) -{ - portals.clip_range = static_cast( gtk_adjustment_get_value(adj)); - SetClipText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnAntiAlias2d(ui::Widget widget, gpointer data) -{ - portals.aa_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - - SceneChangeNotify(); -} - -static void OnConfig2d(ui::Widget widget, gpointer data) -{ - portals.show_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - -static void OnColor2d(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_2d) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnConfig3d(ui::Widget widget, gpointer data) -{ - portals.show_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - - -static void OnAntiAlias3d(ui::Widget widget, gpointer data) -{ - portals.aa_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnColor3d(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_3d) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnColorFog(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_fog) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnFog(ui::Widget widget, gpointer data) -{ - portals.fog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnSelchangeZbuffer(ui::Widget widget, gpointer data) -{ - portals.zbuffer = gpointer_to_int(data); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnPoly(ui::Widget widget, gpointer data) -{ - portals.polygons = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - SceneChangeNotify(); -} - -static void OnLines(ui::Widget widget, gpointer data) -{ - portals.lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - SceneChangeNotify(); -} - -static void OnClip(ui::Widget widget, gpointer data) -{ - portals.clip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - -void DoConfigDialog() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "Portal Viewer Configuration"); - dlg.connect("delete_event", - G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", - G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto frame = ui::Frame("3D View"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - - auto vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, TRUE, 0); - - auto adj = ui::Adjustment(portals.width_3d, 2, 40, 1, 1, 0); - auto lw3slider = ui::HScale(adj); - lw3slider.show(); - hbox.pack_start(lw3slider, TRUE, TRUE, 0); - gtk_scale_set_draw_value(GTK_SCALE(lw3slider), FALSE); - - auto lw3label = ui::Label(""); - lw3label.show(); - hbox.pack_start(lw3label, FALSE, TRUE, 0); - adj.connect("value_changed", G_CALLBACK(OnScroll3d), lw3label); - - auto table = ui::Table(2, 4, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - auto button = ui::Button("Color"); - button.show(); - table.attach(button, {0, 1, 0, 1}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnColor3d), NULL); - - button = ui::Button("Depth Color"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnColorFog), NULL); - - auto aa3check = ui::CheckButton("Anti-Alias (May not work on some video cards)"); - aa3check.show(); - table.attach(aa3check, {1, 4, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - aa3check.connect("toggled", G_CALLBACK(OnAntiAlias3d), NULL); - - auto depthcheck = ui::CheckButton("Depth Cue"); - depthcheck.show(); - table.attach(depthcheck, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - depthcheck.connect("toggled", G_CALLBACK(OnFog), NULL); - - auto linescheck = ui::CheckButton("Lines"); - linescheck.show(); - table.attach(linescheck, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - linescheck.connect("toggled", G_CALLBACK(OnLines), NULL); - - auto polyscheck = ui::CheckButton("Polygons"); - polyscheck.show(); - table.attach(polyscheck, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - polyscheck.connect("toggled", G_CALLBACK(OnPoly), NULL); - - auto zlist = ui::ComboBoxText(ui::New); - zlist.show(); - vbox2.pack_start(zlist, TRUE, FALSE, 0); - - gtk_combo_box_text_append_text(zlist, "Z-Buffer Test and Write (recommended for solid or no polygons)"); - gtk_combo_box_text_append_text(zlist, "Z-Buffer Test Only (recommended for transparent polygons)"); - gtk_combo_box_text_append_text(zlist, "Z-Buffer Off"); - - zlist.connect("changed", G_CALLBACK(+[] (ui::ComboBox self, void *) { - OnSelchangeZbuffer(self, GINT_TO_POINTER(gtk_combo_box_get_active(self))); - }), nullptr); - - table = ui::Table(2, 2, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - adj = ui::Adjustment(portals.trans_3d, 0, 100, 1, 1, 0); - auto transslider = ui::HScale(adj); - transslider.show(); - table.attach(transslider, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_scale_set_draw_value(GTK_SCALE(transslider), FALSE); - - auto translabel = ui::Label(""); - translabel.show(); - table.attach(translabel, {1, 2, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(translabel), 0.0, 0.0); - adj.connect("value_changed", G_CALLBACK(OnScrollTrans), translabel); - - adj = ui::Adjustment(portals.clip_range, 1, 128, 1, 1, 0); - auto clipslider = ui::HScale(adj); - clipslider.show(); - table.attach(clipslider, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_scale_set_draw_value(GTK_SCALE(clipslider), FALSE); - - auto cliplabel = ui::Label(""); - cliplabel.show(); - table.attach(cliplabel, {1, 2, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(cliplabel), 0.0, 0.0); - adj.connect("value_changed", G_CALLBACK(OnScrollClip), cliplabel); - - hbox = ui::HBox(TRUE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - auto show3check = ui::CheckButton("Show"); - show3check.show(); - hbox.pack_start(show3check, TRUE, TRUE, 0); - show3check.connect("toggled", G_CALLBACK(OnConfig3d), NULL); - - auto portalcheck = ui::CheckButton("Portal cubic clipper"); - portalcheck.show(); - hbox.pack_start(portalcheck, TRUE, TRUE, 0); - portalcheck.connect("toggled", G_CALLBACK(OnClip), NULL); - - frame = ui::Frame("2D View"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - - vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - adj = ui::Adjustment(portals.width_2d, 2, 40, 1, 1, 0); - auto lw2slider = ui::HScale(adj); - lw2slider.show(); - hbox.pack_start(lw2slider, TRUE, TRUE, 0); - gtk_scale_set_draw_value(GTK_SCALE(lw2slider), FALSE); - - auto lw2label = ui::Label(""); - lw2label.show(); - hbox.pack_start(lw2label, FALSE, TRUE, 0); - adj.connect("value_changed", G_CALLBACK(OnScroll2d), lw2label); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - button = ui::Button("Color"); - button.show(); - hbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnColor2d), NULL); - button.dimensions(60, -1); - - auto aa2check = ui::CheckButton("Anti-Alias (May not work on some video cards)"); - aa2check.show(); - hbox.pack_start(aa2check, TRUE, TRUE, 0); - aa2check.connect("toggled", G_CALLBACK(OnAntiAlias2d), NULL); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - auto show2check = ui::CheckButton("Show"); - show2check.show(); - hbox.pack_start(show2check, FALSE, FALSE, 0); - show2check.connect("toggled", G_CALLBACK(OnConfig2d), NULL); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - button = ui::Button("OK"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - // initialize dialog - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show2check), portals.show_2d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa2check), portals.aa_2d); - Set2DText(lw2label); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show3check), portals.show_3d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(depthcheck), portals.fog); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(polyscheck), portals.polygons); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linescheck), portals.lines); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa3check), portals.aa_3d); - gtk_combo_box_set_active(zlist, portals.zbuffer); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(portalcheck), portals.clip); - - Set3DText(lw3label); - Set3DTransText(translabel); - SetClipText(cliplabel); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - gtk_grab_remove(dlg); - dlg.destroy(); -} diff --git a/plugins/prtview/ConfigDialog.h b/plugins/prtview/ConfigDialog.h deleted file mode 100644 index a972584..0000000 --- a/plugins/prtview/ConfigDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_CONFIGDIALOG_H ) -#define INCLUDED_CONFIGDIALOG_H - -void DoConfigDialog(); - -#endif diff --git a/plugins/prtview/LICENSE b/plugins/prtview/LICENSE deleted file mode 100644 index 8d1c8b6..0000000 --- a/plugins/prtview/LICENSE +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/prtview/LoadPortalFileDialog.cpp b/plugins/prtview/LoadPortalFileDialog.cpp deleted file mode 100644 index 29709bd..0000000 --- a/plugins/prtview/LoadPortalFileDialog.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// LoadPortalFileDialog.cpp : implementation file -// - -#include "LoadPortalFileDialog.h" - -#include -#include -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/pointer.h" - -#include "qerplugin.h" - -#include "prtview.h" -#include "portals.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -static void change_clicked(ui::Widget widget, gpointer data) -{ - char *filename = NULL; - - auto file_sel = ui::Widget::from( - gtk_file_chooser_dialog_new("Locate portal (.prt) file", nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - nullptr)); - - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_sel), portals.fn); - - if (gtk_dialog_run(GTK_DIALOG (file_sel)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_sel)); - } - ui::Widget(file_sel).destroy(); - - if (filename != NULL) { - strcpy(portals.fn, filename); - gtk_entry_set_text(GTK_ENTRY(data), filename); - g_free(filename); - } -} - -int DoLoadPortalFileDialog() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "Load .prt"); - dlg.connect("delete_event", - G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", - G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto entry = ui::Entry(ui::New); - entry.show(); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - vbox.pack_start(entry, FALSE, FALSE, 0); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - auto check3d = ui::CheckButton("Show 3D"); - check3d.show(); - hbox.pack_start(check3d, FALSE, FALSE, 0); - - auto check2d = ui::CheckButton("Show 2D"); - check2d.show(); - hbox.pack_start(check2d, FALSE, FALSE, 0); - - auto button = ui::Button("Change"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(change_clicked), entry); - button.dimensions(60, -1); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - button = ui::Button("Cancel"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDCANCEL)); - button.dimensions(60, -1); - - button = ui::Button("OK"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - strcpy(portals.fn, GlobalRadiant().getMapName()); - char *fn = strrchr(portals.fn, '.'); - if (fn != NULL) { - strcpy(fn, ".prt"); - } - - StringOutputStream value(256); - value << portals.fn; - gtk_entry_set_text(GTK_ENTRY(entry), value.c_str()); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check2d), portals.show_2d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check3d), portals.show_3d); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - if (ret == IDOK) { - portals.Purge(); - - portals.show_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check3d)) ? true : false; - portals.show_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check2d)) ? true : false; - } - - gtk_grab_remove(dlg); - dlg.destroy(); - - return ret; -} diff --git a/plugins/prtview/LoadPortalFileDialog.h b/plugins/prtview/LoadPortalFileDialog.h deleted file mode 100644 index 62dfc3d..0000000 --- a/plugins/prtview/LoadPortalFileDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_LOADPORTALFILEDIALOG_H ) -#define INCLUDED_LOADPORTALFILEDIALOG_H - -int DoLoadPortalFileDialog(); - -#endif diff --git a/plugins/prtview/Makefile b/plugins/prtview/Makefile deleted file mode 100644 index 0cc18dd..0000000 --- a/plugins/prtview/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - AboutDialog.o ConfigDialog.o LoadPortalFileDialog.o portals.o prtview.o - -# binary target -../../build/plugins/libprtview.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a ../../libs/libprofile.a $(PLUGIN_LDFLAGS) - -# object files -AboutDialog.o: AboutDialog.cpp AboutDialog.h -ConfigDialog.o: ConfigDialog.cpp ConfigDialog.h -LoadPortalFileDialog.o: LoadPortalFileDialog.cpp LoadPortalFileDialog.h -portals.o: portals.cpp portals.h -prtview.o: prtview.cpp prtview.h - -clean: - -rm -f *.o ../../build/plugins/libprtview.$(LIB_EXT) diff --git a/plugins/prtview/PrtView.txt b/plugins/prtview/PrtView.txt deleted file mode 100644 index 50228e0..0000000 --- a/plugins/prtview/PrtView.txt +++ /dev/null @@ -1,12 +0,0 @@ -Put PrtView.dll in the Q3Radiant plugins directory. - -This program is pretty self explanitary, but point needs to -be mentioned. In the configuration menu for 3D view options, -the lines and polygons flags are tri-state. In the third state, -the lines or polygons will only be drawn if the have the -hint flag set. Older version of q3map will not set this flag -and the hint shader may have to be modified to set it. As of -this writing, I do not know all the details. - -Geoffrey DeWan -gdewan@prairienet.org \ No newline at end of file diff --git a/plugins/prtview/portals.cpp b/plugins/prtview/portals.cpp deleted file mode 100644 index 52ee03c..0000000 --- a/plugins/prtview/portals.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "portals.h" -#include "globaldefs.h" -#include -#include - -#if !GDEF_OS_MACOS - -#include - -#endif - -#include - -#include "iglrender.h" -#include "cullable.h" - -#include "prtview.h" - -const int LINE_BUF = 1000; - -CPortals portals; -CPortalsRender render; - -int compare(const void *arg1, const void *arg2) -{ - - if (portals.portal[*((int *) arg1)].dist > portals.portal[*((int *) arg2)].dist) { - return -1; - } else if (portals.portal[*((int *) arg1)].dist < portals.portal[*((int *) arg2)].dist) { - return 1; - } - - return 0; -} - - -CBspPortal::CBspPortal() -{ - memset(this, 0, sizeof(CBspPortal)); -} - -CBspPortal::~CBspPortal() -{ - delete[] point; - delete[] inner_point; -} - -bool CBspPortal::Build(char *def) -{ - char *c = def; - unsigned int n; - int dummy1, dummy2; - int res_cnt, i; - - if (portals.hint_flags) { - res_cnt = sscanf(def, "%u %d %d %d", &point_count, &dummy1, &dummy2, (int *) &hint); - } else { - sscanf(def, "%u", &point_count); - hint = false; - } - - if (point_count < 3 || (portals.hint_flags && res_cnt < 4)) { - return false; - } - - point = new CBspPoint[point_count]; - inner_point = new CBspPoint[point_count]; - - for (n = 0; n < point_count; n++) { - for (; *c != 0 && *c != '('; c++) {} - - if (*c == 0) { - return false; - } - - c++; - - sscanf(c, "%f %f %f", point[n].p, point[n].p + 1, point[n].p + 2); - - center.p[0] += point[n].p[0]; - center.p[1] += point[n].p[1]; - center.p[2] += point[n].p[2]; - - if (n == 0) { - for (i = 0; i < 3; i++) { - min[i] = point[n].p[i]; - max[i] = point[n].p[i]; - } - } else { - for (i = 0; i < 3; i++) { - if (min[i] > point[n].p[i]) { - min[i] = point[n].p[i]; - } - if (max[i] < point[n].p[i]) { - max[i] = point[n].p[i]; - } - } - } - } - - center.p[0] /= (float) point_count; - center.p[1] /= (float) point_count; - center.p[2] /= (float) point_count; - - for (n = 0; n < point_count; n++) { - inner_point[n].p[0] = (0.01f * center.p[0]) + (0.99f * point[n].p[0]); - inner_point[n].p[1] = (0.01f * center.p[1]) + (0.99f * point[n].p[1]); - inner_point[n].p[2] = (0.01f * center.p[2]) + (0.99f * point[n].p[2]); - } - - fp_color_random[0] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[1] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[2] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[3] = 1.0f; - - return true; -} - -CPortals::CPortals() -{ - memset(this, 0, sizeof(CPortals)); -} - -CPortals::~CPortals() -{ - Purge(); -} - -void CPortals::Purge() -{ - delete[] portal; - delete[] portal_sort; - portal = NULL; - portal_sort = NULL; - portal_count = 0; - - /* - delete[] node; - node = NULL; - node_count = 0; - */ -} - -void CPortals::Load() -{ - char buf[LINE_BUF + 1]; - - memset(buf, 0, LINE_BUF + 1); - - Purge(); - - globalOutputStream() << MSG_PREFIX "Loading portal file " << fn << ".\n"; - - FILE *in; - - in = fopen(fn, "rt"); - - if (in == NULL) { - globalOutputStream() << " ERROR - could not open file.\n"; - - return; - } - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - if (strncmp("PRT1", buf, 4) != 0) { - fclose(in); - - globalOutputStream() << " ERROR - File header indicates wrong file type (should be \"PRT1\").\n"; - - return; - } - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - sscanf(buf, "%u", &node_count); -/* - if(node_count > 0xFFFF) - { - fclose(in); - - node_count = 0; - - globalOutputStream() << " ERROR - Extreme number of nodes, aborting.\n"; - - return; - } - */ - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - node_count = 0; - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - sscanf(buf, "%u", &portal_count); - - if (portal_count > 0xFFFF) { - fclose(in); - - portal_count = 0; - node_count = 0; - - globalOutputStream() << " ERROR - Extreme number of portals, aborting.\n"; - - return; - } - - if (portal_count == 0) { - fclose(in); - - portal_count = 0; - node_count = 0; - - globalOutputStream() << " ERROR - number of portals equals 0, aborting.\n"; - - return; - } - -// node = new CBspNode[node_count]; - portal = new CBspPortal[portal_count]; - portal_sort = new int[portal_count]; - - unsigned int n; - bool first = true; - unsigned test_vals_1, test_vals_2; - - hint_flags = false; - - for (n = 0; n < portal_count;) { - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - Purge(); - - globalOutputStream() << " ERROR - Could not find information for portal number " << n + 1 << " of " - << portal_count << ".\n"; - - return; - } - - if (!portal[n].Build(buf)) { - if (first && sscanf(buf, "%d %d", (int *) &test_vals_1, (int *) &test_vals_2) == - 1) { // skip additional counts of later data, not needed - // We can count on hint flags being in the file - hint_flags = true; - continue; - } - - first = false; - - fclose(in); - - Purge(); - - globalOutputStream() << " ERROR - Information for portal number " << n + 1 << " of " << portal_count - << " is not formatted correctly.\n"; - - return; - } - - n++; - } - - fclose(in); - - globalOutputStream() << " " << node_count << " portals read in.\n"; -} - -#include "math/matrix.h" - -const char *g_state_solid = "$plugins/prtview/solid"; -const char *g_state_solid_outline = "$plugins/prtview/solid_outline"; -const char *g_state_wireframe = "$plugins/prtview/wireframe"; -Shader *g_shader_solid = 0; -Shader *g_shader_solid_outline = 0; -Shader *g_shader_wireframe = 0; - -void Portals_constructShaders() -{ - OpenGLState state; - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_2d * 0.5f; - state.m_colour[0] = portals.fp_color_2d[0]; - state.m_colour[1] = portals.fp_color_2d[1]; - state.m_colour[2] = portals.fp_color_2d[2]; - state.m_colour[3] = portals.fp_color_2d[3]; - if (portals.aa_2d) { - state.m_state |= RENDER_BLEND | RENDER_LINESMOOTH; - } - GlobalOpenGLStateLibrary().insert(g_state_wireframe, state); - - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_SMOOTH; - - if (portals.aa_3d) { - state.m_state |= RENDER_POLYGONSMOOTH; - } - - switch (portals.zbuffer) { - case 1: - state.m_state |= RENDER_DEPTHTEST; - break; - case 2: - break; - default: - state.m_state |= RENDER_DEPTHTEST; - state.m_state |= RENDER_DEPTHWRITE; - } - - if (portals.fog) { - state.m_state |= RENDER_FOG; - - state.m_fog.mode = GL_EXP; - state.m_fog.density = 0.001f; - state.m_fog.start = 10.0f; - state.m_fog.end = 10000.0f; - state.m_fog.index = 0; - state.m_fog.colour[0] = portals.fp_color_fog[0]; - state.m_fog.colour[1] = portals.fp_color_fog[1]; - state.m_fog.colour[2] = portals.fp_color_fog[2]; - state.m_fog.colour[3] = portals.fp_color_fog[3]; - } - - GlobalOpenGLStateLibrary().insert(g_state_solid, state); - - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_3d * 0.5f; - state.m_colour[0] = portals.fp_color_3d[0]; - state.m_colour[1] = portals.fp_color_3d[1]; - state.m_colour[2] = portals.fp_color_3d[2]; - state.m_colour[3] = portals.fp_color_3d[3]; - - if (portals.aa_3d) { - state.m_state |= RENDER_LINESMOOTH; - } - - switch (portals.zbuffer) { - case 1: - state.m_state |= RENDER_DEPTHTEST; - break; - case 2: - break; - default: - state.m_state |= RENDER_DEPTHTEST; - state.m_state |= RENDER_DEPTHWRITE; - } - - if (portals.fog) { - state.m_state |= RENDER_FOG; - - state.m_fog.mode = GL_EXP; - state.m_fog.density = 0.001f; - state.m_fog.start = 10.0f; - state.m_fog.end = 10000.0f; - state.m_fog.index = 0; - state.m_fog.colour[0] = portals.fp_color_fog[0]; - state.m_fog.colour[1] = portals.fp_color_fog[1]; - state.m_fog.colour[2] = portals.fp_color_fog[2]; - state.m_fog.colour[3] = portals.fp_color_fog[3]; - } - - GlobalOpenGLStateLibrary().insert(g_state_solid_outline, state); - - g_shader_solid = GlobalShaderCache().capture(g_state_solid); - g_shader_solid_outline = GlobalShaderCache().capture(g_state_solid_outline); - g_shader_wireframe = GlobalShaderCache().capture(g_state_wireframe); -} - -void Portals_destroyShaders() -{ - GlobalShaderCache().release(g_state_solid); - GlobalShaderCache().release(g_state_solid_outline); - GlobalShaderCache().release(g_state_wireframe); - GlobalOpenGLStateLibrary().erase(g_state_solid); - GlobalOpenGLStateLibrary().erase(g_state_solid_outline); - GlobalOpenGLStateLibrary().erase(g_state_wireframe); -} - -void Portals_shadersChanged() -{ - Portals_destroyShaders(); - portals.FixColors(); - Portals_constructShaders(); -} - -void CPortals::FixColors() -{ - fp_color_2d[0] = (float) GetRValue(color_2d) / 255.0f; - fp_color_2d[1] = (float) GetGValue(color_2d) / 255.0f; - fp_color_2d[2] = (float) GetBValue(color_2d) / 255.0f; - fp_color_2d[3] = 1.0f; - - fp_color_3d[0] = (float) GetRValue(color_3d) / 255.0f; - fp_color_3d[1] = (float) GetGValue(color_3d) / 255.0f; - fp_color_3d[2] = (float) GetBValue(color_3d) / 255.0f; - fp_color_3d[3] = 1.0f; - - fp_color_fog[0] = 0.0f; //(float)GetRValue(color_fog) / 255.0f; - fp_color_fog[1] = 0.0f; //(float)GetGValue(color_fog) / 255.0f; - fp_color_fog[2] = 0.0f; //(float)GetBValue(color_fog) / 255.0f; - fp_color_fog[3] = 1.0f; -} - -void CPortalsRender::renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - if (!portals.show_2d || portals.portal_count < 1) { - return; - } - - renderer.SetState(g_shader_wireframe, Renderer::eWireframeOnly); - - renderer.addRenderable(m_drawWireframe, g_matrix4_identity); -} - -void CPortalsDrawWireframe::render(RenderStateFlags state) const -{ - unsigned int n, p; - - for (n = 0; n < portals.portal_count; n++) { - glBegin(GL_LINE_LOOP); - - for (p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].point[p].p); - - glEnd(); - } -} - -CubicClipVolume calculateCubicClipVolume(const Matrix4 &viewproj) -{ - CubicClipVolume clip; - clip.cam = vector4_projected( - matrix4_transformed_vector4( - matrix4_full_inverse(viewproj), - Vector4(0, 0, -1, 1) - ) - ); - clip.min[0] = clip.cam[0] + (portals.clip_range * 64.0f); - clip.min[1] = clip.cam[1] + (portals.clip_range * 64.0f); - clip.min[2] = clip.cam[2] + (portals.clip_range * 64.0f); - clip.max[0] = clip.cam[0] - (portals.clip_range * 64.0f); - clip.max[1] = clip.cam[1] - (portals.clip_range * 64.0f); - clip.max[2] = clip.cam[2] - (portals.clip_range * 64.0f); - return clip; -} - -void CPortalsRender::renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - if (!portals.show_3d || portals.portal_count < 1) { - return; - } - - CubicClipVolume clip = calculateCubicClipVolume( - matrix4_multiplied_by_matrix4(volume.GetProjection(), volume.GetModelview())); - - if (portals.polygons) { - renderer.SetState(g_shader_solid, Renderer::eWireframeOnly); - renderer.SetState(g_shader_solid, Renderer::eFullMaterials); - - m_drawSolid.clip = clip; - renderer.addRenderable(m_drawSolid, g_matrix4_identity); - } - - if (portals.lines) { - renderer.SetState(g_shader_solid_outline, Renderer::eWireframeOnly); - renderer.SetState(g_shader_solid_outline, Renderer::eFullMaterials); - - m_drawSolidOutline.clip = clip; - renderer.addRenderable(m_drawSolidOutline, g_matrix4_identity); - } -} - -void CPortalsDrawSolid::render(RenderStateFlags state) const -{ - float trans = (100.0f - portals.trans_3d) / 100.0f; - - unsigned int n, p; - - if (portals.zbuffer != 0) { - float d; - - for (n = 0; n < portals.portal_count; n++) { - d = (float) clip.cam[0] - portals.portal[n].center.p[0]; - portals.portal[n].dist = d * d; - - d = (float) clip.cam[1] - portals.portal[n].center.p[1]; - portals.portal[n].dist += d * d; - - d = (float) clip.cam[2] - portals.portal[n].center.p[2]; - portals.portal[n].dist += d * d; - - portals.portal_sort[n] = n; - } - - qsort(portals.portal_sort, portals.portal_count, 4, compare); - - for (n = 0; n < portals.portal_count; n++) { - if (portals.polygons == 2 && !portals.portal[portals.portal_sort[n]].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[portals.portal_sort[n]].min[0]) { - continue; - } else if (clip.min[1] < portals.portal[portals.portal_sort[n]].min[1]) { - continue; - } else if (clip.min[2] < portals.portal[portals.portal_sort[n]].min[2]) { - continue; - } else if (clip.max[0] > portals.portal[portals.portal_sort[n]].max[0]) { - continue; - } else if (clip.max[1] > portals.portal[portals.portal_sort[n]].max[1]) { - continue; - } else if (clip.max[2] > portals.portal[portals.portal_sort[n]].max[2]) { - continue; - } - } - - glColor4f(portals.portal[portals.portal_sort[n]].fp_color_random[0], - portals.portal[portals.portal_sort[n]].fp_color_random[1], - portals.portal[portals.portal_sort[n]].fp_color_random[2], trans); - - glBegin(GL_POLYGON); - - for (p = 0; p < portals.portal[portals.portal_sort[n]].point_count; p++) - glVertex3fv(portals.portal[portals.portal_sort[n]].point[p].p); - - glEnd(); - } - } else { - for (n = 0; n < portals.portal_count; n++) { - if (portals.polygons == 2 && !portals.portal[n].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[n].min[0]) { - continue; - } else if (clip.min[1] < portals.portal[n].min[1]) { - continue; - } else if (clip.min[2] < portals.portal[n].min[2]) { - continue; - } else if (clip.max[0] > portals.portal[n].max[0]) { - continue; - } else if (clip.max[1] > portals.portal[n].max[1]) { - continue; - } else if (clip.max[2] > portals.portal[n].max[2]) { - continue; - } - } - - glColor4f(portals.portal[n].fp_color_random[0], portals.portal[n].fp_color_random[1], - portals.portal[n].fp_color_random[2], trans); - - glBegin(GL_POLYGON); - - for (p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].point[p].p); - - glEnd(); - } - } -} - -void CPortalsDrawSolidOutline::render(RenderStateFlags state) const -{ - for (unsigned int n = 0; n < portals.portal_count; n++) { - if (portals.lines == 2 && !portals.portal[n].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[n].min[0]) { - continue; - } - if (clip.min[1] < portals.portal[n].min[1]) { - continue; - } - if (clip.min[2] < portals.portal[n].min[2]) { - continue; - } - if (clip.max[0] > portals.portal[n].max[0]) { - continue; - } - if (clip.max[1] > portals.portal[n].max[1]) { - continue; - } - if (clip.max[2] > portals.portal[n].max[2]) { - continue; - } - } - - glBegin(GL_LINE_LOOP); - - for (unsigned int p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].inner_point[p].p); - - glEnd(); - } -} diff --git a/plugins/prtview/portals.h b/plugins/prtview/portals.h deleted file mode 100644 index 28c77dc..0000000 --- a/plugins/prtview/portals.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _PORTALS_H_ -#define _PORTALS_H_ - -#include -#include "irender.h" -#include "renderable.h" -#include "math/vector.h" - - -class CBspPoint { -public: -float p[3]; -}; - -class CBspPortal { -public: -CBspPortal(); - -~CBspPortal(); - -protected: - -public: -CBspPoint center; -unsigned point_count; -CBspPoint *point; -CBspPoint *inner_point; -float fp_color_random[4]; -float min[3]; -float max[3]; -float dist; -bool hint; - -bool Build(char *def); -}; - -#ifdef PATH_MAX -const int PRTVIEW_PATH_MAX = PATH_MAX; -#else -const int PRTVIEW_PATH_MAX = 260; -#endif -typedef guint32 PackedColour; -#define RGB(r, g, b) ( (guint32)( ( (guint8) ( r ) | ( (guint16) ( g ) << 8 ) ) | ( ( (guint32) (guint8) ( b ) ) << 16 ) ) ) -#define GetRValue(rgb) ( (guint8)( rgb ) ) -#define GetGValue(rgb) ( (guint8)( ( (guint16)( rgb ) ) >> 8 ) ) -#define GetBValue(rgb) ( (guint8)( ( rgb ) >> 16 ) ) - - -class CPortals { -public: - -CPortals(); - -~CPortals(); - -protected: - - -public: - -void Load(); // use filename in fn -void Purge(); - -void FixColors(); - -char fn[PRTVIEW_PATH_MAX]; - -int zbuffer; -int polygons; -int lines; -bool show_3d; -bool aa_3d; -bool fog; -PackedColour color_3d; -float width_3d; // in 8'ths -float fp_color_3d[4]; -PackedColour color_fog; -float fp_color_fog[4]; -float trans_3d; -float clip_range; -bool clip; - -bool show_2d; -bool aa_2d; -PackedColour color_2d; -float width_2d; // in 8'ths -float fp_color_2d[4]; - -CBspPortal *portal; -int *portal_sort; -bool hint_flags; -// CBspNode *node; - -unsigned int node_count; -unsigned int portal_count; -}; - -class CubicClipVolume { -public: -Vector3 cam, min, max; -}; - -class CPortalsDrawSolid : public OpenGLRenderable { -public: -mutable CubicClipVolume clip; - -void render(RenderStateFlags state) const; -}; - -class CPortalsDrawSolidOutline : public OpenGLRenderable { -public: -mutable CubicClipVolume clip; - -void render(RenderStateFlags state) const; -}; - -class CPortalsDrawWireframe : public OpenGLRenderable { -public: -void render(RenderStateFlags state) const; -}; - -class CPortalsRender : public Renderable { -public: -CPortalsDrawSolid m_drawSolid; -CPortalsDrawSolidOutline m_drawSolidOutline; -CPortalsDrawWireframe m_drawWireframe; - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const; - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const; -}; - -extern CPortals portals; -extern CPortalsRender render; - -void Portals_constructShaders(); - -void Portals_destroyShaders(); - -void Portals_shadersChanged(); - - -#endif // _PORTALS_H_ diff --git a/plugins/prtview/prtview.cpp b/plugins/prtview/prtview.cpp deleted file mode 100644 index a6a93c6..0000000 --- a/plugins/prtview/prtview.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "prtview.h" -#include -#include - -#include "profile/profile.h" - -#include "qerplugin.h" -#include "iscenegraph.h" -#include "iglrender.h" -#include "iplugin.h" -#include "stream/stringstream.h" - -#include "portals.h" -#include "AboutDialog.h" -#include "ConfigDialog.h" -#include "LoadPortalFileDialog.h" - -#define Q3R_CMD_SPLITTER "-" -#define Q3R_CMD_ABOUT "About Portal Viewer" -#define Q3R_CMD_LOAD "Load .prt file" -#define Q3R_CMD_RELEASE "Unload .prt file" -#define Q3R_CMD_SHOW_3D "Toggle portals (3D)" -#define Q3R_CMD_SHOW_2D "Toggle portals (2D)" -#define Q3R_CMD_OPTIONS "Configure Portal Viewer" - -CopiedString INIfn; - -///////////////////////////////////////////////////////////////////////////// -// CPrtViewApp construction - -const char *RENDER_2D = "Render2D"; -const char *WIDTH_2D = "Width2D"; -const char *AA_2D = "AntiAlias2D"; -const char *COLOR_2D = "Color2D"; - -const char *RENDER_3D = "Render3D"; -const char *WIDTH_3D = "Width3D"; -const char *AA_3D = "AntiAlias3D"; -const char *COLOR_3D = "Color3D"; -const char *COLOR_FOG = "ColorFog"; -const char *FOG = "Fog"; -const char *ZBUFFER = "ZBuffer"; -const char *POLYGON = "Polygons"; -const char *LINE = "Lines"; -const char *TRANS_3D = "Transparency"; -const char *CLIP_RANGE = "ClipRange"; -const char *CLIP = "Clip"; - - -void PrtView_construct() -{ - StringOutputStream tmp(64); - tmp << GlobalRadiant().getSettingsPath() << "prtview.ini"; - INIfn = tmp.c_str(); - - portals.show_2d = INIGetInt(RENDER_2D, FALSE) ? true : false; - portals.aa_2d = INIGetInt(AA_2D, FALSE) ? true : false; - portals.width_2d = (float) INIGetInt(WIDTH_2D, 10); - portals.color_2d = (PackedColour) INIGetInt(COLOR_2D, RGB(0, 0, 255)) & 0xFFFFFF; - - if (portals.width_2d > 40.0f) { - portals.width_2d = 40.0f; - } else if (portals.width_2d < 2.0f) { - portals.width_2d = 2.0f; - } - - portals.show_3d = INIGetInt(RENDER_3D, TRUE) ? true : false; - - portals.zbuffer = INIGetInt(ZBUFFER, 1); - portals.fog = INIGetInt(FOG, FALSE) ? true : false; - portals.polygons = INIGetInt(POLYGON, TRUE); - portals.lines = INIGetInt(LINE, TRUE); - portals.aa_3d = INIGetInt(AA_3D, FALSE) ? true : false; - portals.width_3d = (float) INIGetInt(WIDTH_3D, 4); - portals.color_3d = (PackedColour) INIGetInt(COLOR_3D, RGB(255, 255, 0)) & 0xFFFFFF; - portals.color_fog = (PackedColour) INIGetInt(COLOR_FOG, RGB(127, 127, 127)) & 0xFFFFFF; - portals.trans_3d = (float) INIGetInt(TRANS_3D, 50); - portals.clip = INIGetInt(CLIP, FALSE) ? true : false; - portals.clip_range = (float) INIGetInt(CLIP_RANGE, 16); - - if (portals.clip_range < 1) { - portals.clip_range = 1; - } else if (portals.clip_range > 128) { - portals.clip_range = 128; - } - - if (portals.zbuffer < 0) { - portals.zbuffer = 0; - } else if (portals.zbuffer > 2) { - portals.zbuffer = 0; - } - - if (portals.width_3d > 40.0f) { - portals.width_3d = 40.0f; - } else if (portals.width_3d < 2.0f) { - portals.width_3d = 2.0f; - } - - if (portals.trans_3d > 100.0f) { - portals.trans_3d = 100.0f; - } else if (portals.trans_3d < 0.0f) { - portals.trans_3d = 0.0f; - } - - SaveConfig(); - - portals.FixColors(); - - Portals_constructShaders(); - GlobalShaderCache().attachRenderable(render); -} - -void PrtView_destroy() -{ - GlobalShaderCache().detachRenderable(render); - Portals_destroyShaders(); -} - -void SaveConfig() -{ - INISetInt(RENDER_2D, portals.show_2d, "Draw in 2D windows"); - INISetInt(WIDTH_2D, (int) portals.width_2d, "Width of lines in 2D windows (in units of 1/2)"); - INISetInt(COLOR_2D, (int) portals.color_2d, "Color of lines in 2D windows"); - INISetInt(AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased"); - - INISetInt(ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window"); - INISetInt(FOG, portals.fog, "Use depth cueing in 3D window"); - INISetInt(POLYGON, portals.polygons, "Render using polygons polygons in 3D window"); - INISetInt(LINE, portals.polygons, "Render using lines in 3D window"); - INISetInt(RENDER_3D, portals.show_3d, "Draw in 3D windows"); - INISetInt(WIDTH_3D, (int) portals.width_3d, "Width of lines in 3D window (in units of 1/2)"); - INISetInt(COLOR_3D, (int) portals.color_3d, "Color of lines/polygons in 3D window"); - INISetInt(COLOR_FOG, (int) portals.color_fog, "Color of distant lines/polygons in 3D window"); - INISetInt(AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased"); - INISetInt(TRANS_3D, (int) portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)"); - INISetInt(CLIP, portals.clip, "Cubic clipper active for portal viewer"); - INISetInt(CLIP_RANGE, (int) portals.clip_range, "Portal viewer cubic clip distance (in units of 64)"); -} - - -const char *CONFIG_SECTION = "Configuration"; - -int INIGetInt(const char *key, int def) -{ - char value[1024]; - - if (read_var(INIfn.c_str(), CONFIG_SECTION, key, value)) { - return atoi(value); - } else { - return def; - } -} - -void INISetInt(const char *key, int val, const char *comment /* = NULL */ ) -{ - char s[1000]; - - if (comment) { - sprintf(s, "%d ; %s", val, comment); - } else { - sprintf(s, "%d", val); - } - save_var(INIfn.c_str(), CONFIG_SECTION, key, s); -} - - -// plugin name -static const char *PLUGIN_NAME = "Portal Viewer"; -// commands in the menu -static const char *PLUGIN_COMMANDS = - Q3R_CMD_ABOUT ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_OPTIONS ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_SHOW_2D ";" - Q3R_CMD_SHOW_3D ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_RELEASE ";" - Q3R_CMD_LOAD; - - -const char *QERPlug_Init(void *hApp, void *pMainWidget) -{ - return "Portal Viewer for WorldSpawn"; -} - -const char *QERPlug_GetName() -{ - return PLUGIN_NAME; -} - -const char *QERPlug_GetCommandList() -{ - return PLUGIN_COMMANDS; -} - - -const char *QERPlug_GetCommandTitleList() -{ - return ""; -} - - -void QERPlug_Dispatch(const char *p, float *vMin, float *vMax, bool bSingleBrush) -{ - globalOutputStream() << MSG_PREFIX "Command \"" << p << "\"\n"; - - if (!strcmp(p, Q3R_CMD_ABOUT)) { - DoAboutDlg(); - } else if (!strcmp(p, Q3R_CMD_LOAD)) { - if (DoLoadPortalFileDialog() == IDOK) { - portals.Load(); - SceneChangeNotify(); - } else { - globalOutputStream() << MSG_PREFIX "Portal file load aborted.\n"; - } - } else if (!strcmp(p, Q3R_CMD_RELEASE)) { - portals.Purge(); - - SceneChangeNotify(); - - globalOutputStream() << MSG_PREFIX "Portals unloaded.\n"; - } else if (!strcmp(p, Q3R_CMD_SHOW_2D)) { - portals.show_2d = !portals.show_2d; - - SceneChangeNotify(); - SaveConfig(); - - if (portals.show_2d) { - globalOutputStream() << MSG_PREFIX "Portals will be rendered in 2D view.\n"; - } else { - globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 2D view.\n"; - } - } else if (!strcmp(p, Q3R_CMD_SHOW_3D)) { - portals.show_3d = !portals.show_3d; - SaveConfig(); - - SceneChangeNotify(); - - if (portals.show_3d) { - globalOutputStream() << MSG_PREFIX "Portals will be rendered in 3D view.\n"; - } else { - globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 3D view.\n"; - } - } else if (!strcmp(p, Q3R_CMD_OPTIONS)) { - DoConfigDialog(); - SaveConfig(); - - SceneChangeNotify(); - } -} - - -#include "modulesystem/singletonmodule.h" - -class PrtViewPluginDependencies : - public GlobalSceneGraphModuleRef, - public GlobalRadiantModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalOpenGLModuleRef, - public GlobalOpenGLStateLibraryModuleRef { -}; - -class PrtViewPluginModule { -_QERPluginTable m_plugin; -public: -typedef _QERPluginTable Type; - -STRING_CONSTANT(Name, "PRT Viewer"); - -PrtViewPluginModule() -{ - m_plugin.m_pfnQERPlug_Init = QERPlug_Init; - m_plugin.m_pfnQERPlug_GetName = QERPlug_GetName; - m_plugin.m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList; - m_plugin.m_pfnQERPlug_GetCommandTitleList = QERPlug_GetCommandTitleList; - m_plugin.m_pfnQERPlug_Dispatch = QERPlug_Dispatch; - - PrtView_construct(); -} - -~PrtViewPluginModule() -{ - PrtView_destroy(); -} - -_QERPluginTable *getTable() -{ - return &m_plugin; -} -}; - -typedef SingletonModule SingletonPrtViewPluginModule; - -SingletonPrtViewPluginModule g_PrtViewPluginModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_PrtViewPluginModule.selfRegister(); -} diff --git a/plugins/prtview/prtview.h b/plugins/prtview/prtview.h deleted file mode 100644 index 2253474..0000000 --- a/plugins/prtview/prtview.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_PRTVIEW_H ) -#define INCLUDED_PRTVIEW_H - -#define MSG_PREFIX "Portal Viewer plugin: " - -void InitInstance(); - -void SaveConfig(); - -int INIGetInt(const char *key, int def); - -void INISetInt(const char *key, int val, const char *comment = 0); - -const int IDOK = 1; -const int IDCANCEL = 2; - - -#endif diff --git a/plugins/shaders/Makefile b/plugins/shaders/Makefile deleted file mode 100644 index 0ce814b..0000000 --- a/plugins/shaders/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - shaders.o plugin.o - -# binary target -../../build/plugins/libshaders.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -shaders.o: shaders.cpp shaders.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libshaders.$(LIB_EXT) diff --git a/plugins/shaders/plugin.cpp b/plugins/shaders/plugin.cpp deleted file mode 100644 index 8e5a453..0000000 --- a/plugins/shaders/plugin.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ishaders.h" -#include "ifilesystem.h" -#include "itextures.h" -#include "iscriplib.h" -#include "qerplugin.h" - -#include "string/string.h" -#include "modulesystem/singletonmodule.h" - -#include "shaders.h" - -class ShadersDependencies : - public GlobalFileSystemModuleRef, - public GlobalTexturesModuleRef, - public GlobalScripLibModuleRef, - public GlobalRadiantModuleRef -{ -ImageModuleRef m_bitmapModule; -public: -ShadersDependencies() : - m_bitmapModule( "tga" ){ -} -ImageModuleRef& getBitmapModule(){ - return m_bitmapModule; -} -}; - -class ShadersQ3API -{ -ShaderSystem* m_shadersq3; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "quake3" ); - -ShadersQ3API( ShadersDependencies& dependencies ){ - g_shadersExtension = "shader"; - g_shadersDirectory = "scripts/"; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersq3 = &GetShaderSystem(); -} -~ShadersQ3API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersq3; -} -}; - -typedef SingletonModule > ShadersQ3Module; - -ShadersQ3Module g_ShadersQ3Module; - - -class ShadersDoom3API -{ -ShaderSystem* m_shadersdoom3; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "doom3" ); - -ShadersDoom3API( ShadersDependencies& dependencies ){ - g_shadersExtension = "mtr"; - g_shadersDirectory = "materials/"; - g_enableDefaultShaders = false; - g_shaderLanguage = SHADERLANGUAGE_DOOM3; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersdoom3 = &GetShaderSystem(); -} -~ShadersDoom3API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersdoom3; -} -}; - -typedef SingletonModule > ShadersDoom3Module; - -ShadersDoom3Module g_ShadersDoom3Module; - - -class ShadersQuake4API -{ -ShaderSystem* m_shadersquake4; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "quake4" ); - -ShadersQuake4API( ShadersDependencies& dependencies ){ - g_shadersExtension = "mtr"; - g_shadersDirectory = "materials/"; - g_enableDefaultShaders = false; - g_shaderLanguage = SHADERLANGUAGE_QUAKE4; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersquake4 = &GetShaderSystem(); -} -~ShadersQuake4API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersquake4; -} -}; - -typedef SingletonModule > ShadersQuake4Module; - -ShadersQuake4Module g_ShadersQuake4Module; - - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ShadersQ3Module.selfRegister(); - g_ShadersDoom3Module.selfRegister(); - g_ShadersQuake4Module.selfRegister(); -} diff --git a/plugins/shaders/shaders.cpp b/plugins/shaders/shaders.cpp deleted file mode 100644 index 3846942..0000000 --- a/plugins/shaders/shaders.cpp +++ /dev/null @@ -1,1842 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Shaders Manager Plugin -// -// Leonardo Zide ( leo@lokigames.com ) -// - -#include "defaults.h" -#include "shaders.h" -#include "globaldefs.h" - -#include -#include -#include -#include - -#include "ifilesystem.h" -#include "ishaders.h" -#include "iscriplib.h" -#include "itextures.h" -#include "qerplugin.h" -#include "irender.h" - -#include - -#include "debugging/debugging.h" -#include "string/pooledstring.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "generic/referencecounted.h" -#include "stream/memstream.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "os/dir.h" -#include "os/file.h" -#include "stringio.h" -#include "shaderlib.h" -#include "texturelib.h" -#include "cmdlib.h" -#include "moduleobservers.h" -#include "archivelib.h" -#include "imagelib.h" - -const char* g_shadersExtension = ""; -const char* g_shadersDirectory = ""; -bool g_enableDefaultShaders = true; -ShaderLanguage g_shaderLanguage = SHADERLANGUAGE_QUAKE3; -bool g_useShaderList = true; -_QERPlugImageTable* g_bitmapModule = 0; -const char* g_texturePrefix = DEFAULT_TEXTURE_DIRNAME; - -void ActiveShaders_IteratorBegin(); - -bool ActiveShaders_IteratorAtEnd(); - -IShader *ActiveShaders_IteratorCurrent(); - -void ActiveShaders_IteratorIncrement(); - -Callback g_ActiveShadersChangedNotify; - -void FreeShaders(); - -void LoadShaderFile( const char *filename ); - -/*! - NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX: - SHADER_NOT_FOUND means we didn't find the raw texture or the shader for this - SHADER_NOTEX means we recognize this as a shader script, but we are missing the texture to represent it - this was in the initial design of the shader code since early GtkRadiant alpha, and got sort of foxed in 1.2 and put back in - */ - -Image* loadBitmap( void* environment, const char* name ){ - DirectoryArchiveFile file( name, name ); - if ( !file.failed() ) { - return g_bitmapModule->loadImage( file ); - } - return 0; -} - -inline byte* getPixel( byte* pixels, int width, int height, int x, int y ){ - return pixels + ( ( ( ( ( y + height ) % height ) * width ) + ( ( x + width ) % width ) ) * 4 ); -} - -class KernelElement -{ -public: -int x, y; -float w; -}; - -Image& convertHeightmapToNormalmap( Image& heightmap, float scale ){ - int w = heightmap.getWidth(); - int h = heightmap.getHeight(); - - Image& normalmap = *( new RGBAImage( heightmap.getWidth(), heightmap.getHeight() ) ); - - byte* in = heightmap.getRGBAPixels(); - byte* out = normalmap.getRGBAPixels(); - -#if 1 - // no filtering - const int kernelSize = 2; - KernelElement kernel_du[kernelSize] = { - {-1, 0,-0.5f }, - { 1, 0, 0.5f } - }; - KernelElement kernel_dv[kernelSize] = { - { 0, 1, 0.5f }, - { 0,-1,-0.5f } - }; -#else - // 3x3 Prewitt - const int kernelSize = 6; - KernelElement kernel_du[kernelSize] = { - {-1, 1,-1.0f }, - {-1, 0,-1.0f }, - {-1,-1,-1.0f }, - { 1, 1, 1.0f }, - { 1, 0, 1.0f }, - { 1,-1, 1.0f } - }; - KernelElement kernel_dv[kernelSize] = { - {-1, 1, 1.0f }, - { 0, 1, 1.0f }, - { 1, 1, 1.0f }, - {-1,-1,-1.0f }, - { 0,-1,-1.0f }, - { 1,-1,-1.0f } - }; -#endif - - int x, y = 0; - while ( y < h ) - { - x = 0; - while ( x < w ) - { - float du = 0; - for ( KernelElement* i = kernel_du; i != kernel_du + kernelSize; ++i ) - { - du += ( getPixel( in, w, h, x + ( *i ).x, y + ( *i ).y )[0] / 255.0 ) * ( *i ).w; - } - float dv = 0; - for ( KernelElement* i = kernel_dv; i != kernel_dv + kernelSize; ++i ) - { - dv += ( getPixel( in, w, h, x + ( *i ).x, y + ( *i ).y )[0] / 255.0 ) * ( *i ).w; - } - - float nx = -du * scale; - float ny = -dv * scale; - float nz = 1.0; - - // Normalize - float norm = 1.0 / sqrt( nx * nx + ny * ny + nz * nz ); - out[0] = float_to_integer( ( ( nx * norm ) + 1 ) * 127.5 ); - out[1] = float_to_integer( ( ( ny * norm ) + 1 ) * 127.5 ); - out[2] = float_to_integer( ( ( nz * norm ) + 1 ) * 127.5 ); - out[3] = 255; - - x++; - out += 4; - } - - y++; - } - - return normalmap; -} - -Image* loadHeightmap( void* environment, const char* name ){ - Image* heightmap = GlobalTexturesCache().loadImage( name ); - if ( heightmap != 0 ) { - Image& normalmap = convertHeightmapToNormalmap( *heightmap, *reinterpret_cast( environment ) ); - heightmap->release(); - return &normalmap; - } - return 0; -} - -class ShaderPoolContext -{ -}; - -typedef Static ShaderPool; -typedef PooledString ShaderString; -typedef ShaderString ShaderVariable; -typedef ShaderString ShaderValue; -typedef CopiedString TextureExpression; - -// clean a texture name to the qtexture_t name format we use internally -// NOTE: case sensitivity: the engine is case sensitive. we store the shader name with case information and save with case -// information as well. but we assume there won't be any case conflict and so when doing lookups based on shader name, -// we compare as case insensitive. That is Radiant is case insensitive, but knows that the engine is case sensitive. -//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present -template -void parseTextureName( StringType& name, const char* token ){ - StringOutputStream cleaned( 256 ); - cleaned << PathCleaned( token ); - name = CopiedString( StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ) ).c_str(); // remove extension -} - -bool Tokeniser_parseTextureName( Tokeniser& tokeniser, TextureExpression& name ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#texture-name" ); - return false; - } - parseTextureName( name, token ); - return true; -} - -bool Tokeniser_parseShaderName( Tokeniser& tokeniser, CopiedString& name ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#shader-name" ); - return false; - } - parseTextureName( name, token ); - return true; -} - -bool Tokeniser_parseString( Tokeniser& tokeniser, ShaderString& string ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#string" ); - return false; - } - string = token; - return true; -} - - -typedef std::list ShaderParameters; -typedef std::list ShaderArguments; - -typedef std::pair BlendFuncExpression; - -class ShaderTemplate -{ -std::size_t m_refcount; -CopiedString m_Name; -CopiedString m_WadName; -public: - -ShaderParameters m_params; - -TextureExpression m_textureName; -TextureExpression m_diffuse; -TextureExpression m_bump; -ShaderValue m_heightmapScale; -TextureExpression m_specular; -TextureExpression m_lightFalloffImage; - -int m_nFlags; -float m_fTrans; - -// alphafunc stuff -IShader::EAlphaFunc m_AlphaFunc; -float m_AlphaRef; -// cull stuff -IShader::ECull m_Cull; - -ShaderTemplate() : - m_refcount( 0 ){ - m_nFlags = 0; - m_fTrans = 1.0f; -} - -void IncRef(){ - ++m_refcount; -} - -void DecRef(){ - ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" ); - if ( --m_refcount == 0 ) { - delete this; - } -} - -std::size_t refcount(){ - return m_refcount; -} - -const char* getName() const { - return m_Name.c_str(); -} - -void setName( const char* name ){ - m_Name = name; -} - -// ----------------------------------------- - -bool parseDoom3( Tokeniser& tokeniser ); - -bool parseQuake3( Tokeniser& tokeniser ); - -bool parseTemplate( Tokeniser& tokeniser ); - - -void CreateDefault( const char *name ){ - if ( g_enableDefaultShaders ) { - m_textureName = name; - } - else - { - m_textureName = ""; - } - setName( name ); -} - - -class MapLayerTemplate -{ -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -public: -MapLayerTemplate( const TextureExpression& texture, const BlendFuncExpression& blendFunc, bool clampToBorder, const ShaderValue& alphaTest ) : - m_texture( texture ), - m_blendFunc( blendFunc ), - m_clampToBorder( false ), - m_alphaTest( alphaTest ){ -} - -const TextureExpression& texture() const { - return m_texture; -} - -const BlendFuncExpression& blendFunc() const { - return m_blendFunc; -} - -bool clampToBorder() const { - return m_clampToBorder; -} - -const ShaderValue& alphaTest() const { - return m_alphaTest; -} -}; - -typedef std::vector MapLayers; -MapLayers m_layers; -}; - - -bool Doom3Shader_parseHeightmap( Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale ){ - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, bump ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "," ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseString( tokeniser, heightmapScale ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - return true; -} - -bool Doom3Shader_parseAddnormals( Tokeniser& tokeniser, TextureExpression& bump ){ - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, bump ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "," ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "heightmap" ) ); - TextureExpression heightmapName; - ShaderValue heightmapScale; - RETURN_FALSE_IF_FAIL( Doom3Shader_parseHeightmap( tokeniser, heightmapName, heightmapScale ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - return true; -} - -bool Doom3Shader_parseBumpmap( Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#bumpmap" ); - return false; - } - if ( string_equal( token, "heightmap" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseHeightmap( tokeniser, bump, heightmapScale ) ); - } - else if ( string_equal( token, "addnormals" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseAddnormals( tokeniser, bump ) ); - } - else - { - parseTextureName( bump, token ); - } - return true; -} - -enum LayerTypeId -{ - LAYER_NONE, - LAYER_BLEND, - LAYER_DIFFUSEMAP, - LAYER_BUMPMAP, - LAYER_SPECULARMAP -}; - -class LayerTemplate -{ -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -ShaderValue m_heightmapScale; - -LayerTemplate() : m_type( LAYER_NONE ), m_blendFunc( "GL_ONE", "GL_ZERO" ), m_clampToBorder( false ), m_alphaTest( "-1" ), m_heightmapScale( "0" ){ -} -}; - -bool parseShaderParameters( Tokeniser& tokeniser, ShaderParameters& params ){ - Tokeniser_parseToken( tokeniser, "(" ); - for (;; ) - { - const char* param = tokeniser.getToken(); - if ( string_equal( param, ")" ) ) { - break; - } - params.push_back( param ); - const char* comma = tokeniser.getToken(); - if ( string_equal( comma, ")" ) ) { - break; - } - if ( !string_equal( comma, "," ) ) { - Tokeniser_unexpectedError( tokeniser, comma, "," ); - return false; - } - } - return true; -} - -bool ShaderTemplate::parseTemplate( Tokeniser& tokeniser ){ - m_Name = tokeniser.getToken(); - if ( !parseShaderParameters( tokeniser, m_params ) ) { - globalErrorStream() << "shader template: " << makeQuoted( m_Name.c_str() ) << ": parameter parse failed\n"; - return false; - } - - return parseDoom3( tokeniser ); -} - -bool ShaderTemplate::parseDoom3( Tokeniser& tokeniser ){ - LayerTemplate currentLayer; - bool isFog = false; - - // we need to read until we hit a balanced } - int depth = 0; - for (;; ) - { - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - return false; - } - - if ( string_equal( token, "{" ) ) { - ++depth; - continue; - } - else if ( string_equal( token, "}" ) ) { - --depth; - if ( depth < 0 ) { // error - return false; - } - if ( depth == 0 ) { // end of shader - break; - } - if ( depth == 1 ) { // end of layer - if ( currentLayer.m_type == LAYER_DIFFUSEMAP ) { - m_diffuse = currentLayer.m_texture; - } - else if ( currentLayer.m_type == LAYER_BUMPMAP ) { - m_bump = currentLayer.m_texture; - } - else if ( currentLayer.m_type == LAYER_SPECULARMAP ) { - m_specular = currentLayer.m_texture; - } - else if ( !string_empty( currentLayer.m_texture.c_str() ) ) { - m_layers.push_back( MapLayerTemplate( - currentLayer.m_texture.c_str(), - currentLayer.m_blendFunc, - currentLayer.m_clampToBorder, - currentLayer.m_alphaTest - ) ); - } - currentLayer.m_type = LAYER_NONE; - currentLayer.m_texture = ""; - } - continue; - } - - if ( depth == 2 ) { // in layer - if ( string_equal_nocase( token, "blend" ) ) { - const char* blend = tokeniser.getToken(); - - if ( blend == 0 ) { - Tokeniser_unexpectedError( tokeniser, blend, "#blend" ); - return false; - } - - if ( string_equal_nocase( blend, "diffusemap" ) ) { - currentLayer.m_type = LAYER_DIFFUSEMAP; - } - else if ( string_equal_nocase( blend, "bumpmap" ) ) { - currentLayer.m_type = LAYER_BUMPMAP; - } - else if ( string_equal_nocase( blend, "specularmap" ) ) { - currentLayer.m_type = LAYER_SPECULARMAP; - } - else - { - currentLayer.m_blendFunc.first = blend; - - const char* comma = tokeniser.getToken(); - - if ( comma == 0 ) { - Tokeniser_unexpectedError( tokeniser, comma, "#comma" ); - return false; - } - - if ( string_equal( comma, "," ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseString( tokeniser, currentLayer.m_blendFunc.second ) ); - } - else - { - currentLayer.m_blendFunc.second = ""; - tokeniser.ungetToken(); - } - } - } - else if ( string_equal_nocase( token, "map" ) ) { - if ( currentLayer.m_type == LAYER_BUMPMAP ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseBumpmap( tokeniser, currentLayer.m_texture, currentLayer.m_heightmapScale ) ); - } - else - { - const char* map = tokeniser.getToken(); - - if ( map == 0 ) { - Tokeniser_unexpectedError( tokeniser, map, "#map" ); - return false; - } - - if ( string_equal( map, "makealpha" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - const char* texture = tokeniser.getToken(); - if ( texture == 0 ) { - Tokeniser_unexpectedError( tokeniser, texture, "#texture" ); - return false; - } - currentLayer.m_texture = texture; - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - } - else - { - parseTextureName( currentLayer.m_texture, map ); - } - } - } - else if ( string_equal_nocase( token, "zeroclamp" ) ) { - currentLayer.m_clampToBorder = true; - } -#if 0 - else if ( string_equal_nocase( token, "alphaTest" ) ) { - Tokeniser_getFloat( tokeniser, currentLayer.m_alphaTest ); - } -#endif - } - else if ( depth == 1 ) { - if ( string_equal_nocase( token, "qer_editorimage" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_textureName ) ); - } - else if ( string_equal_nocase( token, "qer_trans" ) ) { - m_fTrans = string_read_float( tokeniser.getToken() ); - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "translucent" ) ) { - m_fTrans = 1; - m_nFlags |= QER_TRANS; - } - else if ( string_equal( token, "DECAL_MACRO" ) ) { - m_fTrans = 1; - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "bumpmap" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseBumpmap( tokeniser, m_bump, m_heightmapScale ) ); - } - else if ( string_equal_nocase( token, "diffusemap" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_diffuse ) ); - } - else if ( string_equal_nocase( token, "specularmap" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_specular ) ); - } - else if ( string_equal_nocase( token, "twosided" ) ) { - m_Cull = IShader::eCullNone; - m_nFlags |= QER_CULL; - } - else if ( string_equal_nocase( token, "nodraw" ) ) { - m_nFlags |= QER_NODRAW; - } - else if ( string_equal_nocase( token, "nonsolid" ) ) { - m_nFlags |= QER_NONSOLID; - } - else if ( string_equal_nocase( token, "liquid" ) ) { - m_nFlags |= QER_WATER; - } - else if ( string_equal_nocase( token, "areaportal" ) ) { - m_nFlags |= QER_AREAPORTAL; - } - else if ( string_equal_nocase( token, "playerclip" ) - || string_equal_nocase( token, "monsterclip" ) - || string_equal_nocase( token, "ikclip" ) - || string_equal_nocase( token, "moveableclip" ) ) { - m_nFlags |= QER_CLIP; - } - if ( string_equal_nocase( token, "fogLight" ) ) { - isFog = true; - } - else if ( !isFog && string_equal_nocase( token, "lightFalloffImage" ) ) { - const char* lightFalloffImage = tokeniser.getToken(); - if ( lightFalloffImage == 0 ) { - Tokeniser_unexpectedError( tokeniser, lightFalloffImage, "#lightFalloffImage" ); - return false; - } - if ( string_equal_nocase( lightFalloffImage, "makeintensity" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - TextureExpression name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, name ) ); - m_lightFalloffImage = name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - } - else - { - m_lightFalloffImage = lightFalloffImage; - } - } - } - } - - if ( string_empty( m_textureName.c_str() ) ) { - m_textureName = m_diffuse; - } - - return true; -} - -typedef SmartPointer ShaderTemplatePointer; -typedef std::map ShaderTemplateMap; - -ShaderTemplateMap g_shaders; -ShaderTemplateMap g_shaderTemplates; - -ShaderTemplate* findTemplate( const char* name ){ - ShaderTemplateMap::iterator i = g_shaderTemplates.find( name ); - if ( i != g_shaderTemplates.end() ) { - return ( *i ).second.get(); - } - return 0; -} - -class ShaderDefinition -{ -public: -ShaderDefinition( ShaderTemplate* shaderTemplate, const ShaderArguments& args, const char* filename ) - : shaderTemplate( shaderTemplate ), args( args ), filename( filename ){ -} - -ShaderTemplate* shaderTemplate; -ShaderArguments args; -const char* filename; -}; - -typedef std::map ShaderDefinitionMap; - -ShaderDefinitionMap g_shaderDefinitions; - -bool parseTemplateInstance( Tokeniser& tokeniser, const char* filename ){ - CopiedString name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseShaderName( tokeniser, name ) ); - const char* templateName = tokeniser.getToken(); - ShaderTemplate* shaderTemplate = findTemplate( templateName ); - if ( shaderTemplate == 0 ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": shader template not found: " << makeQuoted( templateName ) << "\n"; - } - - ShaderArguments args; - if ( !parseShaderParameters( tokeniser, args ) ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": argument parse failed\n"; - return false; - } - - if ( shaderTemplate != 0 ) { - if ( !g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate, args, filename ) ) ).second ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": already exists, second definition ignored\n"; - } - } - return true; -} - - -const char* evaluateShaderValue( const char* value, const ShaderParameters& params, const ShaderArguments& args ){ - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* other = ( *i ).c_str(); - if ( string_equal( value, other ) ) { - return ( *j ).c_str(); - } - } - return value; -} - -///\todo BlendFunc parsing -BlendFunc evaluateBlendFunc( const BlendFuncExpression& blendFunc, const ShaderParameters& params, const ShaderArguments& args ){ - return BlendFunc( BLEND_ONE, BLEND_ZERO ); -} - -qtexture_t* evaluateTexture( const TextureExpression& texture, const ShaderParameters& params, const ShaderArguments& args, const LoadImageCallback& loader = GlobalTexturesCache().defaultLoader() ){ - StringOutputStream result( 64 ); - const char* expression = texture.c_str(); - const char* end = expression + string_length( expression ); - if ( !string_empty( expression ) ) { - for (;; ) - { - const char* best = end; - const char* bestParam = 0; - const char* bestArg = 0; - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* found = strstr( expression, ( *i ).c_str() ); - if ( found != 0 && found < best ) { - best = found; - bestParam = ( *i ).c_str(); - bestArg = ( *j ).c_str(); - } - } - if ( best != end ) { - result << StringRange( expression, best ); - result << PathCleaned( bestArg ); - expression = best + string_length( bestParam ); - } - else - { - break; - } - } - result << expression; - } - return GlobalTexturesCache().capture( loader, result.c_str() ); -} - -float evaluateFloat( const ShaderValue& value, const ShaderParameters& params, const ShaderArguments& args ){ - const char* result = evaluateShaderValue( value.c_str(), params, args ); - float f; - if ( !string_parse_float( result, f ) ) { - globalErrorStream() << "parsing float value failed: " << makeQuoted( result ) << "\n"; - } - return f; -} - -BlendFactor evaluateBlendFactor( const ShaderValue& value, const ShaderParameters& params, const ShaderArguments& args ){ - const char* result = evaluateShaderValue( value.c_str(), params, args ); - - if ( string_equal_nocase( result, "gl_zero" ) ) { - return BLEND_ZERO; - } - if ( string_equal_nocase( result, "gl_one" ) ) { - return BLEND_ONE; - } - if ( string_equal_nocase( result, "gl_src_color" ) ) { - return BLEND_SRC_COLOUR; - } - if ( string_equal_nocase( result, "gl_one_minus_src_color" ) ) { - return BLEND_ONE_MINUS_SRC_COLOUR; - } - if ( string_equal_nocase( result, "gl_src_alpha" ) ) { - return BLEND_SRC_ALPHA; - } - if ( string_equal_nocase( result, "gl_one_minus_src_alpha" ) ) { - return BLEND_ONE_MINUS_SRC_ALPHA; - } - if ( string_equal_nocase( result, "gl_dst_color" ) ) { - return BLEND_DST_COLOUR; - } - if ( string_equal_nocase( result, "gl_one_minus_dst_color" ) ) { - return BLEND_ONE_MINUS_DST_COLOUR; - } - if ( string_equal_nocase( result, "gl_dst_alpha" ) ) { - return BLEND_DST_ALPHA; - } - if ( string_equal_nocase( result, "gl_one_minus_dst_alpha" ) ) { - return BLEND_ONE_MINUS_DST_ALPHA; - } - if ( string_equal_nocase( result, "gl_src_alpha_saturate" ) ) { - return BLEND_SRC_ALPHA_SATURATE; - } - - globalErrorStream() << "parsing blend-factor value failed: " << makeQuoted( result ) << "\n"; - return BLEND_ZERO; -} - -class CShader : public IShader -{ -std::size_t m_refcount; - -const ShaderTemplate& m_template; -const ShaderArguments& m_args; -const char* m_filename; -// name is shader-name, otherwise texture-name ( if not a real shader ) -CopiedString m_Name; -CopiedString m_WadName; - -qtexture_t* m_pTexture; -qtexture_t* m_notfound; -qtexture_t* m_pDiffuse; -float m_heightmapScale; -qtexture_t* m_pBump; -qtexture_t* m_pSpecular; -qtexture_t* m_pLightFalloffImage; -BlendFunc m_blendFunc; - -bool m_bInUse; - - -public: -static bool m_lightingEnabled; - -CShader( const ShaderDefinition& definition ) : - m_refcount( 0 ), - m_template( *definition.shaderTemplate ), - m_args( definition.args ), - m_filename( definition.filename ), - m_blendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ), - m_bInUse( false ){ - m_pTexture = 0; - m_pDiffuse = 0; - m_pBump = 0; - m_pSpecular = 0; - - m_notfound = 0; - - realise(); -} - -virtual ~CShader(){ - unrealise(); - - ASSERT_MESSAGE( m_refcount == 0, "deleting active shader" ); -} - -// IShaders implementation ----------------- -void IncRef(){ - ++m_refcount; -} - -void DecRef(){ - ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" ); - if ( --m_refcount == 0 ) { - delete this; - } -} - -std::size_t refcount(){ - return m_refcount; -} - -// get/set the qtexture_t* Radiant uses to represent this shader object -qtexture_t* getTexture() const { - return m_pTexture; -} - -qtexture_t* getDiffuse() const { - return m_pDiffuse; -} - -qtexture_t* getBump() const { - return m_pBump; -} - -qtexture_t* getSpecular() const { - return m_pSpecular; -} - -// get shader name -const char* getName() const { - return m_Name.c_str(); -} - -const char* getWadName() const { - return m_WadName.c_str(); -} - -bool IsInUse() const { - return m_bInUse; -} - -void SetInUse( bool bInUse ){ - m_bInUse = bInUse; - g_ActiveShadersChangedNotify(); -} - -// get the shader flags -int getFlags() const { - return m_template.m_nFlags; -} - -// get the transparency value -float getTrans() const { - return m_template.m_fTrans; -} - -int getPolygonOffset() const -{ - return 0; -} - -// test if it's a true shader, or a default shader created to wrap around a texture -bool IsDefault() const { - return string_empty( m_filename ); -} - -// get the alphaFunc -void getAlphaFunc( EAlphaFunc *func, float *ref ) { *func = m_template.m_AlphaFunc; *ref = m_template.m_AlphaRef; }; -BlendFunc getBlendFunc() const { - return m_blendFunc; -} - -// get the cull type -ECull getCull(){ - return m_template.m_Cull; -}; - -// get shader file name ( ie the file where this one is defined ) -const char* getShaderFileName() const { - return m_filename; -} -// ----------------------------------------- - -void realise() -{ - m_pTexture = evaluateTexture(m_template.m_textureName, m_template.m_params, m_args); - - if (m_pTexture->texture_number == 0) { - m_notfound = m_pTexture; - { - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" << (IsDefault() ? "notex.tga" : "shadernotex.tga"); - m_pTexture = GlobalTexturesCache().capture(LoadImageCallback(0, loadBitmap), name.c_str()); - } - } -} - -void unrealise(){ - GlobalTexturesCache().release( m_pTexture ); - - if ( m_notfound != 0 ) { - GlobalTexturesCache().release( m_notfound ); - } - - unrealiseLighting(); -} - -void realiseLighting(){ - if ( m_lightingEnabled ) { - LoadImageCallback loader = GlobalTexturesCache().defaultLoader(); - if ( !string_empty( m_template.m_heightmapScale.c_str() ) ) { - m_heightmapScale = evaluateFloat( m_template.m_heightmapScale, m_template.m_params, m_args ); - loader = LoadImageCallback( &m_heightmapScale, loadHeightmap ); - } - m_pDiffuse = evaluateTexture( m_template.m_diffuse, m_template.m_params, m_args ); - m_pBump = evaluateTexture( m_template.m_bump, m_template.m_params, m_args, loader ); - m_pSpecular = evaluateTexture( m_template.m_specular, m_template.m_params, m_args ); - m_pLightFalloffImage = evaluateTexture( m_template.m_lightFalloffImage, m_template.m_params, m_args ); - - for ( ShaderTemplate::MapLayers::const_iterator i = m_template.m_layers.begin(); i != m_template.m_layers.end(); ++i ) - { - m_layers.push_back( evaluateLayer( *i, m_template.m_params, m_args ) ); - } - - if ( m_layers.size() == 1 ) { - const BlendFuncExpression& blendFunc = m_template.m_layers.front().blendFunc(); - if ( !string_empty( blendFunc.second.c_str() ) ) { - m_blendFunc = BlendFunc( - evaluateBlendFactor( blendFunc.first.c_str(), m_template.m_params, m_args ), - evaluateBlendFactor( blendFunc.second.c_str(), m_template.m_params, m_args ) - ); - } - else - { - const char* blend = evaluateShaderValue( blendFunc.first.c_str(), m_template.m_params, m_args ); - - if ( string_equal_nocase( blend, "add" ) ) { - m_blendFunc = BlendFunc( BLEND_ONE, BLEND_ONE ); - } - else if ( string_equal_nocase( blend, "filter" ) ) { - m_blendFunc = BlendFunc( BLEND_DST_COLOUR, BLEND_ZERO ); - } - else if ( string_equal_nocase( blend, "blend" ) ) { - m_blendFunc = BlendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ); - } - else - { - globalErrorStream() << "parsing blend value failed: " << makeQuoted( blend ) << "\n"; - } - } - } - } -} - -void unrealiseLighting(){ - if ( m_lightingEnabled ) { - GlobalTexturesCache().release( m_pDiffuse ); - GlobalTexturesCache().release( m_pBump ); - GlobalTexturesCache().release( m_pSpecular ); - - GlobalTexturesCache().release( m_pLightFalloffImage ); - - for ( MapLayers::iterator i = m_layers.begin(); i != m_layers.end(); ++i ) - { - GlobalTexturesCache().release( ( *i ).texture() ); - } - m_layers.clear(); - - m_blendFunc = BlendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ); - } -} - -// set shader name -void setName( const char* name ){ - m_Name = name; -} - -void setWadName( const char* name ){ - m_WadName = name; -} - -class MapLayer : public ShaderLayer -{ -qtexture_t* m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -public: -MapLayer( qtexture_t* texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest ) : - m_texture( texture ), - m_blendFunc( blendFunc ), - m_clampToBorder( false ), - m_alphaTest( alphaTest ){ -} - -qtexture_t* texture() const { - return m_texture; -} - -BlendFunc blendFunc() const { - return m_blendFunc; -} - -bool clampToBorder() const { - return m_clampToBorder; -} - -float alphaTest() const { - return m_alphaTest; -} -}; - -static MapLayer evaluateLayer( const ShaderTemplate::MapLayerTemplate& layerTemplate, const ShaderParameters& params, const ShaderArguments& args ){ - return MapLayer( - evaluateTexture( layerTemplate.texture(), params, args ), - evaluateBlendFunc( layerTemplate.blendFunc(), params, args ), - layerTemplate.clampToBorder(), - evaluateFloat( layerTemplate.alphaTest(), params, args ) - ); -} - -typedef std::vector MapLayers; -MapLayers m_layers; - -const ShaderLayer* firstLayer() const { - if ( m_layers.empty() ) { - return 0; - } - return &m_layers.front(); -} - -void forEachLayer(const ShaderLayerCallback &callback) const -{ - for (MapLayers::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) { - callback(*i); - } -} - -qtexture_t* lightFalloffImage() const { - if ( !string_empty( m_template.m_lightFalloffImage.c_str() ) ) { - return m_pLightFalloffImage; - } - return 0; -} -}; - -bool CShader::m_lightingEnabled = false; - -typedef SmartPointer ShaderPointer; -typedef std::map shaders_t; - -shaders_t g_ActiveShaders; - -static shaders_t::iterator g_ActiveShadersIterator; - -void ActiveShaders_IteratorBegin(){ - g_ActiveShadersIterator = g_ActiveShaders.begin(); -} - -bool ActiveShaders_IteratorAtEnd(){ - return g_ActiveShadersIterator == g_ActiveShaders.end(); -} - -IShader *ActiveShaders_IteratorCurrent(){ - return static_cast( g_ActiveShadersIterator->second ); -} - -void ActiveShaders_IteratorIncrement(){ - ++g_ActiveShadersIterator; -} - -void debug_check_shaders( shaders_t& shaders ){ - for ( shaders_t::iterator i = shaders.begin(); i != shaders.end(); ++i ) - { - ASSERT_MESSAGE( i->second->refcount() == 1, "orphan shader still referenced" ); - } -} - -// will free all GL binded qtextures and shaders -// NOTE: doesn't make much sense out of Radiant exit or called during a reload -void FreeShaders(){ - // reload shaders - // empty the actives shaders list - debug_check_shaders( g_ActiveShaders ); - g_ActiveShaders.clear(); - g_shaders.clear(); - g_shaderTemplates.clear(); - g_shaderDefinitions.clear(); - g_ActiveShadersChangedNotify(); -} - -bool ShaderTemplate::parseQuake3( Tokeniser& tokeniser ){ - // name of the qtexture_t we'll use to represent this shader ( this one has the "textures\" before ) - m_textureName = m_Name.c_str(); - - tokeniser.nextLine(); - - // we need to read until we hit a balanced } - int depth = 0; - for (;; ) - { - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - return false; - } - - if ( string_equal( token, "{" ) ) { - ++depth; - continue; - } - else if ( string_equal( token, "}" ) ) { - --depth; - if ( depth < 0 ) { // underflow - return false; - } - if ( depth == 0 ) { // end of shader - break; - } - - continue; - } - - if ( depth == 1 ) { - if ( string_equal_nocase( token, "qer_nocarve" ) ) { - m_nFlags |= QER_NOCARVE; - } - else if ( string_equal_nocase( token, "qer_trans" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, m_fTrans ) ); - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "qer_editorimage" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_textureName ) ); - } - else if ( string_equal_nocase( token, "qer_alphafunc" ) ) { - const char* alphafunc = tokeniser.getToken(); - - if ( alphafunc == 0 ) { - Tokeniser_unexpectedError( tokeniser, alphafunc, "#alphafunc" ); - return false; - } - - if ( string_equal_nocase( alphafunc, "equal" ) ) { - m_AlphaFunc = IShader::eEqual; - } - else if ( string_equal_nocase( alphafunc, "greater" ) ) { - m_AlphaFunc = IShader::eGreater; - } - else if ( string_equal_nocase( alphafunc, "less" ) ) { - m_AlphaFunc = IShader::eLess; - } - else if ( string_equal_nocase( alphafunc, "gequal" ) ) { - m_AlphaFunc = IShader::eGEqual; - } - else if ( string_equal_nocase( alphafunc, "lequal" ) ) { - m_AlphaFunc = IShader::eLEqual; - } - else - { - m_AlphaFunc = IShader::eAlways; - } - - m_nFlags |= QER_ALPHATEST; - - RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, m_AlphaRef ) ); - } - else if ( string_equal_nocase( token, "cull" ) ) { - const char* cull = tokeniser.getToken(); - - if ( cull == 0 ) { - Tokeniser_unexpectedError( tokeniser, cull, "#cull" ); - return false; - } - - if ( string_equal_nocase( cull, "none" ) - || string_equal_nocase( cull, "twosided" ) - || string_equal_nocase( cull, "disable" ) ) { - m_Cull = IShader::eCullNone; - } - else if ( string_equal_nocase( cull, "back" ) - || string_equal_nocase( cull, "backside" ) - || string_equal_nocase( cull, "backsided" ) ) { - m_Cull = IShader::eCullBack; - } - else - { - m_Cull = IShader::eCullBack; - } - - m_nFlags |= QER_CULL; - } - else if ( string_equal_nocase( token, "surfaceparm" ) ) { - const char* surfaceparm = tokeniser.getToken(); - - if ( surfaceparm == 0 ) { - Tokeniser_unexpectedError( tokeniser, surfaceparm, "#surfaceparm" ); - return false; - } - - if ( string_equal_nocase( surfaceparm, "fog" ) ) { - m_nFlags |= QER_FOG; - if ( m_fTrans == 1.0f ) { // has not been explicitly set by qer_trans - m_fTrans = 0.35f; - } - } - else if ( string_equal_nocase( surfaceparm, "nodraw" ) ) { - m_nFlags |= QER_NODRAW; - } - else if ( string_equal_nocase( surfaceparm, "nonsolid" ) ) { - m_nFlags |= QER_NONSOLID; - } - else if ( string_equal_nocase( surfaceparm, "water" ) ) { - m_nFlags |= QER_WATER; - } - else if ( string_equal_nocase( surfaceparm, "lava" ) ) { - m_nFlags |= QER_LAVA; - } - else if ( string_equal_nocase( surfaceparm, "areaportal" ) ) { - m_nFlags |= QER_AREAPORTAL; - } - else if ( string_equal_nocase( surfaceparm, "playerclip" ) ) { - m_nFlags |= QER_CLIP; - } - else if ( string_equal_nocase( surfaceparm, "botclip" ) ) { - m_nFlags |= QER_BOTCLIP; - } - } - } - } - - return true; -} - -class Layer -{ -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -float m_heightmapScale; - -Layer() : m_type( LAYER_NONE ), m_blendFunc( BLEND_ONE, BLEND_ZERO ), m_clampToBorder( false ), m_alphaTest( -1 ), m_heightmapScale( 0 ){ -} -}; - -std::list g_shaderFilenames; - -void ParseShaderFile( Tokeniser& tokeniser, const char* filename ){ - g_shaderFilenames.push_back( filename ); - filename = g_shaderFilenames.back().c_str(); - tokeniser.nextLine(); - for (;; ) - { - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - break; - } - - if ( string_equal( token, "table" ) ) { - if ( tokeniser.getToken() == 0 ) { - Tokeniser_unexpectedError( tokeniser, 0, "#table-name" ); - return; - } - if ( !Tokeniser_parseToken( tokeniser, "{" ) ) { - return; - } - for (;; ) - { - const char* option = tokeniser.getToken(); - if ( string_equal( option, "{" ) ) { - for (;; ) - { - const char* value = tokeniser.getToken(); - if ( string_equal( value, "}" ) ) { - break; - } - } - - if ( !Tokeniser_parseToken( tokeniser, "}" ) ) { - return; - } - break; - } - } - } - else - { - if ( string_equal( token, "guide" ) ) { - parseTemplateInstance( tokeniser, filename ); - } - else - { - if ( !string_equal( token, "material" ) - && !string_equal( token, "particle" ) - && !string_equal( token, "skin" ) ) { - tokeniser.ungetToken(); - } - // first token should be the path + name.. ( from base ) - CopiedString name; - if ( !Tokeniser_parseShaderName( tokeniser, name ) ) { - } - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->setName( name.c_str() ); - - g_shaders.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - bool result = ( g_shaderLanguage == SHADERLANGUAGE_QUAKE3 ) - ? shaderTemplate->parseQuake3( tokeniser ) - : shaderTemplate->parseDoom3( tokeniser ); - if ( result ) { - // do we already have this shader? - if ( !g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( shaderTemplate->getName(), ShaderDefinition( shaderTemplate.get(), ShaderArguments(), filename ) ) ).second ) { -#if GDEF_DEBUG - globalOutputStream() << "WARNING: shader " << shaderTemplate->getName() << " is already in memory, definition in " << filename << " ignored.\n"; -#endif - } - } - else - { - globalErrorStream() << "Error parsing shader " << shaderTemplate->getName() << "\n"; - return; - } - } - } - } -} - -void parseGuideFile( Tokeniser& tokeniser, const char* filename ){ - tokeniser.nextLine(); - for (;; ) - { - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - break; - } - - if ( string_equal( token, "guide" ) ) { - // first token should be the path + name.. ( from base ) - ShaderTemplatePointer shaderTemplate( new ShaderTemplate ); - shaderTemplate->parseTemplate( tokeniser ); - if ( !g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ).second ) { - globalErrorStream() << "guide " << makeQuoted( shaderTemplate->getName() ) << ": already defined, second definition ignored\n"; - } - } - else if ( string_equal( token, "inlineGuide" ) ) { - // skip entire inlineGuide definition - std::size_t depth = 0; - for (;; ) - { - tokeniser.nextLine(); - token = tokeniser.getToken(); - if ( string_equal( token, "{" ) ) { - ++depth; - } - else if ( string_equal( token, "}" ) ) { - if ( --depth == 0 ) { - break; - } - } - } - } - } -} - -void LoadShaderFile( const char* filename ){ - ArchiveTextFile* file = GlobalFileSystem().openTextFile( filename ); - - if ( file != 0 ) { - globalOutputStream() << "Parsing shaderfile " << filename << "\n"; - - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser( file->getInputStream() ); - - ParseShaderFile( tokeniser, filename ); - - tokeniser.release(); - file->release(); - } - else - { - globalOutputStream() << "Unable to read shaderfile " << filename << "\n"; - } -} - -void loadGuideFile( const char* filename ){ - StringOutputStream fullname( 256 ); - fullname << "guides/" << filename; - ArchiveTextFile* file = GlobalFileSystem().openTextFile( fullname.c_str() ); - - if ( file != 0 ) { - globalOutputStream() << "Parsing guide file " << fullname.c_str() << "\n"; - - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser( file->getInputStream() ); - - parseGuideFile( tokeniser, fullname.c_str() ); - - tokeniser.release(); - file->release(); - } - else - { - globalOutputStream() << "Unable to read guide file " << fullname.c_str() << "\n"; - } -} - -CShader* Try_Shader_ForName( const char* name ){ - { - shaders_t::iterator i = g_ActiveShaders.find( name ); - if ( i != g_ActiveShaders.end() ) { - return ( *i ).second; - } - } - // active shader was not found - - // find matching shader definition - ShaderDefinitionMap::iterator i = g_shaderDefinitions.find( name ); - if ( i == g_shaderDefinitions.end() ) { - // shader definition was not found - - // create new shader definition from default shader template - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->CreateDefault( name ); - g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - i = g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate.get(), ShaderArguments(), "" ) ) ).first; - } - - // create shader from existing definition - ShaderPointer pShader( new CShader( ( *i ).second ) ); - pShader->setName( name ); - g_ActiveShaders.insert( shaders_t::value_type( name, pShader ) ); - g_ActiveShadersChangedNotify(); - return pShader; -} - -IShader *Shader_ForName( const char *name ){ - ASSERT_NOTNULL( name ); - - IShader *pShader = Try_Shader_ForName( name ); - pShader->IncRef(); - return pShader; -} - - -// the list of scripts/*.shader files we need to work with -// those are listed in shaderlist file -GSList *l_shaderfiles = 0; - -GSList* Shaders_getShaderFileList(){ - return l_shaderfiles; -} - -/* - ================== - DumpUnreferencedShaders - usefull function: dumps the list of .shader files that are not referenced to the console - ================== - */ -void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){ - bool listed = false; - - for ( GSList* sh = l_shaderfiles; sh != 0; sh = g_slist_next( sh ) ) - { - if ( !strcmp( (char*)sh->data, filename ) ) { - listed = true; - break; - } - } - - if ( !listed ) { - if ( !bFound ) { - bFound = true; - globalOutputStream() << "Following shader files are not referenced in any shaderlist.txt:\n"; - } - globalOutputStream() << "\t" << filename << "\n"; - } -} - -typedef ReferenceCaller IfFoundDumpUnreferencedShaderCaller; - -void DumpUnreferencedShaders(){ - bool bFound = false; - GlobalFileSystem().forEachFile( g_shadersDirectory, g_shadersExtension, IfFoundDumpUnreferencedShaderCaller( bFound ) ); -} - -void ShaderList_addShaderFile( const char* dirstring ){ - bool found = false; - - for ( GSList* tmp = l_shaderfiles; tmp != 0; tmp = tmp->next ) - { - if ( string_equal_nocase( dirstring, (char*)tmp->data ) ) { - found = true; - globalOutputStream() << "duplicate entry \"" << (char*)tmp->data << "\" in shaderlist.txt\n"; - break; - } - } - - if ( !found ) { - l_shaderfiles = g_slist_append( l_shaderfiles, strdup( dirstring ) ); - } -} - -/* - ================== - BuildShaderList - build a CStringList of shader names - ================== - */ -void BuildShaderList( TextInputStream& shaderlist ){ - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser( shaderlist ); - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - StringOutputStream shaderFile( 64 ); - while ( token != 0 ) - { - // each token should be a shader filename - shaderFile << token << "." << g_shadersExtension; - - ShaderList_addShaderFile( shaderFile.c_str() ); - - tokeniser.nextLine(); - token = tokeniser.getToken(); - - shaderFile.clear(); - } - tokeniser.release(); -} - -void FreeShaderList(){ - while ( l_shaderfiles != 0 ) - { - free( l_shaderfiles->data ); - l_shaderfiles = g_slist_remove( l_shaderfiles, l_shaderfiles->data ); - } -} - -void ShaderList_addFromArchive( const char *archivename ){ - const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" ); - if ( string_empty( shaderpath ) ) { - return; - } - - StringOutputStream shaderlist( 256 ); - shaderlist << DirectoryCleaned( shaderpath ) << "shaderlist.txt"; - - Archive *archive = GlobalFileSystem().getArchive( archivename, false ); - if ( archive ) { - ArchiveTextFile *file = archive->openTextFile( shaderlist.c_str() ); - if ( file ) { - globalOutputStream() << "Found shaderlist.txt in " << archivename << "\n"; - BuildShaderList( file->getInputStream() ); - file->release(); - } - } -} - -#include "stream/filestream.h" - -bool shaderlist_findOrInstall( const char* enginePath, const char* toolsPath, const char* shaderPath, const char* gamename ){ - StringOutputStream absShaderList( 256 ); - absShaderList << enginePath << gamename << '/' << shaderPath << "shaderlist.txt"; - if ( file_exists( absShaderList.c_str() ) ) { - return true; - } - { - StringOutputStream directory( 256 ); - directory << enginePath << gamename << '/' << shaderPath; - if ( !file_exists( directory.c_str() ) && !Q_mkdir( directory.c_str() ) ) { - return false; - } - } - { - StringOutputStream defaultShaderList( 256 ); - defaultShaderList << toolsPath << gamename << '/' << "default_shaderlist.txt"; - if ( file_exists( defaultShaderList.c_str() ) ) { - return file_copy( defaultShaderList.c_str(), absShaderList.c_str() ); - } - } - return false; -} - -void Shaders_Load(){ - if ( g_shaderLanguage == SHADERLANGUAGE_QUAKE4 ) { - GlobalFileSystem().forEachFile("guides/", "guide", makeCallbackF(loadGuideFile), 0); - } - - const char* shaderPath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" ); - if ( !string_empty( shaderPath ) ) { - StringOutputStream path( 256 ); - path << DirectoryCleaned( shaderPath ); - - if ( g_useShaderList ) { - // preload shader files that have been listed in shaderlist.txt - const char* basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue( "basegame" ); - const char* gamename = GlobalRadiant().getGameName(); - const char* enginePath = GlobalRadiant().getEnginePath(); - const char* toolsPath = GlobalRadiant().getGameToolsPath(); - - bool isMod = !string_equal( basegame, gamename ); - - if ( !isMod || !shaderlist_findOrInstall( enginePath, toolsPath, path.c_str(), gamename ) ) { - gamename = basegame; - shaderlist_findOrInstall( enginePath, toolsPath, path.c_str(), gamename ); - } - - GlobalFileSystem().forEachArchive(makeCallbackF(ShaderList_addFromArchive), false, true); - DumpUnreferencedShaders(); - } - else - { - GlobalFileSystem().forEachFile(path.c_str(), g_shadersExtension, makeCallbackF(ShaderList_addShaderFile), 0); - } - - GSList *lst = l_shaderfiles; - StringOutputStream shadername( 256 ); - while ( lst ) - { - shadername << path.c_str() << reinterpret_cast( lst->data ); - LoadShaderFile( shadername.c_str() ); - shadername.clear(); - lst = lst->next; - } - } - - //StringPool_analyse( ShaderPool::instance() ); -} - -void Shaders_Free(){ - FreeShaders(); - FreeShaderList(); - g_shaderFilenames.clear(); -} - -ModuleObservers g_observers; - -std::size_t g_shaders_unrealised = 1; // wait until filesystem and is realised before loading anything -bool Shaders_realised(){ - return g_shaders_unrealised == 0; -} - -void Shaders_Realise(){ - if ( --g_shaders_unrealised == 0 ) { - Shaders_Load(); - g_observers.realise(); - } -} - -void Shaders_Unrealise(){ - if ( ++g_shaders_unrealised == 1 ) { - g_observers.unrealise(); - Shaders_Free(); - } -} - -void Shaders_Refresh(){ - Shaders_Unrealise(); - Shaders_Realise(); -} - -class Quake3ShaderSystem : public ShaderSystem, public ModuleObserver -{ -public: -void realise(){ - Shaders_Realise(); -} - -void unrealise(){ - Shaders_Unrealise(); -} - -void refresh(){ - Shaders_Refresh(); -} - -IShader* getShaderForName( const char* name ){ - return Shader_ForName( name ); -} - -void foreachShaderName( const ShaderNameCallback& callback ){ - for ( ShaderDefinitionMap::const_iterator i = g_shaderDefinitions.begin(); i != g_shaderDefinitions.end(); ++i ) - { - callback( ( *i ).first.c_str() ); - } -} - -void beginActiveShadersIterator(){ - ActiveShaders_IteratorBegin(); -} - -bool endActiveShadersIterator(){ - return ActiveShaders_IteratorAtEnd(); -} - -IShader* dereferenceActiveShadersIterator(){ - return ActiveShaders_IteratorCurrent(); -} - -void incrementActiveShadersIterator(){ - ActiveShaders_IteratorIncrement(); -} - -void setActiveShadersChangedNotify( const Callback& notify ){ - g_ActiveShadersChangedNotify = notify; -} - -void attach( ModuleObserver& observer ){ - g_observers.attach( observer ); -} - -void detach( ModuleObserver& observer ){ - g_observers.detach( observer ); -} - -void setLightingEnabled( bool enabled ){ - if ( CShader::m_lightingEnabled != enabled ) { - for ( shaders_t::const_iterator i = g_ActiveShaders.begin(); i != g_ActiveShaders.end(); ++i ) - { - ( *i ).second->unrealiseLighting(); - } - CShader::m_lightingEnabled = enabled; - for ( shaders_t::const_iterator i = g_ActiveShaders.begin(); i != g_ActiveShaders.end(); ++i ) - { - ( *i ).second->realiseLighting(); - } - } -} - -const char* getTexturePrefix() const { - return g_texturePrefix; -} -}; - -Quake3ShaderSystem g_Quake3ShaderSystem; - -ShaderSystem& GetShaderSystem(){ - return g_Quake3ShaderSystem; -} - -void Shaders_Construct(){ - GlobalFileSystem().attach( g_Quake3ShaderSystem ); -} - -void Shaders_Destroy(){ - GlobalFileSystem().detach( g_Quake3ShaderSystem ); - - if ( Shaders_realised() ) { - Shaders_Free(); - } -} diff --git a/plugins/shaders/shaders.h b/plugins/shaders/shaders.h deleted file mode 100644 index 88f193f..0000000 --- a/plugins/shaders/shaders.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H - -void Shaders_Construct(); -void Shaders_Destroy(); -class ShaderSystem; -ShaderSystem& GetShaderSystem(); - -enum ShaderLanguage -{ - SHADERLANGUAGE_QUAKE3, - SHADERLANGUAGE_DOOM3, - SHADERLANGUAGE_QUAKE4 -}; - -extern const char* g_shadersExtension; -extern const char* g_shadersDirectory; -extern ShaderLanguage g_shaderLanguage; -extern bool g_enableDefaultShaders; -extern bool g_useShaderList; -struct _QERPlugImageTable; -extern _QERPlugImageTable* g_bitmapModule; - - -#endif diff --git a/plugins/vfspk3/Makefile b/plugins/vfspk3/Makefile deleted file mode 100644 index eb28767..0000000 --- a/plugins/vfspk3/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o vfs.o vfspk3.o - -# binary target -../../build/plugins/libvfspk3.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libfilematch.a $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -vfs.o: vfs.cpp vfs.h -vfspk3.o: vfspk3.cpp - -clean: - -rm -f *.o ../../build/plugins/libvfspk3.$(LIB_EXT) diff --git a/plugins/vfspk3/archive.cpp b/plugins/vfspk3/archive.cpp deleted file mode 100644 index 49fc1c7..0000000 --- a/plugins/vfspk3/archive.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "iarchive.h" - -#include -#include -#include - -#include "stream/filestream.h" -#include "stream/textfilestream.h" -#include "string/string.h" -#include "os/path.h" -#include "os/file.h" -#include "os/dir.h" -#include "archivelib.h" -#include "fs_path.h" - - -class DirectoryArchive : public Archive { -CopiedString m_root; -public: -DirectoryArchive(const char *root) : m_root(root) -{ -} - -void release() -{ - delete this; -} - -virtual ArchiveFile *openFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - DirectoryArchiveFile *file = new DirectoryArchiveFile(name, path.c_str()); - if (!file->failed()) { - return file; - } - file->release(); - return 0; -} - -virtual ArchiveTextFile *openTextFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - DirectoryArchiveTextFile *file = new DirectoryArchiveTextFile(name, path.c_str()); - if (!file->failed()) { - return file; - } - file->release(); - return 0; -} - -virtual bool containsFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - return file_readable(path.c_str()); -} - -virtual void forEachFile(VisitorFunc visitor, const char *root) -{ - std::vector dirs; - UnixPath path(m_root.c_str()); - path.push(root); - dirs.push_back(directory_open(path.c_str())); - - while (!dirs.empty() && directory_good(dirs.back())) { - const char *name = directory_read_and_increment(dirs.back()); - - if (name == 0) { - directory_close(dirs.back()); - dirs.pop_back(); - path.pop(); - } else if (!string_equal(name, ".") && !string_equal(name, "..")) { - path.push_filename(name); - - bool is_directory = file_is_directory(path.c_str()); - - if (!is_directory) { - visitor.file(path_make_relative(path.c_str(), m_root.c_str())); - } - - path.pop(); - - if (is_directory) { - path.push(name); - - if (!visitor.directory(path_make_relative(path.c_str(), m_root.c_str()), dirs.size())) { - dirs.push_back(directory_open(path.c_str())); - } else { - path.pop(); - } - } - } - } -} -}; - -Archive *OpenArchive(const char *name) -{ - return new DirectoryArchive(name); -} - -#if 0 - -class TestArchive -{ -class TestVisitor : public Archive::IVisitor -{ -public: -virtual void visit( const char* name ){ - int bleh = 0; -} -}; -public: -void test1(){ - Archive* archive = OpenArchive( "d:/quake/id1/" ); - ArchiveFile* file = archive->openFile( "quake101.wad" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( buffer, 1024 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->release(); -} -void test2(){ - Archive* archive = OpenArchive( "d:/gtkradiant_root/baseq3/" ); - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures" ); - archive->release(); -} -TestArchive(){ - test1(); - test2(); -} -}; - -TestArchive g_test; - -#endif diff --git a/plugins/vfspk3/archive.h b/plugins/vfspk3/archive.h deleted file mode 100644 index 2704d25..0000000 --- a/plugins/vfspk3/archive.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ARCHIVE_H ) -#define INCLUDED_ARCHIVE_H - -#include "iarchive.h" - -const _QERArchiveTable *GetArchiveTable(ArchiveModules &archiveModules, const char *type); - -#endif diff --git a/plugins/vfspk3/vfs.cpp b/plugins/vfspk3/vfs.cpp deleted file mode 100644 index df7673b..0000000 --- a/plugins/vfspk3/vfs.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Rules: -// -// - Directories should be searched in the following order: ~/.q3a/baseq3, -// install dir (/usr/local/games/quake3/baseq3) and cd_path (/mnt/cdrom/baseq3). -// -// - Pak files are searched first inside the directories. -// - Case insensitive. -// - Unix-style slashes (/) (windows is backwards .. everyone knows that) -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "vfs.h" -#include "globaldefs.h" - -#include -#include -#include - -#include "qerplugin.h" -#include "idatastream.h" -#include "iarchive.h" - -ArchiveModules &FileSystemQ3API_getArchiveModules(); - -#include "ifilesystem.h" - -#include "generic/callback.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "moduleobservers.h" -#include "filematch.h" -#include "dpkdeps.h" - - -const int VFS_MAXDIRS = 64; - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - -#define gamemode_get GlobalRadiant().getGameMode - - - -// ============================================================================= -// Global variables - -Archive *OpenArchive(const char *name); - -struct archive_entry_t { - CopiedString name; - Archive *archive; - bool is_pakfile; -}; - -#include -#include - -typedef std::list archives_t; - -static archives_t g_archives; -static char g_strDirs[VFS_MAXDIRS][PATH_MAX + 1]; -static int g_numDirs; -static char g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX + 1]; -static int g_numForbiddenDirs = 0; -static bool g_bUsePak = true; - -ModuleObservers g_observers; - -// ============================================================================= -// Static functions - -static void AddSlash(char *str) -{ - std::size_t n = strlen(str); - if (n > 0) { - if (str[n - 1] != '\\' && str[n - 1] != '/') { - globalErrorStream() << "WARNING: directory path does not end with separator: " << str << "\n"; - strcat(str, "/"); - } - } -} - -static void FixDOSName(char *src) -{ - if (src == 0 || strchr(src, '\\') == 0) { - return; - } - - globalErrorStream() << "WARNING: invalid path separator '\\': " << src << "\n"; - - while (*src) { - if (*src == '\\') { - *src = '/'; - } - src++; - } -} - -const _QERArchiveTable *GetArchiveTable(ArchiveModules &archiveModules, const char *ext) -{ - StringOutputStream tmp(16); - tmp << LowerCase(ext); - return archiveModules.findModule(tmp.c_str()); -} - -static Archive *InitPakFile(ArchiveModules &archiveModules, const char *filename) -{ - const _QERArchiveTable *table = GetArchiveTable(archiveModules, path_get_extension(filename)); - - if (table != 0) { - archive_entry_t entry; - entry.name = filename; - - entry.archive = table->m_pfnOpenArchive(filename); - entry.is_pakfile = true; - g_archives.push_back(entry); - globalOutputStream() << " " << path_get_extension(filename) << " file: " << filename << "\n"; - - return entry.archive; - } - - return 0; -} - -static Archive *InitWadFile(ArchiveModules &archiveModules, const char *filename) -{ - const _QERArchiveTable *table = GetArchiveTable(archiveModules, path_get_extension(filename)); - - if (table != 0) { - archive_entry_t entry; - entry.name = filename; - - entry.archive = table->m_pfnOpenArchive(filename); - entry.is_pakfile = false; - g_archives.push_back(entry); - globalOutputStream() << " wad file: " << filename << "\n"; - - return entry.archive; - } - - return 0; -} - -inline void pathlist_prepend_unique(GSList *&pathlist, char *path) -{ - if (g_slist_find_custom(pathlist, path, (GCompareFunc) path_compare) == 0) { - pathlist = g_slist_prepend(pathlist, path); - } else { - g_free(path); - } -} - -class DirectoryListVisitor : public Archive::Visitor { -GSList *&m_matches; -const char *m_directory; -public: -DirectoryListVisitor(GSList *&matches, const char *directory) - : m_matches(matches), m_directory(directory) -{ -} - -void visit(const char *name) -{ - const char *subname = path_make_relative(name, m_directory); - if (subname != name) { - if (subname[0] == '/') { - ++subname; - } - char *dir = g_strdup(subname); - char *last_char = dir + strlen(dir); - if (last_char != dir && *(--last_char) == '/') { - *last_char = '\0'; - } - pathlist_prepend_unique(m_matches, dir); - } -} -}; - -class FileListVisitor : public Archive::Visitor { -GSList *&m_matches; -const char *m_directory; -const char *m_extension; -public: -FileListVisitor(GSList *&matches, const char *directory, const char *extension) - : m_matches(matches), m_directory(directory), m_extension(extension) -{ -} - -void visit(const char *name) -{ - const char *subname = path_make_relative(name, m_directory); - if (subname != name) { - if (subname[0] == '/') { - ++subname; - } - if (m_extension[0] == '*' || extension_equal(path_get_extension(subname), m_extension)) { - pathlist_prepend_unique(m_matches, g_strdup(subname)); - } - } -} -}; - -static GSList *GetListInternal(const char *refdir, const char *ext, bool directories, std::size_t depth) -{ - GSList *files = 0; - - ASSERT_MESSAGE(refdir[strlen(refdir) - 1] == '/', "search path does not end in '/'"); - - if (directories) { - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - DirectoryListVisitor visitor(files, refdir); - (*i).archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eDirectories, depth), refdir); - } - } else { - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - FileListVisitor visitor(files, refdir, ext); - (*i).archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eFiles, depth), refdir); - } - } - - files = g_slist_reverse(files); - - return files; -} - -inline int ascii_to_upper(int c) -{ - if (c >= 'a' && c <= 'z') { - return c - ('a' - 'A'); - } - return c; -} - -/*! - This behaves identically to stricmp(a,b), except that ASCII chars - [\]^`_ come AFTER alphabet chars instead of before. This is because - it converts all alphabet chars to uppercase before comparison, - while stricmp converts them to lowercase. - */ -static int string_compare_nocase_upper(const char *a, const char *b) -{ - for (;;) { - int c1 = ascii_to_upper(*a++); - int c2 = ascii_to_upper(*b++); - - if (c1 < c2) { - return -1; // a < b - } - if (c1 > c2) { - return 1; // a > b - } - if (c1 == 0) { - return 0; // a == b - } - } -} - -// Arnout: note - sort pakfiles in reverse order. This ensures that -// later pakfiles override earlier ones. This because the vfs module -// returns a filehandle to the first file it can find (while it should -// return the filehandle to the file in the most overriding pakfile, the -// last one in the list that is). - -//!\todo Analyse the code in rtcw/q3 to see which order it sorts pak files. -class PakLess { -public: -bool operator()(const CopiedString &self, const CopiedString &other) const -{ - return string_compare_nocase_upper(self.c_str(), other.c_str()) > 0; -} -}; - -typedef std::set Archives; - -Archive *AddPk3Dir(const char *fullpath) -{ - if (g_numDirs == VFS_MAXDIRS) { return 0; } - - strncpy(g_strDirs[g_numDirs], fullpath, PATH_MAX); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - g_numDirs++; - - { - archive_entry_t entry; - entry.name = fullpath; - entry.archive = OpenArchive(fullpath); - entry.is_pakfile = false; - g_archives.push_back(entry); - - return entry.archive; - } -} - -// for Daemon DPK vfs - -Archive *AddDpkDir(const char *fullpath) -{ - return AddPk3Dir(fullpath); -} - -struct pakfile_path_t { - CopiedString fullpath; // full pak dir or pk3dir name - bool is_pakfile; // defines is it .pk3dir or .pk3 file -}; - -typedef std::pair PakfilePathsKV; -typedef std::map PakfilePaths; // key must have no extension, only name - -static PakfilePaths g_pakfile_paths; - -void AddDpkPak(const char *name, const char *fullpath, bool is_pakfile) -{ - pakfile_path_t pakfile_path; - pakfile_path.fullpath = fullpath; - pakfile_path.is_pakfile = is_pakfile; - g_pakfile_paths.insert(PakfilePathsKV(name, pakfile_path)); -} - -// takes name without ext, returns without ext -static const char *GetLatestDpkPakVersion(const char *name) -{ - const char *maxversion = 0; - const char *result = 0; - const char *pakname; - const char *pakversion; - int namelen = string_length(name); - - for (PakfilePaths::iterator i = g_pakfile_paths.begin(); i != g_pakfile_paths.end(); ++i) { - pakname = i->first.c_str(); - if (strncmp(pakname, name, namelen) != 0 || pakname[namelen] != '_') { continue; } - pakversion = pakname + (namelen + 1); - if (maxversion == 0 || DpkPakVersionCmp(pakversion, maxversion) > 0) { - maxversion = pakversion; - result = pakname; - } - } - return result; -} - -// release string after using -static char *GetCurrentMapDpkPakName() -{ - char *mapdir; - char *mapname; - int mapnamelen; - char *result = 0; - - mapname = string_clone(GlobalRadiant().getMapName()); - mapnamelen = string_length(mapname); - - mapdir = strrchr(mapname, '/'); - if (mapdir) { - mapdir -= 12; - if (strncmp(mapdir, ".dpkdir/maps/", 13) == 0) { - *mapdir = '\0'; - mapdir = strrchr(mapname, '/'); - if (mapdir) { mapdir++; } - else { mapdir = mapname; } - result = string_clone(mapdir); - } - } - - string_release(mapname, mapnamelen); - return result; - -} - -// prevent loading duplicates or circular references -static Archives g_loaded_dpk_paks; - -// actual pak adding on initialise, deferred from InitDirectory -// Daemon DPK filesystem doesn't need load all paks it finds -static void LoadDpkPakWithDeps(const char *pakname) -{ - Archive *arc; - ArchiveTextFile *depsFile; - - if (pakname == NULL) { - // load DEPS from game pack - StringOutputStream baseDirectory(256); - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - baseDirectory << GlobalRadiant().getGameToolsPath() << basegame << '/'; - arc = AddDpkDir(baseDirectory.c_str()); - depsFile = arc->openTextFile("DEPS"); - } else { - const char *und = strrchr(pakname, '_'); - if (!und) { - pakname = GetLatestDpkPakVersion(pakname); - } - if (!pakname || g_loaded_dpk_paks.find(pakname) != g_loaded_dpk_paks.end()) { - return; - } - - PakfilePaths::iterator i = g_pakfile_paths.find(pakname); - if (i == g_pakfile_paths.end()) { - return; - } - - if (i->second.is_pakfile) { - arc = InitPakFile(FileSystemQ3API_getArchiveModules(), i->second.fullpath.c_str()); - } else { - arc = AddDpkDir(i->second.fullpath.c_str()); - } - g_loaded_dpk_paks.insert(pakname); - - depsFile = arc->openTextFile("DEPS"); - } - - if (!depsFile) { - return; - } - - { - TextLinesInputStream istream = depsFile->getInputStream(); - - CopiedString line; - char *p_name; - char *p_version; - while (line = istream.readLine(), string_length(line.c_str())) { - if (!DpkReadDepsLine(line.c_str(), &p_name, &p_version)) { continue; } - if (!p_version) { - const char *p_latest = GetLatestDpkPakVersion(p_name); - if (p_latest) { LoadDpkPakWithDeps(p_latest); } - } else { - int len = string_length(p_name) + string_length(p_version) + 1; - char *p_pakname = string_new(len); - sprintf(p_pakname, "%s_%s", p_name, p_version); - LoadDpkPakWithDeps(p_pakname); - string_release(p_pakname, len); - } - string_release(p_name, string_length(p_name)); - if (p_version) { string_release(p_version, string_length(p_version)); } - } - } - - depsFile->release(); -} - -// end for Daemon DPK vfs - -// ============================================================================= -// Global functions - -// reads all pak files from a dir -void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ - int j; - - g_numForbiddenDirs = 0; - StringTokeniser st( GlobalRadiant().getGameDescriptionKeyValue( "forbidden_paths" ), " " ); - for ( j = 0; j < VFS_MAXDIRS; ++j ) - { - const char *t = st.getToken(); - if ( string_empty( t ) ) { - break; - } - strncpy( g_strForbiddenDirs[g_numForbiddenDirs], t, PATH_MAX ); - g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = '\0'; - ++g_numForbiddenDirs; - } - - for ( j = 0; j < g_numForbiddenDirs; ++j ) - { - char* dbuf = g_strdup( directory ); - if ( *dbuf && dbuf[strlen( dbuf ) - 1] == '/' ) { - dbuf[strlen( dbuf ) - 1] = 0; - } - const char *p = strrchr( dbuf, '/' ); - p = ( p ? ( p + 1 ) : dbuf ); - if ( matchpattern( p, g_strForbiddenDirs[j], TRUE ) ) { - g_free( dbuf ); - break; - } - g_free( dbuf ); - } - if ( j < g_numForbiddenDirs ) { - printf( "Directory %s matched by forbidden dirs, removed\n", directory ); - return; - } - - if ( g_numDirs == VFS_MAXDIRS ) { - return; - } - - strncpy( g_strDirs[g_numDirs], directory, PATH_MAX ); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - FixDOSName( g_strDirs[g_numDirs] ); - AddSlash( g_strDirs[g_numDirs] ); - - const char* path = g_strDirs[g_numDirs]; - - g_numDirs++; - - { - g_archives.push_back( archive_entry_t{ path, OpenArchive( path ), false } ); - } - - if ( g_bUsePak ) { - GDir* dir = g_dir_open( path, 0, 0 ); - - if ( dir != 0 ) { - globalOutputStream() << "vfs directory: " << path << "\n"; - - const char* ignore_prefix = ""; - const char* override_prefix = ""; - - { - // See if we are in "sp" or "mp" mapping mode - const char* gamemode = gamemode_get(); - - if ( strcmp( gamemode, "sp" ) == 0 ) { - ignore_prefix = "mp_"; - override_prefix = "sp_"; - } - else if ( strcmp( gamemode, "mp" ) == 0 ) { - ignore_prefix = "sp_"; - override_prefix = "mp_"; - } - } - - Archives archives; - Archives archivesOverride; - for (;; ) - { - const char* name = g_dir_read_name( dir ); - if ( name == 0 ) { - break; - } - - for ( j = 0; j < g_numForbiddenDirs; ++j ) - { - const char *p = strrchr( name, '/' ); - p = ( p ? ( p + 1 ) : name ); - if ( matchpattern( p, g_strForbiddenDirs[j], TRUE ) ) { - break; - } - } - if ( j < g_numForbiddenDirs ) { - continue; - } - - const char *ext = strrchr( name, '.' ); - - if ( ext && !string_compare_nocase_upper( ext, ".pk3dir" ) ) { - if ( g_numDirs == VFS_MAXDIRS ) { - continue; - } - snprintf( g_strDirs[g_numDirs], PATH_MAX, "%s%s/", path, name ); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - FixDOSName( g_strDirs[g_numDirs] ); - AddSlash( g_strDirs[g_numDirs] ); - g_numDirs++; - - { - g_archives.push_back( archive_entry_t{ g_strDirs[g_numDirs - 1], OpenArchive( g_strDirs[g_numDirs - 1] ), false } ); - } - } - - if ( ( ext == 0 ) || *( ++ext ) == '\0' || GetArchiveTable( archiveModules, ext ) == 0 ) { - continue; - } - - // using the same kludge as in engine to ensure consistency - if ( !string_empty( ignore_prefix ) && strncmp( name, ignore_prefix, strlen( ignore_prefix ) ) == 0 ) { - continue; - } - if ( !string_empty( override_prefix ) && strncmp( name, override_prefix, strlen( override_prefix ) ) == 0 ) { - archivesOverride.insert( name ); - continue; - } - - archives.insert( name ); - } - - g_dir_close( dir ); - - // add the entries to the vfs - for ( Archives::iterator i = archivesOverride.begin(); i != archivesOverride.end(); ++i ) - { - char filename[PATH_MAX]; - strcpy( filename, path ); - strcat( filename, ( *i ).c_str() ); - InitPakFile( archiveModules, filename ); - } - for ( Archives::iterator i = archives.begin(); i != archives.end(); ++i ) - { - char filename[PATH_MAX]; - strcpy( filename, path ); - strcat( filename, ( *i ).c_str() ); - InitPakFile( archiveModules, filename ); - } - } - else - { - globalErrorStream() << "vfs directory not found: " << path << "\n"; - } - } -} - -// frees all memory that we allocated -// FIXME TTimo this should be improved so that we can shutdown and restart the VFS without exiting Radiant? -// (for instance when modifying the project settings) -void Shutdown() -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - (*i).archive->release(); - } - g_archives.clear(); - - g_numDirs = 0; - g_numForbiddenDirs = 0; - - g_pakfile_paths.clear(); - g_loaded_dpk_paks.clear(); -} - -const int VFS_SEARCH_PAK = 0x1; -const int VFS_SEARCH_DIR = 0x2; - -int GetFileCount(const char *filename, int flag) -{ - int count = 0; - char fixed[PATH_MAX + 1]; - - strncpy(fixed, filename, PATH_MAX); - fixed[PATH_MAX] = '\0'; - FixDOSName(fixed); - - if (!flag) { - flag = VFS_SEARCH_PAK | VFS_SEARCH_DIR; - } - - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (((*i).is_pakfile && (flag & VFS_SEARCH_PAK) != 0) - || (!(*i).is_pakfile && (flag & VFS_SEARCH_DIR) != 0)) { - if ((*i).archive->containsFile(fixed)) { - ++count; - } - } - } - - return count; -} - -ArchiveFile *OpenFile(const char *filename) -{ - ASSERT_MESSAGE(strchr(filename, '\\') == 0, "path contains invalid separator '\\': \"" << filename << "\""); - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - ArchiveFile *file = (*i).archive->openFile(filename); - if (file != 0) { - return file; - } - } - - return 0; -} - -ArchiveTextFile *OpenTextFile(const char *filename) -{ - ASSERT_MESSAGE(strchr(filename, '\\') == 0, "path contains invalid separator '\\': \"" << filename << "\""); - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - ArchiveTextFile *file = (*i).archive->openTextFile(filename); - if (file != 0) { - return file; - } - } - - return 0; -} - -// NOTE: when loading a file, you have to allocate one extra byte and set it to \0 -std::size_t LoadFile(const char *filename, void **bufferptr, int index) -{ - char fixed[PATH_MAX + 1]; - - strncpy(fixed, filename, PATH_MAX); - fixed[PATH_MAX] = '\0'; - FixDOSName(fixed); - - ArchiveFile *file = OpenFile(fixed); - - if (file != 0) { - *bufferptr = malloc(file->size() + 1); - // we need to end the buffer with a 0 - ((char *) (*bufferptr))[file->size()] = 0; - - std::size_t length = file->getInputStream().read((InputStream::byte_type *) *bufferptr, file->size()); - file->release(); - return length; - } - - *bufferptr = 0; - return 0; -} - -void FreeFile(void *p) -{ - free(p); -} - -GSList *GetFileList(const char *dir, const char *ext, std::size_t depth) -{ - return GetListInternal(dir, ext, false, depth); -} - -GSList *GetDirList(const char *dir, std::size_t depth) -{ - return GetListInternal(dir, 0, true, depth); -} - -void ClearFileDirList(GSList **lst) -{ - while (*lst) { - g_free((*lst)->data); - *lst = g_slist_remove(*lst, (*lst)->data); - } -} - -const char *FindFile(const char *relative) -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if ((*i).archive->containsFile(relative)) { - return (*i).name.c_str(); - } - } - - return ""; -} - -const char *FindPath(const char *absolute) -{ - const char *best = ""; - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (string_length((*i).name.c_str()) > string_length(best)) { - if (path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str()))) { - best = (*i).name.c_str(); - } - } - } - - return best; -} - - -class Quake3FileSystem : public VirtualFileSystem { -public: -void initDirectory(const char *path) -{ - InitDirectory(path, FileSystemQ3API_getArchiveModules()); -} - -void initialise() -{ - load(); - globalOutputStream() << "filesystem initialised\n"; - g_observers.realise(); -} - -void load() -{ - ArchiveModules &archiveModules = FileSystemQ3API_getArchiveModules(); - bool is_dpk_vfs = 1; - - if (is_dpk_vfs) { - const char *pakname; - g_loaded_dpk_paks.clear(); - - // Load DEPS from game pack - LoadDpkPakWithDeps(NULL); - - // prevent VFS double start, for MapName="" and MapName="unnamed.map" - if (string_length(GlobalRadiant().getMapName())) { - // load map's paks from DEPS - char *mappakname = GetCurrentMapDpkPakName(); - if (mappakname != NULL) { - LoadDpkPakWithDeps(mappakname); - string_release(mappakname, string_length(mappakname)); - } - } - - g_pakfile_paths.clear(); - g_loaded_dpk_paks.clear(); - } -} - -void clear() -{ - // like shutdown() but does not unrealise (keep map etc.) - Shutdown(); -} - -void refresh() -{ - // like initialise() but does not realise (keep map etc.) - load(); - globalOutputStream() << "filesystem refreshed\n"; -} - -void shutdown() -{ - g_observers.unrealise(); - globalOutputStream() << "filesystem shutdown\n"; - Shutdown(); -} - -int getFileCount(const char *filename, int flags) -{ - return GetFileCount(filename, flags); -} - -ArchiveFile *openFile(const char *filename) -{ - return OpenFile(filename); -} - -ArchiveTextFile *openTextFile(const char *filename) -{ - return OpenTextFile(filename); -} - -std::size_t loadFile(const char *filename, void **buffer) -{ - return LoadFile(filename, buffer, 0); -} - -void freeFile(void *p) -{ - FreeFile(p); -} - -void forEachDirectory(const char *basedir, const FileNameCallback &callback, std::size_t depth) -{ - GSList *list = GetDirList(basedir, depth); - - for (GSList *i = list; i != 0; i = g_slist_next(i)) { - callback(reinterpret_cast((*i).data )); - } - - ClearFileDirList(&list); -} - -void forEachFile(const char *basedir, const char *extension, const FileNameCallback &callback, std::size_t depth) -{ - GSList *list = GetFileList(basedir, extension, depth); - - for (GSList *i = list; i != 0; i = g_slist_next(i)) { - const char *name = reinterpret_cast((*i).data ); - if (extension_equal(path_get_extension(name), extension)) { - callback(name); - } - } - - ClearFileDirList(&list); -} - -GSList *getDirList(const char *basedir) -{ - return GetDirList(basedir, 1); -} - -GSList *getFileList(const char *basedir, const char *extension) -{ - return GetFileList(basedir, extension, 1); -} - -void clearFileDirList(GSList **lst) -{ - ClearFileDirList(lst); -} - -const char *findFile(const char *name) -{ - return FindFile(name); -} - -const char *findRoot(const char *name) -{ - return FindPath(name); -} - -void attach(ModuleObserver &observer) -{ - g_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - g_observers.detach(observer); -} - -Archive *getArchive(const char *archiveName, bool pakonly) -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (pakonly && !(*i).is_pakfile) { - continue; - } - if (path_equal((*i).name.c_str(), archiveName)) { - return (*i).archive; - } - } - return 0; -} - -void forEachArchive(const ArchiveNameCallback &callback, bool pakonly, bool reverse) -{ - if (reverse) { - g_archives.reverse(); - } - - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (pakonly && !(*i).is_pakfile) { - continue; - } - - callback((*i).name.c_str()); - } - - if (reverse) { - g_archives.reverse(); - } -} -}; - - -Quake3FileSystem g_Quake3FileSystem; - -VirtualFileSystem &GetFileSystem() -{ - return g_Quake3FileSystem; -} - -void FileSystem_Init() -{ -} - -void FileSystem_Shutdown() -{ -} diff --git a/plugins/vfspk3/vfs.h b/plugins/vfspk3/vfs.h deleted file mode 100644 index 277c7b3..0000000 --- a/plugins/vfspk3/vfs.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_VFS_H ) -#define INCLUDED_VFS_H - -void FileSystem_Init(); - -void FileSystem_Shutdown(); - -class VirtualFileSystem; - -VirtualFileSystem &GetFileSystem(); - -#endif diff --git a/plugins/vfspk3/vfspk3.cpp b/plugins/vfspk3/vfspk3.cpp deleted file mode 100644 index 3ff2a12..0000000 --- a/plugins/vfspk3/vfspk3.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "qerplugin.h" -#include "iarchive.h" -#include "ifilesystem.h" - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/modulesmap.h" - -#include "vfs.h" - -class FileSystemDependencies : public GlobalRadiantModuleRef { -ArchiveModulesRef m_archive_modules; -public: -FileSystemDependencies() : - m_archive_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("archivetypes")) -{ -} - -ArchiveModules &getArchiveModules() -{ - return m_archive_modules.get(); -} -}; - -class FileSystemQ3API { -VirtualFileSystem *m_filesystemq3; -public: -typedef VirtualFileSystem Type; - -STRING_CONSTANT(Name, "*"); - -FileSystemQ3API() -{ - FileSystem_Init(); - m_filesystemq3 = &GetFileSystem(); -} - -~FileSystemQ3API() -{ - FileSystem_Shutdown(); -} - -VirtualFileSystem *getTable() -{ - return m_filesystemq3; -} -}; - -typedef SingletonModule FileSystemQ3Module; - -FileSystemQ3Module g_FileSystemQ3Module; - -ArchiveModules &FileSystemQ3API_getArchiveModules() -{ - return g_FileSystemQ3Module.getDependencies().getArchiveModules(); -} - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_FileSystemQ3Module.selfRegister(); -} diff --git a/resources/Makefile b/resources/Makefile deleted file mode 100644 index 3a0821e..0000000 --- a/resources/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -all: - mkdir -p ../build/bitmaps - mkdir -p ../build/games - mkdir -p ../build/gl - mkdir -p ../build/platform.game - mkdir -p ../build/goldsrc.game - cp -vf ./defaultkeys.ini ../build/defaultkeys.ini - cp -vf ./platform.game/default_build_menu.xml ../build/platform.game/default_build_menu.xml - cp -vf ./goldsrc.game/default_build_menu.xml ../build/goldsrc.game/default_build_menu.xml - cp -vf ./games/platform.game ../build/games/platform.game - cp -vf ./games/goldsrc.game ../build/games/goldsrc.game - cp -vf ./gl/lighting_DBS_omni_fp.glp ../build/gl/lighting_DBS_omni_fp.glp - cp -vf ./gl/lighting_DBS_omni_fp.glsl ../build/gl/lighting_DBS_omni_fp.glsl - cp -vf ./gl/lighting_DBS_omni_vp.glp ../build/gl/lighting_DBS_omni_vp.glp - cp -vf ./gl/lighting_DBS_omni_vp.glsl ../build/gl/lighting_DBS_omni_vp.glsl - cp -vf ./gl/lighting_DBS_XY_Z_arbfp1.cg ../build/gl/lighting_DBS_XY_Z_arbfp1.cg - cp -vf ./gl/lighting_DBS_XY_Z_arbvp1.cg ../build/gl/lighting_DBS_XY_Z_arbvp1.cg - cp -vf ./gl/utils.cg ../build/gl/utils.cg - cp -vf ./gl/zfill_arbfp1.cg ../build/gl/zfill_arbfp1.cg - cp -vf ./gl/zfill_arbvp1.cg ../build/gl/zfill_arbvp1.cg - cp -vf ./gl/zfill_fp.glp ../build/gl/zfill_fp.glp - cp -vf ./gl/zfill_fp.glsl ../build/gl/zfill_fp.glsl - cp -vf ./gl/zfill_vp.glp ../build/gl/zfill_vp.glp - cp -vf ./gl/zfill_vp.glsl ../build/gl/zfill_vp.glsl - cp -vf ./bitmaps/black.xpm ../build/bitmaps/black.xpm - cp -vf ./bitmaps/brush_flipx.xpm ../build/bitmaps/brush_flipx.xpm - cp -vf ./bitmaps/brush_flipy.xpm ../build/bitmaps/brush_flipy.xpm - cp -vf ./bitmaps/brush_flipz.xpm ../build/bitmaps/brush_flipz.xpm - cp -vf ./bitmaps/brush_rotatex.xpm ../build/bitmaps/brush_rotatex.xpm - cp -vf ./bitmaps/brush_rotatey.xpm ../build/bitmaps/brush_rotatey.xpm - cp -vf ./bitmaps/brush_rotatez.xpm ../build/bitmaps/brush_rotatez.xpm - cp -vf ./bitmaps/cap_bevel.xpm ../build/bitmaps/cap_bevel.xpm - cp -vf ./bitmaps/cap_curve.xpm ../build/bitmaps/cap_curve.xpm - cp -vf ./bitmaps/cap_cylinder.xpm ../build/bitmaps/cap_cylinder.xpm - cp -vf ./bitmaps/cap_endcap.xpm ../build/bitmaps/cap_endcap.xpm - cp -vf ./bitmaps/cap_ibevel.xpm ../build/bitmaps/cap_ibevel.xpm - cp -vf ./bitmaps/cap_iendcap.xpm ../build/bitmaps/cap_iendcap.xpm - cp -vf ./bitmaps/console.xpm ../build/bitmaps/console.xpm - cp -vf ./bitmaps/copy.xpm ../build/bitmaps/copy.xpm - cp -vf ./bitmaps/cut.xpm ../build/bitmaps/cut.xpm - cp -vf ./bitmaps/dontselectcurve.xpm ../build/bitmaps/dontselectcurve.xpm - cp -vf ./bitmaps/dontselectmodel.xpm ../build/bitmaps/dontselectmodel.xpm - cp -vf ./bitmaps/ellipsis.xpm ../build/bitmaps/ellipsis.xpm - cp -vf ./bitmaps/entities.xpm ../build/bitmaps/entities.xpm - cp -vf ./bitmaps/file_new.xpm ../build/bitmaps/file_new.xpm - cp -vf ./bitmaps/file_open.xpm ../build/bitmaps/file_open.xpm - cp -vf ./bitmaps/file_save.xpm ../build/bitmaps/file_save.xpm - cp -vf ./bitmaps/icon.xpm ../build/bitmaps/icon.xpm - cp -vf ./bitmaps/lightinspector.xpm ../build/bitmaps/lightinspector.xpm - cp -vf ./bitmaps/logo.xpm ../build/bitmaps/logo.xpm - cp -vf ./bitmaps/modify_edges.xpm ../build/bitmaps/modify_edges.xpm - cp -vf ./bitmaps/modify_faces.xpm ../build/bitmaps/modify_faces.xpm - cp -vf ./bitmaps/modify_vertices.xpm ../build/bitmaps/modify_vertices.xpm - cp -vf ./bitmaps/noFalloff.xpm ../build/bitmaps/noFalloff.xpm - cp -vf ./bitmaps/notex.tga ../build/bitmaps/notex.tga - cp -vf ./bitmaps/paste.xpm ../build/bitmaps/paste.xpm - cp -vf ./bitmaps/patch_bend.xpm ../build/bitmaps/patch_bend.xpm - cp -vf ./bitmaps/patch_drilldown.xpm ../build/bitmaps/patch_drilldown.xpm - cp -vf ./bitmaps/patch_insdel.xpm ../build/bitmaps/patch_insdel.xpm - cp -vf ./bitmaps/patch_showboundingbox.xpm ../build/bitmaps/patch_showboundingbox.xpm - cp -vf ./bitmaps/patch_weld.xpm ../build/bitmaps/patch_weld.xpm - cp -vf ./bitmaps/patch_wireframe.xpm ../build/bitmaps/patch_wireframe.xpm - cp -vf ./bitmaps/popup_selection.xpm ../build/bitmaps/popup_selection.xpm - cp -vf ./bitmaps/redo.xpm ../build/bitmaps/redo.xpm - cp -vf ./bitmaps/refresh_models.xpm ../build/bitmaps/refresh_models.xpm - cp -vf ./bitmaps/scalelockx.xpm ../build/bitmaps/scalelockx.xpm - cp -vf ./bitmaps/scalelocky.xpm ../build/bitmaps/scalelocky.xpm - cp -vf ./bitmaps/scalelockz.xpm ../build/bitmaps/scalelockz.xpm - cp -vf ./bitmaps/select_additive.xpm ../build/bitmaps/select_additive.xpm - cp -vf ./bitmaps/select_autoexpand.xpm ../build/bitmaps/select_autoexpand.xpm - cp -vf ./bitmaps/selection_csgmerge.xpm ../build/bitmaps/selection_csgmerge.xpm - cp -vf ./bitmaps/selection_csgsubtract.xpm ../build/bitmaps/selection_csgsubtract.xpm - cp -vf ./bitmaps/selection_makehollow.xpm ../build/bitmaps/selection_makehollow.xpm - cp -vf ./bitmaps/selection_makeroom.xpm ../build/bitmaps/selection_makeroom.xpm - cp -vf ./bitmaps/selection_selectcompletetall.xpm ../build/bitmaps/selection_selectcompletetall.xpm - cp -vf ./bitmaps/selection_selectinside.xpm ../build/bitmaps/selection_selectinside.xpm - cp -vf ./bitmaps/selection_selectpartialtall.xpm ../build/bitmaps/selection_selectpartialtall.xpm - cp -vf ./bitmaps/selection_selecttouching.xpm ../build/bitmaps/selection_selecttouching.xpm - cp -vf ./bitmaps/select_mouseresize.xpm ../build/bitmaps/select_mouseresize.xpm - cp -vf ./bitmaps/select_mouserotate.xpm ../build/bitmaps/select_mouserotate.xpm - cp -vf ./bitmaps/select_mousescale.xpm ../build/bitmaps/select_mousescale.xpm - cp -vf ./bitmaps/select_mousetranslate.xpm ../build/bitmaps/select_mousetranslate.xpm - cp -vf ./bitmaps/shadernotex.tga ../build/bitmaps/shadernotex.tga - cp -vf ./bitmaps/show_entities.xpm ../build/bitmaps/show_entities.xpm - cp -vf ./bitmaps/side_brush.png ../build/bitmaps/side_brush.png - cp -vf ./bitmaps/side_cut.png ../build/bitmaps/side_cut.png - cp -vf ./bitmaps/side_edges.xpm ../build/bitmaps/side_edges.xpm - cp -vf ./bitmaps/side_entities.png ../build/bitmaps/side_entities.png - cp -vf ./bitmaps/side_entspec.png ../build/bitmaps/side_entspec.png - cp -vf ./bitmaps/side_faces.xpm ../build/bitmaps/side_faces.xpm - cp -vf ./bitmaps/side_move.png ../build/bitmaps/side_move.png - cp -vf ./bitmaps/side_patch.png ../build/bitmaps/side_patch.png - cp -vf ./bitmaps/side_patchspec.png ../build/bitmaps/side_patchspec.png - cp -vf ./bitmaps/side_rotate.png ../build/bitmaps/side_rotate.png - cp -vf ./bitmaps/side_scale.png ../build/bitmaps/side_scale.png - cp -vf ./bitmaps/side_select.png ../build/bitmaps/side_select.png - cp -vf ./bitmaps/side_surfspec.png ../build/bitmaps/side_surfspec.png - cp -vf ./bitmaps/side_tex.png ../build/bitmaps/side_tex.png - cp -vf ./bitmaps/side_vertices.xpm ../build/bitmaps/side_vertices.xpm - cp -vf ./bitmaps/side_selectface.png ../build/bitmaps/side_selectface.png - cp -vf ./bitmaps/side_selectwhole.png ../build/bitmaps/side_selectwhole.png - cp -vf ./bitmaps/side_resize.png ../build/bitmaps/side_resize.png - cp -vf ./bitmaps/splash.xcf ../build/bitmaps/splash.xcf - cp -vf ./bitmaps/splash.xpm ../build/bitmaps/splash.xpm - cp -vf ./bitmaps/texture_browser.xpm ../build/bitmaps/texture_browser.xpm - cp -vf ./bitmaps/texture_lock.xpm ../build/bitmaps/texture_lock.xpm - cp -vf ./bitmaps/textures_popup.xpm ../build/bitmaps/textures_popup.xpm - cp -vf ./bitmaps/undo.xpm ../build/bitmaps/undo.xpm - cp -vf ./bitmaps/view_cameratoggle.xpm ../build/bitmaps/view_cameratoggle.xpm - cp -vf ./bitmaps/view_cameraupdate.xpm ../build/bitmaps/view_cameraupdate.xpm - cp -vf ./bitmaps/view_change.xpm ../build/bitmaps/view_change.xpm - cp -vf ./bitmaps/view_clipper.xpm ../build/bitmaps/view_clipper.xpm - cp -vf ./bitmaps/view_cubicclipping.xpm ../build/bitmaps/view_cubicclipping.xpm - cp -vf ./bitmaps/view_entity.xpm ../build/bitmaps/view_entity.xpm - cp -vf ./bitmaps/white.xpm ../build/bitmaps/white.xpm - cp -vf ./bitmaps/window1.xpm ../build/bitmaps/window1.xpm - cp -vf ./bitmaps/window2.xpm ../build/bitmaps/window2.xpm - cp -vf ./bitmaps/window3.xpm ../build/bitmaps/window3.xpm - cp -vf ./bitmaps/window4.xpm ../build/bitmaps/window4.xpm \ No newline at end of file diff --git a/resources/bitmaps/black.xpm b/resources/bitmaps/black.xpm deleted file mode 100644 index add2bbc..0000000 --- a/resources/bitmaps/black.xpm +++ /dev/null @@ -1,16 +0,0 @@ -/* XPM */ -static char *black[] = { -/* columns rows colors chars-per-pixel */ -"8 8 2 1 ", -" c black", -". c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/brush_flipx.xpm b/resources/bitmaps/brush_flipx.xpm deleted file mode 100644 index 859c5c2..0000000 --- a/resources/bitmaps/brush_flipx.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * brush_flipx_xpm[] = { -"16 16 26 1", -" c None", -". c #C9E5F9", -"+ c #CAE3FB", -"@ c #CAE2FF", -"# c #47E0FF", -"$ c #CAE1FF", -"% c #45DEFF", -"& c #46DEFF", -"* c #C9DEFF", -"= c #44DCFF", -"- c #C9DBFF", -"; c #43DBFF", -"> c #43DAFF", -", c #C9D9FF", -"' c #42D9FF", -") c #41D6FF", -"! c #40D7FF", -"~ c #C8D6FF", -"{ c #41D7FF", -"] c #3FD4FF", -"^ c #C8D4FF", -"/ c #3ED5FF", -"( c #3FD5FF", -"_ c #C7D1FF", -": c #C7D0FF", -"< c #C7CDFF", -" ", -" ", -" . ", -" + ", -" @ ", -" # # $ # # ", -" % & * % % ", -" = - ; ", -" > , ' ", -" ) ! ~ { ! ", -" ] ] ^ / ( ", -" _ ", -" : ", -" < ", -" ", -" "}; diff --git a/resources/bitmaps/brush_flipy.xpm b/resources/bitmaps/brush_flipy.xpm deleted file mode 100644 index 4554a8e..0000000 --- a/resources/bitmaps/brush_flipy.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * brush_flipy_xpm[] = { -"16 16 29 1", -" c None", -". c #44FFF9", -"+ c #46FFFB", -"@ c #48FFFF", -"# c #47E0FF", -"$ c #47FFFF", -"% c #45DEFF", -"& c #46DEFF", -"* c #45FFFF", -"= c #46DDFF", -"- c #43DBFF", -"; c #43FFFF", -"> c #44DBFF", -", c #42D9FF", -"' c #42FFFF", -") c #43D9FF", -"! c #42DAFF", -"~ c #40D7FF", -"{ c #40FFFF", -"] c #41D7FF", -"^ c #3FD4FF", -"/ c #3EFFFF", -"( c #3DD2FF", -"_ c #3DFFFF", -": c #3BCFFF", -"< c #3CFFFF", -"[ c #3BD0FF", -"} c #39CDFF", -"| c #39FFFF", -" ", -" ", -" . ", -" + ", -" @ ", -" # # $ # # ", -" % & * % = ", -" - - ; > > ", -" , , ' ) ! ", -" ~ { ] ", -" ^ / ^ ", -" ( _ ( ", -" : < [ ", -" } | } ", -" ", -" "}; diff --git a/resources/bitmaps/brush_flipz.xpm b/resources/bitmaps/brush_flipz.xpm deleted file mode 100644 index 5e1c704..0000000 --- a/resources/bitmaps/brush_flipz.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char * brush_flipz_xpm[] = { -"16 16 23 1", -" c None", -". c #44E5FF", -"+ c #46E3FF", -"@ c #48E2FF", -"# c #47E0FF", -"$ c #47E1FF", -"% c #46DEFF", -"& c #45DEFF", -"* c #43DBFF", -"= c #44DBFF", -"- c #43DAFF", -"; c #42D9FF", -"> c #41D6FF", -", c #40D6FF", -"' c #40D7FF", -") c #3FD4FF", -"! c #3ED4FF", -"~ c #3FD5FF", -"{ c #3DD2FF", -"] c #3CD2FF", -"^ c #3DD1FF", -"/ c #3CD0FF", -"( c #39CDFF", -" ", -" ", -" . ", -" + ", -" @ ", -" #$### $ #$### ", -" % & & ", -" * * = ", -" - ; ; ", -" > , ' ", -" ) ! ~ ", -" {{{]{ ^ {{{^{ ", -" / ", -" ( ", -" ", -" "}; diff --git a/resources/bitmaps/brush_rotatex.xpm b/resources/bitmaps/brush_rotatex.xpm deleted file mode 100644 index f7b078a..0000000 --- a/resources/bitmaps/brush_rotatex.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * brush_rotatex_xpm[] = { -"16 16 30 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #C9E4F8", -"$ c #C9E5F9", -"% c #C9E4F9", -"& c #C9E3FC", -"* c #CAE3FF", -"= c #CAE0FF", -"- c #46DEFF", -"; c #45DEFF", -"> c #C9DEFF", -", c #43DBFF", -"' c #44DBFF", -") c #C9DBFF", -"! c #42D9FF", -"~ c #C9DAFF", -"{ c #40D6FF", -"] c #C8D7FF", -"^ c #3FD4FF", -"/ c #3ED5FF", -"( c #C8D5FF", -"_ c #3DD2FF", -": c #3DD1FF", -"< c #C7D2FF", -"[ c #C7D0FF", -"} c #C7CFFF", -"| c #C7CDFF", -"1 c #C6CAFF", -" ", -" ...+@ ", -" #$% ", -" & ", -" * ", -" = ", -" - ; > ", -" , ' ) ", -" ! ~ ", -" { ] ", -" ^ / ( ", -" _ : < ", -" [[}}}", -" ||| ", -" 1 ", -" "}; diff --git a/resources/bitmaps/brush_rotatey.xpm b/resources/bitmaps/brush_rotatey.xpm deleted file mode 100644 index 90eee14..0000000 --- a/resources/bitmaps/brush_rotatey.xpm +++ /dev/null @@ -1,51 +0,0 @@ -/* XPM */ -static char * brush_rotatey_xpm[] = { -"16 16 32 1", -" c None", -". c #41FFF6", -"+ c #42FFF5", -"@ c #42FFF6", -"# c #43FFF8", -"$ c #44FFF9", -"% c #43FFF9", -"& c #45FFFC", -"* c #48FFFF", -"= c #47FFFF", -"- c #46DEFF", -"; c #45DEFF", -"> c #45FFFF", -", c #44DCFF", -"' c #43DBFF", -") c #44FFFF", -"! c #42D9FF", -"~ c #42FFFF", -"{ c #40D7FF", -"] c #40FFFF", -"^ c #3FD4FF", -"/ c #3FFFFF", -"( c #3DD2FF", -"_ c #3DFFFF", -": c #3BCFFF", -"< c #3BFFFF", -"[ c #3CFFFF", -"} c #3ACDFF", -"| c #3AFFFF", -"1 c #39FFFF", -"2 c #38CAFF", -"3 c #38FFFF", -" ", -" ...+@ ", -" #$% ", -" & ", -" * ", -" = ", -" - ; > ", -" , ' ) ", -" ! ! ~ ", -" { { ] ", -" ^ / ", -" ( _ ", -" : <[<[<", -" } |1| ", -" 2 3 ", -" "}; diff --git a/resources/bitmaps/brush_rotatez.xpm b/resources/bitmaps/brush_rotatez.xpm deleted file mode 100644 index b33c7df..0000000 --- a/resources/bitmaps/brush_rotatez.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * brush_rotatez_xpm[] = { -"16 16 26 1", -" c None", -". c #41E5FF", -"+ c #42E5FF", -"@ c #43E4FF", -"# c #44E5FF", -"$ c #45E3FF", -"% c #48E3FF", -"& c #47E0FF", -"* c #46DEFF", -"= c #45DEFF", -"- c #43DBFF", -"; c #44DBFF", -"> c #42D9FF", -", c #42DAFF", -"' c #40D6FF", -") c #40D7FF", -"! c #3FD4FF", -"~ c #3FD5FF", -"{ c #3DD2FF", -"] c #3BCFFF", -"^ c #3CD0FF", -"/ c #3BD0FF", -"( c #3CCFFF", -"_ c #3ACDFF", -": c #39CDFF", -"< c #38CAFF", -" ", -" ...++ ", -" @#@ ", -" $ ", -" % ", -" & ", -" ***== = ", -" - ; ", -" > , ", -" ' ) ", -" ! ~ ", -" { { ", -" ]]]]^ /^](]", -" _:_ ", -" < ", -" "}; diff --git a/resources/bitmaps/cap_bevel.xpm b/resources/bitmaps/cap_bevel.xpm deleted file mode 100644 index ec79202..0000000 --- a/resources/bitmaps/cap_bevel.xpm +++ /dev/null @@ -1,95 +0,0 @@ -/* XPM */ -static char * cap_bevel_xpm[] = { -"24 24 68 1", -" c None", -". c #3FE6F3", -"+ c #40E6F4", -"@ c #3FE5F3", -"# c #41E5F6", -"$ c #42E5F6", -"% c #BEE480", -"& c #BDE480", -"* c #43E4F8", -"= c #44E5F9", -"- c #BCE380", -"; c #BBE380", -"> c #46E3FC", -", c #B9E380", -"' c #B9E280", -") c #BAE280", -"! c #48E2FE", -"~ c #B7E280", -"{ c #B7E180", -"] c #47E0FF", -"^ c #B8DF80", -"/ c #B8E080", -"( c #45DEFF", -"_ c #B9DD80", -": c #BADD80", -"< c #B9DC80", -"[ c #BADC80", -"} c #43DBFF", -"| c #BBDB80", -"1 c #BCDA80", -"2 c #BBDA80", -"3 c #BCDB80", -"4 c #42D9FF", -"5 c #BDD880", -"6 c #BCD980", -"7 c #BDD980", -"8 c #BCD880", -"9 c #41D6FF", -"0 c #BED580", -"a c #BFD680", -"b c #BFD580", -"c c #BED680", -"d c #3FD4FF", -"e c #C0D380", -"f c #C1D480", -"g c #C1D380", -"h c #C0D480", -"i c #3DD2FF", -"j c #C2D180", -"k c #C3D180", -"l c #C2D080", -"m c #3CCFFF", -"n c #C4CE80", -"o c #C3CF80", -"p c #C4CF80", -"q c #C3CE80", -"r c #3ACDFF", -"s c #C6CC80", -"t c #C5CC80", -"u c #37CBFF", -"v c #C8C980", -"w c #C7C980", -"x c #C7CA80", -"y c #36C8FF", -"z c #CAC780", -"A c #CAC680", -"B c #C9C780", -"C c #C9C680", -" ", -" ", -" ", -" ", -" .+..@ ", -" #$#%%&%% ", -" *=---;;-;- ", -" >,''),,'''' ", -" !~{{{~~~~{{{ ", -" ]^^^/^^/^^^^^ ", -" (___::_::::<[[ ", -" }|112122212213 ", -" 456555557857576 ", -" 90aababacccaaaa ", -" deeeefgffheehgg ", -" ijjjkjjlljjjljlj ", -" mnnnnnnopppponqn ", -" rsssstssstsststt ", -" uvwvvwwvwxwwvwwx ", -" yzABBBCBBzBBBzCC ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_curve.xpm b/resources/bitmaps/cap_curve.xpm deleted file mode 100644 index 1e298a8..0000000 --- a/resources/bitmaps/cap_curve.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * cap_curve_xpm[] = { -"16 16 25 1", -" c None", -". c #48E2FE", -"+ c #48E2FF", -"@ c #48E3FE", -"# c #47E0FF", -"$ c #B8DF80", -"% c #B8E080", -"& c #47E1FF", -"* c #46DEFF", -"= c #B9DD80", -"- c #BADD80", -"; c #45DEFF", -"> c #43DBFF", -", c #BCDA80", -"' c #BBDA80", -") c #44DBFF", -"! c #42D9FF", -"~ c #42DAFF", -"{ c #40D7FF", -"] c #41D7FF", -"^ c #3FD4FF", -"/ c #3FD5FF", -"( c #3ED5FF", -"_ c #3DD2FF", -": c #3DD1FF", -" ", -" .++..@ ", -" ##$%%$$$#& ", -" #$$$%%$$$$%& ", -" *==----==----; ", -" *==----==----; ", -" >>,'',,''''')> ", -" > >)',,''')) > ", -" ! !!!!!~ ! ", -" ! ! ", -" { ] ", -" { ] ", -" ^ / ", -" ^( (/ ", -" _::::_ ", -" "}; diff --git a/resources/bitmaps/cap_cylinder.xpm b/resources/bitmaps/cap_cylinder.xpm deleted file mode 100644 index 0f41c73..0000000 --- a/resources/bitmaps/cap_cylinder.xpm +++ /dev/null @@ -1,102 +0,0 @@ -/* XPM */ -static char * cap_cylinder_xpm[] = { -"24 24 75 1", -" c None", -". c #3FE6F3", -"+ c #40E6F3", -"@ c #41E5F6", -"# c #42E5F5", -"$ c #BDE480", -"% c #BEE480", -"& c #43E4F9", -"* c #BCE380", -"= c #BBE380", -"- c #BBE480", -"; c #43E4F8", -"> c #45E4FB", -", c #B9E280", -"' c #BAE280", -") c #B9E380", -"! c #46E3FB", -"~ c #48E2FE", -"{ c #B7E180", -"] c #B8E180", -"^ c #B7E280", -"/ c #48E2FF", -"( c #47E1FF", -"_ c #B8DF80", -": c #B8E080", -"< c #47E0FF", -"[ c #45DEFF", -"} c #BADD80", -"| c #B9DD80", -"1 c #B9DC80", -"2 c #BADC80", -"3 c #45DDFF", -"4 c #44DBFF", -"5 c #BCDA80", -"6 c #BBDB80", -"7 c #BBDA80", -"8 c #43DCFF", -"9 c #42D9FF", -"0 c #BDD880", -"a c #BCD980", -"b c #BDD980", -"c c #BCD880", -"d c #43DAFF", -"e c #40D7FF", -"f c #BED580", -"g c #BFD680", -"h c #BFD580", -"i c #BED680", -"j c #3FD4FF", -"k c #C0D380", -"l c #C1D480", -"m c #C1D380", -"n c #C0D480", -"o c #3ED4FF", -"p c #3DD2FF", -"q c #C2D180", -"r c #C3D180", -"s c #C2D080", -"t c #3DD1FF", -"u c #3BCFFF", -"v c #C4CE80", -"w c #C3CF80", -"x c #C4CF80", -"y c #3CCFFF", -"z c #39CDFF", -"A c #C6CC80", -"B c #C5CC80", -"C c #37CAFF", -"D c #C7C980", -"E c #C8C980", -"F c #C7CA80", -"G c #38CAFF", -"H c #36C8FF", -"I c #36C7FF", -"J c #35C8FF", -" ", -" ", -" ", -" ", -" ..++.+ ", -" @#$%%%$%@@ ", -" &*==*-***==; ", -" >,,',),,')),,! ", -" ~{]{^{{{^^^^{/ ", -" (_:____:__:____< ", -" [}}|||}}|}}}}123 ", -" 4556557577757758 ", -" 900a00000bc0b0bd ", -" effgghghgiiiggge ", -" jkkkkklmllnkknmo ", -" pqqrqqssqqqsqt ", -" uvvvvvwxxxxwvy ", -" zAABAAABAABz ", -" CCDDEDFDGC ", -" HIHHJH ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_endcap.xpm b/resources/bitmaps/cap_endcap.xpm deleted file mode 100644 index 992d5ce..0000000 --- a/resources/bitmaps/cap_endcap.xpm +++ /dev/null @@ -1,105 +0,0 @@ -/* XPM */ -static char * cap_endcap_xpm[] = { -"24 24 78 1", -" c None", -". c #3FE6F3", -"+ c #40E6F3", -"@ c #41E5F6", -"# c #42E5F5", -"$ c #BDE480", -"% c #BEE480", -"& c #43E4F9", -"* c #BCE380", -"= c #BBE380", -"- c #BBE480", -"; c #43E4F8", -"> c #45E4FB", -", c #B9E280", -"' c #BAE280", -") c #B9E380", -"! c #46E3FB", -"~ c #48E2FE", -"{ c #B7E180", -"] c #B8E180", -"^ c #B7E280", -"/ c #48E2FF", -"( c #47E1FF", -"_ c #B8DF80", -": c #B8E080", -"< c #47E0FF", -"[ c #45DEFF", -"} c #BADD80", -"| c #B9DD80", -"1 c #B9DC80", -"2 c #BADC80", -"3 c #45DDFF", -"4 c #44DBFF", -"5 c #BCDA80", -"6 c #BBDB80", -"7 c #BBDA80", -"8 c #43DCFF", -"9 c #42D9FF", -"0 c #BDD880", -"a c #BCD980", -"b c #BDD980", -"c c #BCD880", -"d c #43DAFF", -"e c #40D7FF", -"f c #BED580", -"g c #BFD680", -"h c #BFD580", -"i c #BED680", -"j c #3FD4FF", -"k c #C0D380", -"l c #C1D480", -"m c #C1D380", -"n c #C0D480", -"o c #3ED4FF", -"p c #3DD2FF", -"q c #C2D180", -"r c #C3D180", -"s c #C2D080", -"t c #3CCFFF", -"u c #C4CE80", -"v c #C3CF80", -"w c #C4CF80", -"x c #C3CE80", -"y c #3BCFFF", -"z c #3ACDFF", -"A c #C6CC80", -"B c #C5CC80", -"C c #37CBFF", -"D c #C8C980", -"E c #C7C980", -"F c #C7CA80", -"G c #38CBFF", -"H c #36C8FF", -"I c #CAC780", -"J c #CAC680", -"K c #C9C780", -"L c #C9C680", -"M c #36C7FF", -" ", -" ", -" ", -" ", -" ..++.+ ", -" @#$%%%$%@@ ", -" &*==*-***==; ", -" >,,',),,')),,! ", -" ~{]{^{{{^^^^{/ ", -" (_:____:__:____< ", -" [}}|||}}|}}}}123 ", -" 4556557577757758 ", -" 900a00000bc0b0bd ", -" effgghghgiiiggge ", -" jkkkkklmllnkknmo ", -" pqqqrqqssqqqsqsp ", -" tuuuuuuvwwwwvuxy ", -" zAAAABAAABAABABz ", -" CDEDDEEDEFEEDEEG ", -" HIJKKKLKKIKKKILM ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_ibevel.xpm b/resources/bitmaps/cap_ibevel.xpm deleted file mode 100644 index 444d7b5..0000000 --- a/resources/bitmaps/cap_ibevel.xpm +++ /dev/null @@ -1,93 +0,0 @@ -/* XPM */ -static char * cap_ibevel_xpm[] = { -"24 24 66 1", -" c None", -". c #C4E780", -"+ c #C5E780", -"@ c #C4E680", -"# c #C1E580", -"$ c #C2E580", -"% c #C2E680", -"& c #BFE580", -"* c #C0E480", -"= c #C0E580", -"- c #BEE480", -"; c #BDE480", -"> c #41E5F6", -", c #42E5F6", -"' c #BBE380", -") c #BCE380", -"! c #BBE480", -"~ c #43E4F9", -"{ c #44E4F9", -"] c #B9E280", -"^ c #BAE280", -"/ c #B9E380", -"( c #BAE380", -"_ c #46E3FB", -": c #B7E180", -"< c #B8E180", -"[ c #B7E280", -"} c #48E2FE", -"| c #B8E080", -"1 c #B8DF80", -"2 c #47E0FF", -"3 c #B9DC80", -"4 c #B9DD80", -"5 c #BADD80", -"6 c #46DEFF", -"7 c #BCDA80", -"8 c #BBDA80", -"9 c #44DCFF", -"0 c #BDD880", -"a c #43DAFF", -"b c #BFD680", -"c c #BED580", -"d c #41D6FF", -"e c #C0D380", -"f c #C0D480", -"g c #3FD4FF", -"h c #C2D180", -"i c #3DD2FF", -"j c #C4CF80", -"k c #C4CE80", -"l c #C3CE80", -"m c #3BCFFF", -"n c #C6CC80", -"o c #C5CC80", -"p c #39CDFF", -"q c #C7C980", -"r c #C8CA80", -"s c #37CAFF", -"t c #C9C780", -"u c #CAC780", -"v c #35C8FF", -"w c #CBC480", -"x c #CBC580", -"y c #34C5FF", -"z c #CDC280", -"A c #32C3FF", -" ", -" ", -" .+.@@@@@@@.....@@... ", -" #$%%%$%$$%%#%#$%#%## ", -" &*&&==*==&&=&=&==*=& ", -" ------;;---;-->,>>>> ", -" '')'))'')!)~~{ ", -" ]^/(]]^]/__ ", -" :::::<:[} ", -" |1|1|112 ", -" 3455546 ", -" 788779 ", -" 00000a ", -" bbbcd ", -" efeeg ", -" hhhhi ", -" jklm ", -" noop ", -" qqrs ", -" tutv ", -" wxwy ", -" zzzA ", -" ", -" "}; diff --git a/resources/bitmaps/cap_iendcap.xpm b/resources/bitmaps/cap_iendcap.xpm deleted file mode 100644 index 2545898..0000000 --- a/resources/bitmaps/cap_iendcap.xpm +++ /dev/null @@ -1,103 +0,0 @@ -/* XPM */ -static char * cap_iendcap_xpm[] = { -"24 24 76 1", -" c None", -". c #C4E780", -"+ c #C5E780", -"@ c #C4E680", -"# c #C1E580", -"$ c #C2E580", -"% c #C2E680", -"& c #BFE580", -"* c #C0E480", -"= c #C0E580", -"- c #BEE480", -"; c #BDE480", -"> c #BBE380", -", c #BCE380", -"' c #44E4F9", -") c #43E4F8", -"! c #44E5F9", -"~ c #43E4F9", -"{ c #B9E280", -"] c #BAE280", -"^ c #B9E380", -"/ c #BAE380", -"( c #46E3FB", -"_ c #45E3FC", -": c #46E4FC", -"< c #46E3FC", -"[ c #B7E180", -"} c #48E2FE", -"| c #B8E280", -"1 c #B8E080", -"2 c #B8DF80", -"3 c #47E0FF", -"4 c #B9DC80", -"5 c #B9DD80", -"6 c #BADD80", -"7 c #45DEFF", -"8 c #45DDFF", -"9 c #BADC80", -"0 c #BCDA80", -"a c #BBDA80", -"b c #44DBFF", -"c c #43DCFF", -"d c #BDD880", -"e c #42D9FF", -"f c #43DAFF", -"g c #BFD680", -"h c #40D7FF", -"i c #C0D380", -"j c #C0D480", -"k c #3FD4FF", -"l c #3ED4FF", -"m c #C1D380", -"n c #C2D180", -"o c #3DD2FF", -"p c #C4CF80", -"q c #C4CE80", -"r c #3CCFFF", -"s c #3BCFFF", -"t c #C3CF80", -"u c #C6CC80", -"v c #C5CC80", -"w c #3ACDFF", -"x c #C7C980", -"y c #37CBFF", -"z c #38CBFF", -"A c #C8C980", -"B c #C9C780", -"C c #CAC780", -"D c #36C8FF", -"E c #36C7FF", -"F c #CBC480", -"G c #CBC580", -"H c #34C5FF", -"I c #CDC280", -"J c #32C3FF", -"K c #CDC180", -" ", -" ", -" .+.@@@@@@@.....@@... ", -" #$%%%$%$$%%#%#$%#%## ", -" &*&&==*==&&=&=&==*=& ", -" ------;;---;---;---- ", -" >>,>,,>')!~~~>>,>,>> ", -" {]^/{(_ :<{{{{{ ", -" [[[[} }[[[| ", -" 1213 3212 ", -" 4567 8966 ", -" 0ab ca0 ", -" dde fdd ", -" ggh hgg ", -" ijk lmm ", -" nno onn ", -" pqr sqt ", -" uvw wuu ", -" xxy zAx ", -" BCD EBB ", -" FGH HFF ", -" IIJ JKI ", -" ", -" "}; diff --git a/resources/bitmaps/console.xpm b/resources/bitmaps/console.xpm deleted file mode 100644 index 0ecdd01..0000000 --- a/resources/bitmaps/console.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * console_xpm[] = { -"16 16 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F7", -"& c #8CFFFF", -"* c #00C7F7", -"= c #00C7F9", -"- c #8AFFFF", -"; c #00C5FD", -"> c #90FFFF", -", c #8EFFFF", -"' c #00C5FF", -") c #00C1FF", -"! c #00C3FF", -"~ c #00BDFF", -"{ c #00BBFF", -"] c #00B7FF", -"^ c #00B9FF", -"/ c #00B3FF", -"( c #84FFFF", -"_ c #00B5FF", -": c #00ADFF", -"< c #82FFFF", -"[ c #00AFFF", -"} c #80FFFF", -"| c #00A9FF", -"1 c #7EFFFF", -"2 c #7CFFFF", -"3 c #00A5FF", -"4 c #7AFFFF", -"5 c #00A3FF", -"6 c #009FFF", -"7 c #76FFFF", -"8 c #78FFFF", -"9 c #009BFF", -"0 c #72FFFF", -"a c #74FFFF", -"b c #0095FF", -"c c #0097FF", -" ", -" ...+.......... ", -" @##$$#$###$$#@ ", -" %&*==%&&-&&&&* ", -" ;>,>>>>>>>>>>' ", -" ),))))!))!,,,) ", -" ~-&&&--&----&{ ", -" ]#^]]]]]]]]]$] ", -" /(#((((((#(((_ ", -" :<[[:}}}<<<}}[ ", -" |111122221111| ", -" 34333355334445 ", -" 67777787777876 ", -" 9000a000a00a09 ", -" bbbbbbbbcbbbbb ", -" "}; diff --git a/resources/bitmaps/copy.xpm b/resources/bitmaps/copy.xpm deleted file mode 100644 index e312da2..0000000 --- a/resources/bitmaps/copy.xpm +++ /dev/null @@ -1,64 +0,0 @@ -/* XPM */ -static char * copy_xpm[] = { -"20 19 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F1", -"& c #00CBF3", -"* c #00C9F7", -"= c #8CFFFF", -"- c #8AFFFF", -"; c #00C7F7", -"> c #00C5FD", -", c #90FFFF", -"' c #00C5FF", -") c #00C7FF", -"! c #00C1FF", -"~ c #8EFFFF", -"{ c #00C3FF", -"] c #00BDFF", -"^ c #00BBFF", -"/ c #00B7FF", -"( c #00B9FF", -"_ c #00B3FF", -": c #84FFFF", -"< c #00B5FF", -"[ c #00ADFF", -"} c #82FFFF", -"| c #80FFFF", -"1 c #00AFFF", -"2 c #00A9FF", -"3 c #00ABFF", -"4 c #7CFFFF", -"5 c #7EFFFF", -"6 c #00A3FF", -"7 c #7AFFFF", -"8 c #00A5FF", -"9 c #00A1FF", -"0 c #76FFFF", -"a c #78FFFF", -"b c #009FFF", -"c c #009BFF", -" ", -" ", -" ", -" ...+.. ", -" @##$$%& ", -" *==-=*=; ", -" >,'>,>'')))) ", -" !~~~~~{~~~~!! ", -" ]-]]]]]=---]=^ ", -" /#$##$/$//#///( ", -" _:<____::#::::< ", -" [}||||[|11111|1 ", -" 222223244555542 ", -" 678886878 ", -" 90000a0ab ", -" ccccccccc ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cut.xpm b/resources/bitmaps/cut.xpm deleted file mode 100644 index a5dba89..0000000 --- a/resources/bitmaps/cut.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * cut_xpm[] = { -"20 19 26 1", -" c None", -". c #00CBED", -"+ c #00C9F1", -"@ c #00C9F3", -"# c #00C9F7", -"$ c #00C9F9", -"% c #00C5FD", -"& c #00C5FF", -"* c #00C7FD", -"= c #00C7FF", -"- c #00C3FF", -"; c #00C1FF", -"> c #00BDFF", -", c #00B7FF", -"' c #00B3FF", -") c #00B5FF", -"! c #00ADFF", -"~ c #00AFFF", -"{ c #00A9FF", -"] c #00ABFF", -"^ c #00A5FF", -"/ c #00A3FF", -"( c #009FFF", -"_ c #00A1FF", -": c #009BFF", -"< c #0095FF", -" ", -" ", -" ", -" . . ", -" + @ ", -" # $ ", -" %& *= ", -" - ; ", -" >>> ", -" , ", -" '') ", -" ! ~~~ ", -" {]{ ] { ", -" ^ / ^ / ", -" ( _ _ _ ", -" : : :: ", -" << ", -" ", -" "}; diff --git a/resources/bitmaps/dontselectcurve.xpm b/resources/bitmaps/dontselectcurve.xpm deleted file mode 100644 index 0e80113..0000000 --- a/resources/bitmaps/dontselectcurve.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * dontselectcurve_xpm[] = { -"16 15 26 1", -" c None", -". c #00A5D9", -"+ c #00A4E2", -"@ c #00A5E0", -"# c #00A4E6", -"$ c #00A4E8", -"% c #00A4EA", -"& c #00A4F0", -"* c #00A4F2", -"= c #00A4EE", -"- c #003469", -"; c #00346B", -"> c #00A4F6", -", c #00A4F4", -"' c #00346D", -") c #00A3FA", -"! c #00346F", -"~ c #003471", -"{ c #00A3FF", -"] c #003473", -"^ c #003472", -"/ c #003476", -"( c #003377", -"_ c #00A2FF", -": c #00A1FF", -"< c #00A0FF", -" ", -" .. . ", -" ++@ @ ", -" #$$% $ ", -" &*&= & ", -"-;->>>>-;>,; ;;;", -"' '))))) ' ! ", -"~ ~ {{{~ ~ ~~ ", -"] ] {{{^ ] ] ", -"/(( /___ _ ////", -" ___ _ ", -" ::: : ", -" ::: : ", -" <<< < ", -"<<< < "}; diff --git a/resources/bitmaps/dontselectmodel.xpm b/resources/bitmaps/dontselectmodel.xpm deleted file mode 100644 index 4adcbed..0000000 --- a/resources/bitmaps/dontselectmodel.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * dontselectmodel_xpm[] = { -"16 15 26 1", -" c None", -". c #00A5D9", -"+ c #00A4E2", -"@ c #00A5E0", -"# c #00A4E6", -"$ c #00A4E8", -"% c #00A4EA", -"& c #00A4F0", -"* c #00A4F2", -"= c #00A4EE", -"- c #003469", -"; c #00A4F6", -"> c #00A4F4", -", c #00346B", -"' c #00346D", -") c #00A3FA", -"! c #00346E", -"~ c #003471", -"{ c #00A3FF", -"] c #003473", -"^ c #003472", -"/ c #003476", -"( c #003377", -"_ c #00A2FF", -": c #00A1FF", -"< c #00A0FF", -" ", -" .. . ", -" ++@ @ ", -" #$$% $ ", -" &*&= & ", -"- -;;;; ;>,, , ", -"''' ' )))) ' ! ", -"~ ~ ~ {{{~ ~~ ~ ", -"] ] ] {{{^ ] ^ ", -"/ ( ___/_ // //", -" ___ _ ", -" ::: : ", -" ::: : ", -" <<< < ", -"<<< < "}; diff --git a/resources/bitmaps/ellipsis.xpm b/resources/bitmaps/ellipsis.xpm deleted file mode 100644 index e825433..0000000 --- a/resources/bitmaps/ellipsis.xpm +++ /dev/null @@ -1,11 +0,0 @@ -/* XPM */ -static char * ellipsis_xpm[] = { -"12 4 4 1", -" c None", -". c #00B7FF", -"+ c #00B3FF", -"@ c #00B5FF", -" ", -" .. .. ..", -" ++ +@ @+", -" "}; diff --git a/resources/bitmaps/entities.xpm b/resources/bitmaps/entities.xpm deleted file mode 100644 index f2b014a..0000000 --- a/resources/bitmaps/entities.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * entities_xpm[] = { -"16 16 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F7", -"& c #8CFFFF", -"* c #00C7F7", -"= c #00C7F9", -"- c #00C9F9", -"; c #00C5FD", -"> c #90FFFF", -", c #8EFFFF", -"' c #00C5FF", -") c #00C1FF", -"! c #00BDFF", -"~ c #8AFFFF", -"{ c #00BBFF", -"] c #00B7FF", -"^ c #00B9FF", -"/ c #00B3FF", -"( c #84FFFF", -"_ c #00B5FF", -": c #00ADFF", -"< c #82FFFF", -"[ c #00AFFF", -"} c #80FFFF", -"| c #00A9FF", -"1 c #7EFFFF", -"2 c #7CFFFF", -"3 c #00A5FF", -"4 c #7AFFFF", -"5 c #00A3FF", -"6 c #009FFF", -"7 c #76FFFF", -"8 c #78FFFF", -"9 c #009BFF", -"0 c #72FFFF", -"a c #74FFFF", -"b c #0095FF", -"c c #0097FF", -" ", -" ...+.......... ", -" @##$$#$###$$#@ ", -" %&*==&&*=--=&* ", -" ;>,>>>>>>>>>>' ", -" ),))),,)),,,,) ", -" !~&&&~~&~~~~&{ ", -" ]#^]]$#]]]#$$] ", -" /(#((((((#(((_ ", -" :<[[:}}[[[[[}[ ", -" |111122221111| ", -" 34333445344445 ", -" 67777787777876 ", -" 9000a000a00a09 ", -" bbbbbbbbcbbbbb ", -" "}; diff --git a/resources/bitmaps/file_new.xpm b/resources/bitmaps/file_new.xpm deleted file mode 100644 index 353b529..0000000 --- a/resources/bitmaps/file_new.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * file_new_xpm[] = { -"16 16 27 1", -" c None", -". c #39E8EB", -"+ c #39E8EA", -"@ c #38E8EB", -"# c #39E9EB", -"$ c #3DE7F1", -"% c #FFFFFF", -"& c #3EE6F0", -"* c #3DE7F0", -"= c #41E5F6", -"- c #46E3FC", -"; c #46E4FC", -"> c #47E0FF", -", c #44DBFF", -"' c #43DBFF", -") c #41D7FF", -"! c #40D7FF", -"~ c #3CD2FF", -"{ c #3DD2FF", -"] c #39CDFF", -"^ c #36C7FF", -"/ c #36C8FF", -"( c #32C3FF", -"_ c #2FBEFF", -": c #2CB9FF", -"< c #2BB9FF", -"[ c #2BB8FF", -" ", -" ", -" .+@#..#. ", -" $%%%%%%&* ", -" =%%%%%%=%= ", -" -%%%%%%;--- ", -" >%%%%%%%%%> ", -" ,%%%%%%%%%' ", -" )%%%%%%%%%! ", -" ~%%%%%%%%%{ ", -" ]%%%%%%%%%] ", -" ^%%%%%%%%%/ ", -" (%%%%%%%%%( ", -" _%%%%%%%%%_ ", -" :<<::[<:[<< ", -" "}; diff --git a/resources/bitmaps/file_open.xpm b/resources/bitmaps/file_open.xpm deleted file mode 100644 index 5b83d14..0000000 --- a/resources/bitmaps/file_open.xpm +++ /dev/null @@ -1,59 +0,0 @@ -/* XPM */ -static char * file_open_xpm[] = { -"16 16 40 1", -" c None", -". c #39E8EB", -"+ c #39E9EB", -"@ c #3EE6F0", -"# c #3DE6F0", -"$ c #41E5F6", -"% c #42E5F6", -"& c #46E3FC", -"* c #45E3FC", -"= c #46E4FC", -"- c #47E0FF", -"; c #FAFEFF", -"> c #FFFFFF", -", c #47E1FF", -"' c #43DBFF", -") c #44DBFF", -"! c #41D7FF", -"~ c #40D7FF", -"{ c #3CD1FF", -"] c #3DD2FF", -"^ c #3DD1FF", -"/ c #39CDFF", -"( c #99E5FF", -"_ c #9AE5FF", -": c #36C7FF", -"< c #F9FDFF", -"[ c #35C8FF", -"} c #97E3FF", -"| c #98E3FF", -"1 c #98E2FF", -"2 c #32C3FF", -"3 c #96E0FF", -"4 c #2FBEFF", -"5 c #94DEFF", -"6 c #94DDFF", -"7 c #2EBDFF", -"8 c #2CB8FF", -"9 c #2BB9FF", -"0 c #2CB9FF", -"a c #2BB8FF", -" ", -" ", -" .+. ", -" @ @ # ", -" $% ", -" &&* &&= ", -"-;>;---,--- ", -"'>;>;>;>;>) ", -"!;>;>;>;>;~ ", -"{>;>;]]^]]]]]{]]", -"/;>;/(_(_((_(_/ ", -":><[}|||}|}1|[ ", -"2<23333333332 ", -"445555666557 ", -"8909900a90a ", -" "}; diff --git a/resources/bitmaps/file_save.xpm b/resources/bitmaps/file_save.xpm deleted file mode 100644 index 08cf5f7..0000000 --- a/resources/bitmaps/file_save.xpm +++ /dev/null @@ -1,83 +0,0 @@ -/* XPM */ -static char * file_save_xpm[] = { -"16 16 64 1", -" c None", -". c #00D5CB", -"+ c #00D5CD", -"@ c #00D7CD", -"# c #00D1D7", -"$ c #37E7EA", -"% c #00D1D5", -"& c #5CF7F8", -"* c #5DF7F8", -"= c #00CFE1", -"- c #3BE6F1", -"; c #00CDE1", -"> c #64F6FA", -", c #66F6FA", -"' c #00CBED", -") c #3FE4F6", -"! c #6BF6FC", -"~ c #6CF6FC", -"{ c #00C7F9", -"] c #44E2FC", -"^ c #71F5FE", -"/ c #73F5FE", -"( c #00C9F9", -"_ c #00C1FF", -": c #45DFFF", -"< c #74F4FF", -"[ c #45E0FF", -"} c #00C3FF", -"| c #00B9FF", -"1 c #42DAFF", -"2 c #00B7FF", -"3 c #6EF2FF", -"4 c #6FF2FF", -"5 c #00AFFF", -"6 c #3FD6FF", -"7 c #3ED6FF", -"8 c #00ADFF", -"9 c #00A5FF", -"0 c #3AD1FF", -"a c #3BD1FF", -"b c #3BD0FF", -"c c #3AD0FF", -"d c #009BFF", -"e c #37CCFF", -"f c #38CCFF", -"g c #008FFF", -"h c #35C5FF", -"i c #34C6FF", -"j c #0091FF", -"k c #57EBFF", -"l c #59EBFF", -"m c #0085FF", -"n c #31C1FF", -"o c #0087FF", -"p c #52E9FF", -"q c #31C0FF", -"r c #007DFF", -"s c #2EBCFF", -"t c #2DBCFF", -"u c #007BFF", -"v c #4BE8FF", -"w c #4BE7FF", -"x c #0073FF", -"y c #0071FF", -" ", -" .+...@.+..+..+ ", -" #$%&*******#&# ", -" =-;>>>>,,>>;;; ", -" ')'!!~!~!~!')' ", -" {]{^///^///{]( ", -" _:_<<<<<<<<_[} ", -" |1234334343212 ", -" 56785885555765 ", -" 90aaaabaaaaac9 ", -" defdddddddddfd ", -" ghijjjjjjkljij ", -" mnnoomoooppoqo ", -" rstrruuurvwrsu ", -" xxxxxyxxyxxxy ", -" "}; diff --git a/resources/bitmaps/icon.xpm b/resources/bitmaps/icon.xpm deleted file mode 100644 index 60cd969..0000000 --- a/resources/bitmaps/icon.xpm +++ /dev/null @@ -1,271 +0,0 @@ -/* XPM */ -static char *icon[] = { -/* columns rows colors chars-per-pixel */ -"32 32 233 2 ", -" c None", -". c #1E345F", -"X c #1E3666", -"o c #243D6B", -"O c #253A69", -"+ c #213D78", -"@ c #2D415A", -"# c #354756", -"$ c #2B426B", -"% c #26436C", -"& c #35486A", -"* c #3A526A", -"= c #264172", -"- c #2B4374", -"; c #2D4478", -": c #2D497B", -"> c #264777", -", c #354974", -"< c #384B77", -"1 c #3A517B", -"2 c #395276", -"3 c #43546A", -"4 c #42567A", -"5 c #445A7C", -"6 c #485A7C", -"7 c #415573", -"8 c #525C79", -"9 c #424F7D", -"0 c #52637E", -"q c #636565", -"w c #63667D", -"e c #977C7E", -"r c #AE7E7C", -"t c #3D5386", -"y c #3B5587", -"u c #3D548C", -"i c #425483", -"p c #445A83", -"a c #4B5B82", -"s c #445B8C", -"d c #4C5D8B", -"f c #41578A", -"g c #435B93", -"h c #475E9A", -"j c #515C80", -"k c #496187", -"l c #54638E", -"z c #5C6A8C", -"x c #596587", -"c c #4D6293", -"v c #4C6599", -"b c #546592", -"n c #536997", -"m c #5C6C95", -"M c #546A9A", -"N c #5A6C9D", -"B c #56679B", -"V c #5E729D", -"C c #626885", -"Z c #677286", -"A c #767689", -"S c #627391", -"D c #6B759B", -"F c #6F7C9A", -"G c #687597", -"H c #767A9A", -"J c #696991", -"K c #4963A1", -"L c #5C6DA3", -"P c #566AA6", -"I c #5E71A3", -"U c #5C72A8", -"Y c #556AB8", -"T c #516BB9", -"R c #6D7AA2", -"E c #6777A6", -"W c #737EA2", -"Q c #757CA6", -"! c #606FB2", -"~ c #6C7CB4", -"^ c #6878B4", -"/ c #767CB5", -"( c #626CAB", -") c #6377C5", -"_ c #727BC1", -"` c #89788B", -"' c #937F87", -"] c #A17E8F", -"[ c #857CAD", -"{ c #7681A3", -"} c #7583AB", -"| c #7C86AD", -" . c #7D86A8", -".. c #7C87B3", -"X. c #7B8AB4", -"o. c #7B86BC", -"O. c #7D8CBC", -"+. c #7582B7", -"@. c #6D80A2", -"#. c #7987C3", -"$. c #7E8CC2", -"%. c #7483C7", -"&. c #7B8AD5", -"*. c #7F93D0", -"=. c #7894E7", -"-. c #6D8CE7", -";. c #868499", -":. c #98839B", -">. c #8C8B92", -",. c #A88699", -"<. c #B89899", -"1. c #A88588", -"2. c #838BAB", -"3. c #8589AA", -"4. c #9489AA", -"5. c #8B93AC", -"6. c #8790AC", -"7. c #9393A5", -"8. c #838CB3", -"9. c #848EBC", -"0. c #8B8EB5", -"q. c #918AB3", -"w. c #8C95B4", -"e. c #8592BA", -"r. c #8B92BB", -"t. c #8E99BE", -"y. c #8790B3", -"u. c #9395BC", -"i. c #959BBD", -"p. c #989BB5", -"a. c #A897AB", -"s. c #A79AB5", -"d. c #B799BC", -"f. c #AC8DAD", -"g. c #9DA3BD", -"h. c #A2A2BE", -"j. c #ABADBD", -"k. c #ABA7BA", -"l. c #BCA5BD", -"z. c #C4909F", -"x. c #D19DB1", -"c. c #E19DA2", -"v. c #CBAEBC", -"b. c #838EC2", -"n. c #8C94C3", -"m. c #8B94CC", -"M. c #8796C8", -"N. c #949CC3", -"B. c #949BCB", -"V. c #9799CB", -"C. c #808FD1", -"Z. c #8595DC", -"A. c #8897D7", -"S. c #969BD8", -"D. c #A49AC5", -"F. c #9BA1C2", -"G. c #9AA3CC", -"H. c #9EAAD6", -"J. c #92A1DA", -"K. c #9BA6DB", -"L. c #99A5DA", -"P. c #8FA3DD", -"I. c #A1A3C3", -"U. c #A5ABCB", -"Y. c #A8ACC6", -"T. c #B8AAC6", -"R. c #AFB1C6", -"E. c #B8B8CB", -"W. c #A3ACD4", -"Q. c #A9ACD2", -"!. c #A5A9D8", -"~. c #ACB3D5", -"^. c #AEB5DC", -"/. c #A5B2DC", -"(. c #B4BADD", -"). c #B8BBD6", -"_. c #B9ACDD", -"`. c #859BE3", -"'. c #8A9DE9", -"]. c #8EA3E3", -"[. c #8BA4EB", -"{. c #98A8E8", -"}. c #99ADF1", -"|. c #96B6F8", -" X c #A6ACE4", -".X c #B7AAE5", -"XX c #ACB5E3", -"oX c #ADB9E4", -"OX c #A4B3EC", -"+X c #A8B6E8", -"@X c #B3BBE5", -"#X c #B3BDEB", -"$X c #B6BAE3", -"%X c #A4B6F1", -"&X c #ADBCF3", -"*X c #A7B8F4", -"=X c #B6B8F2", -"-X c #A3AAF5", -";X c #C7A5C9", -":X c #D7ABCA", -">X c #C9A8D3", -",X c #D8BCDF", -"X:XX;Xd.4.A w C w h.{ { q.:.f.a B B g g h b.B.P ", -" =X>Xf.[ H H D D 8.z w.g.s.p.6.C f i d N d s L !.^ M ", -" }.S./ / n.N.B.i.2.@.h.R.g.7.T.l 6 D 0.Q p.w.(.W U P M 8 ", -" =._ 8.b.n.Q...9X9XZ E.rXj.6Xk...i.r...I. .3.iXB.9.U U x ", -" =.S.&.) n.kXqXU.i.6XF.h.7X6X1X5.m 6XY.h.H 1 : ~ Q B.o.m v * ", -" [.S.! P U R ~.Y.w.~.Y.6XE.E.6X1XH.i.J o i 6 N M p b m.n.I 6 ", -" A.%.M.h ^ E p g.R.i.R.jXE.6X .;. .9.Y.d d & : 1 X.R R L.X.k ", -"%X&.U.e.( } Q.L E.R.g.h.jXjXj.} p S A Y.0.| = f < N S 1 N.B.s # ", -"[.Z.*.qXU.t.{ b ,.;.s.k.E.7.Z l V 2 w & W N l < : f 1 k M D I 3 ", -"-.) P.W.| L g #.0.e 1.<.1.q A 0 6 & q . X O f B ; 6 y c y y n 3 ", -"-.) o.b.W.N.~ $X(.a.r z.a.7.0 V 2 & 2 2 , 9 a F a l y u N c y 2 ", -"-.T ~ ~ v u + + i 4.l.<.l.` x W 4 , - O O o ; 6 r.} I > L : c & ", -"=.Y Y ^ M.(.3.I t i a.7X8X5.} F a < p o = $ % X l i.V = t f c * ", -"'.A.S.U P Q.dX9Xi.W @.8XtXzXrXtXrXE.| , 0 @.G F o 2 t.= c : k 2 ", -"}.%.#X^ / U.9.o.h t X.S w.wXxXzXxXzXrXw.d F D 6.x 4 8.m : s N @ ", -" +XdX$.N.X.w.h.8 & r.B.i.S g.lXxXxX2Xe.z 5.W.G.F V E H.> y 1 ", -" {.gXb.G.i.1XrXh.a x y.kXrXjXxXxXqX(.{ 4 y.~.2Xy.F.X.K.I c & ", -" -.oXeXr.O.r.~.tX^.h.eXtXzXgX6Xw.} | S F 5.e.aX(.2XoX{.$.k @ ", -" +XyXXXb.G.N.(.dX~.@XqXfXwX@XW.G.t.H 5.0 8.{ 1 e.+XO.m 3 ", -" ].2X*X$.uXH.qXlXXXXXN.uX0XXXe.F.} 5.t.N.0 7 $ } +.k 6 # ", -" [.C.oX2XpXb.uX3X@X!.qX@X!.@XW.^.W.r.X.E O.J.*.B s 2 ", -" =.*.b.oXB.b.oXdXlXdX/.dXhXpXoX^.e.!.K.{.A.M.+.n ", -" ].%X2XyXyXdXaXaXfXlXdXhXdXgXsX/./.#X XM.#.L ", -" [.5XaXaXdXaXsXdXlXgXgXgXgXdXyX&X*XJ.^ L ", -" `.&.%X4XyXyXdXdXdXfXyXyX3X&XOX{.%.L ", -" `.}.&X*X3X4X5X3X&X%XOXJ.C.^ ", -" `.}.].{.].`.Z.%. " -}; diff --git a/resources/bitmaps/lightinspector.xpm b/resources/bitmaps/lightinspector.xpm deleted file mode 100644 index baef0de..0000000 --- a/resources/bitmaps/lightinspector.xpm +++ /dev/null @@ -1,192 +0,0 @@ -/* XPM */ -static char *lightinspector[] = { -/* columns rows colors chars-per-pixel */ -"16 15 171 2 ", -" c #323232", -". c #343434", -"X c #373737", -"o c #3A3A3B", -"O c #3E3D3E", -"+ c #414142", -"@ c gray27", -"# c gray29", -"$ c #4E4F4F", -"% c #545353", -"& c #585858", -"* c #5D5D5D", -"= c #636263", -"- c #686768", -"; c #6D6D6D", -": c #727272", -"> c #343535", -", c #3A3A3A", -"< c #3E3E3D", -"1 c #424241", -"2 c #454546", -"3 c #494849", -"4 c #4C4C4C", -"5 c #515151", -"6 c #555656", -"7 c #5C5B5C", -"8 c #626262", -"9 c #676767", -"0 c #6D6C6D", -"q c #777777", -"w c #363737", -"e c #3A393A", -"r c gray24", -"t c #414041", -"y c #484849", -"u c #656462", -"i c #D9CFBE", -"p c #605E5A", -"a c #555555", -"s c #5D5D5C", -"d c gray40", -"f c #6D6C6C", -"g c #717271", -"h c #7C7C7C", -"j c #414141", -"k c #444444", -"l c #494848", -"z c #666562", -"x c #EEE7DB", -"c c #FFF3DC", -"v c #CBBFAB", -"b c #5B5A57", -"n c #707170", -"m c #818281", -"M c #3C3D3D", -"N c #444445", -"B c #484848", -"V c #EBE5D9", -"C c #FFF8EA", -"Z c #DBCEB7", -"A c #C8BDA8", -"S c #5E5B59", -"D c gray38", -"F c #7A7B7A", -"G c #818181", -"H c #878786", -"J c gray25", -"K c gray28", -"L c #636260", -"P c #C8BDA9", -"I c #646260", -"U c #6A6A69", -"Y c gray48", -"T c #848484", -"R c #8B8B8B", -"E c #626260", -"W c #696866", -"Q c #737272", -"! c #8E8F8E", -"~ c #4B4B4B", -"^ c #D8D1C4", -"/ c #FFF5E4", -"( c #FFF5E3", -") c #FEEFD4", -"_ c #C4B8A4", -"` c #C2B7A2", -"' c #A19889", -"] c #6A6A6A", -"[ c #828283", -"{ c #929292", -"} c #4C4D4C", -"| c gray31", -" . c #656360", -".. c #EBDEC8", -"X. c #FFF1D7", -"o. c #D9CCB5", -"O. c #A29887", -"+. c #A19886", -"@. c #948C7C", -"#. c #51504E", -"$. c #838382", -"%. c #949595", -"&. c #535453", -"*. c gray32", -"=. c #62605C", -"-. c #EADEC6", -";. c #D8CBB4", -":. c #948B7C", -">. c #444341", -",. c #717171", -"<. c #8A8B8B", -"1. c #9B9A9B", -"2. c #595A59", -"3. c #5A5A5A", -"4. c #555556", -"5. c #64625F", -"6. c #EADEC7", -"7. c #928A7B", -"8. c #434240", -"9. c gray30", -"0. c #69696A", -"q. c #838383", -"w. c #959596", -"e. c #A0A0A0", -"r. c #5F5F5F", -"t. c #636464", -"y. c gray37", -"u. c #6A6864", -"i. c #EBDEC6", -"p. c #D7CAB4", -"a. c #938A7C", -"s. c #4E4D4D", -"d. c DimGray", -"f. c gray51", -"g. c gray58", -"h. c #9E9F9F", -"j. c #A5A4A4", -"k. c #5F5E5F", -"l. c #6C6C6D", -"z. c #6D6E6D", -"x. c #706F6A", -"c. c #B3AA98", -"v. c #504F4D", -"b. c #515252", -"n. c #9E9F9E", -"m. c #A4A4A5", -"M. c gray66", -"N. c #636463", -"B. c #696868", -"V. c gray43", -"C. c gray45", -"Z. c #717071", -"A. c #656565", -"S. c gray44", -"D. c #939494", -"F. c gray62", -"G. c #A4A4A4", -"H. c #ABABAC", -"J. c #686868", -"K. c #797879", -"L. c #7D7D7E", -"P. c #818182", -"I. c #808181", -"U. c #898988", -"Y. c #949594", -"T. c #9E9D9E", -"R. c gray64", -"E. c #A7A7A7", -"W. c gray67", -"Q. c #AEAEAE", -"!. c white", -/* pixels */ -" . X o O + @ # $ % & * = - ; : ", -"> X , < 1 2 3 4 5 6 7 8 9 0 : q ", -"w e r t @ y u i p a s d f g q h ", -"e r j k l z x c v b & d n q h m ", -"M j N B u V C c Z A S D n F G H ", -"J N K L V C C c Z Z P I U Y T R ", -"k K E V C C C c Z Z Z A W Q T ! ", -"B ~ ^ / / / ( ) _ _ _ ` ' ] [ { ", -"} | ...X.X.X.o.O.O.+.@.#.9 $.%.", -"5 &.*.=.-.X.X.;.O.O.:.>.*.,.<.1.", -"a 2.3.4.5.6.X.;.O.7.8.9.0.q.w.e.", -"3.r.8 t.y.u.i.p.a.>.s.d.f.g.h.j.", -"k.t.d.l.z.9 x.c.v.b.d.G g.n.m.M.", -"N.B.V.C.q q Z.- A.S.[ D.F.G.M.H.", -"J.z.C.K.L.G P.I.P.U.Y.T.R.E.W.Q." -}; diff --git a/resources/bitmaps/logo.xpm b/resources/bitmaps/logo.xpm deleted file mode 100644 index 2234735..0000000 --- a/resources/bitmaps/logo.xpm +++ /dev/null @@ -1,4295 +0,0 @@ -/* XPM */ -static char * logo_xpm[] = { -"126 126 4166 2", -" c #FFFFFF", -". c #000000", -"+ c #010001", -"@ c #010101", -"# c #040404", -"$ c #050505", -"% c #020202", -"& c #030303", -"* c #060606", -"= c #0D0D0D", -"- c #101010", -"; c #070707", -"> c #0A0A0A", -", c #111111", -"' c #0F0F0F", -") c #131313", -"! c #141314", -"~ c #080808", -"{ c #111011", -"] c #131213", -"^ c #0F0E0F", -"/ c #0B0B0B", -"( c #121112", -"_ c #121212", -": c #0C0C0C", -"< c #191919", -"[ c #434343", -"} c #545454", -"| c #363636", -"1 c #181818", -"2 c #414141", -"3 c #555455", -"4 c #393939", -"5 c #242424", -"6 c #4D4D4D", -"7 c #5F5F5F", -"8 c #616061", -"9 c #606060", -"0 c #535353", -"a c #2E2E2E", -"b c #090909", -"c c #303030", -"d c #5E5E5E", -"e c #4B4B4B", -"f c #232323", -"g c #3B3B3B", -"h c #5A595A", -"i c #5C5C5C", -"j c #424142", -"k c #151515", -"l c #C1C0C1", -"m c #E9E9EA", -"n c #909090", -"o c #3D3D3D", -"p c #B1B1B1", -"q c #E7E7E7", -"r c #9C9C9C", -"s c #212121", -"t c #6A696A", -"u c #D4D4D4", -"v c #EAEAEA", -"w c #DFDFDF", -"x c #818181", -"y c #2F2F2F", -"z c #313131", -"A c #848484", -"B c #E0DFE0", -"C c #D3D3D3", -"D c #676667", -"E c #202020", -"F c #0E0E0E", -"G c #444444", -"H c #AAA9AA", -"I c #EAE9EA", -"J c #B3B3B3", -"K c #515151", -"L c #141414", -"M c #2C2C2C", -"N c #A2A2A2", -"O c #F2F1F2", -"P c #F0F0F1", -"Q c #C3C3C3", -"R c #EDEBED", -"S c #EEEEEE", -"T c #727272", -"U c #1E1D1E", -"V c #C9C9C9", -"W c #EDEAED", -"X c #E3D9E4", -"Y c #E4DEE5", -"Z c #E5DFE5", -"` c #E3DAE4", -" . c #E9E3E9", -".. c #DEDEDE", -"+. c #585858", -"@. c #5A5A5B", -"#. c #DFDEDF", -"$. c #E8E3E8", -"%. c #E5DEE5", -"&. c #EDEBEE", -"*. c #C8C8C8", -"=. c #3F3F3F", -"-. c #1F1F1F", -";. c #7E7E7E", -">. c #F0F0F0", -",. c #E5DCE5", -"'. c #E4DCE4", -"). c #E4DDE5", -"!. c #E4DAE4", -"~. c #F0EFF0", -"{. c #979697", -"]. c #2A2A2A", -"^. c #090809", -"/. c #353435", -"(. c #B5B5B6", -"_. c #E8E0E9", -":. c #ECE8ED", -"<. c #4C4B4C", -"[. c #C2C2C3", -"}. c #E6DBE6", -"|. c #EEEBEE", -"1. c #838283", -"2. c #D6D6D6", -"3. c #E2D3E3", -"4. c #E8E2E8", -"5. c #E8E8E8", -"6. c #E8E7E8", -"7. c #EAE7EA", -"8. c #E0CBE0", -"9. c #E6E6E6", -"0. c #666667", -"a. c #161516", -"b. c #070607", -"c. c #171617", -"d. c #696869", -"e. c #E0CAE0", -"f. c #EAE9EB", -"g. c #E8E2E9", -"h. c #E3D3E3", -"i. c #D6D5D6", -"j. c #0E0D0E", -"k. c #252525", -"l. c #919091", -"m. c #EEEAEE", -"n. c #E1CFE2", -"o. c #EBEBEB", -"p. c #E7E7E8", -"q. c #E3D4E3", -"r. c #E9E1E9", -"s. c #333233", -"t. c #0A090A", -"u. c #353535", -"v. c #B4B4B5", -"w. c #E5D6E6", -"x. c #E9E1EA", -"y. c #A1A0A1", -"z. c #4B4A4B", -"A. c #E2D1E3", -"B. c #EBE5EC", -"C. c #838184", -"D. c #080809", -"E. c #4E4D4E", -"F. c #D5D4D5", -"G. c #DFC8E0", -"H. c #E5E2E5", -"I. c #8B8A8B", -"J. c #7F7E7F", -"K. c #DAD9DA", -"L. c #DDC3DF", -"M. c #E4E3E4", -"N. c #060607", -"O. c #DEC6DF", -"P. c #D9D9DA", -"Q. c #7C7B7D", -"R. c #8F8D8F", -"S. c #EEECEF", -"T. c #D4D4D5", -"U. c #0D0C0E", -"V. c #050405", -"W. c #262526", -"X. c #918F91", -"Y. c #EBE4EB", -"Z. c #E3D2E4", -"`. c #C6C5C7", -" + c #767576", -".+ c #B2B1B3", -"++ c #E6DBE7", -"@+ c #E5D8E6", -"#+ c #A9A8AA", -"$+ c #333333", -"%+ c #343435", -"&+ c #B3B2B4", -"*+ c #DDCCE3", -"=+ c #E4D9E8", -"-+ c #9F9EA0", -";+ c #4A494B", -">+ c #BFBEC0", -",+ c #D9C5E1", -"'+ c #E7DEEA", -")+ c #817F82", -"!+ c #242324", -"~+ c #080708", -"{+ c #0E0C0E", -"]+ c #4D4C4D", -"^+ c #D3D2D4", -"/+ c #D4B9DD", -"(+ c #E1DDE2", -"_+ c #716F72", -":+ c #5E5D5E", -"<+ c #D4D3D5", -"[+ c #D5B5DC", -"}+ c #E2E1E3", -"|+ c #636263", -"1+ c #141415", -"2+ c #161517", -"3+ c #686769", -"4+ c #E1DFE2", -"5+ c #D6B8DD", -"6+ c #767477", -"7+ c #D3BADD", -"8+ c #D2D2D3", -"9+ c #4A4A4B", -"0+ c #0D0C0D", -"a+ c #040405", -"b+ c #080709", -"c+ c #252426", -"d+ c #8F8D90", -"e+ c #E7DCE9", -"f+ c #DAC9E2", -"g+ c #BDBCBE", -"h+ c #A5A4A6", -"i+ c #E1D3E5", -"j+ c #DECEE4", -"k+ c #A7A6A8", -"l+ c #323233", -"m+ c #09080A", -"n+ c #343334", -"o+ c #B1AFB2", -"p+ c #D4C3E0", -"q+ c #DED1E5", -"r+ c #9D9C9F", -"s+ c #49484A", -"t+ c #CEB9DE", -"u+ c #E2D7E7", -"v+ c #7F7D81", -"w+ c #232223", -"x+ c #D0D0D2", -"y+ c #C6ABDA", -"z+ c #DFD8E0", -"A+ c #6E6C70", -"B+ c #59585A", -"C+ c #D2D1D3", -"D+ c #E5DBE7", -"E+ c #CBCACC", -"F+ c #676568", -"G+ c #DFDAE0", -"H+ c #C7A8D9", -"I+ c #D2D0D3", -"J+ c #585659", -"K+ c #767478", -"L+ c #E9E2EB", -"M+ c #C7ACDA", -"N+ c #D0CFD1", -"O+ c #0C0B0D", -"P+ c #242425", -"Q+ c #8D8B8E", -"R+ c #E1D6E6", -"S+ c #D1BEDF", -"T+ c #BBBABC", -"U+ c #4B4A4C", -"V+ c #A3A1A4", -"W+ c #D9CAE2", -"X+ c #D5C5E1", -"Y+ c #A5A3A7", -"Z+ c #323132", -"`+ c #333234", -" @ c #AFADB0", -".@ c #CAB8DD", -"+@ c #D6C8E2", -"@@ c #9B999D", -"#@ c #484749", -"$@ c #BAB9BD", -"%@ c #C2ADDA", -"&@ c #DCCFE4", -"*@ c #7D7A80", -"=@ c #222123", -"-@ c #070608", -";@ c #020102", -">@ c #4A494C", -",@ c #CECDD0", -"'@ c #B79AD6", -")@ c #DBD2DE", -"!@ c #737176", -"~@ c #535255", -"{@ c #A6A5A7", -"]@ c #626162", -"^@ c #060506", -"/@ c #151416", -"(@ c #656367", -"_@ c #DCD5DE", -":@ c #B796D6", -"<@ c #D0CED2", -"[@ c #6A686C", -"}@ c #9A979E", -"|@ c #DACEE4", -"1@ c #B69BD6", -"2@ c #CECDCF", -"3@ c #484649", -"4@ c #0B0A0D", -"5@ c #242325", -"6@ c #8B888D", -"7@ c #DACDE4", -"8@ c #C5B1DC", -"9@ c #BBB9BD", -"0@ c #575659", -"a@ c #A4A1A6", -"b@ c #D0C0DF", -"c@ c #CCBADE", -"d@ c #A3A1A5", -"e@ c #313032", -"f@ c #030203", -"g@ c #323133", -"h@ c #ACAAAF", -"i@ c #BEACD8", -"j@ c #CEBFDE", -"k@ c #99979B", -"l@ c #464548", -"m@ c #B8B6BB", -"n@ c #B6A0D4", -"o@ c #D3C6E2", -"p@ c #7A767E", -"q@ c #212023", -"r@ c #49474B", -"s@ c #CBCACE", -"t@ c #A688CE", -"u@ c #D0C2DC", -"v@ c #BDBAC1", -"w@ c #B6B4B9", -"x@ c #B9B7BB", -"y@ c #A9A7AB", -"z@ c #59575B", -"A@ c #1D1C1D", -"B@ c #050506", -"C@ c #141315", -"D@ c #636065", -"E@ c #D7CEDB", -"F@ c #997BCB", -"G@ c #D7CFDB", -"H@ c #BEBBC2", -"I@ c #D9D0DF", -"J@ c #9D82C9", -"K@ c #C0ABD8", -"L@ c #C4C3C6", -"M@ c #3E3D3F", -"N@ c #09080B", -"O@ c #030304", -"P@ c #232224", -"Q@ c #88858B", -"R@ c #D2C4E1", -"S@ c #AD94D0", -"T@ c #D2CFD5", -"U@ c #B8B6BC", -"V@ c #CAC7CE", -"W@ c #B9A3D4", -"X@ c #C0AED8", -"Y@ c #A09DA3", -"Z@ c #302F31", -"`@ c #070609", -" # c #020203", -".# c #312F32", -"+# c #A9A7AD", -"@# c #B3A0CE", -"## c #C5B5D8", -"$# c #969499", -"%# c #454347", -"&# c #B5B3B8", -"*# c #A790C8", -"=# c #CBBDDC", -"-# c #77737C", -";# c #201F22", -"># c #060507", -",# c #010102", -"'# c #040304", -")# c #0A080C", -"!# c #474549", -"~# c #C8C5CB", -"{# c #9175BB", -"]# c #8269B2", -"^# c #AA94C7", -"/# c #AE9AC8", -"(# c #CCBDDB", -"_# c #444245", -":# c #121114", -"<# c #605D64", -"[# c #D1C7D9", -"}# c #715BA9", -"|# c #9077BA", -"1# c #A790C6", -"2# c #7F66AF", -"3# c #836AB6", -"4# c #D3CBD8", -"5# c #767379", -"6# c #242426", -"7# c #858289", -"8# c #C9BBDB", -"9# c #6E58A4", -"0# c #9D85C1", -"a# c #AD99C8", -"b# c #A28AC3", -"c# c #705AA6", -"d# c #B5A3CF", -"e# c #9D9AA1", -"f# c #2E2D30", -"g# c #060608", -"h# c #060508", -"i# c #302E31", -"j# c #A6A3AA", -"k# c #A792C4", -"l# c #BAA9D1", -"m# c #939097", -"n# c #444146", -"o# c #B2AFB6", -"p# c #9980BB", -"q# c #C3B3D6", -"r# c #746E7A", -"s# c #1F1E21", -"t# c #050507", -"u# c #464348", -"v# c #C5BEC9", -"w# c #7D64AB", -"x# c #876FB2", -"y# c #BDAAD3", -"z# c #C2B0D6", -"A# c #C1B0D6", -"B# c #C7B4DA", -"C# c #D7D2D9", -"D# c #0F0F10", -"E# c #121013", -"F# c #5E5A62", -"G# c #CBBED6", -"H# c #5F4B94", -"I# c #9D85C2", -"J# c #B9A6D2", -"K# c #866EB1", -"L# c #69549C", -"M# c #D0C2DA", -"N# c #86828A", -"O# c #29272A", -"P# c #837E87", -"Q# c #C0B0D5", -"R# c #614D96", -"S# c #AF98CC", -"T# c #C1AFD6", -"U# c #B6A0CF", -"V# c #6B559D", -"W# c #AA95C5", -"X# c #9A969F", -"Y# c #2D2B2F", -"Z# c #060407", -"`# c #2E2B30", -" $ c #A39BA8", -".$ c #9A83B8", -"+$ c #AF9BC7", -"@$ c #908995", -"#$ c #423D45", -"$$ c #AFA6B3", -"%$ c #8B71AE", -"&$ c #B8A5CE", -"*$ c #706777", -"=$ c #1E1C20", -"-$ c #050406", -";$ c #08070A", -">$ c #443F47", -",$ c #C2B4C6", -"'$ c #6C569C", -")$ c #B9A4CE", -"!$ c #92899A", -"~$ c #86818B", -"{$ c #8E8893", -"]$ c #908A95", -"^$ c #7A777D", -"/$ c #343335", -"($ c #040305", -"_$ c #110F13", -":$ c #5C5560", -"<$ c #C4B1D3", -"[$ c #5D4A95", -"}$ c #C4B0CD", -"|$ c #968D9D", -"1$ c #CBBBD3", -"2$ c #7B64A5", -"3$ c #856CAB", -"4$ c #C1B7C5", -"5$ c #3D383F", -"6$ c #201D21", -"7$ c #7F7785", -"8$ c #B6A2CC", -"9$ c #876DAC", -"0$ c #BBAFC1", -"a$ c #8A8390", -"b$ c #ABA0B2", -"c$ c #9F86BD", -"d$ c #9C86BA", -"e$ c #978E9C", -"f$ c #2C292E", -"g$ c #050407", -"h$ c #2D272F", -"i$ c #A090A5", -"j$ c #8C73AA", -"k$ c #A58CBE", -"l$ c #8D7F92", -"m$ c #403843", -"n$ c #AB9AB0", -"o$ c #7A61A0", -"p$ c #AE96C4", -"q$ c #6C5F74", -"r$ c #1D191F", -"s$ c #030204", -"t$ c #080609", -"u$ c #423A45", -"v$ c #BDA6C3", -"w$ c #58458B", -"x$ c #B59DC9", -"y$ c #625768", -"z$ c #49414C", -"A$ c #A896AC", -"B$ c #BDA7C1", -"C$ c #6B5E70", -"D$ c #272128", -"E$ c #100D12", -"F$ c #594E5E", -"G$ c #BAA2CD", -"H$ c #514087", -"I$ c #BBA4C4", -"J$ c #574E5C", -"K$ c #7A6D82", -"L$ c #B69CCC", -"M$ c #5B478B", -"N$ c #BEA8C3", -"O$ c #070509", -"P$ c #040306", -"Q$ c #1F1A21", -"R$ c #7C6E82", -"S$ c #AB93C2", -"T$ c #846AA5", -"U$ c #473F4A", -"V$ c #918397", -"W$ c #9D84B9", -"X$ c #8F77AD", -"Y$ c #938499", -"Z$ c #2B252D", -"`$ c #050306", -" % c #2B232E", -".% c #9C84A2", -"+% c #7E649F", -"@% c #987DB4", -"#% c #8A7590", -"$% c #3F3443", -"%% c #A88DAD", -"&% c #67528F", -"*% c #A386BC", -"=% c #685770", -"-% c #1C161E", -";% c #403544", -">% c #B698C0", -",% c #453577", -"'% c #AB8EC2", -")% c #5B4C62", -"!% c #4C4051", -"~% c #B395C1", -"{% c #7D64A7", -"]% c #BC9FC6", -"^% c #46394A", -"/% c #0B080D", -"(% c #0F0B11", -"_% c #55475C", -":% c #B193C6", -"<% c #3D2F6F", -"[% c #B496C0", -"}% c #493D4E", -"|% c #605067", -"1% c #B698CC", -"2% c #48387A", -"3% c #B79AC0", -"4% c #3E3342", -"5% c #060408", -"6% c #1E1820", -"7% c #78657F", -"8% c #A184BA", -"9% c #735B99", -"0% c #A68DAC", -"a% c #3D3341", -"b% c #8C7792", -"c% c #9075AE", -"d% c #8268A1", -"e% c #8F7996", -"f% c #29222C", -"g% c #040205", -"h% c #2A212C", -"i% c #997F9E", -"j% c #735E92", -"k% c #856C9F", -"l% c #8D7493", -"m% c #514257", -"n% c #A789B0", -"o% c #4F4074", -"p% c #9B7FB3", -"q% c #65526D", -"r% c #1B151D", -"s% c #3E3242", -"t% c #B192BC", -"u% c #382E5D", -"v% c #A386BA", -"w% c #5A4961", -"x% c #4C3E51", -"y% c #A88BBC", -"z% c #282049", -"A% c #AD8FC0", -"B% c #504156", -"C% c #0D090F", -"D% c #000001", -"E% c #0F0A10", -"F% c #534359", -"G% c #A98CBE", -"H% c #302753", -"I% c #AD8FBD", -"J% c #46394B", -"K% c #5C4B63", -"L% c #AF91C2", -"M% c #3C3162", -"N% c #B293BC", -"O% c #3C3040", -"P% c #1D161F", -"Q% c #75617C", -"R% c #987DB0", -"S% c #675488", -"T% c #A487A8", -"U% c #3B303F", -"V% c #89718F", -"W% c #876EA1", -"X% c #776196", -"Y% c #8C7392", -"Z% c #28202B", -"`% c #271E29", -" & c #987D9B", -".& c #7C6693", -"+& c #392E4E", -"@& c #AC8DBB", -"#& c #977C9F", -"$& c #A487B6", -"%& c #191326", -"&& c #A285B3", -"*& c #624F68", -"=& c #19121A", -"-& c #040204", -";& c #3D3140", -">& c #AF8FBA", -",& c #352B4A", -"'& c #997EAD", -")& c #6F5A78", -"!& c #695671", -"~& c #A184B3", -"{& c #201A2F", -"]& c #AA8BBA", -"^& c #504155", -"/& c #0D090E", -"(& c #0E0A10", -"_& c #524257", -":& c #A789B9", -"<& c #2D2440", -"[& c #AB8DBA", -"}& c #453749", -"|& c #5B4961", -"1& c #AD8EBB", -"2& c #392E50", -"3& c #B091BA", -"4& c #3B2F3F", -"5& c #1C151E", -"6& c #745F79", -"7& c #967BA6", -"8& c #65527D", -"9& c #A285A6", -"0& c #3A2E3D", -"a& c #88708C", -"b& c #846C99", -"c& c #745F8A", -"d& c #8B7290", -"e& c #281F2A", -"f& c #19131B", -"g& c #624F66", -"h& c #B191BD", -"i& c #4C3E60", -"j& c #3A2F4C", -"k& c #6D5985", -"l& c #241D31", -"m& c #6D5982", -"n& c #B090B8", -"o& c #4B3C4E", -"p& c #3C2F3E", -"q& c #B090B9", -"r& c #3A2F4E", -"s& c #58476C", -"t& c #A285B2", -"u& c #A588B5", -"v& c #705C84", -"w& c #14101B", -"x& c #4F3F53", -"y& c #0D080E", -"z& c #0E090F", -"A& c #514155", -"B& c #AA8BB9", -"C& c #2D253D", -"D& c #5B4A61", -"E& c #AD8EBA", -"F& c #3F3354", -"G& c #B292B9", -"H& c #1B141D", -"I& c #745E78", -"J& c #997DA9", -"K& c #64527B", -"L& c #89708C", -"M& c #836C98", -"N& c #79638E", -"O& c #8B718F", -"P& c #070508", -"Q& c #2B222D", -"R& c #69566E", -"S& c #B292C3", -"T& c #645283", -"U& c #473A64", -"V& c #7D669A", -"W& c #55455B", -"X& c #201922", -"Y& c #2E2530", -"Z& c #9D82A1", -"`& c #9C80B6", -" * c #4A3C68", -".* c #473964", -"+* c #473A65", -"@* c #816A9F", -"#* c #B192B8", -"$* c #3F3342", -"%* c #09060A", -"&* c #0A070B", -"** c #413545", -"=* c #B091B9", -"-* c #876FAB", -";* c #B192BD", -">* c #453848", -",* c #5C4B61", -"'* c #BA99CD", -")* c #A083BA", -"!* c #977D9B", -"~* c #2D242F", -"{* c #140F15", -"]* c #59495D", -"^* c #B595C5", -"/* c #8F75B2", -"(* c #8A718E", -"_* c #9E81B9", -":* c #B292C5", -"<* c #6F5B74", -"[* c #1D161E", -"}* c #0A060B", -"|* c #2C222E", -"1* c #65526A", -"2* c #A285A7", -"3* c #A184A8", -"4* c #9E81A2", -"5* c #211923", -"6* c #120D13", -"7* c #453748", -"8* c #947997", -"9* c #A083A8", -"0* c #A183A8", -"a* c #9E81A1", -"b* c #1C151D", -"c* c #1E161F", -"d* c #544458", -"e* c #A083A3", -"f* c #8E7490", -"g* c #342935", -"h* c #483A4A", -"i* c #A487A6", -"j* c #8F7593", -"k* c #433546", -"l* c #110C12", -"m* c #2B212D", -"n* c #6B576F", -"o* c #A587A8", -"p* c #7C657D", -"q* c #2B212C", -"r* c #68556A", -"s* c #7A637E", -"t* c #342936", -"u* c #080508", -"v* c #1F1720", -"w* c #322734", -"x* c #362A38", -"y* c #2F2531", -"z* c #181219", -"A* c #120C13", -"B* c #352A38", -"C* c #362B39", -"D* c #362B38", -"E* c #2E2430", -"F* c #171118", -"G* c #2B222C", -"H* c #0F0B10", -"I* c #302631", -"J* c #2A212B", -"K* c #100B11", -"L* c #070407", -"M* c #201821", -"N* c #322733", -"O* c #251C25", -"P* c #0B070B", -"Q* c #201921", -"R* c #241C25", -"S* c #050305", -"T* c #060406", -"U* c #020103", -"V* c #020204", -"W* c #030305", -"X* c #050307", -"Y* c #09070E", -"Z* c #0E0B15", -"`* c #0B0910", -" = c #0A080D", -".= c #09080C", -"+= c #09070B", -"@= c #09070C", -"#= c #0A080E", -"$= c #0A080F", -"%= c #09070F", -"&= c #07050C", -"*= c #050409", -"== c #040308", -"-= c #050408", -";= c #030205", -">= c #0F0C14", -",= c #13101A", -"'= c #1A1625", -")= c #1D182B", -"!= c #201A2C", -"~= c #201A2A", -"{= c #241D2E", -"]= c #261F30", -"^= c #261F32", -"/= c #2A2338", -"(= c #231D31", -"_= c #1D192B", -":= c #1C182A", -"<= c #1A1527", -"[= c #181425", -"}= c #171324", -"|= c #151121", -"1= c #120F1F", -"2= c #0B0815", -"3= c #030206", -"4= c #0B080E", -"5= c #14101A", -"6= c #241E30", -"7= c #2A233A", -"8= c #2D253E", -"9= c #362D4D", -"0= c #4C3F6D", -"a= c #403457", -"b= c #44375A", -"c= c #4B3D64", -"d= c #554673", -"e= c #5A4A7B", -"f= c #625188", -"g= c #64538D", -"h= c #504271", -"i= c #463A64", -"j= c #433762", -"k= c #433764", -"l= c #392F56", -"m= c #342B4F", -"n= c #332B50", -"o= c #26203C", -"p= c #30284C", -"q= c #2A2343", -"r= c #0F0C1B", -"s= c #010103", -"t= c #1A1622", -"u= c #272032", -"v= c #2F273C", -"w= c #473A60", -"x= c #7A65A3", -"y= c #846DAA", -"z= c #A388BE", -"A= c #BCA4D2", -"B= c #BFA9D1", -"C= c #C9B6D6", -"D= c #D1C1DC", -"E= c #DACCE1", -"F= c #DACAE1", -"G= c #D4C3DE", -"H= c #C8B3D8", -"I= c #B49ACB", -"J= c #A084BE", -"K= c #967CBF", -"L= c #7964A7", -"M= c #5A4B81", -"N= c #4F4276", -"O= c #51447C", -"P= c #453A6B", -"Q= c #2A2341", -"R= c #1E192F", -"S= c #100C1A", -"T= c #090710", -"U= c #060509", -"V= c #100D16", -"W= c #1F1A28", -"X= c #2A2336", -"Y= c #352B45", -"Z= c #554671", -"`= c #9178AC", -" - c #C8B5D7", -".- c #DED1E2", -"+- c #E6DCE7", -"@- c #D9D6D9", -"#- c #C3C3C4", -"$- c #ADACAE", -"%- c #A4A3A4", -"&- c #8D8C8F", -"*- c #8E8D90", -"=- c #A3A3A3", -"-- c #AEACAF", -";- c #BFBFBF", -">- c #D7D5D7", -",- c #DCCEE2", -"'- c #C6AFD8", -")- c #AB8ECC", -"!- c #9F85C8", -"~- c #473B65", -"{- c #2B2440", -"]- c #28213E", -"^- c #1A1629", -"/- c #151223", -"(- c #0C0914", -"_- c #040307", -":- c #0C0A11", -"<- c #1E1826", -"[- c #292235", -"}- c #382E4A", -"|- c #675486", -"1- c #A78DBE", -"2- c #D3C3DD", -"3- c #E3DEE3", -"4- c #C6C5C6", -"5- c #9A9B9B", -"6- c #646465", -"7- c #565656", -"8- c #505050", -"9- c #4C4C4D", -"0- c #484848", -"a- c #444445", -"b- c #404040", -"c- c #3C3C3D", -"d- c #373737", -"e- c #47464B", -"f- c #939294", -"g- c #E3E0E4", -"h- c #E7E0E9", -"i- c #AF96C8", -"j- c #75609C", -"k- c #5C4C85", -"l- c #443967", -"m- c #403664", -"n- c #30284B", -"o- c #0E0B17", -"p- c #07060D", -"q- c #0E0C15", -"r- c #17131E", -"s- c #282133", -"t- c #342B44", -"u- c #685588", -"v- c #AD94C3", -"w- c #DBCEE1", -"x- c #D6D4D6", -"y- c #A5A5A6", -"z- c #666565", -"A- c #636363", -"B- c #616161", -"C- c #605F62", -"D- c #5C5C5E", -"E- c #5C5B62", -"F- c #666277", -"G- c #68627C", -"H- c #605B70", -"I- c #53505D", -"J- c #4B4952", -"K- c #544F66", -"L- c #464451", -"M- c #38383A", -"N- c #35343A", -"O- c #2E2D2E", -"P- c #29292A", -"Q- c #1E1E1E", -"R- c #383738", -"S- c #9B9A9C", -"T- c #D3D1D4", -"U- c #DED1E3", -"V- c #BFA6D2", -"W- c #836CA9", -"X- c #3F345A", -"Y- c #27213A", -"Z- c #1E192C", -"`- c #171323", -" ; c #06050A", -".; c #06050B", -"+; c #08070F", -"@; c #0D0A15", -"#; c #120E1C", -"$; c #181423", -"%; c #221C2E", -"&; c #2B243A", -"*; c #4A3C62", -"=; c #9A81B5", -"-; c #D7C8DF", -";; c #D8D6D8", -">; c #6E6E6E", -",; c #6C6C6C", -"'; c #6A6A6A", -"); c #69696A", -"!; c #6C6B73", -"~; c #78738A", -"{; c #736E83", -"]; c #726D83", -"^; c #8A7FAA", -"/; c #9E8FC3", -"(; c #8378A3", -"_; c #6D6684", -":; c #595567", -"<; c #6C6388", -"[; c #58526B", -"}; c #42404A", -"|; c #484358", -"1; c #464157", -"2; c #353340", -"3; c #33303F", -"4; c #242329", -"5; c #1C1C1D", -"6; c #161616", -"7; c #818182", -"8; c #D8D6D9", -"9; c #9E83BD", -"0; c #50416D", -"a; c #2B243D", -"b; c #2D2643", -"c; c #201A32", -"d; c #0D0A16", -"e; c #07050D", -"f; c #07060E", -"g; c #06040B", -"h; c #110E1C", -"i; c #0C0A14", -"j; c #120F1C", -"k; c #120F1E", -"l; c #1C172C", -"m; c #241E38", -"n; c #2C2542", -"o; c #453963", -"p; c #79639D", -"q; c #BEA7CF", -"r; c #E1DBE2", -"s; c #ADADAD", -"t; c #747474", -"u; c #747475", -"v; c #747377", -"w; c #7A7783", -"x; c #7C7888", -"y; c #7E7A8D", -"z; c #9088AC", -"A; c #87809E", -"B; c #877FA0", -"C; c #9A8DBD", -"D; c #A998CE", -"E; c #9587B4", -"F; c #7B7297", -"G; c #726A8B", -"H; c #9182B5", -"I; c #655D7C", -"J; c #605877", -"K; c #544E68", -"L; c #665B86", -"M; c #4C4562", -"N; c #594E78", -"O; c #3B364E", -"P; c #272531", -"Q; c #201E28", -"R; c #17161D", -"S; c #9F9E9F", -"T; c #E3DCE4", -"U; c #C1ABD2", -"V; c #9C82C2", -"W; c #665599", -"X; c #352C50", -"Y; c #1E192E", -"Z; c #161223", -"`; c #161323", -" > c #1B172B", -".> c #120F1D", -"+> c #06050C", -"@> c #08060F", -"#> c #161222", -"$> c #100D1A", -"%> c #130F1E", -"&> c #1D182E", -"*> c #251F3A", -"=> c #261F3B", -"-> c #2D2647", -";> c #5E4E8F", -">> c #7C67B1", -",> c #A589CB", -"'> c #E0D4E4", -")> c #888889", -"!> c #7A7A7A", -"~> c #7B7B7B", -"{> c #7E7D83", -"]> c #898596", -"^> c #888495", -"/> c #817E8A", -"(> c #8D879F", -"_> c #938BAA", -":> c #9990B5", -"<> c #A296C0", -"[> c #837D97", -"}> c #9C8FB7", -"|> c #B4A3D5", -"1> c #DCCDEE", -"2> c #C4B2E0", -"3> c #C6B1E3", -"4> c #DAC4EF", -"5> c #CBBBE1", -"6> c #AC98D5", -"7> c #9C89C7", -"8> c #8B79B7", -"9> c #786AA1", -"0> c #7969A5", -"a> c #594E79", -"b> c #342F43", -"c> c #40385B", -"d> c #221F2E", -"e> c #15141A", -"f> c #0D0C10", -"g> c #5A595C", -"h> c #D1D0D2", -"i> c #DDCDE2", -"j> c #8871AB", -"k> c #2E2645", -"l> c #201B32", -"m> c #1A1628", -"n> c #231D36", -"o> c #0E0C17", -"p> c #1E1930", -"q> c #231D37", -"r> c #251F39", -"s> c #3C325C", -"t> c #8670B8", -"u> c #CAAEDB", -"v> c #E4DAE6", -"w> c #BFBFC0", -"x> c #7D7D7D", -"y> c #7F7F7F", -"z> c #85848B", -"A> c #948FA4", -"B> c #A39BB7", -"C> c #A69DBA", -"D> c #A59DBE", -"E> c #918CA0", -"F> c #8F899E", -"G> c #ACA1C4", -"H> c #B2A6CB", -"I> c #C1B3D8", -"J> c #C3B6D8", -"K> c #9F93BC", -"L> c #C1B1DC", -"M> c #D3BFE7", -"N> c #E3D5F1", -"O> c #E3D4F1", -"P> c #EDE0F3", -"Q> c #F3EDF6", -"R> c #E2CFF1", -"S> c #E4CDF2", -"T> c #9B87C9", -"U> c #8C7ABA", -"V> c #B8A3DE", -"W> c #7968A1", -"X> c #51476E", -"Y> c #5D5083", -"Z> c #41385D", -"`> c #2A243C", -" , c #1B1829", -"., c #100D19", -"+, c #010104", -"@, c #B7B6B8", -"#, c #E2D7E5", -"$, c #BAA1D4", -"%, c #514374", -"&, c #1F1A2D", -"*, c #292240", -"=, c #191527", -"-, c #040407", -";, c #0C0913", -">, c #231D34", -",, c #423765", -"', c #645390", -"), c #A58AC5", -"!, c #E5DFE6", -"~, c #B4B3B5", -"{, c #808080", -"], c #848386", -"^, c #908D9B", -"/, c #A49EB7", -"(, c #B7ADC8", -"_, c #C6BED4", -":, c #C6BFD4", -"<, c #B9B0CA", -"[, c #B3A9C6", -"}, c #AEA5C1", -"|, c #BCB1CF", -"1, c #D8CFE8", -"2, c #DAD1EB", -"3, c #E3D9EF", -"4, c #C9BDDF", -"5, c #CBBCE0", -"6, c #E0D2EE", -"7, c #E6DBF2", -"8, c #F5F0F6", -"9, c #F2EAF5", -"0, c #DDCBEE", -"a, c #D0B9EC", -"b, c #D3BEEC", -"c, c #AC95D9", -"d, c #AD96DC", -"e, c #EFE3F5", -"f, c #B39ED2", -"g, c #B19CCE", -"h, c #9880C9", -"i, c #5B4D81", -"j, c #2E2942", -"k, c #3A3158", -"l, c #332A50", -"m, c #08060E", -"n, c #A1A1A2", -"o, c #E4DBE6", -"p, c #947BB4", -"q, c #44385F", -"r, c #27213B", -"s, c #0E0B16", -"t, c #040408", -"u, c #13101F", -"v, c #1D182D", -"w, c #231E37", -"x, c #29223B", -"y, c #473B64", -"z, c #A78CC7", -"A, c #E1D8E3", -"B, c #A7A7A8", -"C, c #858585", -"D, c #8E8D95", -"E, c #AAA3BC", -"F, c #BBB3C8", -"G, c #C8C3D6", -"H, c #CEC8DF", -"I, c #D9D1E9", -"J, c #D0C9DF", -"K, c #C3BAD0", -"L, c #CEC7DE", -"M, c #C6BDD7", -"N, c #DCD3EB", -"O, c #DDD4EC", -"P, c #EADFF2", -"Q, c #E7DCF0", -"R, c #DCD0EB", -"S, c #DED2EB", -"T, c #E7DCF2", -"U, c #F2ECF5", -"V, c #E9DFF2", -"W, c #B9A4DB", -"X, c #E2D0F1", -"Y, c #D7C4ED", -"Z, c #BCA6DE", -"`, c #C2ADE4", -" ' c #FDFCFE", -".' c #F3EBF8", -"+' c #F7F1F8", -"@' c #BAA0E1", -"#' c #65568B", -"$' c #4D416D", -"%' c #645392", -"&' c #372E54", -"*' c #100D1B", -"=' c #020104", -"-' c #A0A0A0", -";' c #DFD2E3", -">' c #8F76AF", -",' c #352B49", -"'' c #1F1A30", -")' c #0A0812", -"!' c #1B162A", -"~' c #29223A", -"{' c #443861", -"]' c #977DBF", -"^' c #E0D5E4", -"/' c #B4B2B4", -"(' c #868687", -"_' c #9A97A8", -":' c #A19CAF", -"<' c #A5A0B4", -"[' c #BAB4C7", -"}' c #CAC4D8", -"|' c #E8DEF2", -"1' c #F8F4F9", -"2' c #E8E3EF", -"3' c #D1CAE0", -"4' c #DAD2EA", -"5' c #D8CFE6", -"6' c #E3D9EE", -"7' c #F2EDF6", -"8' c #F1E9F5", -"9' c #ECE3F3", -"0' c #E4DAF0", -"a' c #EBE2F3", -"b' c #E6DAF1", -"c' c #C0ADDD", -"d' c #EADDF2", -"e' c #F7F4F8", -"f' c #EEE3F5", -"g' c #F5EFFA", -"h' c #E3CDF4", -"i' c #A48DCA", -"j' c #AE95D1", -"k' c #1A152A", -"l' c #06040C", -"m' c #9F9F9F", -"n' c #DCCFE2", -"o' c #8770A8", -"p' c #2E2640", -"q' c #07060B", -"r' c #030207", -"s' c #151122", -"t' c #3E3360", -"u' c #352C4B", -"v' c #8971AD", -"w' c #DBCDE2", -"x' c #C0C0C1", -"y' c #868688", -"z' c #918F99", -"A' c #A19DAF", -"B' c #B4AEC1", -"C' c #B3AEBF", -"D' c #B8B4C2", -"E' c #D2CCDF", -"F' c #D3CCE2", -"G' c #D2CBE2", -"H' c #EEE8F4", -"I' c #FEFEFE", -"J' c #F7F4F9", -"K' c #F8F5F9", -"L' c #DCD4EA", -"M' c #F2ECF6", -"N' c #F9F6F9", -"O' c #FBF9FB", -"P' c #FAF9FA", -"Q' c #F6F3F7", -"R' c #F6F2F8", -"S' c #F4EEF7", -"T' c #F5F1F8", -"U' c #C7B5DF", -"V' c #EEE4F5", -"W' c #E7D7F2", -"X' c #FCFBFC", -"Y' c #FAFAFB", -"Z' c #F9F5FA", -"`' c #E6D2F4", -" ) c #B395E0", -".) c #5A4B80", -"+) c #483C6B", -"@) c #372D54", -"#) c #221B39", -"$) c #151025", -"%) c #05030A", -"&) c #BCBBBC", -"*) c #D3C2DC", -"=) c #715D95", -"-) c #292239", -";) c #1C1727", -">) c #08060D", -",) c #030306", -"') c #0E0B18", -")) c #251E38", -"!) c #4B3F72", -"~) c #675591", -"{) c #CCB7D8", -"]) c #7D7E7E", -"^) c #838384", -"/) c #93909D", -"() c #A19CB0", -"_) c #ABA5BA", -":) c #C4BECF", -"<) c #C7C1D3", -"[) c #CEC8DE", -"}) c #DBD2E8", -"|) c #DED7EA", -"1) c #DED7E8", -"2) c #F7F3F8", -"3) c #FBFAFB", -"4) c #F1EAF5", -"5) c #F5F0F8", -"6) c #FCFCFC", -"7) c #FBFBFB", -"8) c #E3D6EF", -"9) c #FBFBFC", -"0) c #D3C0E7", -"a) c #D0BEEB", -"b) c #A58BD2", -"c) c #9179C5", -"d) c #5D4E83", -"e) c #8A7BA9", -"f) c #7A679F", -"g) c #282040", -"h) c #292043", -"i) c #282043", -"j) c #0C0918", -"k) c #151022", -"l) c #D4D2D5", -"m) c #C2AAD4", -"n) c #564778", -"o) c #2B2441", -"p) c #1B172A", -"q) c #110E1B", -"r) c #0B0813", -"s) c #473B6E", -"t) c #5F4F8A", -"u) c #AB8FCD", -"v) c #89898A", -"w) c #89888E", -"x) c #A19CB1", -"y) c #B3ACC1", -"z) c #BCB7C7", -"A) c #C8C2D5", -"B) c #EEE9F3", -"C) c #CDC8DB", -"D) c #E4DDEE", -"E) c #EAE2F3", -"F) c #DAD2E8", -"G) c #E9E0F1", -"H) c #F8F6F9", -"I) c #FDFDFD", -"J) c #F6F0F7", -"K) c #F5F1F7", -"L) c #F7F2F8", -"M) c #FAF8FB", -"N) c #F9F7FA", -"O) c #F8F5FA", -"P) c #B5A2D4", -"Q) c #EEE6F5", -"R) c #FBF8FC", -"S) c #EEE5F6", -"T) c #8A76B3", -"U) c #8772B2", -"V) c #8F78BE", -"W) c #7A66A2", -"X) c #E5DAEF", -"Y) c #A98CD1", -"Z) c #554481", -"`) c #7059A1", -" ! c #483970", -".! c #1A142D", -"+! c #04030A", -"@! c #5F5E60", -"#! c #E5E0E7", -"$! c #A389C3", -"%! c #4E4171", -"&! c #2C2544", -"*! c #0D0B16", -"=! c #28223D", -"-! c #65549A", -";! c #AC90D1", -">! c #DBCCE1", -",! c #AFAEB0", -"'! c #838387", -")! c #9592A2", -"!! c #ADA7BD", -"~! c #CBC4D9", -"{! c #DDD6E7", -"]! c #E4DCED", -"^! c #F8F6FA", -"/! c #E6DFF0", -"(! c #E6DEEF", -"_! c #E7DEF0", -":! c #F6F1F7", -"~ c #E1D0EC", -",~ c #8D73C2", -"'~ c #8169AD", -")~ c #B8A5CD", -"!~ c #A18AC3", -"~~ c #392D59", -"{~ c #281F41", -"]~ c #2E244C", -"^~ c #080612", -"/~ c #979798", -"(~ c #D5C6DE", -"_~ c #705D98", -":~ c #403560", -"<~ c #241E37", -"[~ c #090711", -"}~ c #272036", -"|~ c #42375A", -"1~ c #BDA3D2", -"2~ c #6F6F6E", -"3~ c #757576", -"4~ c #83808B", -"5~ c #9490A3", -"6~ c #BAB3CB", -"7~ c #DAD2E6", -"8~ c #E5DFED", -"9~ c #EEE9F4", -"0~ c #EDE6F4", -"a~ c #EBE5F2", -"b~ c #D2CBDF", -"c~ c #C7C2D2", -"d~ c #D7CFE4", -"e~ c #F1EBF5", -"f~ c #F9F9FA", -"g~ c #F9F8FA", -"h~ c #EBE2F2", -"i~ c #ECE4F2", -"j~ c #F3ECF5", -"k~ c #F7F4F7", -"l~ c #EFE7F4", -"m~ c #EFE6F4", -"n~ c #F4EFF6", -"o~ c #F2E9F5", -"p~ c #E9DEF3", -"q~ c #E1CDF1", -"r~ c #EBDCF3", -"s~ c #F2E6F5", -"t~ c #FAF6FB", -"u~ c #DCCCE8", -"v~ c #D9C7E3", -"w~ c #DCC8E1", -"x~ c #BCA2D2", -"y~ c #8269B0", -"z~ c #45376C", -"A~ c #2B2247", -"B~ c #0D0918", -"C~ c #DAD7DA", -"D~ c #AA90C4", -"E~ c #3A304F", -"F~ c #0F0D19", -"G~ c #06040A", -"H~ c #4C3F74", -"I~ c #7C679F", -"J~ c #DECEE1", -"K~ c #A9A9A9", -"L~ c #6D6D6D", -"M~ c #747476", -"N~ c #82808A", -"O~ c #A69EBA", -"P~ c #D0C8E1", -"Q~ c #D9D1EB", -"R~ c #E4DBEF", -"S~ c #FBFAFC", -"T~ c #FDFCFD", -"U~ c #F6F4F8", -"V~ c #E3DDEA", -"W~ c #D2CADD", -"X~ c #E4DBED", -"Y~ c #F1E8F4", -"Z~ c #F2EBF5", -"`~ c #F2EFF6", -" { c #E0D7EB", -".{ c #EBE6F2", -"+{ c #F2E9F4", -"@{ c #F0E6F3", -"#{ c #EEE6F4", -"${ c #E4D8F0", -"%{ c #E1CFEF", -"&{ c #E3D0F1", -"*{ c #E5D0F1", -"={ c #EDDCF4", -"-{ c #E7D2F3", -";{ c #C8B3DF", -">{ c #E1C9F2", -",{ c #EDE3F6", -"'{ c #ECE1F6", -"){ c #D8C9E5", -"!{ c #F3F0F5", -"~{ c #BAACD0", -"{{ c #5D4A8A", -"]{ c #2E254A", -"^{ c #110D1E", -"/{ c #0D0A19", -"({ c #A3A3A5", -"_{ c #D1C0DC", -":{ c #534471", -"<{ c #221C2F", -"[{ c #16121F", -"}{ c #0D0A14", -"|{ c #302846", -"1{ c #6A589E", -"2{ c #C1A5D9", -"3{ c #E3E0E3", -"4{ c #6C6A6D", -"5{ c #6B6C6B", -"6{ c #868392", -"7{ c #9690A7", -"8{ c #DFD6EC", -"9{ c #DBD3E9", -"0{ c #D8D0E7", -"a{ c #E4DEEE", -"b{ c #F3ECF6", -"c{ c #F4EFF7", -"d{ c #E8E0F1", -"e{ c #F4F1F7", -"f{ c #F7F5F8", -"g{ c #E6DFEF", -"h{ c #DED6EB", -"i{ c #ECE6F1", -"j{ c #E5DBEF", -"k{ c #DDD2EC", -"l{ c #E4D9EE", -"m{ c #E3D7F0", -"n{ c #E1D1EE", -"o{ c #BFACD9", -"p{ c #E2D2EE", -"q{ c #F1E6F5", -"r{ c #EFDFF4", -"s{ c #BFA9D7", -"t{ c #9984C1", -"u{ c #D5BCEC", -"v{ c #B9A0DE", -"w{ c #EBD3F3", -"x{ c #E5D7F0", -"y{ c #EFE6F5", -"z{ c #F4EFF5", -"A{ c #BEABD4", -"B{ c #675395", -"C{ c #1D172F", -"D{ c #1A152C", -"E{ c #1D1631", -"F{ c #0D0A1A", -"G{ c #484549", -"H{ c #E5DEE7", -"I{ c #9379B5", -"J{ c #312844", -"K{ c #1A1623", -"L{ c #0D0B14", -"M{ c #13101D", -"N{ c #2D2645", -"O{ c #816BB2", -"P{ c #DAC5E0", -"Q{ c #C8C8C9", -"R{ c #646464", -"S{ c #6C6C70", -"T{ c #7E7A8A", -"U{ c #8C879D", -"V{ c #9A93AE", -"W{ c #A59DB9", -"X{ c #BFB7CF", -"Y{ c #DBD3E8", -"Z{ c #ECE5F2", -"`{ c #E4DCEE", -" ] c #E9E1F2", -".] c #F6F3F8", -"+] c #EFE7F3", -"@] c #D5CDE3", -"#] c #D8D1E5", -"$] c #E0D8ED", -"%] c #E5DEEE", -"&] c #EBE2F1", -"*] c #CFC7DB", -"=] c #E0D6E9", -"-] c #ECE3F2", -";] c #BEB2CF", -">] c #C0B5D0", -",] c #B3A6C7", -"'] c #BBADD0", -")] c #D6C8E6", -"!] c #DAC7EC", -"~] c #A997C6", -"{] c #EEE3F4", -"]] c #DBCEE9", -"^] c #8C7AB0", -"/] c #CBB5E8", -"(] c #C7B1E1", -"_] c #D9BDEF", -":] c #CBB3E7", -"<] c #C9B0DF", -"[] c #D7CAE6", -"}] c #DBCEE5", -"|] c #6B569B", -"1] c #3B2F5B", -"2] c #1D1730", -"3] c #261E3F", -"4] c #CAC9CB", -"5] c #BBA2D1", -"6] c #41365C", -"7] c #211C2E", -"8] c #100D17", -"9] c #13101B", -"0] c #312842", -"a] c #9279B5", -"b] c #E4DAE7", -"c] c #A0A0A1", -"d] c #626262", -"e] c #6F6D77", -"f] c #7A7685", -"g] c #8B859D", -"h] c #B8ACCE", -"i] c #C7BDD7", -"j] c #CDC3DC", -"k] c #D9D1E5", -"l] c #F1ECF5", -"m] c #F1ECF6", -"n] c #D5CEE3", -"o] c #CCC6D7", -"p] c #D1C9DD", -"q] c #D5CEE2", -"r] c #D5CEE0", -"s] c #DBD2E6", -"t] c #BFB4CD", -"u] c #B1A8C0", -"v] c #7B7784", -"w] c #666568", -"x] c #636166", -"y] c #5E5D62", -"z] c #7B7389", -"A] c #AA9BBE", -"B] c #AC99C8", -"C] c #E0CEEE", -"D] c #F0E5F4", -"E] c #E8DBF2", -"F] c #D0B8E7", -"G] c #DCC7EC", -"H] c #EFDDF4", -"I] c #E7D5F3", -"J] c #DFC1F2", -"K] c #DDC3ED", -"L] c #CCB3E4", -"M] c #FAF7FB", -"N] c #F9F9F9", -"O] c #ECE3EE", -"P] c #DECAE4", -"Q] c #BBA3D4", -"R] c #584784", -"S] c #30264C", -"T] c #231C3A", -"U] c #06040D", -"V] c #9E9EA0", -"W] c #D5C3DE", -"X] c #5E4D82", -"Y] c #221D30", -"Z] c #181426", -"`] c #14111B", -" ^ c #3B3150", -".^ c #B094CB", -"+^ c #EBE8EC", -"@^ c #6D6C6F", -"#^ c #606061", -"$^ c #706D7A", -"%^ c #847E97", -"&^ c #9A90B2", -"*^ c #BEB3D1", -"=^ c #DFD6EB", -"-^ c #CAC0DA", -";^ c #D7CFE2", -">^ c #E4DBEE", -",^ c #ECE6F3", -"'^ c #F4EEF6", -")^ c #EDE4F3", -"!^ c #E4DBEC", -"~^ c #DCD3E8", -"{^ c #D8CFE2", -"]^ c #E4DAEE", -"^^ c #CDC3DA", -"/^ c #888290", -"(^ c #686868", -"_^ c #595959", -":^ c #4F4F4F", -"<^ c #5B5664", -"[^ c #86799C", -"}^ c #B7A2D0", -"|^ c #B69EDC", -"1^ c #CDBBE5", -"2^ c #F7F2F7", -"3^ c #F6EFF9", -"4^ c #CAB4E7", -"5^ c #A58EC6", -"6^ c #B596D8", -"7^ c #F6F2F7", -"8^ c #ECE5F0", -"9^ c #8F74C1", -"0^ c #403362", -"a^ c #151023", -"b^ c #0E0B1A", -"c^ c #05040C", -"d^ c #5B5B5E", -"e^ c #DDD0E2", -"f^ c #6A578D", -"g^ c #28213A", -"h^ c #211C34", -"i^ c #07060C", -"j^ c #15121D", -"k^ c #3B3151", -"l^ c #9E82BB", -"m^ c #DAD6DA", -"n^ c #575757", -"o^ c #5F5E61", -"p^ c #716D7E", -"q^ c #7E798F", -"r^ c #A99EC3", -"s^ c #E6DCF0", -"t^ c #F4EDF6", -"u^ c #F8F4FA", -"v^ c #F9F7FB", -"w^ c #F0E9F5", -"x^ c #EEE7F3", -"y^ c #ECE3F0", -"z^ c #F1E9F4", -"A^ c #CDC4DA", -"B^ c #8B8595", -"C^ c #646564", -"D^ c #5B5B5B", -"E^ c #515152", -"F^ c #4C4C4C", -"G^ c #474747", -"H^ c #424242", -"I^ c #414043", -"J^ c #544E5F", -"K^ c #8575A2", -"L^ c #D9BFEF", -"M^ c #EFE2F5", -"N^ c #DDD0ED", -"O^ c #C1A4E5", -"P^ c #A087CA", -"Q^ c #D4C6E2", -"R^ c #A692C4", -"S^ c #4D3E72", -"T^ c #2E2548", -"U^ c #1B162D", -"V^ c #2E244B", -"W^ c #18122A", -"X^ c #DED7DF", -"Y^ c #997EBE", -"Z^ c #433864", -"`^ c #16121D", -" / c #332A43", -"./ c #C7C6C8", -"+/ c #5F5D65", -"@/ c #6A6775", -"#/ c #787387", -"$/ c #9C90B7", -"%/ c #C0B3D7", -"&/ c #EEE5F4", -"*/ c #EFE9F4", -"=/ c #ECE4F3", -"-/ c #DFD6E9", -";/ c #E1D7EC", -">/ c #E2D8EC", -",/ c #E2D9ED", -"'/ c #E7DDEE", -")/ c #9D96A9", -"!/ c #696969", -"~/ c #656565", -"{/ c #4E4E4E", -"]/ c #4A4949", -"^/ c #454545", -"// c #40403F", -"(/ c #3A3A3A", -"_/ c #534C61", -":/ c #C1A6DC", -"( c #B398D8", -",( c #D1B2E7", -"'( c #D7BCEC", -")( c #DDBEEB", -"!( c #ECDFF0", -"~( c #D0C2E2", -"{( c #9E83C6", -"]( c #BCA5D2", -"^( c #AD93C8", -"/( c #6C579A", -"(( c #AD9BC9", -"_( c #B89BD6", -":( c #AB8BD3", -"<( c #9980BC", -"[( c #7760A7", -"}( c #5A4888", -"|( c #3D3062", -"1( c #A7A6A9", -"2( c #B9A3CB", -"3( c #392F4C", -"4( c #191521", -"5( c #08070B", -"6( c #1F1A29", -"7( c #44385B", -"8( c #CBB8D8", -"9( c #A6A6A6", -"0( c #4B4B4D", -"a( c #656078", -"b( c #887DA9", -"c( c #B1A0D1", -"d( c #D8CBE9", -"e( c #E7DCF1", -"f( c #EEE7F4", -"g( c #EEE5F3", -"h( c #BAAECB", -"i( c #676669", -"j( c #5E5E5F", -"k( c #555554", -"l( c #494949", -"m( c #323232", -"n( c #2D2D2D", -"o( c #282828", -"p( c #34303A", -"q( c #6A5C85", -"r( c #8975B1", -"s( c #AC91D1", -"t( c #BEA0DC", -"u( c #B697D1", -"v( c #967BBD", -"w( c #8169A7", -"x( c #C8B3D9", -"y( c #B69DCD", -"z( c #AA90C5", -"A( c #CAAFDA", -"B( c #C7A4D9", -"C( c #8C72B9", -"D( c #645094", -"E( c #9F82C9", -"F( c #8B70BA", -"G( c #4B3B74", -"H( c #161027", -"I( c #9B9B9C", -"J( c #C1ADD2", -"K( c #3D3251", -"L( c #1C1725", -"M( c #07060A", -"N( c #08060B", -"O( c #221C2C", -"P( c #483B60", -"Q( c #8D8C90", -"R( c #464648", -"S( c #5D596D", -"T( c #766D90", -"U( c #9285B3", -"V( c #B09DD2", -"W( c #B3A1D4", -"X( c #B2A1D2", -"Y( c #C5B7DD", -"Z( c #E7DEF2", -"`( c #EDE8F3", -" _ c #AB9FBD", -"._ c #59595A", -"+_ c #404041", -"@_ c #3C3C3C", -"#_ c #222223", -"$_ c #564B6B", -"%_ c #7D6AA1", -"&_ c #A489C8", -"*_ c #B093D3", -"=_ c #9177B2", -"-_ c #886FB0", -";_ c #8169A5", -">_ c #AD96C5", -",_ c #CBADD9", -"'_ c #BFA0D5", -")_ c #CAA9DA", -"!_ c #AC8BD1", -"~_ c #B697D4", -"{_ c #B198CF", -"]_ c #5D4B8B", -"^_ c #2D244A", -"/_ c #130F24", -"(_ c #9C9C9D", -"__ c #C5B1D4", -":_ c #403455", -"<_ c #1E1927", -"[_ c #0B090F", -"}_ c #231D2D", -"|_ c #483B5F", -"1_ c #CFC0DB", -"2_ c #8E8C90", -"3_ c #504D59", -"4_ c #635D76", -"5_ c #8A7DAD", -"6_ c #877BA6", -"7_ c #9386B4", -"8_ c #B6A6D2", -"9_ c #CAB7E3", -"0_ c #DDCFED", -"a_ c #DDD1EA", -"b_ c #9D90B3", -"c_ c #5B5A5C", -"d_ c #525252", -"e_ c #343434", -"f_ c #272727", -"g_ c #222222", -"h_ c #1F1F20", -"i_ c #504565", -"j_ c #8E77B3", -"k_ c #D4BAE4", -"l_ c #D4BAE3", -"m_ c #9D81C1", -"n_ c #59487B", -"o_ c #7A63A1", -"p_ c #AD90D0", -"q_ c #E0D0E4", -"r_ c #C9AFD9", -"s_ c #A78ACB", -"t_ c #9C7ECD", -"u_ c #987CC5", -"v_ c #715B9D", -"w_ c #4F4079", -"x_ c #403364", -"y_ c #362B57", -"z_ c #1A142E", -"A_ c #423658", -"B_ c #0B0914", -"C_ c #CBB9D8", -"D_ c #A5A5A5", -"E_ c #47454C", -"F_ c #5E5870", -"G_ c #7B709A", -"H_ c #8B7EAE", -"I_ c #B19ED8", -"J_ c #DFCDEF", -"K_ c #DDCCEE", -"L_ c #EEE4F4", -"M_ c #F3EEF6", -"N_ c #AA9DBC", -"O_ c #545455", -"P_ c #4A4A4A", -"Q_ c #383938", -"R_ c #232126", -"S_ c #594C71", -"T_ c #947CB7", -"U_ c #D8CAE2", -"V_ c #EFE9F0", -"W_ c #CAAFDC", -"X_ c #A287C6", -"Y_ c #E5D9E9", -"Z_ c #E1D4E8", -"`_ c #E1D7EA", -" : c #E5DBE9", -".: c #B4A0CD", -"+: c #8C72B6", -"@: c #635092", -"#: c #5D4A89", -"$: c #31274F", -"%: c #1C1630", -"&: c #0A0713", -"*: c #C2AED2", -"=: c #3E3352", -"-: c #1D1825", -";: c #28223F", -">: c #2C2543", -",: c #45385E", -"': c #A4A4A4", -"): c #424148", -"!: c #58536A", -"~: c #696180", -"{: c #7C719A", -"]: c #BDAADD", -"^: c #CEB9E9", -"/: c #EEE4F3", -"(: c #CDBCE0", -"_: c #B4A3CB", -":: c #6E677B", -"<: c #1B1B1B", -"[: c #2D2836", -"}: c #8F78B2", -"|: c #C9ACDC", -"1: c #D5C1E2", -"2: c #DDCAE4", -"3: c #DBCEE3", -"4: c #9176BA", -"5: c #BEA8D1", -"6: c #F1EBF2", -"7: c #F2F1F3", -"8: c #F1EFF2", -"9: c #E7E3ED", -"0: c #947CBA", -"a: c #836AB3", -"b: c #CFB7DC", -"c: c #AD8CD2", -"d: c #5B4988", -"e: c #18132A", -"f: c #A8A7AB", -"g: c #BAA3CC", -"h: c #392F4B", -"i: c #09080D", -"j: c #0F0C19", -"k: c #211B2E", -"l: c #403558", -"m: c #BAA3CE", -"n: c #B6B5B6", -"o: c #3B3A3F", -"p: c #4E495C", -"q: c #6B6287", -"r: c #887AAE", -"s: c #A793D3", -"t: c #DCCAEF", -"u: c #EFE5F4", -"v: c #E2D1EE", -"w: c #DDC9EE", -"x: c #8C7EA2", -"y: c #464546", -"z: c #1C1C1C", -"A: c #19191A", -"B: c #453B58", -"C: c #796596", -"D: c #9178BB", -"E: c #D5C1E4", -"F: c #EAE6EB", -"G: c #E6E2EC", -"H: c #D2BEDE", -"I: c #E0D3E5", -"J: c #DCCDE4", -"K: c #EEEAF0", -"L: c #D4BADE", -"M: c #AD90CE", -"N: c #E0D5E7", -"O: c #AF92CB", -"P: c #52427D", -"Q: c #1E1733", -"R: c #342B45", -"S: c #0A070E", -"T: c #1B1725", -"U: c #3B3152", -"V: c #B59ACC", -"W: c #C6C6C7", -"X: c #38373D", -"Y: c #534C67", -"Z: c #7D6FA4", -"`: c #8A7AB3", -" < c #A390CE", -".< c #E5D3F2", -"+< c #F9F5F9", -"@< c #EADEF3", -"#< c #DBCDEA", -"$< c #D7C2EA", -"%< c #8B7DA2", -"&< c #524E59", -"*< c #25222C", -"=< c #736196", -"-< c #C7ADDC", -";< c #EAE0EC", -">< c #EFEDF0", -",< c #EFEAF0", -"'< c #F7F7F7", -")< c #CAB6DC", -"!< c #C9B0DB", -"~< c #A286C4", -"{< c #8067B4", -"]< c #8E73B5", -"^< c #8B70B4", -"/< c #3C305F", -"(< c #181229", -"_< c #CDC9CF", -":< c #9D82B6", -"<< c #322942", -"[< c #16121E", -"}< c #2E263F", -"|< c #A085BC", -"1< c #DAD7DB", -"2< c #302F32", -"3< c #48435A", -"4< c #595171", -"5< c #8676AF", -"6< c #D8C6EF", -"7< c #EFE3F4", -"8< c #E6D6F2", -"9< c #ECDDF2", -"0< c #F5EDF5", -"a< c #F0E3F4", -"b< c #C3ADE0", -"c< c #CCB8E2", -"d< c #766B8C", -"e< c #4F4A58", -"f< c #1B191D", -"g< c #443A57", -"h< c #8E76B2", -"i< c #D1BBE2", -"j< c #EAE3EB", -"k< c #CFB3DB", -"l< c #D2BCDF", -"m< c #F9F7F9", -"n< c #F3F0F4", -"o< c #F6F4F6", -"p< c #E6DBEC", -"q< c #8E77AD", -"r< c #433565", -"s< c #4D3E74", -"t< c #413464", -"u< c #3E3161", -"v< c #1B1530", -"w< c #DDD4DF", -"x< c #866EAD", -"y< c #181424", -"z< c #0F0C18", -"A< c #120F19", -"B< c #745F99", -"C< c #E3D9E5", -"D< c #2A2A2B", -"E< c #383542", -"F< c #524A6A", -"G< c #907DBE", -"H< c #C1AAE0", -"I< c #F2E5F5", -"J< c #F4EBF5", -"K< c #EDE1F4", -"L< c #ECDFF4", -"M< c #F8F3F9", -"N< c #D1C0E2", -"O< c #C6AEDF", -"P< c #A48FC2", -"Q< c #645A78", -"R< c #3E3A45", -"S< c #292929", -"T< c #282430", -"U< c #3E354F", -"V< c #685788", -"W< c #544670", -"X< c #BDA4D3", -"Y< c #B8A0CF", -"Z< c #D6BEDE", -"`< c #DCD0E3", -" [ c #E6DBE9", -".[ c #FAFAFA", -"+[ c #F6F5F7", -"@[ c #C7B2DB", -"#[ c #A082C0", -"$[ c #7F66A2", -"%[ c #352A54", -"&[ c #020205", -"*[ c #625F65", -"=[ c #604F7F", -"-[ c #312845", -";[ c #110E19", -">[ c #0F0C16", -",[ c #231D33", -"'[ c #53446F", -")[ c #CEBCDA", -"![ c #939394", -"~[ c #343140", -"{[ c #5C527C", -"][ c #6A5D8D", -"^[ c #8F7CBD", -"/[ c #C4ACDF", -"([ c #F3E8F5", -"_[ c #F5EEF7", -":[ c #EBE1F3", -"<[ c #DDC9F0", -"[[ c #E7D1F2", -"}[ c #DEC5EF", -"|[ c #A28BC5", -"1[ c #4E465E", -"2[ c #272628", -"3[ c #222124", -"4[ c #2D2935", -"5[ c #2E2937", -"6[ c #4B4061", -"7[ c #6F5D8E", -"8[ c #7E6A9C", -"9[ c #8B73B1", -"0[ c #C8B2D6", -"a[ c #836DA4", -"b[ c #9D80C2", -"c[ c #8B72B1", -"d[ c #D6CCDF", -"e[ c #EDE9EF", -"f[ c #EFEAF3", -"g[ c #CBB5DD", -"h[ c #6F59A0", -"i[ c #31274E", -"j[ c #1D1732", -"k[ c #A0A0A3", -"l[ c #C6B3D5", -"m[ c #45395C", -"n[ c #2D253F", -"o[ c #09070D", -"p[ c #1C1726", -"q[ c #382E4B", -"r[ c #C5C4C6", -"s[ c #292730", -"t[ c #3E3851", -"u[ c #51486B", -"v[ c #6F6195", -"w[ c #9681C9", -"x[ c #CDB2ED", -"y[ c #E9D8F4", -"z[ c #F5EDF7", -"A[ c #E8DAF3", -"B[ c #C5AEDE", -"C[ c #F3EBF6", -"D[ c #D9BDF1", -"E[ c #8471A2", -"F[ c #62557C", -"G[ c #8F7AAF", -"H[ c #BC9ED5", -"I[ c #816E99", -"J[ c #9B81C5", -"K[ c #8770AE", -"L[ c #BDAAD5", -"M[ c #A890CB", -"N[ c #CAB0D9", -"O[ c #DDD2E3", -"P[ c #8F7BAF", -"Q[ c #A286C6", -"R[ c #BDA1D5", -"S[ c #C7B7D9", -"T[ c #D0C7E0", -"U[ c #EEE9F0", -"V[ c #DFCFE5", -"W[ c #F3F2F4", -"X[ c #F7F7F8", -"Y[ c #E0D5E9", -"Z[ c #BCA8D4", -"`[ c #55447A", -" } c #271F3F", -".} c #171226", -"+} c #110D1F", -"@} c #CCCBCE", -"#} c #CFB8DD", -"$} c #7E69B5", -"%} c #4A3E73", -"&} c #010002", -"*} c #171320", -"=} c #362D4E", -"-} c #9C81BE", -";} c #E4DFE5", -">} c #1D1D1D", -",} c #27252F", -"'} c #353144", -")} c #584D77", -"!} c #8C77BE", -"~} c #B498E5", -"{} c #D9C4F2", -"]} c #EAD9F4", -"^} c #F3EEF8", -"/} c #DDD4EB", -"(} c #CAB5DD", -"_} c #DCC5F1", -":} c #F3EAF6", -"<} c #D1BFEA", -"[} c #CDB0E7", -"}} c #917BB7", -"|} c #BFA0DF", -"1} c #EDD8F1", -"2} c #D4C7E1", -"3} c #7A65A1", -"4} c #B297D4", -"5} c #AD91D2", -"6} c #DDD1E7", -"7} c #B59DCE", -"8} c #B196C8", -"9} c #CBB5D8", -"0} c #B295CF", -"a} c #886FB8", -"b} c #987CC0", -"c} c #7C65A9", -"d} c #9B86B7", -"e} c #B89ED3", -"f} c #E0D6E7", -"g} c #D7C9E3", -"h} c #AE95D0", -"i} c #675398", -"j} c #453767", -"k} c #2A2144", -"l} c #1C162F", -"m} c #49494A", -"n} c #E0D5E3", -"o} c #876FB1", -"p} c #6A59A0", -"q} c #433869", -"r} c #110E18", -"s} c #2E2742", -"t} c #7B66A3", -"u} c #E4D9E6", -"v} c #9D9C9D", -"w} c #171817", -"x} c #1A1A1B", -"y} c #282531", -"z} c #4F446C", -"A} c #8571B7", -"B} c #CAB1E8", -"C} c #ECD3F4", -"D} c #F9F4FA", -"E} c #F4ECF7", -"F} c #F3ECF7", -"G} c #C5AEE2", -"H} c #D0B4EA", -"I} c #EDE6F3", -"J} c #D2BAEB", -"K} c #DDCAED", -"L} c #CFBEE7", -"M} c #EDDDF4", -"N} c #EBD9F3", -"O} c #D1B7E6", -"P} c #DFC0E9", -"Q} c #EADDF0", -"R} c #F4F0F5", -"S} c #9080A5", -"T} c #8878A1", -"U} c #C1AAD7", -"V} c #AE8FCE", -"W} c #C6B8D5", -"X} c #A187C9", -"Y} c #9E85B9", -"Z} c #BC9ED0", -"`} c #BEA9D5", -" | c #B79DCF", -".| c #A58DC1", -"+| c #655290", -"@| c #AA97C7", -"#| c #EAE4EF", -"$| c #D6C5E1", -"%| c #9079B3", -"&| c #6C5798", -"*| c #1B152E", -"=| c #A5A5A7", -"-| c #C6B2D4", -";| c #473A5E", -">| c #322946", -",| c #07050F", -"'| c #7460A1", -")| c #CEB7DC", -"!| c #D7D5D8", -"~| c #242130", -"{| c #554979", -"]| c #8872BE", -"^| c #A68CDB", -"/| c #CDACEE", -"(| c #F0E2F6", -"_| c #E4D3F4", -":| c #A98FCF", -"<| c #7C6AA1", -"[| c #AF96D2", -"}| c #D4C3E6", -"|| c #B29BD1", -"1| c #E7E0EF", -"2| c #EBE0F1", -"3| c #CCB0DE", -"4| c #DCD0E7", -"5| c #E1CFE9", -"6| c #C2A3DA", -"7| c #E3D1E7", -"8| c #EDE8EE", -"9| c #C5B8D3", -"0| c #524371", -"a| c #C7BCD4", -"b| c #DBD0E5", -"c| c #BC9BD3", -"d| c #E4DBEA", -"e| c #C4AFDA", -"f| c #CDB9DD", -"g| c #EDE6EE", -"h| c #EFE9F1", -"i| c #D8D0E3", -"j| c #ECE6F0", -"k| c #F0ECF1", -"l| c #D7C6E2", -"m| c #B195CB", -"n| c #51417A", -"o| c #191429", -"p| c #05040A", -"q| c #010007", -"r| c #DBD7DD", -"s| c #9980B5", -"t| c #302843", -"u| c #1B1627", -"v| c #0A0810", -"w| c #1A1525", -"x| c #2E2642", -"y| c #705C93", -"z| c #D9C9E0", -"A| c #838285", -"B| c #1D1A28", -"C| c #443A63", -"D| c #7461A3", -"E| c #6C5B99", -"F| c #B597E1", -"G| c #DCBFF1", -"H| c #F9F2F9", -"I| c #FEFEFF", -"J| c #F4E8F7", -"K| c #CAB9E2", -"L| c #9F85C3", -"M| c #DEBFEE", -"N| c #FAF6FA", -"O| c #B499D3", -"P| c #DACFE9", -"Q| c #D9C1E4", -"R| c #EADEF0", -"S| c #D9C8E3", -"T| c #D9C8E1", -"U| c #C8ACD6", -"V| c #EAE6EC", -"W| c #E4DAE8", -"X| c #9A7EC0", -"Y| c #C8B4D8", -"Z| c #DFD2E5", -"`| c #C5AED7", -" 1 c #DDD1E5", -".1 c #E8DCEB", -"+1 c #F1EFF3", -"@1 c #F4F1F5", -"#1 c #F4F3F5", -"$1 c #EEEBF1", -"%1 c #9278B6", -"&1 c #765FA6", -"*1 c #51417C", -"=1 c #211A36", -"-1 c #130F22", -";1 c #959597", -">1 c #D2C2DC", -",1 c #615082", -"'1 c #29223C", -")1 c #15121E", -"!1 c #0D0A13", -"~1 c #261F35", -"{1 c #4E416F", -"]1 c #AA8FC3", -"^1 c #D7D4D8", -"/1 c #0E0E12", -"(1 c #252037", -"_1 c #342C4C", -":1 c #6D5B9D", -"<1 c #C1A1E3", -"[1 c #DFC2EE", -"}1 c #F6ECF8", -"|1 c #F6F0F8", -"11 c #EBDEF3", -"21 c #A388CA", -"31 c #A98ED0", -"41 c #AE92D2", -"51 c #E0D2EB", -"61 c #DBCCE9", -"71 c #EFE9F2", -"81 c #EFEBF0", -"91 c #E7DCE8", -"01 c #D6C1DE", -"a1 c #DED4E5", -"b1 c #F5F4F6", -"c1 c #BFADD5", -"d1 c #886FB3", -"e1 c #D5C2E0", -"f1 c #F4F1F6", -"g1 c #DCCAE2", -"h1 c #F5F2F6", -"i1 c #F0EDF1", -"j1 c #BFAED7", -"k1 c #362B54", -"l1 c #201934", -"m1 c #151125", -"n1 c #080610", -"o1 c #312E33", -"p1 c #D9D5DA", -"q1 c #A289BD", -"r1 c #1E1929", -"s1 c #1B1628", -"t1 c #453A67", -"u1 c #7B65A7", -"v1 c #D8C8DF", -"w1 c #0C0B10", -"x1 c #231D35", -"y1 c #463A69", -"z1 c #A689D2", -"A1 c #DDC0E9", -"B1 c #E3D7EF", -"C1 c #E1CAEC", -"D1 c #F6EDF7", -"E1 c #D3BFE6", -"F1 c #B99ADC", -"G1 c #C8ADDE", -"H1 c #B6AACF", -"I1 c #EADDEB", -"J1 c #F8F8F8", -"K1 c #DBD1E3", -"L1 c #B79ACE", -"M1 c #E3D5E6", -"N1 c #E2D5E5", -"O1 c #BFB3D2", -"P1 c #BFA2D7", -"Q1 c #E6DCEC", -"R1 c #E1D3E7", -"S1 c #F1EDF3", -"T1 c #DED3E6", -"U1 c #120E20", -"V1 c #A9A9AB", -"W1 c #D1BEDB", -"X1 c #5D4C7C", -"Y1 c #272035", -"Z1 c #1A1627", -"`1 c #0F0C1A", -" 2 c #4B3E6D", -".2 c #BBA2D2", -"+2 c #E8E6E9", -"@2 c #110E1D", -"#2 c #3D325F", -"$2 c #755FAA", -"%2 c #A98BD3", -"&2 c #BC9EDB", -"*2 c #8D76BF", -"=2 c #C2A8DE", -"-2 c #F0E8F2", -";2 c #D8C0E6", -">2 c #E8DDEE", -",2 c #A58CC9", -"'2 c #BCA0D5", -")2 c #E8E1EE", -"!2 c #F4F4F5", -"~2 c #DECBE3", -"{2 c #F2EEF4", -"]2 c #E8E2EE", -"^2 c #7A639C", -"/2 c #C4B6D6", -"(2 c #E7DEE9", -"_2 c #E4D7E8", -":2 c #E4DBE8", -"<2 c #F1EDF5", -"[2 c #F8F8F9", -"}2 c #CBB2DB", -"|2 c #D9C5E2", -"12 c #E3D7E6", -"22 c #EEEBF2", -"32 c #C7B5DA", -"42 c #7863A3", -"52 c #261E3E", -"62 c #140F24", -"72 c #E0D8E2", -"82 c #8A72AA", -"92 c #342B49", -"02 c #251F38", -"a2 c #2B2443", -"b2 c #2C2545", -"c2 c #0B0812", -"d2 c #1E192D", -"e2 c #4E4177", -"f2 c #A68AD2", -"g2 c #DDCCE2", -"h2 c #493B72", -"i2 c #6C57A1", -"j2 c #675394", -"k2 c #564681", -"l2 c #A086C7", -"m2 c #E0CDE5", -"n2 c #A184C8", -"o2 c #F1EBF4", -"p2 c #D2C5DE", -"q2 c #8C75AE", -"r2 c #B69BCF", -"s2 c #F3EDF4", -"t2 c #DACBE2", -"u2 c #C9AED9", -"v2 c #D8C8DE", -"w2 c #B29BCA", -"x2 c #E4DCE8", -"y2 c #E0D4E5", -"z2 c #ECE7ED", -"A2 c #E9E3EC", -"B2 c #B59FD1", -"C2 c #E7DFEC", -"D2 c #8A70B0", -"E2 c #624F89", -"F2 c #9E85BC", -"G2 c #C8B0D9", -"H2 c #BEACD5", -"I2 c #BEA6D7", -"J2 c #665298", -"K2 c #3F3262", -"L2 c #B9A1CE", -"M2 c #4F416D", -"N2 c #3A3159", -"O2 c #31294C", -"P2 c #141120", -"Q2 c #0D0B15", -"R2 c #050308", -"S2 c #151020", -"T2 c #6C5A9E", -"U2 c #B496D6", -"V2 c #E3DAE6", -"W2 c #B7B7B8", -"X2 c #231B3B", -"Y2 c #332851", -"Z2 c #2F254B", -"`2 c #443668", -" 3 c #BA9ED5", -".3 c #725CA3", -"+3 c #E8DDEC", -"@3 c #B192CE", -"#3 c #685495", -"$3 c #E6DAE8", -"%3 c #F7F6F8", -"&3 c #F0EEF1", -"*3 c #EBE2ED", -"=3 c #B395CF", -"-3 c #BFA2D8", -";3 c #E9E0EC", -">3 c #D1BBDD", -",3 c #E3D6E7", -"'3 c #F5F5F6", -")3 c #EAE4EC", -"!3 c #DAC5E1", -"~3 c #D1C0E0", -"{3 c #B796D2", -"]3 c #614E86", -"^3 c #5C4A88", -"/3 c #6F5996", -"(3 c #5C4A87", -"_3 c #7B63A9", -":3 c #090612", -"<3 c #BCBBBF", -"[3 c #CFBBDA", -"}3 c #6A578E", -"|3 c #2D2642", -"13 c #1A162A", -"23 c #1B1528", -"33 c #322948", -"43 c #7A65A9", -"53 c #C7ABDB", -"63 c #E9E5EB", -"73 c #403365", -"83 c #5F4C8F", -"93 c #765FAA", -"03 c #705A9E", -"a3 c #D9C8E2", -"b3 c #CAB5DB", -"c3 c #EBE7EC", -"d3 c #D5C1E0", -"e3 c #DDCBE2", -"f3 c #A68ACD", -"g3 c #E6D7E8", -"h3 c #F1EEF2", -"i3 c #D9CBE2", -"j3 c #C2B1D5", -"k3 c #F3F1F3", -"l3 c #F1F1F2", -"m3 c #EBE6ED", -"n3 c #F5F3F5", -"o3 c #CEB5DD", -"p3 c #C4A4D9", -"q3 c #B498D5", -"r3 c #C6ACD8", -"s3 c #9177C2", -"t3 c #443769", -"u3 c #271F40", -"v3 c #241C3C", -"w3 c #A3A1A6", -"x3 c #D6C6DE", -"y3 c #745F94", -"z3 c #221C33", -"A3 c #110E1A", -"B3 c #1D182A", -"C3 c #3F3556", -"D3 c #7F69AD", -"E3 c #CEB3DC", -"F3 c #E5DDE7", -"G3 c #9E9D9E", -"H3 c #50407A", -"I3 c #695498", -"J3 c #675397", -"K3 c #7A62AE", -"L3 c #C0A8D6", -"M3 c #D3BCDF", -"N3 c #AF92D3", -"O3 c #BBA5CF", -"P3 c #C1ACD3", -"Q3 c #EDEBEF", -"R3 c #B293D5", -"S3 c #B49BD2", -"T3 c #CCB8DC", -"U3 c #E5DEE8", -"V3 c #EFEDF1", -"W3 c #EBE4EE", -"X3 c #CAB9DC", -"Y3 c #C4B4D4", -"Z3 c #B997D4", -"`3 c #9176C7", -" 4 c #685497", -".4 c #6A5598", -"+4 c #433668", -"@4 c #181329", -"#4 c #0C0916", -"$4 c #DBCDE1", -"%4 c #826BA0", -"&4 c #2E263E", -"*4 c #1F1A2A", -"=4 c #110D19", -"-4 c #0A0811", -";4 c #211B2F", -">4 c #382E55", -",4 c #6D5B9E", -"'4 c #080611", -")4 c #1F1834", -"!4 c #322750", -"~4 c #392D5A", -"{4 c #3B2F5C", -"]4 c #554480", -"^4 c #B49ACF", -"/4 c #C7A6D9", -"(4 c #9679C6", -"_4 c #C4A9D9", -":4 c #B497CA", -"<4 c #8269B5", -"[4 c #D4C1DE", -"}4 c #E2D6E6", -"|4 c #C7B3DC", -"14 c #7E66B5", -"24 c #997EBD", -"34 c #AF8FD3", -"44 c #BFA4D8", -"54 c #AD8DD2", -"64 c #C7ACDB", -"74 c #BE9FD8", -"84 c #8B74B5", -"94 c #46386A", -"04 c #725C9C", -"a4 c #493A70", -"b4 c #30264D", -"c4 c #120E21", -"d4 c #9F9FA2", -"e4 c #DACCE0", -"f4 c #876FA4", -"g4 c #342B46", -"h4 c #1F1A2C", -"i4 c #362D52", -"j4 c #524474", -"k4 c #967DB7", -"l4 c #B4B4B4", -"m4 c #0D0A18", -"n4 c #1A142C", -"o4 c #231B39", -"p4 c #372C57", -"q4 c #292041", -"r4 c #755EAB", -"s4 c #9B7DCA", -"t4 c #BC9DD6", -"u4 c #6F5AA2", -"v4 c #C9AADA", -"w4 c #B899D2", -"x4 c #9075BB", -"y4 c #7C64A5", -"z4 c #584783", -"A4 c #A384CA", -"B4 c #886EC1", -"C4 c #6D58A0", -"D4 c #8B70C0", -"E4 c #876DB7", -"F4 c #6F5A99", -"G4 c #2E2549", -"H4 c #292042", -"I4 c #2F254C", -"J4 c #0C0917", -"K4 c #292731", -"L4 c #BCBBBD", -"M4 c #826BA1", -"N4 c #352C47", -"O4 c #241E2E", -"P4 c #151120", -"Q4 c #1C182B", -"R4 c #272137", -"S4 c #957BBB", -"T4 c #CFCECF", -"U4 c #58585A", -"V4 c #19132B", -"W4 c #140F23", -"X4 c #282042", -"Y4 c #443669", -"Z4 c #9579BF", -"`4 c #735C9F", -" 5 c #423464", -".5 c #594883", -"+5 c #8F74BD", -"@5 c #69559A", -"#5 c #594784", -"$5 c #634F92", -"%5 c #4C3D73", -"&5 c #534379", -"*5 c #705A9B", -"=5 c #4F3F77", -"-5 c #5C4A8A", -";5 c #645196", -">5 c #2F254A", -",5 c #2A2143", -"'5 c #1D1731", -")5 c #0B0814", -"!5 c #5E5E61", -"~5 c #D7C5DF", -"{5 c #8B73AF", -"]5 c #352C48", -"^5 c #251E2F", -"/5 c #0E0B13", -"(5 c #08060C", -"_5 c #08070E", -":5 c #100D18", -"<5 c #2E2646", -"[5 c #483C68", -"}5 c #77629F", -"|5 c #C7B0D8", -"15 c #E4DEE4", -"25 c #0B0816", -"35 c #2E254B", -"45 c #3F3263", -"55 c #3E3160", -"65 c #1A152B", -"75 c #5D4B8C", -"85 c #453769", -"95 c #2B2244", -"05 c #4A3B71", -"a5 c #221B38", -"b5 c #3F3264", -"c5 c #0E0B1B", -"d5 c #06050D", -"e5 c #0E0C14", -"f5 c #A8A8AB", -"g5 c #9077C1", -"h5 c #4E4172", -"i5 c #241E36", -"j5 c #15111E", -"k5 c #382E52", -"l5 c #604F85", -"m5 c #A388BF", -"n5 c #D9CBE0", -"o5 c #D9D7D9", -"p5 c #848384", -"q5 c #110D20", -"r5 c #0E0B19", -"s5 c #161126", -"t5 c #372C58", -"u5 c #352A55", -"v5 c #1D1630", -"w5 c #151024", -"x5 c #100C1D", -"y5 c #07050E", -"z5 c #969698", -"A5 c #DBDADC", -"B5 c #AA8FCD", -"C5 c #7B66B2", -"D5 c #6B59A2", -"E5 c #3A315A", -"F5 c #1C172B", -"G5 c #1E182B", -"H5 c #282136", -"I5 c #362D49", -"J5 c #68568A", -"K5 c #B198C7", -"L5 c #DFD3E4", -"M5 c #D6D4D8", -"N5 c #9A9A9A", -"O5 c #353335", -"P5 c #040309", -"Q5 c #130F23", -"R5 c #0F0C1C", -"S5 c #353538", -"T5 c #9E9DA0", -"U5 c #D9D8DA", -"V5 c #E6E2E8", -"W5 c #C2ABD7", -"X5 c #7B65A5", -"Y5 c #5D4D89", -"Z5 c #64549B", -"`5 c #514480", -" 6 c #231E38", -".6 c #07050B", -"+6 c #1F1928", -"@6 c #2A2337", -"#6 c #705C92", -"$6 c #B298C9", -"%6 c #D9CAE1", -"&6 c #C5C5C6", -"*6 c #919192", -"=6 c #504D54", -"-6 c #949397", -";6 c #E3DDE5", -">6 c #CFBDDC", -",6 c #CAACDA", -"'6 c #BA9DD3", -")6 c #665594", -"!6 c #433866", -"~6 c #332A4E", -"{6 c #241D39", -"]6 c #141021", -"^6 c #08070C", -"/6 c #110D16", -"(6 c #705D99", -"_6 c #9D82BD", -":6 c #BCA6D0", -"<6 c #D1C1DD", -"[6 c #E4DBE7", -"}6 c #DBD7DB", -"|6 c #C3C2C4", -"16 c #B4B3B6", -"26 c #989899", -"36 c #98989A", -"46 c #9E9D9F", -"56 c #C8C7C8", -"66 c #DBD6DC", -"76 c #E1D6E5", -"86 c #D5C2DE", -"96 c #C1AAD4", -"06 c #8E75B2", -"a6 c #7561A6", -"b6 c #7A65AF", -"c6 c #715FA5", -"d6 c #362D53", -"e6 c #120E1F", -"f6 c #17131F", -"g6 c #1E192A", -"h6 c #262036", -"i6 c #332A46", -"j6 c #3C3150", -"k6 c #4D3F66", -"l6 c #6A568A", -"m6 c #8C73A9", -"n6 c #A78DBF", -"o6 c #B79FC9", -"p6 c #C1AED2", -"q6 c #CAB7D7", -"r6 c #CFBEDB", -"s6 c #CEBDDA", -"t6 c #B7A0CA", -"u6 c #A88EBF", -"v6 c #8E75AA", -"w6 c #6B588D", -"x6 c #5F4F84", -"y6 c #463A62", -"z6 c #4A3E70", -"A6 c #423764", -"B6 c #393058", -"C6 c #2F2747", -"D6 c #1F192F", -"E6 c #130F1F", -"F6 c #0A0712", -"G6 c #030307", -"H6 c #0B0911", -"I6 c #0F0C15", -"J6 c #15111C", -"K6 c #1B1724", -"L6 c #2B2338", -"M6 c #443759", -"N6 c #4A3D63", -"O6 c #3E3351", -"P6 c #382E49", -"Q6 c #312840", -"R6 c #2D253A", -"S6 c #282134", -"T6 c #251F32", -"U6 c #241E32", -"V6 c #1A1528", -"W6 c #0C0A0F", -"X6 c #100D15", -"Y6 c #1C1724", -"Z6 c #211B2B", -"`6 c #1C1624", -" 7 c #18141F", -".7 c #0D0A10", -"+7 c #0D0B13", -"@7 c #313031", -"#7 c #3A393A", -"$7 c #414041", -"%7 c #3F3E3F", -"&7 c #222122", -"*7 c #3E3E3E", -"=7 c #BABABA", -"-7 c #BEBEBE", -";7 c #666666", -">7 c #BCBCBC", -",7 c #C5C5C5", -"'7 c #C6C6C6", -")7 c #252526", -"!7 c #262626", -"~7 c #6B6B6B", -"{7 c #BDBDBD", -"]7 c #C4C4C4", -"^7 c #A2A1A2", -"/7 c #BDBCBD", -"(7 c #C4C3C4", -"_7 c #707070", -":7 c #C3C2C2", -"<7 c #D2D2D2", -"[7 c #D9D9D9", -"}7 c #575657", -"|7 c #737373", -"17 c #F6F6F7", -"27 c #F1F1F1", -"37 c #ABABAB", -"47 c #171717", -"57 c #D4D3D4", -"67 c #EAE6EA", -"77 c #EBE7EB", -"87 c #AAAAAA", -"97 c #EFEEEF", -"07 c #EAE8EB", -"a7 c #EAE7EB", -"b7 c #EBE8EB", -"c7 c #363536", -"d7 c #D5D5D5", -"e7 c #EBE9EB", -"f7 c #F2F2F2", -"g7 c #A3A3A4", -"h7 c #D8D8D8", -"i7 c #EBE9EC", -"j7 c #EBEAEC", -"k7 c #ECEAEC", -"l7 c #F3F3F3", -"m7 c #A1A1A1", -"n7 c #1A191A", -"o7 c #DBDADB", -"p7 c #ECEBEC", -"q7 c #D9D8D9", -"r7 c #767676", -"s7 c #E6DDE6", -"t7 c #F1F0F1", -"u7 c #E1CFE1", -"v7 c #E4D9E4", -"w7 c #F2F2F3", -"x7 c #6C6B6C", -"y7 c #E1D3E2", -"z7 c #E5DDE6", -"A7 c #E6DEE7", -"B7 c #636364", -"C7 c #ECECEC", -"D7 c #E1D1E1", -"E7 c #E5DDE5", -"F7 c #EFEFEF", -"G7 c #C2C2C2", -"H7 c #717171", -"I7 c #E2D6E2", -"J7 c #EFEFF0", -"K7 c #E6DFE6", -"L7 c #212021", -"M7 c #747374", -"N7 c #F4F4F4", -"O7 c #E2D7E3", -"P7 c #E5DEE6", -"Q7 c #E9E4E9", -"R7 c #F3F3F4", -"S7 c #E3D8E3", -"T7 c #ECEBED", -"U7 c #EAE5EA", -"V7 c #C3C2C3", -"W7 c #E5E5E5", -"X7 c #D7D7D7", -"Y7 c #595859", -"Z7 c #757476", -"`7 c #8B8B8B", -" 8 c #E3D4E4", -".8 c #ECE8EC", -"+8 c #A7A6A7", -"@8 c #1B1A1B", -"#8 c #6E6D6E", -"$8 c #E5E4E5", -"%8 c #E1CEE1", -"&8 c #DDDCDD", -"*8 c #949394", -"=8 c #A3A2A4", -"-8 c #D1D1D2", -";8 c #484849", -">8 c #3D3C3D", -",8 c #8D8D8D", -"'8 c #D0CFD0", -")8 c #A5A4A5", -"!8 c #838383", -"~8 c #737273", -"{8 c #E2D2E3", -"]8 c #DDDDDD", -"^8 c #939293", -"/8 c #A6A5A6", -"(8 c #E4D6E5", -"_8 c #C4C4C5", -":8 c #DBDBDC", -"<8 c #929293", -"[8 c #EDEAEE", -"}8 c #E5D8E5", -"|8 c #797879", -"18 c #E3D6E4", -"28 c #D3D3D4", -"38 c #929292", -"48 c #A9A8A9", -"58 c #403F40", -"68 c #0C0B0C", -"78 c #686668", -"88 c #E3E2E4", -"98 c #DCC1DE", -"08 c #D5D4D6", -"a8 c #585758", -"b8 c #747375", -"c8 c #EEEBEF", -"d8 c #DBC2DF", -"e8 c #0E0D0F", -"f8 c #E0CEE3", -"g8 c #EBE4EC", -"h8 c #848284", -"i8 c #181819", -"j8 c #6D6C6D", -"k8 c #E2E0E3", -"l8 c #DCC3DF", -"m8 c #D5D5D6", -"n8 c #5C5B5C", -"o8 c #7D7C7E", -"p8 c #DEC7E1", -"q8 c #CFCFD0", -"r8 c #474647", -"s8 c #E1CDE2", -"t8 c #EDE8ED", -"u8 c #807E80", -"v8 c #0C0C0D", -"w8 c #727172", -"x8 c #828082", -"y8 c #EDE9ED", -"z8 c #E0CCE2", -"A8 c #454445", -"B8 c #757475", -"C8 c #EFECEF", -"D8 c #E0CAE1", -"E8 c #848385", -"F8 c #E1CEE2", -"G8 c #C2C1C3", -"H8 c #434243", -"I8 c #787678", -"J8 c #878587", -"K8 c #E3D1E4", -"L8 c #0B0B0C", -"M8 c #666567", -"N8 c #E0DDE1", -"O8 c #D0B1DB", -"P8 c #575658", -"Q8 c #737174", -"R8 c #CFB5DC", -"S8 c #100F10", -"T8 c #3E3D3E", -"U8 c #BEBDBF", -"V8 c #D7C3E0", -"W8 c #7F7D80", -"X8 c #252425", -"Y8 c #181718", -"Z8 c #6B6A6C", -"`8 c #E0DBE1", -" 9 c #D1B5DC", -".9 c #555456", -"+9 c #787779", -"@9 c #E4D9E7", -"#9 c #0B0A0B", -"$9 c #424243", -"%9 c #C0BFC1", -"&9 c #D7C1DF", -"*9 c #7B797C", -"=9 c #1A191B", -"-9 c #716F71", -";9 c #D4BBDE", -">9 c #525152", -",9 c #7D7B7E", -"'9 c #D6BFDF", -")9 c #C1C0C2", -"!9 c #444344", -"~9 c #201F21", -"{9 c #747274", -"]9 c #D6BDDE", -"^9 c #515051", -"/9 c #807E81", -"(9 c #EAE1EB", -"_9 c #D7C2E0", -":9 c #212022", -"<9 c #D7BFDF", -"[9 c #504F51", -"}9 c #E8E0EA", -"|9 c #ADACAD", -"19 c #656366", -"29 c #DED8DF", -"39 c #C0A1D8", -"49 c #D0CFD2", -"59 c #565457", -"69 c #716F73", -"79 c #E8E1EA", -"89 c #CFCED1", -"99 c #0C0B0E", -"09 c #0C0A0C", -"a9 c #3C3B3D", -"b9 c #BCBABD", -"c9 c #CBB6DD", -"d9 c #7D7A7F", -"e9 c #09090A", -"f9 c #171618", -"g9 c #6A686B", -"h9 c #DDD7DF", -"i9 c #C2A5D9", -"j9 c #565558", -"k9 c #E1E1E2", -"l9 c #C9C8CA", -"m9 c #1D1D1E", -"n9 c #403F41", -"o9 c #BEBCBF", -"p9 c #CBB4DC", -"q9 c #E5DCE9", -"r9 c #79767A", -"s9 c #1F1E20", -"t9 c #6F6D70", -"u9 c #E9E2EA", -"v9 c #C7ADDA", -"w9 c #7B787C", -"x9 c #E6DCE9", -"y9 c #CAB3DC", -"z9 c #BFBDC0", -"A9 c #434244", -"B9 c #201E20", -"C9 c #727073", -"D9 c #CAB0DB", -"E9 c #4F4D4F", -"F9 c #7D7B7F", -"G9 c #E5DBE8", -"H9 c #CCB6DD", -"I9 c #BEBDC0", -"J9 c #414042", -"K9 c #747276", -"L9 c #CBB3DC", -"M9 c #C3C2C5", -"N9 c #515052", -"O9 c #706F70", -"P9 c #E2E2E3", -"Q9 c #5B5A5B", -"R9 c #636165", -"S9 c #DBD3DD", -"T9 c #B090D5", -"U9 c #CECCD0", -"V9 c #545256", -"W9 c #6F6C71", -"X9 c #E3DAE8", -"Y9 c #B195D5", -"Z9 c #CDCCCF", -"`9 c #49474A", -" 0 c #0C0A0D", -".0 c #070708", -"+0 c #0A080B", -"@0 c #3B3A3C", -"#0 c #B9B8BC", -"$0 c #C0AADA", -"%0 c #DCD0E4", -"&0 c #202022", -"*0 c #68666A", -"=0 c #D9D0DD", -"-0 c #AF90D4", -";0 c #848089", -">0 c #7E7B82", -",0 c #8B888E", -"'0 c #757377", -")0 c #3A393B", -"!0 c #0A090B", -"~0 c #3F3E40", -"{0 c #BBBABE", -"]0 c #BFA8D9", -"^0 c #E0D5E6", -"/0 c #1E1D1F", -"(0 c #19181A", -"_0 c #6D6B6F", -":0 c #B99DD7", -"<0 c #4E4D50", -"[0 c #78767B", -"}0 c #BEA6D9", -"|0 c #424143", -"10 c #1F1D20", -"20 c #706D72", -"30 c #BBA1D8", -"40 c #CBCACD", -"50 c #4D4C4E", -"60 c #7B787E", -"70 c #DFD4E6", -"80 c #C0A9DA", -"90 c #BCBABE", -"00 c #727074", -"a0 c #BA9FD7", -"b0 c #837F87", -"c0 c #817E84", -"d0 c #8C8A8F", -"e0 c #717073", -"f0 c #353436", -"g0 c #131215", -"h0 c #615F64", -"i0 c #D6CCDB", -"j0 c #9E7FCC", -"k0 c #CBC7CE", -"l0 c #525155", -"m0 c #6C6970", -"n0 c #DDD4E5", -"o0 c #A285CA", -"p0 c #CAC9CD", -"q0 c #474649", -"r0 c #39383B", -"s0 c #B7B5B9", -"t0 c #B49DD2", -"u0 c #D4C7E2", -"v0 c #78747C", -"w0 c #141316", -"x0 c #646166", -"y0 c #D6CCDA", -"z0 c #896EC1", -"A0 c #BFABD6", -"B0 c #D3C7E2", -"C0 c #D4C9E2", -"D0 c #D7CBE3", -"E0 c #D6D2D9", -"F0 c #3E3C3F", -"G0 c #B9B7BC", -"H0 c #B199D3", -"I0 c #747077", -"J0 c #1D1C1E", -"K0 c #181719", -"L0 c #6B686E", -"M0 c #DFD5E5", -"N0 c #A98DD0", -"O0 c #4D4B4F", -"P0 c #76737A", -"Q0 c #AF97D1", -"R0 c #BAB8BC", -"S0 c #413F42", -"T0 c #1E1C1F", -"U0 c #6E6B71", -"V0 c #DFD5E6", -"W0 c #AC91D2", -"X0 c #C9C8CB", -"Y0 c #4C4A4D", -"Z0 c #78757C", -"`0 c #D8CCE3", -" a c #B39CD3", -".a c #3F3D40", -"+a c #1D1C1F", -"@a c #6E6B70", -"#a c #E0D7E6", -"$a c #9074C8", -"%a c #C7B5DB", -"&a c #D7CCE3", -"*a c #D8D5DA", -"=a c #6F6D71", -"-a c #201F20", -";a c #5F5C62", -">a c #D0C5D8", -",a c #896FBD", -"'a c #C8C1CB", -")a c #514E53", -"!a c #6A666E", -"~a c #9074BC", -"{a c #C7C4CA", -"]a c #464448", -"^a c #0A090C", -"/a c #38373A", -"(a c #B4B2B7", -"_a c #A58EC7", -":a c #CBBEDC", -"b c #C6C0C9", -",b c #4A474C", -"'b c #706B75", -")b c #CABBDB", -"!b c #9277B7", -"~b c #B4AFB8", -"{b c #3E3B40", -"]b c #1B1A1E", -"^b c #69646D", -"/b c #8C71B6", -"(b c #C3BFC6", -"_b c #48464B", -":b c #736D78", -"c c #4B3B80", -",c c #B9A0C3", -"'c c #4B414F", -")c c #615467", -"!c c #BFA5D2", -"~c c #554388", -"{c c #BCA4C2", -"]c c #403844", -"^c c #342D37", -"/c c #AA98AF", -"(c c #78609F", -"_c c #B097C6", -":c c #6A5D72", -"d c #604B8A", -",d c #AD90C4", -"'d c #64546C", -")d c #5C4E63", -"!d c #B89ACE", -"~d c #4C3B7F", -"{d c #B99CC1", -"]d c #443949", -"^d c #66556E", -"/d c #AD90C5", -"(d c #5C4888", -"_d c #A88EAF", -":d c #382F3C", -"e c #5E4D65", -",e c #AD8EC2", -"'e c #473973", -")e c #A789B2", -"!e c #58485E", -"~e c #6F5B79", -"{e c #9D80B6", -"]e c #5B4982", -"^e c #A588AB", -"/e c #332936", -"(e c #433646", -"_e c #AE8FB6", -":e c #66537C", -"f c #181320", -",f c #251E31", -"'f c #221B2D", -")f c #16111D", -"!f c #7E6794", -"~f c #A789AA", -"{f c #312733", -"]f c #4E3F51", -"^f c #BA99C5", -"/f c #4B3D62", -"(f c #1A1523", -"_f c #120E18", -":f c #241D30", -"g c #2C232E", -",g c #483B4C", -"'g c #1A141C", -")g c #3E3240", -"!g c #181218", -"~g c #2B232D", -"{g c #493C4C", -"]g c #3D3240", -"^g c #4D3F51", -"/g c #19131A", -"(g c #0C080D", -"_g c #0C070D", -":g c #0C080E", -" , > % . . . . . . . . @ * ' ) ! ! ) - ~ @ . . . . . . . . @ ~ { ) ! ! ] ^ $ @ . . . . . . . . % / ( ! ! ! _ : & . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ & < [ } | 1 2 3 4 { % . . . . . . @ $ 5 6 7 8 8 9 0 a b @ . . . . . . @ > c } 9 8 8 d e f $ @ . . . . . . % _ g h 9 8 8 i j 1 & @ . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ # k } l m n o p q r 2 = & . . . . @ * s t u v v v v w x y ~ % . . . . % ~ z A B v v v v C D E $ @ . . . . & F G H m v v v I J K L # @ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % b M N O P N e Q R S T U ; @ . . . # : 2 V W X Y Z ` ...+._ $ @ . . @ $ ) @.#.$.` %.Y X &.*.=.: # . . . @ ; -.;.>.,.'.%.).!.~.{.].^.% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & > /.(._.:.N <.[.}.|.1.5 ^.% . . . $ F 6 2.3.4.5.6.7.8.9.0.a.b.@ . . @ ; c.d.9.e.f.6.5.g.h.i.e j.$ . . . % ^.k.l.m.n.o.p.v q.r.H s.t.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & t.u.v.w.x.y.z.l A.B.C.5 D.% . . . $ j.E.F.G.H.I.J.K.L.M.D a.N.@ . . @ b.c.d.M.O.P.Q.R.S.G.T.e U.V.. . . % ^.W.X.Y.Z.`. +.+++@+#+$+t.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & t.%+&+*+=+-+;+>+,+'+)+!+~+% . . . V.{+]+^+/+(+_+:+<+[+}+|+1+* @ . . @ N.2+3+4+5+<+h 6+:.7+8+9+0+a+. . . % b+c+d+e+f+g+E.h+i+j+k+l+m+& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & m+n+o+p+q+r+s+g+t+u+v+w+~+% . . . a+U.<.x+y+z+A+B+C+D+E+<.^ # . . . @ * a.F+G+H+I+J+K+L+M+N+s+O+# . . . % ~+P+Q+R+S+T+U+V+W+X+Y+Z+^.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & b+`+ @.@+@@@#@$@%@&@*@=@-@;@. . . # O+>@,@'@)@!@~@{@.+]@s $ @ . . . @ ^@/@(@_@:@<@[@}@|@1@2@3@4@# . . . % -@5@6@7@8@9@0@a@b@c@d@e@b+f@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . f@b+g@h@i@j@k@l@m@n@o@p@q@-@;@. . . # 4@r@s@t@u@v@w@x@y@z@A@# @ . . . @ B@C@D@E@F@G@H@I@J@K@L@M@N@O@. . . ;@-@P@Q@R@S@T@U@V@W@X@Y@Z@`@f@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . #-@.#+#@###$#%#&#*#=#-#;#>#,#. . . '#)#!#~#{#]#^#/#/#(#&#_#O+& . . . @ B@:#<#[#}#|#1#2#3#4#5#6#>#% . . . ;@>#q@7#8#9#0#a#b#c#d#e#f#g# #. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . #h#i#j#k#l#m#n#o#p#q#r#s#t#@ . . . '#N@u#v#w#x#y#z#A#B#C#~@D#a+@ . . @ V.E#F#G#H#I#J#K#L#M#N#O#>#% . . . ,#t#;#P#Q#R#S#T#U#V#W#X#Y#>#% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % Z#`# $.$+$@$#$$$%$&$*$=$-$@ . . . O@;$>$,$'$)$!$~${$]$^$/$; % . . . @ ($_$:$<$[$}$|$1$2$3$4$5$`@& . . . @ -$6$7$8$9$0$a$b$c$d$e$f$g$% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % -$h$i$j$k$l$m$n$o$p$q$r$($@ . . . s$t$u$v$w$x$y$z$A$B$C$D$-$@ . . . + ($E$F$G$H$I$J$K$L$M$N$m$O$f@. . . @ P$Q$R$S$T$n$U$V$W$X$Y$Z$`$% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@P$ %.%+%@%#%$%%%&%*%=%-%($@ . . . f@O$;%>%,%'%)%!%~%{%]%^%/%f@. . . + O@(%_%:%<%[%}%|%1%2%3%4%5%f@. . . @ ($6%7%8%9%0%a%b%c%d%e%f%P$;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@g%h%i%j%k%l%m%n%o%p%q%r%g%@ . . . f@5%s%t%u%v%w%x%y%z%A%B%C%s$D%. . + s$E%F%G%H%I%J%K%L%M%N%O%Z#f@. . . @ g%P%Q%R%S%T%U%V%W%X%Y%Z%g%;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@g%`% &.&+&@&#&$&%&&&*&=&-&@ . . . f@Z#;&>&,&'&)&!&~&{&]&^&/&f@+ . . + s$(&_&:&<&[&}&|&1&2&3&4&Z# #. . . @ s$5&6&7&8&9&0&a&b&c&d&e&-&;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ s$f&g&h&i&j&k&l&m&n&o&E%f@+ . . . f@Z#p&q&r&s&t&u&v&w&@&x&y&s$D%. . + s$z&A&B&C&[&}&D&E&F&G&0&Z# #. . . @ -&H&I&J&K&9&0&L&M&N&O&`%g%;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ P&Q&R&S&T&U&V&t%W&X&($@ . . . . ;@`$Y&Z&`& *.*.*+*@*#*$*%*f@. . . . f@&***=*-*;*>*,*'*)*!*~*`$;@. . . + s${*]*^*/*T%0&(*_*:*<*[*-&@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . ;@}*|*1*2*3*4*_&5*Z#@ . . . . . . #6*7*8*3*9*9*0*a*A&b*s$+ . . . . + -&c*d*e*f*g*h*i*j*k*l* #. . . . . @ Z#m*n*o*p*q*r*o*s*t*%*;@. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ;@u*v*w*x*y*z*`$@ . . . . . . . . ;@A*q*B*C*C*D*E*F*f@. . . . . . . . s$=&y*G*H*z*I*J*K*;@. . . . . . . + L*M*N*O*P*Q*N*R*}*@ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ -&`$S*`$s$@ . . . . . . . . . . #S*`$`$`$`$`$f@+ . . . . . . . . + s$Z#S*@ ;@T*`$U*. . . . . . . . . @ ($Z#-&+ f@Z#($,#. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . @ ;@U*;@+ . . . . . . . . . . . . ;@U*U*U*U*;@+ . . . . . . . . . . @ #;@. + ;@;@. . . . . . . . . . . @ ;@@ . @ ;@,#. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%D%. . . . D%D%. . . @ @ . . . D%D%. . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%. . . D%D%,#V*U*U*U*;@ #V* #U*,#U* #,#+ D%@ ,#U*@ . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . D%@ @ @ U*W*X*Y*Z*`* =.=+=@= =#=$=Y*Y*%=&=*===*=-=;=@ . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . D%,# #-$@=>=,='=)=!=~={=]=^=/=(=(=)=_=:=<=[=}=|=1=2=3=D%. . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . D%U*W*h#4=5=6=7=8=9=0=a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=3=s=+ . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . @ ($@=>=t=u=v=w=x=y=z=A=B=C=D=E=E=F=G=H=I=J=K=L=M=N=O=P=Q=R=S=T===V*@ . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . D%D%,#,#@ U*U=V=W=X=Y=Z=`= -.-+-@-#-$-%-&-J.;.*-=---;->-g.,-'-)-!-~-{-]-[=^-/-(-_-U*+ . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . D%,#W*W*P$U=-=:-<-[-}-|-1-2-3-4-5-6-7-0 8-9-0-a-b-c-d-$+a ].e-f-l g-h-i-j-k-l-m-n-}=o-p-;=,#D%. . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . D%+ ,#U*W*p-%=Y*q-r-s-t-u-v-w-x-y-z-A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-f Q-R-S-T-U-V-W-X-Y-Z-`-o- ;V*,#,#D%. . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . ,#;=_-.; ;.;+;@;#;$;%;&;*;=;-;;;r >;,;';);!;~;{;];^;/;(;_;:;<;[;};|;1;2;3;4;5;6;, 7;8;,-9;0;a;b;c;d;e;&=f;==,#. . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . + g;h;i;|=j;k;|=l;m;n;o;p;q;r;s;t;t;u;v;w;x;y;z;A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;F b S;T;U;V;W;X;Y;Z;`; >.>+>,#. . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ,#@>#>$>%>&>*>=>->;>>>,>'>T.)>!>~>{>]>^>/>(>_>:><>[>}>|>1>2>3>4>5>6>7>8>9>0>a>b>c>d>e>f>$ g>h>i>j>+*k>l>m>n>R=@;_-,#. . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ,# ;o>p>q>l;r>->s>t>u>v>w>x>y>z>A>B>C>D>E>F>G>H>I>J>K>L>M>N>O>P>Q>R>S>T>U>V>W>X>Y>Z>`> ,.,% +,@,#,$,%,&,Y;*,=,@;*= #D%. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . @ -,;,Z;m;*>>,,,',),!,~,{,],^,/,(,_,:,<,[,},|,1,2,3,4,5,6,7,8,9,0,a,b,c,d,e,f,g,h,i,j,k,l,m,D%. n,o,p,q,r,Y;|=s,%=P$,#. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . @ t,u,v,l;w,x,y,z,A,B,x C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,`, '.'+'@'#'$'%'&'*'='. . -';'>','Z-''.,Y*-=V*+ . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%V*)'u,!'~'{']'^'/'x ('_':'<'['}'I,|'1'2'3'4'5'6'7'8'9'0'a'9,b'c'd'e'9,f' g'h'i'j'',k>k'*=l',#. m'n'o'p')=.,q' ;P$,#+ . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . D%. . . . ,#r's't'u'v'w'x'{,y'z'A'B'C'D'E'F'G'H'I'J'K'L'M'N'O'P'Q'R'S'T'U'Q>V'W'X' Y'Z'`' ).)+)@)#)$)%)D%. &)*)=)-);)s,>)-,;=,#. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . ,#_-,),#. D%_-')))!)~){)i.])^)/)()_):)<)[)})M'|)1)2)3)1'4)5)6)7)I'I' X'8)9)0)R, I'a)b)c)d)e)f)g)h)i)j)+ k)l)m)n)o)p)$>&=W*,#+ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%_-$>q)-=@ U*r)^-s)t)u)3-v)y>w)x)y)z)A)B)C)D)E)E)F)G)H)I)J)K)L)7) M)N)O)P)Q) R)S)T)U)V)W)X)Y)Z)`) !.!+!. @!#!$!%!&!''*!_-s$s=D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%_-(-)'==,#V*@;=!-!;!>!,!~>'!)!!!~!{!]!2)^!/!(!H'_!N)M'6)3):!==+ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%+ X*Q!R!S!T!U!k!V!W!X!Y!J,Z!R'I'I'I'`! ~s!.~+~2) X'P'6)I'@~3)6)#~R'$~N)%~&~*~=~-~%~;~ >~,~'~)~!~~~{~]~^~. /~(~_~:~<~^-[~s=. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ #;,}~|~1~P.2~3~4~5~6~7~8~9~0~J'I'I'O)a~b~c~d~e~f~g~h~i~O'j~k~1'l~m~n~o~p~q~r~s~@~H)I)t~X'm~u~v~w~x~y~z~A~B~. . C~D~E~(=[=F~_-+ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%V*G~Y;H~I~J~K~L~M~N~O~P~Q~R~$~x!S~S~ T~e'U~V~W~X~Y~Z~`~ {.{9,+{j~@{#{${%{&{*{={-{;{>{,{'{X' N'){!{~{{{]{^{/{==. ({_{:{<{[{f!.;U*. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#_-}{|{1{2{3{4{5{v;6{7{_,8{9{0{a{b{c{Z'H)d{U,e{f{g{h{h{Q'i{5'j{k{l{m{n~n{o{p{q{r{s{t{u{v{w{x{y{I'I)z{A{B{C{D{E{F{. G{H{I{J{K{L{ ;;=,#. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . + V**=M{N{O{P{Q{R{S{T{U{V{W{X{Y{Z{`{ ].]Q>+]@]#]$]%].]&]*]=]-];]>],]'])]j~!]~]{]f~]]^]/](]_]:]<][] x!}]|]1]2]3]/{. . 4]5]6]7]8]T=U= #. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . + U*X*9]0]a]b]c]d]e]f]g]h]i]j]k]l]2)q!9)M)m]n]o]p]q]r]q!s]t]u]v]w]x]y]z]A]B]C]D]E]F]G]H]I]J]K]L]M]T~N]O]P]Q]R]S]T]U]+ . V]W]X]Y]v,Z])',)@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#g$`] ^.^+^@^#^$^%^&^*^=^-^;^>^,^P'I):!'^)^!^~^{^=^]^^^/^(^A-d _^} :^9+<^[^}^|^1^2^3^4^5^6^w!I'I'6)6)7^8^9^0^a^b^c^. d^e^f^g^Q=h^o-i^V*. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ g$j^k^l^m^n^o^p^q^r^s^t^u^[!I)v^7)N'N'w^x^y^)^l~z^A^B^);C^9 D^7-E^F^G^H^I^J^K^L^M^N^O^P^Q^u!7)6)u! S~R^S^T^U^V^W^,#. X^Y^Z^h^=,)'.;;=. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#g$`^ /1-./} +/@/#/$/%/a'&/T'I'u!-]*/=/-/;/>/,/z^'/)/!/~/B-i +.0 {/]/^///(/u._/:/f/-=@ . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#h#g/j&h/i/K j/k/l/m/n/N)`!e~3) 6)o/p/>^q/r/,/s/t/u/~/B-v/_^} 8-e G^H^o w/$+x/y/z/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/0/P/. Q/R/ /S/f!T/U/m,,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#V/<-W/X/Y/6 Z/`/ (.(+(q!8,@($~ I'#(N'e'(,('()(!(~({(](^(/(((_(:(<([(}(|(W^. 1(2(3(4(@=f/q)+>@ . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#5(6(7(8(9(0(a(b(c(d(e(f(F/+'.]I' I'K)g(3/j{h(i(j(D^+.k(K 6 l(G b-g d-m(n(o(p(q(r(s(t(u(v(w(x(y(z(A(B(C(D(E(F(G(H(. I(J(K(L(M(P$-=V*. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#N(O(P(D=Q(R(S(T(U(V(W(X(Y(Z(q/:!x! N)`('^+] _@!._n^} 8-F^l(^/+_@_w/$+y ].k.#_$_%_&_*_=_-_;_>_,_'_i+)_!_~_{_]_^_/_. (___:_<_@= #,#@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . s$[_}_|_1_2_H^3_4_5_6_7_8_9_0_l~X'u! 6)O'a_b_c_k(d_:^e 0-G 2 @_w/e_c -(f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z_s=(___A_W=[_P$s$V*,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . U*B_[=Y]7(C_D_o E_F_G_H_I_J_K_L_X'6)x! I'6)M_8)N_O_:^6 P_G^G b-@_Q_e_c M o(f -.R_S_T_U_V_W_X_Y_Z_`_ :.:+:@:o_#:$:%:&:,#I(*:=:-:#=-=P$s$,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . D%==e!;:>:,:<$':4 ):!:~:{:]:^:E]g~u! I'[!/:(:_:::P_0-^/H^=.g w/e_c M o(5 E <:[:}:|:1:2:3:4:5:6:7:8:9:0:a:b:c:d:e:==. f:g:h:g/i:*= #@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,)j:}=k:l:m:n:e_o:p:q:r:s:t:t^T~ I'u!7)r/u:v:w:x:y:[ b-o (/d-$+c M o(5 E z:A:B:C:D:E:F:7:G:H:I:J: :K:L:M:N:O:P:Q:c^. Q/v-R:r-N(W*@ . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,#P$S:T:U:V:W:y X:Y:Z:`: <.<,);=D%. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . D%,#h#`^}<|<1<-(2<3<4<5<6[,['[)[![5 ~[{[][^[/[={([M},}'})}!}~}{}M] x!]}^}/}(}m<1'@~_}:}<}[}}}|}1}2}3}4}5}6}7}8}9}0}a}b}c}d}e}f}g}h}i}j}k}l}/{D%m}n}o}p}q}k'==+ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,#,#@ ;=r}s}t}u}v}w}x}y}z}A}B}C}P'I' D}E}F}G}H}I}J}K}L}P'M}N}O}P}Q}R}S}T}U}V}W}X}Y}Z}`} |.|+|@|#|$|%|&|i[*|^{%). =|-|;|>|k',|,#. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . + ,)-=V*;=`*}<'|)|!|_ 1+~|{|]|^|/|(|I) O'_|:|<|[|}|||1|2|3|4|5|6|7|8|9|0|a|b|c|d|e|f|g|e+h|i|j|k|l|m|n|o|[~p|+ q|r|s|t|u|v|V*. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%+ W*-=W*;=i^w|x|y|z|A|' B|C|D|E|F|G|H|I' u! I|J|K|L|M|N|O|M)P|Q|R|S|T|U|V|W|X|Y|.[Z|`| 1.1+1@1X[#1I)$1%1&1*1=1-1U*. ;1>1,1'1)1v|,)D%. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . @ ;@ #-,.;!1~1{1]1^1b /1(1_1:1<1[1}1I'M]|1I) 11213141e'51I'6171o/819101a1b1c1d1e1X'f1R@g1W[I'h1X[P'i1j1k1l1m1n1,#o1p1q10]r1}{>);=D%. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%,#P$_- ;s1t1u1v1-'* w1x1y1z1A1R'B1C1D1+'Y'E1F1G1H1+[f{D!I1+[J17)P K1L1M1N1O1P1Q1 6)R1S1D!I'I)I)3)T1I!U1@>D%. V1W1X1Y1Z1^-`1_-,#D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%@ ,#;=f!'1 2.2+2@.% @2#2$2%2&2*2=2-2;2P'>2,2'2)2J1I)!2~2{2I).[X[]2^2/2(2_2M1:2<2[2}2|212f1X'2232425262l'. w]72829202a2b2}=c2-=,#. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%@ @ U*T=d2e2f2g28+. &[0/h2i2j2k2l2m2n2o2p2q2r2s2N]P2Q2 ;;@. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . D%@ D%,#R2S2o)T2U2V2W2. r'X2Y2Z2`2J[ 3.3+3@3#3$3%3&3*3=3-3u!I);3>3o/O',3n<'3I')3!3~3{3]3^3/3(3_3u<$):3,#. <3[3}3|3e/ >13h;f/p-W*D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ D%D%,#g;2333435363n,. c^62A~73839303a3&|&1b3c3d3e3f3g3I'I'h3i3j3k3l3m3f~J1n3o3p3q3r3s3t3=1u3v3/{D%. w3x3y3-[z3A3i;)'-=V* #@ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%. . ,#e;B3C3D3E3F3G3. +!$)*|$:H3n|I3J3K3L3M3N3O3P3i3Q3.[4/R3S3T3l3U3V3W3X3Y3Z3`3 4.4+4@4#4c^&[. (_$4%4&4*4=4 ;P$V*@ . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%D%. D%V*-4;4>4,4F!C<-'. D%'4)4!4~4{4{{]4^4/4(4_4:4<4[4}4|414243444546474849404}(a4u3b4c4s=. . d4e4f4g4h48]P$,#+ D%D%. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ ,#,#. . # ;j;n>i4j4k4;'l4. D%r'm4n4o4p4q4.4r4s4t4N/u4v4w4x4y4z4A4B4C4D4E4F4G4S]H4I4e:J4^~. K4L4v1M4N4O4r}i^;=@ D%. . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ ,#+ . . + V*%=P4Q4R4i=S4W]T4U4. . 2=V4W4X4K2Y4Z4`4 5.5+5@5#5$5%5&5*5=5-5;5>5,5'5U1)5n1='. !5<+~5{5]5^5/5(5v|_5W*U*@ . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%D%+ . . @ P$%=:5m><5[5}5|515-'. . ;=25e:#)354555a^6575859505*1a5S] }H4b5a!$)c5d5,#. e5f5Y G2g5h5i5j5>)i^f/-4-= #+ . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ s=,#. + U*W*.;s,[=<~k5l5m5n5o5p5. . ,#K!q5/{r=r5s5t5T]3]H4u5v5#4w5b^U1x5y5+ . . z5A5w'B5C5D5E5F5.,%= ;.;-=V*@ . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . ,#W*V*D%D%D%D%,#;=%=u,G5H5I5J5K5L5M5N5O5. . . U*P5'4+}#4c4Q5c4R5l'D%='@ . . S5T5U5V5W5X5Y5Z5`5 6|=f/q'P$V*,#D%. . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ # #,#@ . . . D%,#_-.6V=+6@6R!#6$6%6;}&6*6;+. . . . D%. . . D%. . . =6-6Q{;6>6,6'6)6!6~6n={6]6)'-=V*,#D%. . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . D%@ ,#,#. . . . . D%U*-=^6/66(}~6](6_6:6<6[6}6|616m'S;263646m'@,566676869606a6b6c6d6&!&>e6'43=V*,#D%. . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . D%D%. . . . . . D%;@V*($`*f6g6h6i6j6k6l6m6n6o6p6q6r6s6C=J(t6u6v6w6x6y6z6A6B6C6D6E6F6G6s=@ D%. . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . D%,#-,Y*H6I6J6K6{=u=L6<<3(=:M6c=N6M6O6P6Q6R6S6T6U6r>*>V6j:p|3=U*,#D%. . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . D%U*V* #s$P$h#+=W6X6J6S/Y6+6Z6Z6+6`6 7`]X6.7[_+7j;$>y5&[,#D%D%. . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%@ ,#;@ #W*-$h#h#`@M(M(`@h#g$-$W*s$P$.6p-_-,#D%. . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%+ . . D%+ @ ,#,#,#,#,#,#+ D%D%D%,#V* #+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%D%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . @ & % . @ & & @ . . . @ & # # # # & @ . . . @ & # # # # f@@ . . . @ & # # # # % @ . . . @ & # # # # % . . . . @ & # # # # % . . . . @ & # # # # % . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . @ $ > ; % & b b # . . @ $ / : : : : b & . . @ $ / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . # >}| z _ <:| z L % @ $ Q-w/2 2 2 =.z L % @ $ -.4 2 2 2 =.@7) % @ $ -.4 2 2 2 =.c _ % @ * E 4 2 2 2 =.y _ % @ * s #7$72 2 %7a , % @ ; &7(/b-2 $7*7O-, % . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . @ $ g_6-=7':o 0 -7':8-6;b 5 ;7>7,7'7'7,7':{/k b )7(^>7'7'7'7,7=-6 k b !7!/>7'7'7'7,7N e L b o(~7{74-'74-]7^7P_) b S -(_7{7]7]7]7:7U!G^, & @ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ # - :^<7O [7}7|71727374 47K 57~.676767772787d-47} u 977.07a7b7O Y/c71 *(d7~.b7a7a7e7f7g7$+1 +.h797b7e7e7i7f7N m(< @.[797e7j7j7k7l7m7z n7v/o797k7k7k7p7f7U!a b & . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ b.6;;7q ).q7h r7l7s72.e <:7 5.t7k7u7v797w7u H^>}x7q y7a7>.97z7A7<7G^z:B7C727k7D7E7F7l7G7*7-.H7l7I7j7P J7K74.]7[ L7M7N7O7p727~.P7Q7(72 &7r7R7S7T727~.!,U7V7*7: # . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ ; 6;d.W7u7X7Y7Z7t7n.i.]+! (/H7`7T4 8.8+8p5A-o(@8#8$8%8&8*8=8S.h.-8;8! >8|7,8'8 8|.)8!8#^k.A@~8P {8]8^8/8|.(8_8^/s +l3q.:8<8k+[8}8(7[ g_|8t718283848W }.V75868# . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ b.a.78889808a8b8c8d857<.e8- s G^l f8g8h8m(z:0+i8j8k8l8m8n8o8[8p8q8r8j., g_z.V7s8t8u8@7<:v8@8w8S.G.F.Y7x8y8z8V7A8L7B8C8D88+a8E8:.F8G8H8&7I8S.z856}7J8z2K8l *7L8# . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ * a.M8N8O8^+P8Q8z2R8C+U+U.t.S8T8U8V8(2W8X8= b Y8Z8`8 9^+.9+9:.@9x'g #9^.{ $9%9&9j<*9#_0+b =9-9z2;98+>9,9j<'9)9!9~9{9:.]9N+^9/9(9_9%9j :96+z2<9r[[9x8B.}9|9n+t.& . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ ^@/@192939495969792{89;+99~ 09a9b9c9u+d9=@e9D.f9g9h9i9h>j93+k9l9]@m9$ $ O+n9o9p9q9r9s9e9D.n7t9u9v949[9w9x9y9z9A9B9C9j0,0'0)0: ## !0~0{0]0^05#/0b+~+(0_0x2:0,@<0[0^0}0<3|01020q930405060708090n9s#00:2a0~#b0c0d0e0f0> % @ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ B@g0h0i0j0k0l0m0n0o0p0q04@.0m+r0s0t0u0v0~9-@.0w0x0y0z0A0B0C0D0E0'0X8^@$ N@F0G0H0|@I0J0.0.0K0L0M0N0s@O0P0|@Q0R0S0T0U0V0W0X0Y0Z0`0 aG0.a+a@a#a$a%aD0&ab|*a=a-aB@% . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ -$:#;a>a,a'a)a!a`0~a{a]a^ab.;$/a(a_a:a#`@RaSaTaUaVaT0t#f@$ P@WaXaYaZa`a b.b+b@b;$N.V/#b$b%b8#&b*bh#>#=b-bia;b>b,b'b)b!b~b{b]b^bia/b(b_b:b#P&hbibjbkblbmb-$ #'#nbobpbqbrbsbtbubvbwbt$>#`@xbybzbAbBbCb>#>#DbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb`b c.c+c@c#c$c%c&c*ch#'#. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + + ($=c-c;c>c,c'c)c!c~c{c]cO$Z#V/^c/c(c_c:c#9c0cacbcccdcecP&Z#fcgchcicjckclcmcncocpcqcy$m)rcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJc5%O@. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + + s$E%KcLcMcNcOcPcQcRcSc4%P&P&C%TcUcVcWcXcYcZcZ#`c d.d+d@d#d$d%d&d*d=d5%P&C%-d;d>d,d'dP%ZcZ#zc)d!d~d{d]d^d/d(d_d:de,e'e)e!e~e{e]e^e/e`$f@. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . f@}*(e_e:e-[f,f'f)f!f~f{fA*]f^f/f(f#f_f:ffifjfkf($ #. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . @ L*lfTe=*mfnfofZef&`$Z#h%pfqfrf,e,esftfd*uf%*Q&vfwfxfxfxfyfzfAf=&%*cfBfCfAeDfAeEfFfGfz*%*E*HfCfIfAeIfJfKfLfF*}*y*MfNfOfPfQfRfSfTfUf}*VfMfWfXfXfXfYfZf=f{*f@@ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . @ L*M*`f g.g+g`e($@ @ @gh%#g$g%g$g gCe[*-&;@%*h%&g*g=g=g g-gb*s$;@%*Q&Qd*g*g*g;gKdr%f@;@&*>g,g*g*g*g;gqd'gf@;@&*~*vd)g!g~g{g]gf&f@;@ZcE*Ze}f*g*g^god/gf@+ + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . @ -&%*(g_gP&f@+ . . @ `$Zc:g(g:g:g%*-&. . @ `$&*:g:g:g(gV/s$. . @ T*Zc:g(g(g(g%*s$. . @ -$Zc(g:g:g(gt$f@. . @ T*/% c #00BBFF", -", c #00B7FF", -"' c #00B3FF", -") c #00B5FF", -"! c #00ADFF", -"~ c #00AFFF", -"{ c #00A9FF", -"] c #00A5FF", -"^ c #00A3FF", -"/ c #009FFF", -"( c #00A1FF", -"_ c #009BFF", -": c #0095FF", -"< c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ % $ ", -" &&*&&&*&&*& = ", -" *********** - ", -" ; ; > ", -" , , , ", -" ' ' ) ", -" ! ~ ~ ", -" { { { ", -" ] ] ^ ", -" / ( / ", -" _ __ ", -" ::::::::<:: ", -" "}; diff --git a/resources/bitmaps/modify_faces.xpm b/resources/bitmaps/modify_faces.xpm deleted file mode 100644 index 1860c82..0000000 --- a/resources/bitmaps/modify_faces.xpm +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * modify_faces_xpm[] = { -"16 16 28 1", -" c None", -". c #00CBEB", -"+ c #00CBED", -"@ c #00C9F1", -"# c #00C9F3", -"$ c #00C7F7", -"% c #00C7F9", -"& c #00C5FD", -"* c #00C5FF", -"= c #00C7FD", -"- c #00C7FF", -"; c #00C1FF", -"> c #00FFFF", -", c #00BDFF", -"' c #00BBFF", -") c #00B7FF", -"! c #00B3FF", -"~ c #00B5FF", -"{ c #00ADFF", -"] c #00AFFF", -"^ c #00A9FF", -"/ c #00A5FF", -"( c #00A3FF", -"_ c #009FFF", -": c #00A1FF", -"< c #009BFF", -"[ c #0095FF", -"} c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ % $ ", -" &&*&=&*&=-= * ", -" ;>>>>>>>>>; ; ", -" ,>>>>>>>>>, ' ", -" )>>>>>>>>>) ) ", -" !>>>>>>>>>! ~ ", -" {>>>>>>>>>] ] ", -" ^>>>>>>>>>^ ^ ", -" />>>>>>>>>/ ( ", -" _>>>>>>>>>: _ ", -" <>>>>>>>>><< ", -" [[[[[[[[}[[ ", -" "}; diff --git a/resources/bitmaps/modify_vertices.xpm b/resources/bitmaps/modify_vertices.xpm deleted file mode 100644 index 11715eb..0000000 --- a/resources/bitmaps/modify_vertices.xpm +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * modify_vertices_xpm[] = { -"16 16 28 1", -" c None", -". c #00CBEB", -"+ c #00CBED", -"@ c #00C9F1", -"# c #00C9F3", -"$ c #00C7F7", -"% c #00FFF9", -"& c #00C5FD", -"* c #00C5FF", -"= c #00C7FD", -"- c #00FFFF", -"; c #00FFFD", -"> c #00C1FF", -", c #00BDFF", -"' c #00BBFF", -") c #00B7FF", -"! c #00B3FF", -"~ c #00B5FF", -"{ c #00ADFF", -"] c #00AFFF", -"^ c #00A9FF", -"/ c #00A5FF", -"( c #00A3FF", -"_ c #009FFF", -": c #00A1FF", -"< c #009BFF", -"[ c #0095FF", -"} c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ %%% $ ", -" &&*&=&*&=-;- * ", -" > --- > ", -" , , ' ", -" ) ) ) ", -" ! ! ~ ", -" { ] ] ", -" ^ ^ ^ ", -" / / ( ", -" _ : _ ", -" < << ", -" [[[[[[[[}[[ ", -" "}; diff --git a/resources/bitmaps/noFalloff.xpm b/resources/bitmaps/noFalloff.xpm deleted file mode 100644 index 7225685..0000000 --- a/resources/bitmaps/noFalloff.xpm +++ /dev/null @@ -1,15 +0,0 @@ -/* XPM */ -static char *noFalloff[] = { -/* columns rows colors chars-per-pixel */ -"64 8 1 1 ", -" c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/notex.tga b/resources/bitmaps/notex.tga deleted file mode 100644 index 594a463ca681da0301b0e9eee0c11f05203d64af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 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 AfdBvi diff --git a/resources/bitmaps/paste.xpm b/resources/bitmaps/paste.xpm deleted file mode 100644 index 3e048d7..0000000 --- a/resources/bitmaps/paste.xpm +++ /dev/null @@ -1,77 +0,0 @@ -/* XPM */ -static char * paste_xpm[] = { -"20 19 55 1", -" c None", -". c #00CBED", -"+ c #00C9F3", -"@ c #00C9F1", -"# c #86FFF1", -"$ c #88FFF3", -"% c #00C9F7", -"& c #0BFFF7", -"* c #0DFFFF", -"= c #0DFFF7", -"- c #00C7F9", -"; c #8CFFF9", -"> c #00C7F7", -", c #8CFFF7", -"' c #0DFFF9", -") c #00C5FD", -"! c #11FFFF", -"~ c #00C5FF", -"{ c #68FFFF", -"] c #00C7FF", -"^ c #00C3FF", -"/ c #0FFFFF", -"( c #8EFFFF", -"_ c #00C1FF", -": c #00BDFF", -"< c #0BFFFF", -"[ c #00BBFF", -"} c #00B7FF", -"| c #07FFFF", -"1 c #09FFFF", -"2 c #00B3FF", -"3 c #05FFFF", -"4 c #84FFFF", -"5 c #86FFFF", -"6 c #00B5FF", -"7 c #00AFFF", -"8 c #03FFFF", -"9 c #01FFFF", -"0 c #80FFFF", -"a c #82FFFF", -"b c #00A9FF", -"c c #00FFFF", -"d c #00ABFF", -"e c #7CFFFF", -"f c #7EFFFF", -"g c #00A5FF", -"h c #7AFFFF", -"i c #009FFF", -"j c #78FFFF", -"k c #00A1FF", -"l c #009BFF", -"m c #72FFFF", -"n c #74FFFF", -"o c #0095FF", -"p c #0097FF", -" ", -" ", -" ", -" .... ", -" ++@++#$++++@ ", -" %&*=-;%>,-*'*- ", -" )!!~{{{{{{]!!) ", -" ^/(____^__^//_ ", -" :<<***<<*<<<<[ ", -" }||1||}}}}}}}} ", -" 233|3324445462 ", -" 788999700aaa707 ", -" bcccccdedddfbdbb ", -" gcccccghhhhhhhhg ", -" icccccijkkkkkiji ", -" llllllmmnmmnmnl ", -" ooopooooop ", -" ", -" "}; diff --git a/resources/bitmaps/patch_bend.xpm b/resources/bitmaps/patch_bend.xpm deleted file mode 100644 index abcf6f5..0000000 --- a/resources/bitmaps/patch_bend.xpm +++ /dev/null @@ -1,56 +0,0 @@ -/* XPM */ -static char * patch_bend_xpm[] = { -"16 15 38 1", -" c None", -". c #00CBE7", -"+ c #00CDE7", -"@ c #00CBED", -"# c #51FFFF", -"$ c #4FFFFF", -"% c #00C9F3", -"& c #53FFFF", -"* c #55FFFF", -"= c #00C9F1", -"- c #00CBF3", -"; c #00C7F7", -"> c #00C7F9", -", c #59FFFF", -"' c #57FFFF", -") c #00C9F9", -"! c #00C7FD", -"~ c #00C5FD", -"{ c #5DFFFF", -"] c #00C3FF", -"^ c #00C1FF", -"/ c #5BFFFF", -"( c #00BDFF", -"_ c #00BBFF", -": c #00B7FF", -"< c #00B9FF", -"[ c #00B5FF", -"} c #00B3FF", -"| c #00AFFF", -"1 c #4DFFFF", -"2 c #00A9FF", -"3 c #00ABFF", -"4 c #4BFFFF", -"5 c #00A5FF", -"6 c #00A3FF", -"7 c #47FFFF", -"8 c #009FFF", -"9 c #00A1FF", -" .++++ ", -" @##$$@@@ ", -" %&**=-&&&% ", -" ;;>>,,,'))> ", -" !~{{!{{{~ ", -" ]^////^ ", -" ( ('''(__ ", -" :<: :*:**: ", -" [ [}###[ ", -" | |$11| ", -" 2 2 34442 ", -" 5555566 5775 ", -" 88 9 999 ", -" ", -" "}; diff --git a/resources/bitmaps/patch_drilldown.xpm b/resources/bitmaps/patch_drilldown.xpm deleted file mode 100644 index 0148477..0000000 --- a/resources/bitmaps/patch_drilldown.xpm +++ /dev/null @@ -1,36 +0,0 @@ -/* XPM */ -static char * patch_drilldown_xpm[] = { -"16 15 18 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #19C7FD", -"$ c #17C1FF", -"% c #00BDFF", -"& c #00B7FF", -"* c #00B3FF", -"= c #00B5FF", -"- c #0BAFFF", -"; c #00A9FF", -"> c #00ABFF", -", c #00A5FF", -"' c #00A3FF", -") c #00A1FF", -"! c #009FFF", -"~ c #009BFF", -" ", -" ... ", -" +++ ", -" @@@ ", -" # ", -" $ ", -" %%% ", -" &&& ", -" **= ", -" - ", -" ;;> ", -" ,', ", -" ))! ", -" ~ ", -" "}; diff --git a/resources/bitmaps/patch_insdel.xpm b/resources/bitmaps/patch_insdel.xpm deleted file mode 100644 index 18ac12c..0000000 --- a/resources/bitmaps/patch_insdel.xpm +++ /dev/null @@ -1,51 +0,0 @@ -/* XPM */ -static char * patch_insdel_xpm[] = { -"16 15 33 1", -" c None", -". c #46E373", -"+ c #45E374", -"@ c #46E374", -"# c #46E473", -"$ c #48E376", -"% c #47E077", -"& c #45DE77", -"* c #46DE77", -"= c #44DB77", -"- c #43DA77", -"; c #42D977", -"> c #42DA77", -", c #47D6FF", -"' c #40D777", -") c #40D677", -"! c #48D7FF", -"~ c #48D6FF", -"{ c #47D7FF", -"] c #3FD477", -"^ c #3FD577", -"/ c #3ED477", -"( c #3DD277", -"_ c #3BCFFF", -": c #3CD0FF", -"< c #3BD077", -"[ c #3BCF77", -"} c #39CDFF", -"| c #39CD77", -"1 c #3ACD77", -"2 c #38CAFF", -"3 c #37CAFF", -"4 c #38CA77", -" ", -" ", -" ", -" ..+@#..+ ", -" $ ", -" % ", -" &*&&& ", -" === ", -" -;; > >;> ", -" ,'')!~!{{{'''!", -" ]]] ]^/ ", -" ( ", -" _ : < [ ", -" } ||1| ", -" 2 3 4 "}; diff --git a/resources/bitmaps/patch_showboundingbox.xpm b/resources/bitmaps/patch_showboundingbox.xpm deleted file mode 100644 index 0c8e9ed..0000000 --- a/resources/bitmaps/patch_showboundingbox.xpm +++ /dev/null @@ -1,67 +0,0 @@ -/* XPM */ -static char * patch_showboundingbox_xpm[] = { -"16 15 49 1", -" c None", -". c #067682", -"+ c #077681", -"@ c #047584", -"# c #08DCF7", -"$ c #9DF1FB", -"% c #08DBF7", -"& c #9CF1FC", -"* c #09DCF6", -"= c #037585", -"- c #9BF0FD", -"; c #04D9FB", -"> c #037485", -", c #017387", -"' c #01D7FE", -") c #99EFFF", -"! c #9AEFFE", -"~ c #007388", -"{ c #007288", -"] c #007188", -"^ c #99EEFF", -"/ c #00D4FF", -"( c #007088", -"_ c #00D2FF", -": c #99EDFF", -"< c #99ECFF", -"[ c #006F88", -"} c #006E88", -"| c #99EBFF", -"1 c #00CEFF", -"2 c #006D88", -"3 c #00CCFF", -"4 c #99EAFF", -"5 c #006B88", -"6 c #99E9FF", -"7 c #00CAFF", -"8 c #006C88", -"9 c #006A88", -"0 c #00C6FF", -"a c #99E8FF", -"b c #006888", -"c c #99E7FF", -"d c #00C4FF", -"e c #006788", -"f c #00C1FF", -"g c #99E6FF", -"h c #00C2FF", -"i c #006688", -"j c #006588", -" ", -" ...+.......... ", -" @#$%&*&#&#&*$@ ", -" =-----------;> ", -" ,')!!!)!,~!)!{ ", -" ]^^^^^{]^^^^/] ", -" (_:::(::::::<[ ", -" }|<|}|||||||1} ", -" 23|42444|44|42 ", -" 56445464444478 ", -" 90aaa99666aa69 ", -" bccccccbbcccdb ", -" efgfgfghchchge ", -" iiiijiiijiijij ", -" "}; diff --git a/resources/bitmaps/patch_weld.xpm b/resources/bitmaps/patch_weld.xpm deleted file mode 100644 index fba2eeb..0000000 --- a/resources/bitmaps/patch_weld.xpm +++ /dev/null @@ -1,57 +0,0 @@ -/* XPM */ -static char * patch_weld_xpm[] = { -"16 15 39 1", -" c None", -". c #84E6F3", -"+ c #84E5F6", -"@ c #83E4F9", -"# c #83E3FC", -"$ c #46E304", -"% c #46E403", -"& c #83E2FF", -"* c #83E2FE", -"= c #48E277", -"- c #83E0FF", -"; c #83E1FF", -"> c #47E177", -", c #47E077", -"' c #83DEFF", -") c #46DE00", -"! c #45DE77", -"~ c #46DE77", -"{ c #45DE00", -"] c #83DCFF", -"^ c #84DBFF", -"/ c #44DB77", -"( c #84D9FF", -"_ c #43D9FF", -": c #42D9FF", -"< c #42DAFF", -"[ c #84D6FF", -"} c #40D600", -"| c #41D7FF", -"1 c #40D7FF", -"2 c #84D4FF", -"3 c #3FD5FF", -"4 c #3FD4FF", -"5 c #84D2FF", -"6 c #3DD2FF", -"7 c #84CFFF", -"8 c #3BD0FF", -"9 c #3CCFFF", -"0 c #84CDFF", -" . ", -" + ", -" @ ", -" ## $ % ", -" & * = ", -" -; >,, ", -" ' ) !~! { ", -" ] ^/ ", -" ( ( _:<:< ", -" [ } ||11 ", -" 2 344 ", -" 5 5 66 6 ", -" 7 8 9 ", -" 0 ", -" "}; diff --git a/resources/bitmaps/patch_wireframe.xpm b/resources/bitmaps/patch_wireframe.xpm deleted file mode 100644 index 90e1168..0000000 --- a/resources/bitmaps/patch_wireframe.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * patch_wireframe_xpm[] = { -"16 15 28 1", -" c None", -". c #027486", -"+ c #017387", -"@ c #9AEFFE", -"# c #007388", -"$ c #007288", -"% c #99EEFF", -"& c #007188", -"* c #007088", -"= c #99EDFF", -"- c #006F88", -"; c #006E88", -"> c #99EBFF", -", c #006D88", -"' c #99EAFF", -") c #006B88", -"! c #99E9FF", -"~ c #006C88", -"{ c #006A88", -"] c #99E8FF", -"^ c #006888", -"/ c #99E7FF", -"( c #006788", -"_ c #99E6FF", -": c #006588", -"< c #99E5FF", -"[ c #006688", -"} c #006488", -" ", -" ", -" ", -" . ", -" +@# ", -" $%%$& ", -" **=*==* ", -" -;;>>;>>;>; ", -" ,>',',',,'>', ", -" )!'~)~!')')'~ ", -" {{]]!{{!!]{ ", -" ^//^^^//^ ", -" ((__((( ", -" :<[ ", -" } "}; diff --git a/resources/bitmaps/popup_selection.xpm b/resources/bitmaps/popup_selection.xpm deleted file mode 100644 index 1b987e1..0000000 --- a/resources/bitmaps/popup_selection.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */ -static char * popup_selection_xpm[] = { -"16 15 23 1", -" c None", -". c #0CDEF3", -"+ c #09DCF6", -"@ c #FFFFFF", -"# c #01D7FE", -"$ c #00D8FF", -"% c #00D7FF", -"& c #00D4FF", -"* c #00D2FF", -"= c #007088", -"- c #006E88", -"; c #00CCFF", -"> c #006D88", -", c #00CDFF", -"' c #00C8FF", -") c #006C88", -"! c #00CAFF", -"~ c #00C1FF", -"{ c #00C2FF", -"] c #000000", -"^ c #11C3FF", -"/ c #11C0FF", -"( c #11C1FF", -" ", -" .. .. .. .. ", -" + ", -" @ ", -" # @ $ % ", -" & @ & ", -" * * ==== ", -" @ --- ", -" ; >> , ", -" ' @) ! ", -" ", -" ", -" ~~ ~~ {{ ]]]", -" ]^^", -" ]/("}; diff --git a/resources/bitmaps/redo.xpm b/resources/bitmaps/redo.xpm deleted file mode 100644 index 435a652..0000000 --- a/resources/bitmaps/redo.xpm +++ /dev/null @@ -1,36 +0,0 @@ -/* XPM */ -static char * redo_xpm[] = { -"16 16 17 1", -" c None", -". c #47E0FF", -"+ c #47E1FF", -"@ c #46DEFF", -"# c #45DEFF", -"$ c #46DDFF", -"% c #43DBFF", -"& c #44DBFF", -"* c #42D9FF", -"= c #42DAFF", -"- c #41D6FF", -"; c #41D7FF", -"> c #40D7FF", -", c #3FD4FF", -"' c #3ED5FF", -") c #3FD5FF", -"! c #3DD2FF", -" ", -" ", -" ", -" ", -" ", -" ...+ ", -" @ @# $ ", -" % & && ", -" * *=* ", -" - ;;>> ", -" , '),,) ", -" ! ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/refresh_models.xpm b/resources/bitmaps/refresh_models.xpm deleted file mode 100644 index 330f96b..0000000 --- a/resources/bitmaps/refresh_models.xpm +++ /dev/null @@ -1,91 +0,0 @@ -/* XPM */ -static char * refresh_models_xpm[] = { -"16 16 72 1", -" c None", -". c #3FCBE7", -"+ c #3FCDE7", -"@ c #41CDE7", -"# c #43CBED", -"$ c #84FFEB", -"% c #84FFED", -"& c #82FFED", -"* c #49C9F3", -"= c #86FFF3", -"- c #86FFF1", -"; c #88FFF3", -"> c #49C9F1", -", c #47C9F1", -"' c #47C9F3", -") c #4BC9F7", -"! c #8CFFF7", -"~ c #4DC7F7", -"{ c #4BC7F9", -"] c #4DC7F9", -"^ c #4DC9F7", -"/ c #8AFFF9", -"( c #8CFFF9", -"_ c #51C5FD", -": c #90FFFD", -"< c #51C7FD", -"[ c #90FFFF", -"} c #4FC3FF", -"| c #4FC1FF", -"1 c #8EFFFF", -"2 c #4BBDFF", -"3 c #8AFFFF", -"4 c #8CFFFF", -"5 c #4BBBFF", -"6 c #49B7FF", -"7 c #47B7FF", -"8 c #49B9FF", -"9 c #88FFFF", -"0 c #86FFFF", -"a c #47B9FF", -"b c #45B3FF", -"c c #84FFFF", -"d c #45B5FF", -"e c #47B3FF", -"f c #47B5FF", -"g c #41AFFF", -"h c #82FFFF", -"i c #80FFFF", -"j c #41ADFF", -"k c #3FA9FF", -"l c #7EFFFF", -"m c #3DA9FF", -"n c #3BA5FF", -"o c #7AFFFF", -"p c #78FFFF", -"q c #3BA3FF", -"r c #399FFF", -"s c #76FFFF", -"t c #37A1FF", -"u c #39A1FF", -"v c #359BFF", -"w c #72FFFF", -"x c #339BFF", -"y c #74FFFF", -"z c #2F97FF", -"A c #2F95FF", -"B c #3195FF", -"C c #70FFFF", -"D c #6EFFFF", -"E c #2D91FF", -"F c #2D8FFF", -"G c #2B91FF", -" .++@@+ .", -" ##$%&&&%## ##", -" *=-;;-;===;>,;'", -" )!~{]^~!/((((!]", -"_:_ _<[:[:[_", -"}| }1111|", -"2 233435", -"67787767 690990a", -"bcc0ccb bdebdbdf", -"ghhiij g", -"kllllk mm", -"noooponq non", -"rsssssspttttusr ", -"vwxxwywwwywwywv ", -"zA ABCDCCCCAB ", -"E FEEGEE "}; diff --git a/resources/bitmaps/scalelockx.xpm b/resources/bitmaps/scalelockx.xpm deleted file mode 100644 index 9a64cfb..0000000 --- a/resources/bitmaps/scalelockx.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelockx[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .oooXXooXXooo. ", -" .oooXXooXXooo. ", -" .ooooXXXXoooo. ", -" .oooooXXooooo. ", -" .ooooXXXXoooo. ", -" .oooXXooXXooo. ", -" .oooXXooXXooo. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/scalelocky.xpm b/resources/bitmaps/scalelocky.xpm deleted file mode 100644 index a8e72ad..0000000 --- a/resources/bitmaps/scalelocky.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelocky[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .ooXXooooXXoo. ", -" .ooXXooooXXoo. ", -" .oooXXooXXooo. ", -" .ooooXXXXoooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/scalelockz.xpm b/resources/bitmaps/scalelockz.xpm deleted file mode 100644 index bb4f5c2..0000000 --- a/resources/bitmaps/scalelockz.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelockz[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .oooXXXXXoooo. ", -" .ooooooXXoooo. ", -" .oooooXXooooo. ", -" .ooooXXoooooo. ", -" .ooooXXoooooo. ", -" .oooXXooooooo. ", -" .oooXXXXXoooo. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/select_additive.xpm b/resources/bitmaps/select_additive.xpm deleted file mode 100644 index 565faac..0000000 --- a/resources/bitmaps/select_additive.xpm +++ /dev/null @@ -1,22 +0,0 @@ -/* XPM */ -static char * select_additive_xpm[] = { -"16 16 3 1", -" c None", -". c #46E3FB", -"+ c #23727E", -" ", -" .............. ", -" . . ", -" . . ", -" . . . ", -" . .+ . ", -" . .+ . ", -" . ....... . ", -" . ++.++++ . ", -" . .+ . ", -" . .+ . ", -" . + . ", -" . . ", -" . . ", -" .............. ", -" "}; diff --git a/resources/bitmaps/select_autoexpand.xpm b/resources/bitmaps/select_autoexpand.xpm deleted file mode 100644 index 4ff8b7a..0000000 --- a/resources/bitmaps/select_autoexpand.xpm +++ /dev/null @@ -1,22 +0,0 @@ -/* XPM */ -static char * select_autoexpand_xpm[] = { -"16 16 3 1", -" c None", -". c #46E3FB", -"+ c #2C909F", -" ", -" .............. ", -" . . ", -" . .. . ", -" . .. +.. . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ......+ . ", -" . ..++..+ . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ++ ++ . ", -" . . ", -" .............. ", -" "}; diff --git a/resources/bitmaps/select_mouseresize.xpm b/resources/bitmaps/select_mouseresize.xpm deleted file mode 100644 index 03fd817..0000000 --- a/resources/bitmaps/select_mouseresize.xpm +++ /dev/null @@ -1,40 +0,0 @@ -/* XPM */ -static char * select_mouseresize_xpm[] = { -"16 16 21 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #00C9F7", -"$ c #00C7F7", -"% c #00C5FD", -"& c #00C5FF", -"* c #00C1FF", -"= c #00BBFF", -"- c #00B7FF", -"; c #00B3FF", -"> c #00B5FF", -", c #00ADFF", -"' c #00A9FF", -") c #00A5FF", -"! c #00A3FF", -"~ c #009FFF", -"{ c #009BFF", -"] c #0095FF", -"^ c #0097FF", -" ", -" ..+ ... ... ", -" @ ", -" # $ ", -" % & ", -" * ", -" = ", -" - - ", -" ; > ", -" , ", -" ' ", -" ) ! ", -" ~ ~ ", -" { ", -" ]]] ]]^ ]]] ", -" "}; diff --git a/resources/bitmaps/select_mouserotate.xpm b/resources/bitmaps/select_mouserotate.xpm deleted file mode 100644 index fa75182..0000000 --- a/resources/bitmaps/select_mouserotate.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char * select_mouserotate_xpm[] = { -"16 16 23 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #00C5FF", -"$ c #00C5FD", -"% c #00C7FD", -"& c #00C1FF", -"* c #00C3FF", -"= c #00BDFF", -"- c #00BBFF", -"; c #00B7FF", -"> c #00B9FF", -", c #00B3FF", -"' c #00B5FF", -") c #00AFFF", -"! c #00A9FF", -"~ c #00ABFF", -"{ c #00A5FF", -"] c #00A3FF", -"^ c #009FFF", -"/ c #009BFF", -"( c #0095FF", -" ", -" .... ", -" ++ ++ ", -" @ + ", -" # #$%$#$%@ @ ", -" & & * & ", -"= = = - ", -"; > ;;;;;>", -", ' , ',' ", -") ) ) ) ", -" ! ! ~ ", -" { {{{{]]{{ ", -" ^ ", -" // ", -" (( ", -" "}; diff --git a/resources/bitmaps/select_mousescale.xpm b/resources/bitmaps/select_mousescale.xpm deleted file mode 100644 index 3bc4f2b..0000000 --- a/resources/bitmaps/select_mousescale.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */ -static char * select_mousescale_xpm[] = { -"16 16 22 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #00C5FF", -"$ c #00C1FF", -"% c #00C3FF", -"& c #00BDFF", -"* c #00B7FF", -"= c #00B9FF", -"- c #00B3FF", -"; c #00B5FF", -"> c #00ADFF", -", c #00AFFF", -"' c #00A9FF", -") c #00ABFF", -"! c #00A5FF", -"~ c #00A3FF", -"{ c #009FFF", -"] c #00A1FF", -"^ c #009BFF", -"/ c #0095FF", -" ", -" ... ... ... ", -" ", -" + @@++@ @ ", -" # @@@@ # ", -" $ %$$ $ ", -" & && ", -" **=***** * * ", -" - - ; ", -" > , , ", -" ' ) ", -" ! ~ ~ ", -" { ] { ", -" ^ ^ ^ ", -" //////// /// ", -" "}; diff --git a/resources/bitmaps/select_mousetranslate.xpm b/resources/bitmaps/select_mousetranslate.xpm deleted file mode 100644 index f2b007e..0000000 --- a/resources/bitmaps/select_mousetranslate.xpm +++ /dev/null @@ -1,31 +0,0 @@ -/* XPM */ -static char * select_mousetranslate_xpm[] = { -"16 16 12 1", -" c None", -". c #000000", -"+ c #01D8FE", -"@ c #00D4FF", -"# c #00D2FF", -"$ c #00D0FF", -"% c #00CEFF", -"& c #00CCFF", -"* c #00CDFF", -"= c #00C9FF", -"- c #00CAFF", -"; c #00C6FF", -" ", -" ....... ", -" . . ", -" . . ", -" . . + ", -" . . @@ ", -" . . ##$ ", -" . .%%%%%%% ", -" . . &*& ", -" . . =- ", -" . . ; ", -" . . ", -" . . ", -" . . ", -" ....... ", -" "}; diff --git a/resources/bitmaps/selection_csgmerge.xpm b/resources/bitmaps/selection_csgmerge.xpm deleted file mode 100644 index 3c4e514..0000000 --- a/resources/bitmaps/selection_csgmerge.xpm +++ /dev/null @@ -1,63 +0,0 @@ -/* XPM */ -static char * selection_csgmerge_xpm[] = { -"16 16 44 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #41FFFF", -"# c #42FFFF", -"$ c #43E4F8", -"% c #44E4F9", -"& c #44FFFF", -"* c #43FFFF", -"= c #46E4FB", -"- c #45E3FC", -"; c #46FFFF", -"> c #48E2FE", -", c #48FFFF", -"' c #47E1FF", -") c #47E0FF", -"! c #47FFFF", -"~ c #45DEFF", -"{ c #46DEFF", -"] c #45FFFF", -"^ c #44DBFF", -"/ c #43DBFF", -"( c #44DCFF", -"_ c #42D9FF", -": c #40D7FF", -"< c #40FFFF", -"[ c #3FD4FF", -"} c #3EFFFF", -"| c #3FFFFF", -"1 c #3DD2FF", -"2 c #3CD2FF", -"3 c #3DFFFF", -"4 c #3CCFFF", -"5 c #3BCFFF", -"6 c #3BFFFF", -"7 c #3ACDFF", -"8 c #39CDFF", -"9 c #39FFFF", -"0 c #3AFFFF", -"a c #37CBFF", -"b c #37CAFF", -"c c #38CAFF", -"d c #38FFFF", -"e c #37FFFF", -" ", -"....+ @@#@@", -"$ % & *", -"= - ; ;", -"> > , , ,", -"' ) !! ! !", -"~ { ]]; ] ]", -"^//(/ &*&& * *", -"_ _ ### # *", -": : << @ <", -"[ [ } | }", -"1 2 3 3", -"4 5 6 6", -"7 8 9 0", -"abcbb deddd", -" "}; diff --git a/resources/bitmaps/selection_csgsubtract.xpm b/resources/bitmaps/selection_csgsubtract.xpm deleted file mode 100644 index 638918f..0000000 --- a/resources/bitmaps/selection_csgsubtract.xpm +++ /dev/null @@ -1,63 +0,0 @@ -/* XPM */ -static char * selection_csgsubtract_xpm[] = { -"16 16 44 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #42E5F6", -"# c #44E4F9", -"$ c #45E4FB", -"% c #46E4FC", -"& c #46E3FB", -"* c #48E2FE", -"= c #47E2FF", -"- c #48E3FE", -"; c #48E2FF", -"> c #48E3FF", -", c #47E0FF", -"' c #47FFFF", -") c #45DEFF", -"! c #46DEFF", -"~ c #46FFFF", -"{ c #45FFFF", -"] c #45DDFF", -"^ c #43DBFF", -"/ c #44FFFF", -"( c #42D9FF", -"_ c #42FFFF", -": c #42DAFF", -"< c #41D6FF", -"[ c #40D7FF", -"} c #40FFFF", -"| c #41FFFF", -"1 c #41D7FF", -"2 c #3FD4FF", -"3 c #3FFFFF", -"4 c #3EFFFF", -"5 c #3ED4FF", -"6 c #3DD2FF", -"7 c #3CD2FF", -"8 c #3DD1FF", -"9 c #3BCFFF", -"0 c #3CCFFF", -"a c #39CDFF", -"b c #3ACDFF", -"c c #37CAFF", -"d c #38CAFF", -"e c #38CBFF", -" ", -" ...+@...@...@. ", -" # # # ", -" $ % & ", -" **=*-*;*->- ; ", -" , , ' ' ', , ", -" ) !~ { { ) ] ", -" ^ ^ / / /^ ^ ", -" ( (_ _ _ ( : ", -" < [ } } |1 [ ", -" 2 23 4 4 2 5 ", -" 6 76688666868 ", -" 9 9 0 ", -" a a b ", -" cdccddcdeddcdd ", -" "}; diff --git a/resources/bitmaps/selection_makehollow.xpm b/resources/bitmaps/selection_makehollow.xpm deleted file mode 100644 index b640ded..0000000 --- a/resources/bitmaps/selection_makehollow.xpm +++ /dev/null @@ -1,58 +0,0 @@ -/* XPM */ -static char * selection_makehollow_xpm[] = { -"16 16 39 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #42E5F6", -"# c #44E4F9", -"$ c #45E4FB", -"% c #46FFFF", -"& c #45FFFF", -"* c #46E3FB", -"= c #48E2FE", -"- c #48FFFF", -"; c #48E2FF", -"> c #47E0FF", -", c #47FFFF", -"' c #45DEFF", -") c #45DDFF", -"! c #43DBFF", -"~ c #44FFFF", -"{ c #42D9FF", -"] c #43FFFF", -"^ c #42DAFF", -"/ c #41D6FF", -"( c #40FFFF", -"_ c #40D7FF", -": c #3FD4FF", -"< c #3FFFFF", -"[ c #3ED4FF", -"} c #3DD2FF", -"| c #3DFFFF", -"1 c #3DD1FF", -"2 c #3BCFFF", -"3 c #3BFFFF", -"4 c #3CFFFF", -"5 c #3CCFFF", -"6 c #39CDFF", -"7 c #3ACDFF", -"8 c #37CAFF", -"9 c #38CAFF", -"0 c #38CBFF", -" ", -" ...+@...@...@. ", -" # # ", -" $ %& %% &% % * ", -" = - ; ", -" > , > ", -" ' % & ) ", -" ! ~ ! ", -" { ] ^ ", -" / ( ( _ ", -" : < [ ", -" } | 1 ", -" 2 3 33 33 34 5 ", -" 6 7 ", -" 89889989099899 ", -" "}; diff --git a/resources/bitmaps/selection_makeroom.xpm b/resources/bitmaps/selection_makeroom.xpm deleted file mode 100644 index dad129e..0000000 --- a/resources/bitmaps/selection_makeroom.xpm +++ /dev/null @@ -1,57 +0,0 @@ -/* XPM */ -static char * selection_makeroom_xpm[] = { -"16 16 38 1", -" c None", -". c #41FFFF", -"+ c #42FFFF", -"@ c #44FFFF", -"# c #45FFFF", -"$ c #46E3FB", -"% c #45E3FC", -"& c #46E3FC", -"* c #46E4FB", -"= c #46E4FC", -"- c #47E2FF", -"; c #48E3FF", -"> c #48FFFF", -", c #47FFFF", -"' c #47E0FF", -") c #46DEFF", -"! c #45DEFF", -"~ c #43FFFF", -"{ c #44DCFF", -"] c #44DBFF", -"^ c #43DAFF", -"/ c #42DAFF", -"( c #40D7FF", -"_ c #40FFFF", -": c #3FFFFF", -"< c #3FD4FF", -"[ c #3EFFFF", -"} c #3DFFFF", -"| c #3DD2FF", -"1 c #3DD1FF", -"2 c #3BCFFF", -"3 c #3CD0FF", -"4 c #3BD0FF", -"5 c #3CFFFF", -"6 c #39FFFF", -"7 c #3AFFFF", -"8 c #37FFFF", -"9 c #38FFFF", -" ", -" ... +.. +.. +. ", -" @ @ ", -" # $%&*$$%==& ", -" - ; > ", -" , ' ' , ", -" # ) ! # ", -" ~ { ] ", -" ^ / + ", -" . ( ( _ ", -" : < < [ ", -" } | 1 ", -" 2222344443 5 ", -" 6 7 ", -" 89 899 999 899 ", -" "}; diff --git a/resources/bitmaps/selection_selectcompletetall.xpm b/resources/bitmaps/selection_selectcompletetall.xpm deleted file mode 100644 index 841c164..0000000 --- a/resources/bitmaps/selection_selectcompletetall.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * selection_selectcompletetall_xpm[] = { -"16 16 27 1", -" c None", -". c #09A7B7", -"+ c #0AA7B6", -"@ c #06A5BA", -"# c #04A5BC", -"$ c #04A4BC", -"% c #01A2BF", -"& c #00A2C0", -"* c #00A0C0", -"= c #00A1C0", -"- c #009EC0", -"; c #009DC0", -"> c #009BC0", -", c #0099C0", -"' c #009AC0", -") c #0097C0", -"! c #0098C0", -"~ c #0095C0", -"{ c #0096C0", -"] c #0093C0", -"^ c #0094C0", -"/ c #0092C0", -"( c #0091C0", -"_ c #0090C0", -": c #008FC0", -"< c #008DC0", -"[ c #008EC0", -" ", -" ...+.......... ", -" @ @ ", -" # $ ", -" % & ", -" *=****=**=**** ", -" - - - ; ", -" > > >>>> > > ", -" , , , ' , ' ", -" ) ! ! ! ! ! ", -" ~ ~ { { ~ ~ ", -" ] ^ ] ] ] / ", -" ( ( ( / / ( ", -" _ _ _ : _ : ", -" <<<< <<<[ <<<< ", -" "}; diff --git a/resources/bitmaps/selection_selectinside.xpm b/resources/bitmaps/selection_selectinside.xpm deleted file mode 100644 index 2efef7f..0000000 --- a/resources/bitmaps/selection_selectinside.xpm +++ /dev/null @@ -1,73 +0,0 @@ -/* XPM */ -static char * selection_selectinside_xpm[] = { -"16 16 54 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #41E5F6", -"$ c #42E5F6", -"% c #C9E4F9", -"& c #44E4F9", -"* c #C9E4FB", -"= c #CAE3FB", -"- c #C9E3FC", -"; c #CAE3FC", -"> c #CAE4FB", -", c #46E4FC", -"' c #46E3FB", -") c #CAE2FE", -"! c #CAE2FF", -"~ c #48E3FE", -"{ c #48E2FF", -"] c #CAE0FF", -"^ c #CAE1FF", -"/ c #47E0FF", -"( c #C9DEFF", -"_ c #CADEFF", -": c #45DEFF", -"< c #45DDFF", -"[ c #C9DBFF", -"} c #C9DCFF", -"| c #43DBFF", -"1 c #C9DAFF", -"2 c #42D9FF", -"3 c #42DAFF", -"4 c #C8D6FF", -"5 c #C8D7FF", -"6 c #41D7FF", -"7 c #40D7FF", -"8 c #C8D4FF", -"9 c #C8D5FF", -"0 c #3FD4FF", -"a c #3ED4FF", -"b c #C7D2FF", -"c c #3DD2FF", -"d c #3DD1FF", -"e c #C7CFFF", -"f c #C7D0FF", -"g c #3BD0FF", -"h c #3CCFFF", -"i c #C7CDFF", -"j c #39CDFF", -"k c #3ACDFF", -"l c #C6CAFF", -"m c #C6CBFF", -"n c #38CAFF", -"o c #37CAFF", -" ", -" .. +@ .. ##$# ", -" % & & ", -" * =-;>= - , ' ", -" ) ! ! ~ { ", -" ] ^ ] / / ", -" ( _ ( ( : < ", -" [ }[[[[ | | ", -" 1 2 3 ", -" 4 5545 5 6 7 ", -" 8 8 9 0 a ", -" b b b c d ", -" e eeee f g h ", -" i j k ", -" ll ll lm nonn ", -" "}; diff --git a/resources/bitmaps/selection_selectpartialtall.xpm b/resources/bitmaps/selection_selectpartialtall.xpm deleted file mode 100644 index 47067ff..0000000 --- a/resources/bitmaps/selection_selectpartialtall.xpm +++ /dev/null @@ -1,32 +0,0 @@ -/* XPM */ -static char * selection_selectpartialtall_xpm[] = { -"16 16 13 1", -" c None", -". c #000000", -"+ c #01A2BF", -"@ c #00A0C0", -"# c #009EC0", -"$ c #009BC0", -"% c #0099C0", -"& c #0097C0", -"* c #0098C0", -"= c #0095C0", -"- c #0096C0", -"; c #0093C0", -"> c #0092C0", -" ", -" ...... ....... ", -" . . . . ", -" . . . . ", -" + + + . ", -" @ @ @ . ", -" # # # . ", -" $ $ $$$$$.. ", -" % % ", -" & * *****.. ", -" = - - . ", -" ; ; > . ", -" . . . . ", -" . . . . ", -" ...... ....... ", -" "}; diff --git a/resources/bitmaps/selection_selecttouching.xpm b/resources/bitmaps/selection_selecttouching.xpm deleted file mode 100644 index d32bf3a..0000000 --- a/resources/bitmaps/selection_selecttouching.xpm +++ /dev/null @@ -1,65 +0,0 @@ -/* XPM */ -static char * selection_selecttouching_xpm[] = { -"16 16 46 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #C9E4F9", -"$ c #C9E4FB", -"% c #CAE3FB", -"& c #CAE2FE", -"* c #CAE2FF", -"= c #CAE3FE", -"- c #CAE3FF", -"; c #CAE0FF", -"> c #45DEFF", -", c #46DEFF", -"' c #C9DEFF", -") c #46DDFF", -"! c #45DDFF", -"~ c #43DBFF", -"{ c #C9DBFF", -"] c #42D9FF", -"^ c #C9D9FF", -"/ c #C9DAFF", -"( c #42DAFF", -"_ c #41D6FF", -": c #40D7FF", -"< c #C8D7FF", -"[ c #41D7FF", -"} c #3FD4FF", -"| c #C8D5FF", -"1 c #3ED4FF", -"2 c #3DD2FF", -"3 c #3CD2FF", -"4 c #C7D2FF", -"5 c #3DD1FF", -"6 c #3BCFFF", -"7 c #C7CFFF", -"8 c #C7D0FF", -"9 c #3BD0FF", -"0 c #3CCFFF", -"a c #39CDFF", -"b c #C7CDFF", -"c c #3ACDFF", -"d c #37CAFF", -"e c #38CAFF", -"f c #C6CAFF", -"g c #C6CBFF", -" ", -" ...+@...@...@. ", -" # # ", -" $ % ", -" &&*&=&*&=-=-&* ", -" ; ; ", -" >>,, ' ' >>)! ", -" ~ ~ { { ~ ~ ", -" ] ] ^ / ] ( ", -" _ : < < [ : ", -" } } | | } 1 ", -" 2 3 4 4 2 5 ", -" 6 6 7 8 9 0 ", -" a a b b a c ", -" dedd fffg edee ", -" "}; diff --git a/resources/bitmaps/shadernotex.tga b/resources/bitmaps/shadernotex.tga deleted file mode 100644 index a666c7b93883b96b63795adfa107dbc2eb17580c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4494 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 diff --git a/resources/bitmaps/side_clipper.xpm b/resources/bitmaps/side_clipper.xpm deleted file mode 100644 index bcb87e1..0000000 --- a/resources/bitmaps/side_clipper.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char *side_clipper[] = { -/* columns rows colors chars-per-pixel */ -"40 32 7 1 ", -" c None", -". c black", -"X c #800000", -"o c red", -"O c #008000", -"+ c green", -"@ c #808080", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" +++++X ", -" ++++++XoXX ", -" +++++++oXoXXXX ", -" ++++++XoXoXoXXXX ", -" OOOOO@oXoXoXoXXXX ", -" OOOOOO@oXoXoXXXXXX ", -" OOOOOOO@oXoXoXXXXXX ", -" OOOOOOOO@oXoXXXXXX@ ", -" OOOOOOOOO@oXoXXXX@@ ", -" OOOOOOOOO@oXoXX@@@ ", -" OOOOOOOOOO@oXX@@@. ", -" OOOOOOOOOOO@o@@@@ ", -" OOOOOOOOOOOO@@@@@ ", -" OOOOOOOOOOOO@@@@ ", -" OOOOOOOOOOO@@@ ", -" OOOOOOOOOO@@@ ", -" OOOOOOO@@ ", -" OOOO@ ", -" OO ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_cut.png b/resources/bitmaps/side_cut.png deleted file mode 100644 index c04d87f7f79e19e01c19a33376c94aabc70bb3bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8924 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 diff --git a/resources/bitmaps/side_edges.xpm b/resources/bitmaps/side_edges.xpm deleted file mode 100644 index 12ed1df..0000000 --- a/resources/bitmaps/side_edges.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * side_edges_xpm[] = { -"19 16 26 1", -" c None", -". c #FFFFFF", -"+ c #C0C0C0", -"@ c #000000", -"# c #808080", -"$ c #00D8FF", -"% c #006A80", -"& c #006B80", -"* c #00CEFF", -"= c #006780", -"- c #00CBFF", -"; c #00CCFF", -"> c #006480", -", c #00C6FF", -"' c #00C7FF", -") c #006380", -"! c #006280", -"~ c #00C4FF", -"{ c #00C3FF", -"] c #006080", -"^ c #00BEFF", -"/ c #005E80", -"( c #005B80", -"_ c #00B6FF", -": c #005980", -"< c #005880", -" . . ", -" .....+...@@ ", -"#........@@@ ", -"######..+@@@ ", -" #####.#@$@@ ", -" ####.##@%&@ ", -" #######@@**=@ ", -" ##.####@@-;;=@ ", -" #######@@>,',)@ ", -" #######@@ !~{@ ", -" #######@@ ]^]@ ", -" ####@ /// ", -" # (_(@ ", -" :::@", -" <@@", -" @ "}; diff --git a/resources/bitmaps/side_entities.png b/resources/bitmaps/side_entities.png deleted file mode 100644 index 644dae50c9613a152ef3531290ded5aad7ecdbb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7431 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 diff --git a/resources/bitmaps/side_entities.xpm b/resources/bitmaps/side_entities.xpm deleted file mode 100644 index adf3bea..0000000 --- a/resources/bitmaps/side_entities.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char *side_entities[] = { -/* columns rows colors chars-per-pixel */ -"40 32 7 1 ", -" c None", -". c black", -"X c #0C0C0C", -"o c #808080", -"O c #C0C0C0", -"+ c #F3F3F3", -"@ c white", -/* pixels */ -" ", -" ", -" ", -" ", -" @ ", -" @ @ ", -" @ @O@O@ooo ", -" @@O@O@Oo.oo ", -" @@@@@OOoo.oo ", -" @@@@OOOOo..o ", -" O@@@OOOOo..o ", -" @@@@OOOOo..o ", -" @@OOO@OOOo..o ", -" @OOOOO@Oo...o ", -" @ OOOOOO@O..oo ", -" @ OOOooo@o.o ", -" @ Oooo.oOo ", -" ooo..o o ", -" Oo...o o ", -" Ooo..o ", -" OOoooo ", -" OOOo.. ", -" @@@OOO.. ", -" OOoo.. ", -" O@@Ooo.. ", -" OOoo.o ", -" @ o ", -" X X X ", -" + + + ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_entspec.png b/resources/bitmaps/side_entspec.png deleted file mode 100644 index 98fcf2083658f7f77828087b67cd5d818f63ff29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8838 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 T`uW+>Z c #007280", -", c #006C80", -"' c #006D80", -") c #00D8FF", -"! c #000000", -"~ c #006A80", -"{ c #006B80", -"] c #006780", -"^ c #006880", -"/ c #00CEFF", -"( c #006680", -"_ c #00CBFF", -": c #00CCFF", -"< c #006480", -"[ c #006380", -"} c #00C6FF", -"| c #00C7FF", -"1 c #006280", -"2 c #00C4FF", -"3 c #00C3FF", -"4 c #006080", -"5 c #00BEFF", -"6 c #005E80", -"7 c #005B80", -"8 c #00B6FF", -"9 c #005980", -"0 c #005880", -" .++..+.+ ", -"@@@#$@@@@@%% ", -"&&*&===--%%% ", -";;>;>;>;%%%% ", -",,,,,',)!%%% ", -"~~{{~~~~{!%% ", -" ]]]^]]]//]! ", -" (((](((_::]! ", -" <[[[[<<<}|}[! ", -" 11111111123! ", -" 444444%454! ", -" 6666 666 ", -" 787! ", -" 999!", -" 0!!", -" ! "}; diff --git a/resources/bitmaps/side_find.xpm b/resources/bitmaps/side_find.xpm deleted file mode 100644 index 2e5ef63..0000000 --- a/resources/bitmaps/side_find.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_find[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #800000", -"o c red", -"O c #808000", -"+ c #808080", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" oooX+ ", -" ooXXooX+ ", -" oXXooXXoX+ ", -" XoooooXXoX ", -" oXoooooXXoX+ ", -" o.ooooXXXoo. ", -" oXoooXXX.Xo+ ", -" +XooXoXX+Xo. ", -" .XXoXXX.OXX ", -" XXoXXX..oX+ ", -" o.XXX+.+oX ", -" X.X+.+oX+ ", -" oooooXX.+ ", -" oXXoX.+ ", -" XoX.+ ", -" XoX. ", -" ooX.+ ", -" XoX.. ", -" XoX+ ", -" oX+ ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_move.png b/resources/bitmaps/side_move.png deleted file mode 100644 index 8a5a7a26a6214b6052920a766fb9d1b56b2d803a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7217 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 diff --git a/resources/bitmaps/side_patch.png b/resources/bitmaps/side_patch.png deleted file mode 100644 index 51ca2f236844e92db31c0433f18270ff00f1098e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7307 zcmeHKXH=7E(+(mZO(a;C-=-;Gjq+{_nAA&(%f{L$UYGe z2(%4vW^|JG3toSO1$o~r4rd+&+VY5FZOcAM^Z_%y7%o�L=Dd0${+G>H-4!zAa0m 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 c #670000", -", c #690000", -"< c #740000", -"1 c #7F0000", -"2 c #7F0100", -"3 c #7F0001", -"4 c #7F0101", -"5 c #171B42", -"6 c #1E235A", -"7 c #1E245B", -"8 c #232968", -"9 c #232969", -"0 c #242A6B", -"q c #242A6C", -"w c #262D72", -"e c #272D74", -"r c #2E3477", -"t c #29307B", -"y c #29317C", -"u c #800100", -"i c #800001", -"p c #800101", -"a c #820202", -"s c #8C0C0C", -"d c #8D0E0C", -"f c #8D0C0E", -"g c #8D0E0E", -"h c #981919", -"j c #991919", -"k c #981A19", -"l c #991A19", -"z c #98191A", -"x c #99191A", -"c c #981A1A", -"v c #991A1A", -"b c #9F2420", -"n c #9F2421", -"m c #A12420", -"M c #A12421", -"N c #A42424", -"B c #AC302D", -"V c #AD312E", -"C c #B03131", -"Z c #B13131", -"A c #B33331", -"S c #B33133", -"D c #B13333", -"F c #B33333", -"G c #B73C38", -"H c #B93D3A", -"J c #C44846", -"K c #D05452", -"L c #DC5F5C", -"P c #DD5F5C", -"I c #DC5F5D", -"U c #DC615C", -"Y c #DD615C", -"T c #DE625E", -"R c #E76B69", -"E c #EA6D6A", -"W c #F47876", -"Q c #F47976", -"! c #F47877", -"~ c #F67876", -"^ c #2C3485", -"/ c #2D3586", -"( c #2E3689", -") c #2E368B", -"_ c #323983", -"` c #30388F", -"' c #313A93", -"] c #323A95", -"[ c #323B96", -"{ c #383F91", -"} c #333D9A", -"| c #343D9C", -" . c #3E4492", -".. c #4C52A5", -"X. c #565CB1", -"o. c #6B70B7", -"O. c #7B7FBA", -"+. c #4550C1", -"@. c #4651C1", -"#. c #4E58C4", -"$. c #4F59C4", -"%. c #535DC6", -"&. c #606ACA", -"*. c #7980CB", -"=. c #7F86D4", -"-. c #FF8482", -";. c #FF8582", -":. c #FF8584", -">. c #878DD0", -",. c #8189D5", -"<. c #838BD6", -"1. c #868DD7", -"2. c #8990D8", -"3. c #8A91D8", -"4. c #8B92D8", -"5. c #9198DA", -"6. c #9399DB", -"7. c #989EDD", -"8. c #F3F3F3", -/* pixels */ -" ", -" ", -" D * ", -" D :.N W B - m * ", -" D -.N W k E g T a K < J , H ; B = b * ", -" r D -.N W j E g T a K < J , H ; C = m * ", -" .O D :.N W j E g T a K < J , H : B = b * ", -" O & _ S -.N W j E f T a K < J , H ; C = m * ", -" ..X 7 q Z -.N W k E g T 1 K < J , H : B = m * ", -" @ + e y { Z -.N ! k E f T 1 K < J , H : B = b * ", -" X.X 6 9 ' } D -.N ~ k E f T a K < J , H ; B = b * ", -" $ O ^ w ) $.*. Z -.N W x E g T 1 K < J , H : B = b * ", -" o.O & 9 ] | %.2. D -.N W k E g T 1 K < J , H ; B = b * ", -" 5 X ^ w ` +.=.=.1. D -.N W k E g T 1 K < J , H ; B = m * ", -" O.O & 9 t ) #.=.2.6. C -.N W k E g L 1 K < J , H ; B = m * ", -" # X 6 9 ` X.&.5.2.7. C -.N W k E g L a K < J , H ; C = b * ", -" + + e y ^ $.,.2.6.7. D -.N W k E g L a K < J , H ; B = b * ", -" q ] | &.6.2. C -.N W x E f L 1 K < J , H ; B = b * ", -" C -.N W k E s P a K < J , H ; B = m * ", -" C -.N W k E s P 1 K < J , G ; B = b * ", -" C -.N W k E s L 1 K < J , G ; B = m * ", -" C -.N W k E s T 1 K < J , G ; B = m * ", -" D -.N W h R s L 1 K < J , G ; B = m * ", -" C -.N W h R s U 1 K < J , G : B = b * ", -" -.N W k R s L 1 K < J > G : B = m ", -" k R s L a K < J > G : ", -" ", -" . . . ", -" 8. 8. 8. ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_patchspec.png b/resources/bitmaps/side_patchspec.png deleted file mode 100644 index ef83a3ae8c14d6dd5d1a92e834ac23f332f3fcae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8332 zcmeHqc{r49^#9mp$xxXEkYqnD6(%^lA$cA$lfMf zOqNP|$&!kMknkPe-tGE*|9P+L_xw4ySp0j+;IiLGH_jR8H3o`?54j~Qz0Kjcz zsB1;P1NSa=R{DQHXy_^czy%1kaiCbCgMnm!Up&DF2c(=QkGWPZ5M z9lN`7So0z~ze`Hjn#N@N({(oE?8d->DZiNpD=Q-x5FzRkCcX zA8sV5*b(xsecJgrH(wi)GG|cW=C?i58n&x_Utr_lIxb?{!>=%4*Jad`e>ZeTW$;rs zynl82C{<&9YjkT{(4uEOxe*3(B5`lD~aZG1!`Lm~$5y>z$j<8;J#Q_%++>s=AM zn4;C49qmt_T1S1?yTXJv>q@@C>ch|SeN9ma+v#3-SO57@e;4H5jj@1G)wS0>$mtG} zSN2ftp?R3gniE)nRzsHfpkqC-WH2Xx16q{%}H$Y>8{X z&+}5V-}m{TmbhEzDY@u3-_BmqS{YHA_{uV2K9Dgb*t_y%Yg*IoXU0Hk^mkRCM{PaA zawC#Q;^ez-)JvG3j-TWyhb|oK-r-)I6O&MFFA}}MDePn4c6ok5t3e>i^Gf8*p<1IT{B&uRRG(ABxijL9v1QjX#>p?lpH?Gh^3K#exNhO` zGTj(bMjNW4y}v`Cc4NSeBO^B&VE)rzo*beEek^`kqp|k(Ozk7?4@y&mY5Jl#+RO6Z z_fpa7!@c#rs5jp@WvKTlW!LQ;0~?cRL1TWO%+!|ZK9PJ!MD5z@zUM#C!uM%aKNpup z9Ng>^Y6^(t{;ki9hKPYBh(4)@MHM|pG$*E7COx3bz8$nI?v#D?Ec@NDn2!4`^WS|J zHE(Q5`a&{y6X2Wuc}fdAV!g=HMd1Lg^II(5!|5G}qTkQvHr`Myn4W4r;R2 zNTsb;htV3x+y*Dg!PTramb_(5Fcx{p6|sl*a5b)o)TF@BBhW`A!xcWA7tP6cf?b47 ziS;kkKX0idial-)<5FBJOzQN0k&;A7T{(Z4)o+&~SsQoXElIIHd06M_h{0#?>Icnw zdSB*{r$>`Y8cC}{UoJ+UJ=ykSWE>xln_0*4W06NRM$t188cB0m42N0L%GCF=8 zM|-FHhbD%mDTF0kal;4}J*UX0} zA7|)oTk%DM%bx!wHD5k8%h30d^xI<*oR%J%=Va$MqURlgW}kMZqjuV_5sa|ipDzv^ zprP5qwIxR~o*uySr^wzl`KY~i@e1F|G9pK^Q5qRiZ5-L^y3{ks`Qo{xRT7l^F;+cA zGW66)6d4#~zr|zE+X*VFd2GBA*e%gVO{+~%{>rSJnE9>JkXz*Nj;#UkHM5x0p_>B* zX~sD3q!BVAyHYX8lNNE>iD!uK4%f$*Aj6aQ$`GEy8%r!MP54JS38M*)w{;o|Pi2o) zEZv9a*g9W3PQ4nM>Zw!NIc8W=w9zu+@>9TYrPDb0NJQg zwe@6cp55x&nFp!YGpPKJNE@b>xxU`P%{9!@xqPD@z(B3L+6* z@+1y~RU|Wc;TT?5{wC*W5r=cvYc@Sy{*P)!4Z!DC<~TTY;M05AOWy2dVh(De>+-x7 z%RW`q4;d^oH7%}uUO%F2S?d%X>O0QK|D=7sJ}12hG#Ovt(Qlp|UDhnF>A>DC$|(-( zHMPB;HQAJ;U=^A>oI<*r0<95yIpL$7y~H&-u$pQQSVl&E<5&kJzpuGgkhdP1`c)i5 z=2Ft}K3J+^wIFNU{}#|Fof*!oKWcwn)X4jAIFl(%?t0hkI$N)^b42D^iKuBBEV$#q zh+(~qfc@}-2`zW^RGsJ4K{ZY{Zfx$GQG$%%+PS%fADgBuqr4Xa^SJFU&2M?!GcyI~ zuoT`AtS(9q0fME(n`O6*PxPOP9+!q?2$H!LU84O;)KF{H0vrXp-tBi~>e^BVMTKxp z40zUCcI^h(SHU7JlLq7jmv+q4CB~O`=Et7(cH3st>S6F6&ac=L3yCaO*{2<%9W}W# zOCDOV2HpcFxLO_k6n~~u{zr&cCh@vuExx#$^h5Bs)cwYL z7Zwg=qDq>oev56Z&(9SY=M!RD7VBS}a|~(Hg+vBS`36Q_suShqOyn{n+)R&~6@KCJ z87B$4dQuQBvY-2-i=)dNm$bcNxx1y7uB+Ris8q`!upJg~1_JW^zO)d7W zZOLa(-sV(kNIC%;$-KPOs`McFJt=RnM}Cwc4L=j-*0}k;s<1z{=GL7I;#1pO45KP> zv6!`4bgNX=GE8;5b`oHtwsa-hs-cA# zcxtu(=fKF0_N`rAg6wJCRccV_;Zq4W>WDl_%%1T*AH^1vloy`{D@fKpksT=^b za|l1_PPuG(TUCT{{t3puV~oU5#z*j5)(HD z=}AO=M6OsDkIZ}7)lR+{S^APB-3dmfu#!2g!W_C-AqVYlFCw zU-I9~iSO2>oYTmf|3KfwR|PPo5nh@WSHpmg6;o+Kk1CwKMl~g@D^3cDk?)K}W~VC= zS$kenMvW*N-?PeuqkoJAtz9@6wWY$yW!TtpU`DVwiFY>gXI{`VKqb<7DO5aiDE!38 z2FMd#tb91O@Kv$HL*8DQ*0(gDXWbr)kZEIGu3{b&CPd3g)l4~?QcuH_GSv$oROc?g z9lQVK2FD@29^4u_#l~RUr${1aqPSx_Vk$d8GDEOG|HT+J7mgf)yeZZ-K?_IYpPjTN zow=T%h<|yE+hs}QH1{z(_3UIU`9546u`-QG{XDVL7EerYIv_F|!xUu3?l8|A>bgvj zOMKO^c%b??81G`%`v;LYTB zC}D{;GhWh@+czQJ#N?H6nDLpw-ciel$9cQ0=nK0+yOgLlB=6Q_{li_x@J*>><>{F3 z002WQK}W~JNJr<7S%5wPIBHnfE*!ai5Yqn;b)Vznd!G2*+>DYd*FxN^y!fVLUTh(j^1C9|8MGhu zD&Lkk==G3To^b${>&&N9JFgutn-ZDr_@w$o+56_!MZWi2u1TJolUo66Rp+lTFr3{nGP3IGn-~+*JQE} zec^VCX}Iv_sFTww`}`YLNR4w&9h=J{AjbTXPfyL^oBSLs@3)g$W!SjhGHTp@_cmt^ z5dlzCzD?sMli8Dw$b|LHO-y_V*jhIWh}6;y_fMZ~@-(B*Y(fP3Z02BUg2MO`A!w|x z2M!WKB-3X%06<+Ugp9^`<0wE6oF{>#0a|Kq0|5zG4UoNxDb$p#gYzO7hWg{IL(Ob3 zq23rI7Nn)gp&o*w0}yc(G%$qdLkd8JXn^){QS|3Mu>uIVZ$k0b06Cai0Cjx*aX@8= zG6V|N3n2t4f;2gR>i$?f%1T%N7X!NI|hU?qsJzo!BWi9{+u6%`Z} z!E_67zz9FcAsK#vOhM@R!BQ;R=6_9*Zq5Xt*qbh7_pNg?3>BI_Ty?P>PQ z`FkRC_djv}Vf{z#`^I!DQ&W_#FD7s=JtJKW&|Z8L))zy-qV^wEacE_XGEx| zWn~;5?4gRlg7FwMLJ0=Lp^-Sm-=K_00TeU|gWH3mgF^^(9JmKu2@gjg>E3u4SQ)K~ z1$%g?V(2)kDymQwILrg9`Zox3e*(QL(LR6AY7YuaheE&hpuLoUd!GC44OIVqQ49$Ibc^$Q9sjH6 zt#N+8zy1CR_z?D0K;VAcqR^P%g9M<1aM=AobidzK7%w!*6G#8Pe>Kz}a>Dl`BcX~g7)A+$#{3gKz!y&mM*HJVd(tbVS3_^0{c3>H z`&7#O(>mA-x5pD53k+2SL*X`1BnpN=DZ%BSiYO=)r0}a?g}tx(kBZe5{vS@%_YMBG z4bc65m(jNu`fjE0=XUjrvppLB4}ZVb;{PxL9s0i@|BB!L==zVYf5pJRGXAf-{-f(( zG4QX9|Ld;*Z*+0|HSpj_^ixnUeVoZ(98;x_LaZKV40QL0BEY6j^9B0T0kWZE0001y z*t-})%Cv&$LNU0^fWts~{D zesa!Czy*f>@#Aj20#TO~nj(aD&-)b|T;;Oh(-i>w71IP5Od`J2EF$GH-^Kg25#ND| zB-Zo*OV)1EIeM( zy6v_c-vQS>8j76oZ`%OqYqayyMyz3XjaD?~Ubg0SXYJ^hvI{>x#*)zo5?~N=R-Ddd zKj-}{{|BGBMvZUyZy@)l^8#P=!*&A$lP^Ed1pv~|kvyH-8&GNdtn-!Vd3h9E5Y#ir^g~#gMm+n_djLMsoiSVwy zl}{_2Lb%hqr|#jEWnyLDrB6)Dwmu}`_+loH`sxO;m9n?0CI)LNYi9VZ~kD9XUB9+GdGTv&e z&u4^{_o%^#d9F$DW&(M+5vds}wRs`a0#%;9Qp3>k;tyBD@B=pIKjDS>FQ4L%ZhYRV z8*Z|u;Gg2;cpH<9O1rVFEfQIwx9hty&fS3Bd(}sr39ROu52n(a^&DJgSTr9(TP)f$pBKg6`ivsDl6UX zG$%jx{qAu*N6A&2r)AX;-K_i&9=mP-ve*M|Bo;;jtqL+{^wiak)2iU+btS#h22HN< zXyuF22@k8c%^|}*(m6l@)a2BiXT{j&AnNA+w}G289@6j1DrR_+*6Yc{k(U*S#V9~!ohDy_N|HD zx%uApdi>ZfH(SaNDoV$_wewJWh`SFhKyhhObH+J(sjDEPc6V)ohWV*Q>eyhr=P+Y1 T%N=35w<#Oxnd#POyI=etk}Lfi diff --git a/resources/bitmaps/side_resize.png b/resources/bitmaps/side_resize.png deleted file mode 100644 index 0501c336deed2faa3ef6f33ea1d14d9e0e852d03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1095 zcmV-N1i1T&P)EX>4Tx04R}tkv&MmKpe$iQ>9WW9gH9%n4vmZ5EXIMDionYs1;guFdzMbCJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLxj8AiNQwVT3N2zhIPS;0dyl(!0N1D}n$t~4AUmwAfDc| z4aWP#yi$@>;&b9LlP*a7$aLA`H^xPmIhM(rne;p{Pb?HWSngn@WNO4y#4%OVDWA)F ztTNtWtW|1C>z?d|k-WaL%ygPVNMaF75FtQD4P{hdBTlPMiiI@oCw%;au3sdVOs+B% zax9<<4U+2z`-9)zT7}68FDa4$x?ddUV+0880?oSPd>=bb^8^S!16O+6Uu^(0pQP8@ zTI>jjZUYzBZB5<-E_Z-|CqptNR|?YP3I*W(jJ_!c^xXpCHLthUK29Hi40V;d0S*p< z(IRE9`@FlSv$ucGwEFu2Uwd+&7lHJr00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNlirueSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00JLLL_t(o!_AkyZWJ*TM$cuv1qH<-wheTfjtGg43i%o6 zw&EFh3g7`!5AP5OS*hqEArRXj(S$Y;i1rmaNF(~fIDZS z4dA{4A}N%niwL6nTgv%2mwzem>uyB=MS;5j2i*sg`D|-*KHI7#`(*y<)#Ur^HGlya zsF|k3Kh#KIpu;zkq%r_Tjk{9Lf7FZ`ONc+*DNvRC{(LckFtiDkohk_g*HQw%S%F5z-&s4PM1HR=8FaTbx z5a*G?%Mt}bOYVfB$S>_st39JT-e N002ovPDHLkV1k5L*A)N& diff --git a/resources/bitmaps/side_resize.xpm b/resources/bitmaps/side_resize.xpm deleted file mode 100644 index 354f6f5..0000000 --- a/resources/bitmaps/side_resize.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *side_resize[] = { -/* columns rows colors chars-per-pixel */ -"40 32 5 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c #F8F8F8", -/* pixels */ -" ", -" ", -" ... ... ... ", -" . ", -" . . ", -" . . ", -" . ", -" . ", -" . . ", -" . . ", -" . ", -" . OOOOOOO ", -" . . OOOOOOOOOOOOOOOo ", -" . . XOOOOOOOOOOOOOOOOoo ", -" . XXXXXXOOOOOOOOOoooo ", -" ... ... ... XXXXXXXXXXOOOOooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_rotate.png b/resources/bitmaps/side_rotate.png deleted file mode 100644 index b273e1819ff857641465b36b91da926f746c064b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7573 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 diff --git a/resources/bitmaps/side_scale.xpm b/resources/bitmaps/side_scale.xpm deleted file mode 100644 index 0362663..0000000 --- a/resources/bitmaps/side_scale.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_scale[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c blue", -"+ c #F8F8F8", -/* pixels */ -" ", -" ", -" ", -" OOO OOO OOO ", -" ", -" O OOOOO O ", -" O OOOO O ", -" O OOO O ", -" O OO ", -" ........ O O ", -" . . O ", -" . . O +++++++ ", -" . . +++++++++++++++o ", -" . . O++++++++++++++++oo ", -" . . OXXXXX+++++++++oooo ", -" . . OXXXXXXXXX++++ooooo ", -" ........ OOO XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_select.png b/resources/bitmaps/side_select.png deleted file mode 100644 index b8f30aadb656e71fcc391b0314c57ce5bacfa5e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6478 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 VwY)u)1au9^#L(QJ^x(0m{{Tosa1sCj diff --git a/resources/bitmaps/side_selectface.png b/resources/bitmaps/side_selectface.png deleted file mode 100644 index 946ab14cbd8e365a21c391ce190e87919d119088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1730 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 JPDHLkV1k|itXTj6 diff --git a/resources/bitmaps/side_surface.xpm b/resources/bitmaps/side_surface.xpm deleted file mode 100644 index c5849fa..0000000 --- a/resources/bitmaps/side_surface.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char *side_surface[] = { -/* columns rows colors chars-per-pixel */ -"40 32 10 1 ", -" c None", -". c #0C0C0C", -"X c #800000", -"o c red", -"O c #FF0100", -"+ c #FF0001", -"@ c #008000", -"# c yellow", -"$ c #C3C3C3", -"% c #F3F3F3", -/* pixels */ -" ", -" ", -" $$$$ ", -" $oooo$$$ ", -" $o$$$$ooo$ ", -" $o$ $$o$ ", -" $oo$ $o$ ", -" $oo$ $o$ ", -" $oo$ $o$ ", -" $oo$$$$ $ ", -" $oooooo$$ ", -" $ooooooo$ ####### ", -" $$$ooooo$ ###############@ ", -" $$$ooo$ X################@@ ", -" $ $oo$ XXXXXX#########@@@@ ", -" $o$ $oo$ XXXXXXXXXX####@@@@@ ", -" $o$ $oo$ XXXXXXXXXXXXX@@@@@ ", -" $oo$ $oo$ XXXXXXXXXXXXX@@@@@ ", -" $oo$$ $$o$ XXXXXXXXXXXXX@@@@@ ", -" $o$oo$$$oo$ XXXXXXXXXXXX@@@@@ ", -" $ $$ooo$$ XXXXXXXXXXXX@@@@@ ", -" $$$ XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXX@@@@ ", -" XXXXXXXXXX@@@ ", -" . . . XXXXXXX@@ ", -" % % % XXXX@ ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_surfspec.png b/resources/bitmaps/side_surfspec.png deleted file mode 100644 index eeb0f89b0207bff203e3f27d5d0e5ec0b55ba901..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7631 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 diff --git a/resources/bitmaps/side_textures.xpm b/resources/bitmaps/side_textures.xpm deleted file mode 100644 index 25c2197..0000000 --- a/resources/bitmaps/side_textures.xpm +++ /dev/null @@ -1,148 +0,0 @@ -/* XPM */ -static char *side_textures[] = { -/* columns rows colors chars-per-pixel */ -"40 32 110 2 ", -" c None", -". c #0C0C0C", -"X c #240C04", -"o c #291207", -"O c #3C1D09", -"+ c #381D14", -"@ c #372116", -"# c #3E271F", -"$ c #452B21", -"% c #4E372F", -"& c #533C33", -"* c #5A3F34", -"= c #5B402B", -"- c #62463A", -"; c #63483D", -": c #6F543F", -"> c #634B44", -", c #694F42", -"< c #6A5248", -"1 c #725647", -"2 c #72574B", -"3 c #775D50", -"4 c #7C6251", -"5 c #FF0000", -"6 c #9E5113", -"7 c #AC4F0C", -"8 c #A5540F", -"9 c #B2530F", -"0 c #A05116", -"q c #AD5514", -"w c #AC5B1D", -"e c #B45514", -"r c #B35A15", -"t c #B95914", -"y c #B45C1B", -"u c #BB5E1B", -"i c #B36317", -"p c #B6641F", -"a c #BB631C", -"s c #BB6B1C", -"d c #AD5F22", -"f c #B55F20", -"g c #B85D22", -"h c #B46425", -"j c #BB6621", -"k c #BB6A22", -"l c #B76729", -"z c #B46C2B", -"x c #BC6E2B", -"c c #BF702B", -"v c #BC6932", -"b c #BE7130", -"n c #C16A1E", -"m c #C26724", -"M c #C26C25", -"N c #C36C29", -"B c #C96D28", -"V c #C77326", -"C c #C4732B", -"Z c #C9732C", -"A c #CA792E", -"S c #C37432", -"D c #CB7431", -"F c #C77C33", -"G c #C97A33", -"H c #C27738", -"J c #CC7D3B", -"K c #D27737", -"L c #D17A3E", -"P c #856856", -"I c #8E7362", -"U c #927565", -"Y c #CC7E42", -"T c #CE823B", -"R c #D1853E", -"E c #A28975", -"W c #A3877B", -"Q c #AE917F", -"! c #CE8342", -"~ c #D78941", -"^ c #D18E4D", -"/ c #DD9555", -"( c #637BB5", -") c #6681B5", -"_ c #6A82B7", -"` c #6781B9", -"' c #6C85BB", -"] c #6F88BD", -"[ c #728CBD", -"{ c #728CC1", -"} c #788EC0", -"| c #7791C4", -" . c #7B94C3", -".. c #7F9AC5", -"X. c #7C95C9", -"o. c #7F9AC8", -"O. c #B29681", -"+. c #B29583", -"@. c #B59888", -"#. c #B99C8A", -"$. c #BAA393", -"%. c #C8AD98", -"&. c #839ECE", -"*. c #84A0C9", -"=. c #88A4C8", -"-. c #87A2D1", -";. c #8FA9D6", -":. c #9CB5DD", -">. c #C3C3C3", -",. c #F3F3F3", -/* pixels */ -" ", -" ", -" ", -" >.>.>.>.>.>.>.>.>.>.>.>.>.>. ", -" >.5 5 5 5 5 5 5 5 5 5 5 5 5 5 >. ", -" >.5 >.>.>.>.>.5 5 >.>.>.>.>.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >. >.5 5 >. >. ", -" >.5 5 >. ", -" >.5 5 >. O +.1 W - + $ ", -" >.5 5 >. E : O.#.@.U < * > X & X 3 4 * ' ", -" >.5 5 >. k o $.I %.Q I U - > $ * # % o ; I ' [ ", -" >.5 5 >. C F x x k v P 1 2 - < > % X @ ' _ ) ' ", -" >.5 5 >. C F F k h S 6 x J q & & * X { ] ] | [ ", -" >.5 5 >. h G F j r S w w Y e u p N { } X.| . ", -" >.5 5 >. 8 T C D a S c d S q N N j [ [ X.&.&. ", -" >.>.>.5 5 >.>.>. p R S Z N G c b z q j j k { { ' ' ' ", -" >.5 5 5 5 5 5 5 5 >. R R j B J z / ! S N M x | [ ( ( ( ", -" >.>.>.>.>.>.>.>. G C C a x z ^ / g N D G &.;.&.[ ' ", -" ! x j d l h J L w n m V _ [ .:.' ", -" R m m N Y d x S g t s C ( ( X. .( ", -" F N 7 C v 6 Y D e u B M ( ( ` ( ( ", -" F M 9 m h f K B r u B V ( ( ( ( ( ", -" n a r u e r a s B k C ' ( ( _ ", -" a i s n 9 n s A A s | ' [ ", -" . . . n s s s s A V ..-. ", -" ,. ,. ,. V s G C =. ", -" C ", -" ", -" " -}; diff --git a/resources/bitmaps/side_transform.xpm b/resources/bitmaps/side_transform.xpm deleted file mode 100644 index b7e6f85..0000000 --- a/resources/bitmaps/side_transform.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_transform[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c blue", -"+ c #F8F8F8", -/* pixels */ -" ", -" ", -" ", -" ....... ", -" . . ", -" . . ", -" . . O ", -" . . OO ", -" . . OOO ", -" . .OOOOOOO ", -" . . OOO ", -" . . OO +++++++ ", -" . . O +++++++++++++++o ", -" . . X++++++++++++++++oo ", -" . . XXXXXX+++++++++oooo ", -" . . XXXXXXXXXX++++ooooo ", -" ....... XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_vertices.xpm b/resources/bitmaps/side_vertices.xpm deleted file mode 100644 index 85ef028..0000000 --- a/resources/bitmaps/side_vertices.xpm +++ /dev/null @@ -1,52 +0,0 @@ -/* XPM */ -static char * side_vertices_xpm[] = { -"19 16 33 1", -" c None", -". c #00FBFF", -"+ c #808080", -"@ c #00F1FF", -"# c #00EFFF", -"$ c #00EDFF", -"% c #00EAFF", -"& c #000000", -"* c #00EBFF", -"= c #00E1FF", -"- c #007280", -"; c #00D8FF", -"> c #006D80", -", c #006A80", -"' c #00D4FF", -") c #006780", -"! c #00CEFF", -"~ c #00CCFF", -"{ c #00CDFF", -"] c #00C6FF", -"^ c #00C4FF", -"/ c #00C3FF", -"( c #006280", -"_ c #006080", -": c #00BEFF", -"< c #00BBFF", -"[ c #005E80", -"} c #00BCFF", -"| c #00B7FF", -"1 c #00B6FF", -"2 c #005B80", -"3 c #005980", -"4 c #005880", -" .. ", -" +@@ +@# ", -"$%& +&$* ", -"== +&-+ + ", -" + +;>+ ", -" & &,'& ", -" & & )!!& ", -" ++ + )~{)) ", -" ]] + ]]]]& ", -" ^/ & (//( ", -" &&+ &+& _:_& ", -" +&&+<& [[}[ ", -" | 12& ", -" 333&", -" 4&&", -" & "}; diff --git a/resources/bitmaps/splash.xcf b/resources/bitmaps/splash.xcf deleted file mode 100644 index 2884cb230217d4542c74ef37df63dea989ac8f10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 455574 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%0Dk(jYYRO3YEz`Ox}Yl*Y9Z26b-t7MkIkr7lEb~ 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 F{{W|)-|YYZ diff --git a/resources/bitmaps/splash.xpm b/resources/bitmaps/splash.xpm deleted file mode 100644 index 14c3fdc..0000000 --- a/resources/bitmaps/splash.xpm +++ /dev/null @@ -1,15768 +0,0 @@ -/* XPM */ -static char * splash_xpm[] = { -"340 188 15577 3", -" c #000000", -". c #FFFFFF", -"+ c #07000E", -"@ c #070E03", -"# c #160B1A", -"$ c #03161D", -"% c #342C38", -"& c #000E1A", -"* c #47565D", -"= c #0E1D25", -"- c #4E4756", -"; c #21474B", -"> c #071A21", -", c #0E0312", -"' c #213038", -") c #1A1221", -"! c #A59D96", -"~ c #C7B4B0", -"{ c #615A65", -"] c #292530", -"^ c #3C4B52", -"/ c #291A16", -"( c #69787F", -"_ c #C7D6E1", -": c #1A2930", -"< c #1D0B07", -"[ c #032138", -"} c #61524E", -"| c #7F706C", -"1 c #70615D", -"2 c #303F47", -"3 c #30211D", -"4 c #1A344B", -"5 c #43473F", -"6 c #56656C", -"7 c #E9DAD6", -"8 c #2C5D70", -"9 c #3F302C", -"0 c #2C475D", -"a c #96BFC3", -"b c #252921", -"c c #564743", -"d c #38303C", -"e c #523C29", -"f c #9D6C4E", -"g c #3C2912", -"h c #29383F", -"i c #968783", -"j c #653F30", -"k c #433C47", -"l c #695A43", -"m c #010101", -"n c #000101", -"o c #52787B", -"p c #000001", -"q c #020101", -"r c #454443", -"s c #676564", -"t c #ACA7A3", -"u c #B6B0AC", -"v c #B2AFAA", -"w c #BEBBB6", -"x c #CCC8C6", -"y c #CBC7C5", -"z c #C5C2BC", -"A c #BDBAB8", -"B c #BCB9B3", -"C c #C3C0BA", -"D c #CAC6C4", -"E c #C8C7C7", -"F c #878686", -"G c #5F5F5E", -"H c #070707", -"I c #010000", -"J c #020202", -"K c #B08374", -"L c #232121", -"M c #42403F", -"N c #878584", -"O c #999493", -"P c #ACA8A7", -"Q c #A6A1A0", -"R c #A29E9C", -"S c #A4A09F", -"T c #94908E", -"U c #9C9897", -"V c #9A9594", -"W c #A09B9A", -"X c #B6B2AE", -"Y c #BBB8B3", -"Z c #C7C3C2", -"` c #CFCECC", -" . c #D2D1CF", -".. c #D9D8D5", -"+. c #D5D4D2", -"@. c #8A8789", -"#. c #4B4A4A", -"$. c #789DA1", -"%. c #4B3C38", -"&. c #0B0A0A", -"*. c #464545", -"=. c #72716E", -"-. c #646260", -";. c #62605F", -">. c #7F7A79", -",. c #807977", -"'. c #7A7674", -"). c #6C6867", -"!. c #706B6A", -"~. c #656461", -"{. c #6E6D6B", -"]. c #7E7978", -"^. c #777271", -"/. c #898483", -"(. c #989392", -"_. c #8C8786", -":. c #AEA9A8", -"<. c #B3B0AF", -"[. c #C3C0BE", -"}. c #DCD9D8", -"|. c #E3DFDF", -"1. c #DBD9D8", -"2. c #BEBCBB", -"3. c #706E6E", -"4. c #1E1E1E", -"5. c #050505", -"6. c #0A0A0A", -"7. c #494846", -"8. c #5E5C5B", -"9. c #53534E", -"0. c #555451", -"a. c #5C5B59", -"b. c #4F4A49", -"c. c #494844", -"d. c #51504D", -"e. c #666561", -"f. c #847F7E", -"g. c #777672", -"h. c #868582", -"i. c #84837F", -"j. c #908B8A", -"k. c #938E8D", -"l. c #7D7877", -"m. c #787372", -"n. c #686462", -"o. c #6D6867", -"p. c #6C6766", -"q. c #767170", -"r. c #908986", -"s. c #9E9794", -"t. c #B3AFAE", -"u. c #BBB7B6", -"v. c #B2ACAC", -"w. c #AEA8A4", -"x. c #AFABAB", -"y. c #737271", -"z. c #292826", -"A. c #050504", -"B. c #3A3939", -"C. c #53514F", -"D. c #42403E", -"E. c #464543", -"F. c #494845", -"G. c #605F5C", -"H. c #666564", -"I. c #8D8A89", -"J. c #959190", -"K. c #918C8B", -"L. c #9F9A99", -"M. c #878483", -"N. c #85807F", -"O. c #7D7978", -"P. c #868280", -"Q. c #797473", -"R. c #676662", -"S. c #5C5B58", -"T. c #706E6B", -"U. c #868382", -"V. c #9B9795", -"W. c #A8A3A2", -"X. c #6D6D6D", -"Y. c #151515", -"Z. c #211A29", -"`. c #928B96", -" + c #0E293F", -".+ c #292926", -"++ c #666664", -"@+ c #4A4946", -"#+ c #403F3D", -"$+ c #454442", -"%+ c #444340", -"&+ c #4B4A48", -"*+ c #706E6C", -"=+ c #5F5E5B", -"-+ c #656460", -";+ c #625E5C", -">+ c #83827F", -",+ c #6D6C6A", -"'+ c #6C6B68", -")+ c #65605F", -"!+ c #878382", -"~+ c #837E7D", -"{+ c #736E6D", -"]+ c #807D7C", -"^+ c #A2A19F", -"/+ c #5A5856", -"(+ c #7B8B92", -"_+ c #0B3C4E", -":+ c #83969D", -"<+ c #FBE5E1", -"[+ c #5E5C5A", -"}+ c #4E4D4A", -"|+ c #3F3E3D", -"1+ c #3F3D3E", -"2+ c #403F3F", -"3+ c #444242", -"4+ c #423F3E", -"5+ c #484644", -"6+ c #6D6C68", -"7+ c #4E4D49", -"8+ c #4B4A46", -"9+ c #585654", -"0+ c #504D4E", -"a+ c #4F4E4B", -"b+ c #6B6A67", -"c+ c #928D8C", -"d+ c #9E9998", -"e+ c #726D6C", -"f+ c #706C6B", -"g+ c #7C7776", -"h+ c #8D8987", -"i+ c #AEAAA9", -"j+ c #B8B4B3", -"k+ c #033447", -"l+ c #1F1F1E", -"m+ c #5B5A5A", -"n+ c #3F3E3B", -"o+ c #3D3B3B", -"p+ c #454344", -"q+ c #403E3F", -"r+ c #423F40", -"s+ c #62615F", -"t+ c #6A6865", -"u+ c #5C5856", -"v+ c #43423F", -"w+ c #403F3E", -"x+ c #51504E", -"y+ c #605C5B", -"z+ c #918C8C", -"A+ c #AFAAA9", -"B+ c #807C7A", -"C+ c #716C6B", -"D+ c #6B6665", -"E+ c #73706D", -"F+ c #6E6B68", -"G+ c #A19C9B", -"H+ c #B9B4B3", -"I+ c #D2D1D1", -"J+ c #504F4F", -"K+ c #020204", -"L+ c #33334D", -"M+ c #49487E", -"N+ c #565C94", -"O+ c #747AAE", -"P+ c #8D97CE", -"Q+ c #9CA3E2", -"R+ c #9AA8EC", -"S+ c #A3B2F4", -"T+ c #A8B1F5", -"U+ c #A7AEF1", -"V+ c #A3AEEF", -"W+ c #A2ACEE", -"X+ c #A8ABF3", -"Y+ c #9CABF2", -"Z+ c #9EA7F4", -"`+ c #A0AAF7", -" @ c #A0A9F6", -".@ c #9AA4F1", -"+@ c #9BA4F3", -"@@ c #929AEE", -"#@ c #909AED", -"$@ c #949FEE", -"%@ c #929BEF", -"&@ c #9098ED", -"*@ c #8B94E0", -"=@ c #878AD1", -"-@ c #6C6EB1", -";@ c #545197", -">@ c #42407F", -",@ c #302F51", -"'@ c #292929", -")@ c #555453", -"!@ c #3B3A38", -"~@ c #3E3B3D", -"{@ c #434042", -"]@ c #494646", -"^@ c #5A5956", -"/@ c #666562", -"(@ c #595855", -"_@ c #403E3E", -":@ c #43403F", -"<@ c #4D4B49", -"[@ c #615E5C", -"}@ c #928D8D", -"|@ c #8B8685", -"1@ c #6A6866", -"2@ c #797673", -"3@ c #94918C", -"4@ c #BEBAB9", -"5@ c #565554", -"6@ c #282A49", -"7@ c #555884", -"8@ c #747DAA", -"9@ c #97A1DD", -"0@ c #A0A7F4", -"a@ c #A0A9F5", -"b@ c #A3AAF7", -"c@ c #AAB7FF", -"d@ c #B1BCFF", -"e@ c #B0C2FF", -"f@ c #B2C3FF", -"g@ c #B1C1FF", -"h@ c #B0BEFF", -"i@ c #AEB8FF", -"j@ c #AFBAFF", -"k@ c #B1B9FF", -"l@ c #A7B0FF", -"m@ c #A6AFFB", -"n@ c #9BA2F4", -"o@ c #9598EE", -"p@ c #9FA3FA", -"q@ c #A6ACF9", -"r@ c #A9AEFA", -"s@ c #A4A9FA", -"t@ c #ABACFD", -"u@ c #A9ACFE", -"v@ c #A9AEFE", -"w@ c #A7AAFE", -"x@ c #A1AAF9", -"y@ c #9FA7F9", -"z@ c #9FA6FC", -"A@ c #9AA2FD", -"B@ c #9BA3F3", -"C@ c #979EF8", -"D@ c #949FF4", -"E@ c #949CF9", -"F@ c #959FF9", -"G@ c #939AF5", -"H@ c #9299E1", -"I@ c #8B8EE9", -"J@ c #7E82C4", -"K@ c #5B5BA6", -"L@ c #46457E", -"M@ c #29254A", -"N@ c #323232", -"O@ c #3B393A", -"P@ c #3F3E3E", -"Q@ c #3D3A3B", -"R@ c #464445", -"S@ c #454342", -"T@ c #504F4D", -"U@ c #74706E", -"V@ c #C1BCBB", -"W@ c #C2BDBC", -"X@ c #292A4F", -"Y@ c #596190", -"Z@ c #959ED5", -"`@ c #ACB6F6", -" # c #AAB9FB", -".# c #AFC2FF", -"+# c #BCC6FF", -"@# c #BAC0FE", -"## c #A9AFFF", -"$# c #A6B2FF", -"%# c #B6BBFF", -"&# c #B7B9FF", -"*# c #B0B6FF", -"=# c #ACB0FF", -"-# c #A9AEFF", -";# c #A0A7FA", -"># c #99A0F5", -",# c #8E94F1", -"'# c #989AF1", -")# c #8E91F2", -"!# c #8482E9", -"~# c #7D80E4", -"{# c #7E7AEA", -"]# c #8586E6", -"^# c #8D86E4", -"/# c #948CE0", -"(# c #9F99E4", -"_# c #9C95E5", -":# c #9F97E5", -"<# c #9490E5", -"[# c #9A95ED", -"}# c #A29EF2", -"|# c #A3A0EE", -"1# c #A4A2EE", -"2# c #A4A3EF", -"3# c #A09FF1", -"4# c #B0ACFD", -"5# c #A7A9FC", -"6# c #A8ACFD", -"7# c #A0A7FD", -"8# c #A0A9F4", -"9# c #999EF1", -"0# c #9C97F3", -"a# c #9998E3", -"b# c #9898E6", -"c# c #9797F0", -"d# c #989BF0", -"e# c #979EF5", -"f# c #949BF8", -"g# c #8C93EF", -"h# c #8E95EC", -"i# c #878ADC", -"j# c #515590", -"k# c #2D2A5B", -"l# c #302F2F", -"m# c #4D4D4B", -"n# c #424040", -"o# c #393638", -"p# c #3A3936", -"q# c #434040", -"r# c #4B4A49", -"s# c #545350", -"t# c #5E5B5A", -"u# c #676261", -"v# c #8E8B89", -"w# c #8E8A89", -"x# c #827D7C", -"y# c #797674", -"z# c #73706E", -"A# c #6A6664", -"B# c #666160", -"C# c #B8B3B2", -"D# c #5B5B5A", -"E# c #020402", -"F# c #363961", -"G# c #666EAB", -"H# c #9CA6EB", -"I# c #9EA9F6", -"J# c #9BA9FD", -"K# c #A7B1FF", -"L# c #B3BBFF", -"M# c #B7C0FF", -"N# c #BDC6FF", -"O# c #BBC0FF", -"P# c #B6B4FF", -"Q# c #B3B2F7", -"R# c #A9ABF9", -"S# c #AEB1FD", -"T# c #A4A8FB", -"U# c #9E9EF0", -"V# c #9892E6", -"W# c #8E8BE2", -"X# c #958CE0", -"Y# c #8B84DD", -"Z# c #867EDD", -"`# c #8982DF", -" $ c #9087E4", -".$ c #8C89E2", -"+$ c #938CE1", -"@$ c #9A92E4", -"#$ c #A19AE9", -"$$ c #A49FF2", -"%$ c #BBB7F9", -"&$ c #C2B8FA", -"*$ c #BDB8F9", -"=$ c #B0AAF7", -"-$ c #AFABF6", -";$ c #A7A1F0", -">$ c #A299E9", -",$ c #A7A0E6", -"'$ c #AEA8EE", -")$ c #B1B1FA", -"!$ c #9C99E7", -"~$ c #9F99EC", -"{$ c #9895E9", -"]$ c #9C99E9", -"^$ c #A4A6F5", -"/$ c #B1AFFF", -"($ c #B0B0FC", -"_$ c #9E99ED", -":$ c #9090E7", -"<$ c #9794EA", -"[$ c #9B9AE5", -"}$ c #A09EF0", -"|$ c #9B9BF0", -"1$ c #A3A3F7", -"2$ c #A0A4F4", -"3$ c #99A2F5", -"4$ c #959EF4", -"5$ c #9B9FF4", -"6$ c #9BA1F4", -"7$ c #999CEF", -"8$ c #6667AF", -"9$ c #423D6C", -"0$ c #2E2D2D", -"a$ c #494948", -"b$ c #504F4E", -"c$ c #3A3838", -"d$ c #444243", -"e$ c #5B5A58", -"f$ c #6B6666", -"g$ c #989493", -"h$ c #ABA7A6", -"i$ c #979291", -"j$ c #A7A2A1", -"k$ c #4D4B4A", -"l$ c #242548", -"m$ c #5A5F9A", -"n$ c #9BA4E7", -"o$ c #A6B7F9", -"p$ c #ABBDFF", -"q$ c #B3C1FF", -"r$ c #B0B8FF", -"s$ c #B4B8FF", -"t$ c #BAC1FF", -"u$ c #BEC2FF", -"v$ c #BABDF7", -"w$ c #B2B2FC", -"x$ c #B2AEF5", -"y$ c #A19EE6", -"z$ c #A09ADF", -"A$ c #A39BE1", -"B$ c #9A91DE", -"C$ c #9B91D9", -"D$ c #9F94DC", -"E$ c #A093D8", -"F$ c #9E93D5", -"G$ c #A295D8", -"H$ c #A393CE", -"I$ c #A993DA", -"J$ c #A898D2", -"K$ c #B09AD3", -"L$ c #AE9CD3", -"M$ c #A999DB", -"N$ c #AF9FDE", -"O$ c #A89ADE", -"P$ c #A9A0DF", -"Q$ c #B6AADE", -"R$ c #B6A8E1", -"S$ c #ACA3DF", -"T$ c #A79ED8", -"U$ c #A8A0D7", -"V$ c #BDB3EE", -"W$ c #BAB0EF", -"X$ c #ABA3DF", -"Y$ c #998ED3", -"Z$ c #A99FDE", -"`$ c #B3AAEB", -" % c #AEA9EA", -".% c #AEA9ED", -"+% c #B3B1F5", -"@% c #B8B6F5", -"#% c #A9A2F3", -"$% c #B0AEF3", -"%% c #A4A7EC", -"&% c #9C9BEF", -"*% c #A1A1F5", -"=% c #8E8DE4", -"-% c #8685D9", -";% c #958EDF", -">% c #9390DD", -",% c #9B94DE", -"'% c #9C95DF", -")% c #9593E0", -"!% c #9992DC", -"~% c #9B93D9", -"{% c #9892DE", -"]% c #9A92E1", -"^% c #9B97E9", -"/% c #9599F5", -"(% c #9299EF", -"_% c #9397E6", -":% c #5E5C9C", -"<% c #28264F", -"[% c #2B2B2B", -"}% c #494946", -"|% c #3A3839", -"1% c #50504E", -"2% c #4A4948", -"3% c #676664", -"4% c #8C8984", -"5% c #938D8A", -"6% c #B0ABAA", -"7% c #B2AEAC", -"8% c #3A3B6D", -"9% c #7E8AC2", -"0% c #A8B7F8", -"a% c #A9B7FD", -"b% c #A3B2FD", -"c% c #B3BEFF", -"d% c #BEC4FF", -"e% c #BEC1FF", -"f% c #C1C1FF", -"g% c #C2C2FF", -"h% c #BEBBFF", -"i% c #AFA9F6", -"j% c #A39AE5", -"k% c #8B89D7", -"l% c #9891DE", -"m% c #8D89D2", -"n% c #9890D4", -"o% c #9C92DF", -"p% c #A99FE2", -"q% c #B4A4E0", -"r% c #AFA6E1", -"s% c #B1A4E4", -"t% c #B09ED8", -"u% c #AA99CF", -"v% c #A092CD", -"w% c #9487CB", -"x% c #9887CB", -"y% c #9E8DC8", -"z% c #AB95CC", -"A% c #B99ED3", -"B% c #B49BD2", -"C% c #B39ACD", -"D% c #B19CD2", -"E% c #AE9AD0", -"F% c #B79CD3", -"G% c #B79FDC", -"H% c #B9A4D9", -"I% c #BAAADB", -"J% c #B6A4D7", -"K% c #B0A1D4", -"L% c #A498D2", -"M% c #B3A2D9", -"N% c #C0B4E7", -"O% c #C3B9F1", -"P% c #C2BBEF", -"Q% c #C3BCF3", -"R% c #CDC5FF", -"S% c #C1BEFF", -"T% c #C1C0FF", -"U% c #C4C0FF", -"V% c #BCBBFF", -"W% c #BCBCFC", -"X% c #B9B8F5", -"Y% c #BDB9FB", -"Z% c #B7B6FF", -"`% c #ABB1F9", -" & c #A8A9F6", -".& c #A9ACFA", -"+& c #ACA8FA", -"@& c #A7A3EF", -"#& c #A8A4EA", -"$& c #A29EE5", -"%& c #AAA0E0", -"&& c #9F97DE", -"*& c #9C93D5", -"=& c #9990D4", -"-& c #938CD0", -";& c #978ED3", -">& c #958DDB", -",& c #9C92E1", -"'& c #9590DF", -")& c #9590EA", -"!& c #9390E6", -"~& c #807CC1", -"{& c #3F3A70", -"]& c #1B1B1B", -"^& c #61605E", -"/& c #3F3D3B", -"(& c #434240", -"_& c #565553", -":& c #444342", -"<& c #494645", -"[& c #686765", -"}& c #747371", -"|& c #7E7C7A", -"1& c #6E6D6A", -"2& c #2D2D2D", -"3& c #3D3A67", -"4& c #9093DC", -"5& c #A4B1FA", -"6& c #B1C5FF", -"7& c #AFBBFF", -"8& c #A8B1FD", -"9& c #A8AEFC", -"0& c #AFB4FF", -"a& c #BBBEFF", -"b& c #B6B2F8", -"c& c #AAA4F0", -"d& c #9E9BEB", -"e& c #AAA2F3", -"f& c #A4A3F1", -"g& c #B4ACF2", -"h& c #B7AFF0", -"i& c #B2ACF0", -"j& c #BDB4F4", -"k& c #BBB2F5", -"l& c #C2B8F8", -"m& c #B9B1F0", -"n& c #ACA6EC", -"o& c #B6B1F4", -"p& c #BCB3F2", -"q& c #BCB1F2", -"r& c #B9AEEE", -"s& c #AFA4E3", -"t& c #A99FE5", -"u& c #9992DF", -"v& c #8D86D8", -"w& c #B098D2", -"x& c #BA9FD1", -"y& c #C4A4D3", -"z& c #C2A6D1", -"A& c #C3A6D1", -"B& c #BCA3D3", -"C& c #B9A3CF", -"D& c #B8A0D1", -"E& c #BBA4D7", -"F& c #C0A4DA", -"G& c #BDA6D7", -"H& c #BEA8D3", -"I& c #B9A0D0", -"J& c #B49CD7", -"K& c #AF97CC", -"L& c #AC99CF", -"M& c #AAA1CD", -"N& c #ACA2D4", -"O& c #CCC2EF", -"P& c #D0CAFF", -"Q& c #D4D0FF", -"R& c #D3D0FF", -"S& c #CBC7FF", -"T& c #CDC6FF", -"U& c #C8BEF6", -"V& c #C0B7EB", -"W& c #CABEE9", -"X& c #CAC2F0", -"Y& c #CCC3FA", -"Z& c #C3BEFF", -"`& c #CABDFF", -" * c #C1B9F7", -".* c #B6ACF4", -"+* c #B2ABF1", -"@* c #B4ABEE", -"#* c #B6ACEF", -"$* c #B3AFF8", -"%* c #B1ABF2", -"&* c #B1A9EB", -"** c #A79CE9", -"=* c #9F97D3", -"-* c #9E90D0", -";* c #988DD2", -">* c #978CD1", -",* c #978BD4", -"'* c #958AD8", -")* c #908AE2", -"!* c #8C8AE4", -"~* c #9590DD", -"{* c #443E72", -"]* c #6E6E6D", -"^* c #3D3B39", -"/* c #3A3938", -"(* c #353432", -"_* c #353434", -":* c #393636", -"<* c #40403E", -"[* c #64645E", -"}* c #797974", -"|* c #8A8985", -"1* c #6C6B67", -"2* c #85827F", -"3* c #898383", -"4* c #837F7E", -"5* c #8B8783", -"6* c #7F7976", -"7* c #8A8685", -"8* c #999595", -"9* c #2E2D54", -"0* c #666AB3", -"a* c #909EF3", -"b* c #91A2F8", -"c* c #9AAAFC", -"d* c #9CA1F7", -"e* c #9392EE", -"f* c #AEAFFF", -"g* c #C1C5FF", -"h* c #C2C5FF", -"i* c #B7B4FE", -"j* c #AEA8F6", -"k* c #C1B9FF", -"l* c #C3BCF9", -"m* c #D3CBFF", -"n* c #E7DAFF", -"o* c #EADCFF", -"p* c #EED7FF", -"q* c #CCC5FF", -"r* c #CDC4FF", -"s* c #CBC3F9", -"t* c #CDC3FC", -"u* c #ACA8E9", -"v* c #948CDF", -"w* c #9086DC", -"x* c #948CD7", -"y* c #8E84C6", -"z* c #9084D2", -"A* c #8E85D7", -"B* c #9087DB", -"C* c #7E7ACD", -"D* c #938DD7", -"E* c #B2A1D2", -"F* c #BDA1C7", -"G* c #CAAAD2", -"H* c #CEAFD5", -"I* c #CDABD7", -"J* c #C7ACD9", -"K* c #C8A4D3", -"L* c #CCA9D0", -"M* c #C7A3C8", -"N* c #C5A6CA", -"O* c #C8A4CC", -"P* c #C6A8C8", -"Q* c #C6A9D0", -"R* c #B39FC6", -"S* c #AF9BD0", -"T* c #AA9CD7", -"U* c #AA9ED8", -"V* c #A998CF", -"W* c #AF97CB", -"X* c #AB9AC4", -"Y* c #B19FCE", -"Z* c #B9ABDB", -"`* c #C5BBEA", -" = c #D8CBF8", -".= c #D4CEFF", -"+= c #D7D0FF", -"@= c #D4CCFF", -"#= c #C2BDFF", -"$= c #C4C0F3", -"%= c #B2AEEC", -"&= c #BEB7EF", -"*= c #B4B0EE", -"== c #AEA7E2", -"-= c #A79ED7", -";= c #9E93CB", -">= c #9A93D0", -",= c #9F93D5", -"'= c #A99CE3", -")= c #ACA8EA", -"!= c #AEA9F1", -"~= c #A9A8F3", -"{= c #AFA7ED", -"]= c #ABA4E6", -"^= c #AFA4E7", -"/= c #9F95D7", -"(= c #9F95DD", -"_= c #A098E3", -":= c #A09AE5", -"<= c #9C94DE", -"[= c #958CD5", -"}= c #938AD8", -"|= c #978EE3", -"1= c #9792E6", -"2= c #6D6AB1", -"3= c #35325A", -"4= c #51504F", -"5= c #71706D", -"6= c #3E3D3A", -"7= c #343330", -"8= c #383536", -"9= c #4B4949", -"0= c #706D6A", -"a= c #716E6B", -"b= c #71706C", -"c= c #8A8584", -"d= c #686764", -"e= c #827E7D", -"f= c #7D7773", -"g= c #84807A", -"h= c #6A6766", -"i= c #060606", -"j= c #13041B", -"k= c #341F3F", -"l= c #372342", -"m= c #18081D", -"n= c #0F1D25", -"o= c #08010E", -"p= c #0B0A1E", -"q= c #545B9E", -"r= c #99A0F2", -"s= c #97A3FA", -"t= c #93A3F9", -"u= c #8C94F2", -"v= c #8C92EF", -"w= c #8B91F1", -"x= c #8B8BEB", -"y= c #9F99F0", -"z= c #AFA9F3", -"A= c #BDBDFF", -"B= c #CEC8FF", -"C= c #D3CCFF", -"D= c #DFD2FF", -"E= c #DAD0FF", -"F= c #E4D8FF", -"G= c #DED2FF", -"H= c #DBD2F1", -"I= c #DBD4F9", -"J= c #D7CFF8", -"K= c #FFF1FF", -"L= c #BDB8EA", -"M= c #BAB0EC", -"N= c #B2AAEA", -"O= c #9F9AE5", -"P= c #9A94E4", -"Q= c #8D89D9", -"R= c #867ECF", -"S= c #7E73CB", -"T= c #7E74CB", -"U= c #8C84DB", -"V= c #8E8AD7", -"W= c #9A95DB", -"X= c #AAA0DA", -"Y= c #BCA7D5", -"Z= c #BEA4CD", -"`= c #BAA2CE", -" - c #C4A9CD", -".- c #C3A3D2", -"+- c #BC9FC6", -"@- c #BD9BBE", -"#- c #CAA0CA", -"$- c #C7A1C5", -"%- c #C2A2BA", -"&- c #CAA3C8", -"*- c #C1A1BD", -"=- c #C6A1C8", -"-- c #CAA8CA", -";- c #BEA1D0", -">- c #BBA0D0", -",- c #9F91C4", -"'- c #A694CC", -")- c #9F92C7", -"!- c #998CC4", -"~- c #AB97CE", -"{- c #A497D1", -"]- c #A293C3", -"^- c #A394CB", -"/- c #AB9ED0", -"(- c #CDC3EA", -"_- c #E1D5F8", -":- c #E3D7FF", -"<- c #C8BEE9", -"[- c #C0B6EB", -"}- c #CAC1FD", -"|- c #CCC2FE", -"1- c #C1B9FA", -"2- c #C0B7F8", -"3- c #AFAAEB", -"4- c #AFA8E3", -"5- c #ABA1DE", -"6- c #A99FDF", -"7- c #AA9FE0", -"8- c #B7ABEE", -"9- c #B3ACF1", -"0- c #C3B8F8", -"a- c #B8B1EC", -"b- c #B1ACF4", -"c- c #B3ACF2", -"d- c #ACA8ED", -"e- c #B2AAF5", -"f- c #AEAAF2", -"g- c #A4A4EC", -"h- c #A7A1ED", -"i- c #A9A0E6", -"j- c #A097E2", -"k- c #988EDB", -"l- c #9990DD", -"m- c #9991E3", -"n- c #625B94", -"o- c #0B0B1B", -"p- c #341E3F", -"q- c #362142", -"r- c #372242", -"s- c #362441", -"t- c #34203F", -"u- c #13051B", -"v- c #2D2B2A", -"w- c #73736E", -"x- c #3D3A3A", -"y- c #4B3F50", -"z- c #493D4F", -"A- c #493C4E", -"B- c #4D4154", -"C- c #4D4153", -"D- c #4C4152", -"E- c #4F4355", -"F- c #4F4455", -"G- c #524758", -"H- c #584E5B", -"I- c #524F50", -"J- c #535350", -"K- c #574D5B", -"L- c #574D5A", -"M- c #5A515E", -"N- c #554B59", -"O- c #5E5460", -"P- c #665E68", -"Q- c #5B535F", -"R- c #6C656D", -"S- c #716C6C", -"T- c #6D6A69", -"U- c #63615F", -"V- c #77736D", -"W- c #76726D", -"X- c #767472", -"Y- c #737270", -"Z- c #646461", -"`- c #777673", -" ; c #6C6A68", -".; c #979292", -"+; c #A19E9C", -"@; c #484848", -"#; c #835234", -"$; c #562C21", -"%; c #100317", -"&; c #6D8B83", -"*; c #CBD1C3", -"=; c #EDE7DF", -"-; c #B18BC2", -";; c #A67BBC", -">; c #B08AC1", -",; c #EAE3D8", -"'; c #E0DBBB", -"); c #8D8567", -"!; c #110618", -"~; c #07000D", -"{; c #121B1D", -"]; c #D2EFDD", -"^; c #D2CE93", -"/; c #30345B", -"(; c #9899E3", -"_; c #A1A9FC", -":; c #A8B3FE", -"<; c #9AA6FD", -"[; c #949AF8", -"}; c #8C93F5", -"|; c #8C92F0", -"1; c #8383EA", -"2; c #7A7DEA", -"3; c #9291EE", -"4; c #8E8ADF", -"5; c #B3B1F2", -"6; c #CFCBFF", -"7; c #D1CFFF", -"8; c #DDD3FF", -"9; c #D1CAFF", -"0; c #D3C8FF", -"a; c #9F9CE3", -"b; c #8E87D8", -"c; c #8E87D5", -"d; c #8B80D2", -"e; c #AAA1E3", -"f; c #9A95DE", -"g; c #948BD9", -"h; c #8C86D4", -"i; c #918AD2", -"j; c #8279CF", -"k; c #736CC3", -"l; c #6C68B9", -"m; c #6E68C0", -"n; c #6C67BD", -"o; c #7972C8", -"p; c #736EBA", -"q; c #8279C0", -"r; c #A795C8", -"s; c #B19CCA", -"t; c #B9A1C5", -"u; c #B09AC6", -"v; c #B198C7", -"w; c #B197C4", -"x; c #B99CC8", -"y; c #B897BD", -"z; c #B495BA", -"A; c #B89CB1", -"B; c #C1A1B3", -"C; c #CDA6BA", -"D; c #D1AACC", -"E; c #CAA7C8", -"F; c #C7A3C5", -"G; c #C8A4C8", -"H; c #CAA6C5", -"I; c #CDA6CD", -"J; c #C1A3C8", -"K; c #B9A0CC", -"L; c #AF9CCC", -"M; c #9B8EBE", -"N; c #988AC4", -"O; c #9486C7", -"P; c #A091CE", -"Q; c #9C92CD", -"R; c #B0A9E1", -"S; c #A9A3D0", -"T; c #C6BDE3", -"U; c #C3B6DB", -"V; c #B9A8CF", -"W; c #B1A2C7", -"X; c #B8ACD2", -"Y; c #CBBDEC", -"Z; c #C1B8F0", -"`; c #C2B6F1", -" > c #B6ACE5", -".> c #C6BCF9", -"+> c #BAB3EC", -"@> c #C3B3EF", -"#> c #B9ACED", -"$> c #B7B0F1", -"%> c #BEB6F6", -"&> c #CFC2FB", -"*> c #C6BDFD", -"=> c #BCB1F3", -"-> c #B7ACF0", -";> c #B0AAF0", -">> c #B2ACF2", -",> c #ACA7EE", -"'> c #A89EDD", -")> c #A29AE0", -"!> c #A399DB", -"~> c #9E94DD", -"{> c #9A91D9", -"]> c #948AD8", -"^> c #9189D5", -"/> c #988DDB", -"(> c #3A345A", -"_> c #9FCABC", -":> c #B28BC4", -"<> c #A97CBE", -"[> c #AE82C1", -"}> c #A87CBD", -"|> c #A47BB9", -"1> c #A37BB8", -"2> c #A67BBB", -"3> c #A67ABC", -"4> c #A87BBD", -"5> c #B791C7", -"6> c #BEB78B", -"7> c #07010D", -"8> c #7C7B79", -"9> c #656560", -"0> c #AFD6C7", -"a> c #AB7EBF", -"b> c #A77BBC", -"c> c #B28BC3", -"d> c #F3EEE4", -"e> c #AAA774", -"f> c #403F3C", -"g> c #444341", -"h> c #53524F", -"i> c #5E5D5A", -"j> c #C4E1D4", -"k> c #B48DC5", -"l> c #A77BBD", -"m> c #DBD4AA", -"n> c #6F6E6C", -"o> c #696866", -"p> c #5C5A58", -"q> c #82817E", -"r> c #949190", -"s> c #8C8683", -"t> c #9E9894", -"u> c #0F0E0E", -"v> c #659382", -"w> c #DBE0DA", -"x> c #D1B8DE", -"y> c #C7A5D8", -"z> c #F0E7E5", -"A> c #B98AC9", -"B> c #AF76C6", -"C> c #B684C9", -"D> c #E3D5E0", -"E> c #E8DDEC", -"F> c #D9C4E3", -"G> c #F5F0D9", -"H> c #908D5C", -"I> c #090F05", -"J> c #100B13", -"K> c #90C4AF", -"L> c #ECE9ED", -"M> c #E5E2B0", -"N> c #06000C", -"O> c #06000D", -"P> c #515389", -"Q> c #9CA7F7", -"R> c #98A0F7", -"S> c #9295EE", -"T> c #8586EC", -"U> c #8585E5", -"V> c #8484E4", -"W> c #7F7FE9", -"X> c #8483E3", -"Y> c #938EEE", -"Z> c #8E8AE2", -"`> c #A19BEB", -" , c #9493E6", -"., c #B0AAF5", -"+, c #BEB9FE", -"@, c #BAB8F8", -"#, c #C4C0ED", -"$, c #9E95DA", -"%, c #ACA4EA", -"&, c #B7B0EF", -"*, c #8C89D7", -"=, c #8078CD", -"-, c #938CDC", -";, c #8279CC", -">, c #7A74C3", -",, c #7971C7", -"', c #837ACC", -"), c #7F77CA", -"!, c #7972BE", -"~, c #7870C6", -"{, c #7C74BE", -"], c #948BCF", -"^, c #9993D9", -"/, c #A69BD9", -"(, c #B1A2D4", -"_, c #BAA8D7", -":, c #C0AAD9", -"<, c #C1A8CE", -"[, c #BDA2CB", -"}, c #A995BB", -"|, c #B094C2", -"1, c #B69AC0", -"2, c #B399B9", -"3, c #B99BBE", -"4, c #BA9BBD", -"5, c #BD9EB6", -"6, c #CAA6B8", -"7, c #D2ACBE", -"8, c #D0ACC3", -"9, c #CDACBA", -"0, c #CAAAC1", -"a, c #CBA9C3", -"b, c #CCABC3", -"c, c #C7A8B9", -"d, c #CBA8C5", -"e, c #C4A6C6", -"f, c #C3A8C3", -"g, c #C2A7CE", -"h, c #BCAAD1", -"i, c #B0A0C1", -"j, c #AE9BC7", -"k, c #A194C5", -"l, c #9E91CC", -"m, c #B7AEEC", -"n, c #C6BCF6", -"o, c #ABA2DF", -"p, c #A89AC7", -"q, c #B4A6CB", -"r, c #B3A0CA", -"s, c #C3B2D7", -"t, c #A99BC3", -"u, c #B3A2C6", -"v, c #B9AFE1", -"w, c #CFC1F1", -"x, c #CBBEF6", -"y, c #C8BDF4", -"z, c #D2C5FF", -"A, c #D2C3F7", -"B, c #B8B0EB", -"C, c #AAA2D8", -"D, c #B6AEE6", -"E, c #C3BAF8", -"F, c #CDC0FF", -"G, c #CFC0FA", -"H, c #BAB2F0", -"I, c #AFA8EA", -"J, c #B2A8E9", -"K, c #B2ABED", -"L, c #B7AEF0", -"M, c #ABA4E0", -"N, c #A99FE0", -"O, c #A49ADC", -"P, c #9E94D4", -"Q, c #9C91D7", -"R, c #9A8ED8", -"S, c #988CD4", -"T, c #978BD9", -"U, c #928ED8", -"V, c #4D487D", -"W, c #9BC8B9", -"X, c #BE8FD1", -"Y, c #B985CF", -"Z, c #D2B8DF", -"`, c #B783CF", -" ' c #A36DBF", -".' c #9E6FBA", -"+' c #9E70B9", -"@' c #A16FBD", -"#' c #B179CC", -"$' c #B57BCF", -"%' c #B883CF", -"&' c #D2B7D8", -"*' c #BBB485", -"=' c #05000B", -"-' c #323230", -";' c #706F6C", -">' c #4E4D4B", -",' c #413F3D", -"'' c #ACD4C5", -")' c #B780CE", -"!' c #C49DD7", -"~' c #B47ECE", -"{' c #B37BCD", -"]' c #BC8DD2", -"^' c #BF91D2", -"/' c #F5F1E4", -"(' c #A4A16F", -"_' c #4F4E4C", -":' c #C4E2D4", -"<' c #C69FD6", -"[' c #B57ECF", -"}' c #B279CC", -"|' c #A36CC0", -"1' c #B47BCE", -"2' c #BE90D1", -"3' c #D9D2A8", -"4' c #666563", -"5' c #52514E", -"6' c #5C5A57", -"7' c #949391", -"8' c #7F7E7C", -"9' c #999591", -"0' c #8D8787", -"a' c #646161", -"b' c #040404", -"c' c #98C7B1", -"d' c #F8F6F6", -"e' c #D5BCE3", -"f' c #EDE6D4", -"g' c #92896C", -"h' c #1B0823", -"i' c #371843", -"j' c #3A1B47", -"k' c #381A44", -"l' c #250E2D", -"m' c #3D4F53", -"n' c #B3CFBE", -"o' c #FCFDF6", -"p' c #FFFEF8", -"q' c #CAC590", -"r' c #556166", -"s' c #D8D6DC", -"t' c #BB99CD", -"u' c #E0DAB2", -"v' c #07020C", -"w' c #05000A", -"x' c #010105", -"y' c #575E90", -"z' c #A8B3F5", -"A' c #A2ACFC", -"B' c #8C94F5", -"C' c #848CF2", -"D' c #848CEB", -"E' c #878CEC", -"F' c #8D94ED", -"G' c #837FE4", -"H' c #8482EB", -"I' c #8A8AEE", -"J' c #807AE1", -"K' c #9C94E7", -"L' c #B8B7F8", -"M' c #A2A2EE", -"N' c #A4A2E7", -"O' c #B3B0F2", -"P' c #AFAAF4", -"Q' c #9C98E0", -"R' c #A199E9", -"S' c #C1BAF4", -"T' c #9991DE", -"U' c #B9B0E5", -"V' c #A399D7", -"W' c #7E74CA", -"X' c #8479D0", -"Y' c #7771BC", -"Z' c #7A72C4", -"`' c #7C72C2", -" ) c #897EC8", -".) c #9086CA", -"+) c #9C93D3", -"@) c #A49ED8", -"#) c #B4A7DA", -"$) c #BDAED7", -"%) c #D7B6DB", -"&) c #D3B6DA", -"*) c #D1B8D5", -"=) c #CFB4DB", -"-) c #C2AAD7", -";) c #C3A6CA", -">) c #B69ABD", -",) c #BC9BBD", -"') c #AE95A8", -")) c #AF90AB", -"!) c #AF8EAC", -"~) c #B28EAB", -"{) c #BA98B2", -"]) c #BE9BAB", -"^) c #B99AA9", -"/) c #C69FA9", -"() c #CE9BA2", -"_) c #CB9B9F", -":) c #CC99A8", -"<) c #C89BA9", -"[) c #C5A0AE", -"}) c #C6A2B7", -"|) c #C5A6B8", -"1) c #C2A6BA", -"2) c #C5A6C5", -"3) c #C6A9CB", -"4) c #C0A8C3", -"5) c #BEA9C2", -"6) c #C0A9CB", -"7) c #BCA3CD", -"8) c #A395CA", -"9) c #807CC3", -"0) c #9494DA", -"a) c #8E8DD5", -"b) c #8B84C0", -"c) c #9991CC", -"d) c #A393C3", -"e) c #B1A1C6", -"f) c #B3A3CA", -"g) c #AF99C0", -"h) c #A795B6", -"i) c #B3A1CD", -"j) c #B0A2CA", -"k) c #B9AED4", -"l) c #C2B4EA", -"m) c #CAC3FC", -"n) c #D1CAFD", -"o) c #C1B9F1", -"p) c #B8B0E3", -"q) c #B1A8DE", -"r) c #B4ABE0", -"s) c #C7BBF6", -"t) c #BCB3EC", -"u) c #B6AFED", -"v) c #B9B2EE", -"w) c #B6B1EC", -"x) c #B4AFE7", -"y) c #ABA9ED", -"z) c #AAA6E7", -"A) c #B0A7E5", -"B) c #A49CE1", -"C) c #A49ADB", -"D) c #9992D3", -"E) c #998ECF", -"F) c #988CD0", -"G) c #988AD8", -"H) c #988CD7", -"I) c #60548C", -"J) c #020206", -"K) c #14041C", -"L) c #391946", -"M) c #3C1B49", -"N) c #3C444F", -"O) c #D2E2E0", -"P) c #C18FD8", -"Q) c #A973C5", -"R) c #A673C1", -"S) c #B07FC9", -"T) c #E7DCCD", -"U) c #605055", -"V) c #3B1C48", -"W) c #30173A", -"X) c #22151A", -"Y) c #030007", -"Z) c #525050", -"`) c #61615D", -" ! c #535250", -".! c #3A3638", -"+! c #4B3852", -"@! c #4A3552", -"#! c #525D65", -"$! c #DEE6E7", -"%! c #AA73C5", -"&! c #A973C4", -"*! c #BF8FD6", -"=! c #E4D9C2", -"-! c #564554", -";! c #483550", -">! c #433F42", -",! c #2F2D2C", -"'! c #32302F", -")! c #3E3D3B", -"!! c #545351", -"~! c #787775", -"{! c #6A6966", -"]! c #646360", -"^! c #504D4D", -"/! c #5A4D5E", -"(! c #748B8A", -"_! c #D9E1E0", -":! c #C492DC", -"~ c #CDA9B3", -",~ c #D3AAB9", -"'~ c #D2A3B6", -")~ c #D1A0A8", -"!~ c #C6A0AB", -"~~ c #C5A1B1", -"{~ c #BE9CA6", -"]~ c #BA99A7", -"^~ c #BA97A8", -"/~ c #B999A4", -"(~ c #BB9BA9", -"_~ c #C3A0C3", -":~ c #C6A4C8", -"<~ c #C2A2C2", -"[~ c #C4A4C7", -"}~ c #BEA4C4", -"|~ c #C0A6C8", -"1~ c #BAA3CB", -"2~ c #A998C1", -"3~ c #9E93D3", -"4~ c #B0AFEF", -"5~ c #B8B0F4", -"6~ c #AFAAEC", -"7~ c #9A97D4", -"8~ c #A495BE", -"9~ c #A894BA", -"0~ c #A894B8", -"a~ c #A999B2", -"b~ c #A695B1", -"c~ c #B099BE", -"d~ c #A793B0", -"e~ c #B09EC5", -"f~ c #AB9ABB", -"g~ c #B4A4C8", -"h~ c #C5B7E4", -"i~ c #CEC2ED", -"j~ c #D1C3F5", -"k~ c #B4AADD", -"l~ c #A99BD2", -"m~ c #B9AFE7", -"n~ c #C2B8F0", -"o~ c #BDB3F6", -"p~ c #B7B3EC", -"q~ c #B0A9E9", -"r~ c #C2B9F0", -"s~ c #D1C8FF", -"t~ c #C7BEF1", -"u~ c #B6AFF1", -"v~ c #B9B1EF", -"w~ c #AEA8E9", -"x~ c #A8A1DE", -"y~ c #A69BE0", -"z~ c #9E95D5", -"A~ c #A094D5", -"B~ c #9B8DD4", -"C~ c #9485D0", -"D~ c #9285CC", -"E~ c #5C538C", -"F~ c #090616", -"G~ c #5D8C7C", -"H~ c #EEE8F2", -"I~ c #B689CC", -"J~ c #AD7DC5", -"K~ c #B78BCC", -"L~ c #D6CFA6", -"M~ c #080808", -"N~ c #010002", -"O~ c #1C1C1C", -"P~ c #5E5E59", -"Q~ c #565651", -"R~ c #474643", -"S~ c #343331", -"T~ c #32312F", -"U~ c #31302D", -"V~ c #80B7A2", -"W~ c #EFE8F3", -"X~ c #B78ACC", -"Y~ c #B388C9", -"Z~ c #DED3E3", -"`~ c #C2BE89", -" { c #181817", -".{ c #1B1B1A", -"+{ c #212120", -"@{ c #232321", -"#{ c #2E2D2C", -"${ c #333230", -"%{ c #4C4C47", -"&{ c #6F6F69", -"*{ c #6C6C66", -"={ c #5E5D5C", -"-{ c #504E4C", -";{ c #505453", -">{ c #E7F2ED", -",{ c #F9F5FB", -"'{ c #DCD9A3", -"){ c #232221", -"!{ c #171715", -"~{ c #1A1918", -"{{ c #201F1E", -"]{ c #504D4C", -"^{ c #75736F", -"/{ c #928E8B", -"({ c #7C7873", -"_{ c #888483", -":{ c #989490", -"<{ c #6C6866", -"[{ c #598676", -"}{ c #E5E1E7", -"|{ c #D4B7E3", -"1{ c #F1EBCA", -"2{ c #06010A", -"3{ c #020005", -"4{ c #121B1F", -"5{ c #131D21", -"6{ c #040C11", -"7{ c #182A24", -"8{ c #D3EBE0", -"9{ c #C89DDD", -"0{ c #B37ECB", -"a{ c #B88CCD", -"b{ c #E2DCB8", -"c{ c #62678B", -"d{ c #565D85", -"e{ c #5C6299", -"f{ c #676EBE", -"g{ c #7E84DA", -"h{ c #8C91ED", -"i{ c #A5A3F2", -"j{ c #9498ED", -"k{ c #9292EA", -"l{ c #9E9AE9", -"m{ c #7E78DB", -"n{ c #9090EA", -"o{ c #B6B0FD", -"p{ c #ACAEF2", -"q{ c #C3BBFD", -"r{ c #C8C1FA", -"s{ c #D8CFF5", -"t{ c #E7D1F6", -"u{ c #E3C4EE", -"v{ c #DDB7E4", -"w{ c #CFB1DA", -"x{ c #C7A8CB", -"y{ c #D1AED7", -"z{ c #D5B1D7", -"A{ c #D3B0D7", -"B{ c #D9B7CB", -"C{ c #EBC0D4", -"D{ c #D9B9CE", -"E{ c #D0B4D3", -"F{ c #CBB3D5", -"G{ c #D5BAE2", -"H{ c #CBB4D5", -"I{ c #C7ACCE", -"J{ c #D2B3D5", -"K{ c #B9A8D1", -"L{ c #C8B6E1", -"M{ c #CFBAE2", -"N{ c #C8B2DA", -"O{ c #B7A7D5", -"P{ c #B2A4D4", -"Q{ c #AF9BC5", -"R{ c #AA95BC", -"S{ c #988CBC", -"T{ c #AC9AD0", -"U{ c #AC9ABC", -"V{ c #A993B2", -"W{ c #9C8AA9", -"X{ c #9F8CAE", -"Y{ c #AC98B9", -"Z{ c #C2A6BD", -"`{ c #CCAEC6", -" ] c #D5B3C3", -".] c #D1ABBE", -"+] c #CAA7B6", -"@] c #C2A2B2", -"#] c #B99AA7", -"$] c #AA91A8", -"%] c #B294B4", -"&] c #B094B0", -"*] c #B79EB2", -"=] c #B69FAB", -"-] c #B99CAF", -";] c #BB99A4", -">] c #C197A0", -",] c #B794A6", -"'] c #B79AAE", -")] c #BCA1B8", -"!] c #BEA3BE", -"~] c #CEACCE", -"{] c #C5ABCA", -"]] c #C6AECF", -"^] c #B8A2C8", -"/] c #A799CA", -"(] c #C5C0F4", -"_] c #B8B2F1", -":] c #9A97D7", -"<] c #8D85B3", -"[] c #978CB4", -"}] c #A897B9", -"|] c #AC99BA", -"1] c #B19ABB", -"2] c #AF99B6", -"3] c #A290AF", -"4] c #A190B2", -"5] c #A699C1", -"6] c #C4B7E9", -"7] c #A79FCC", -"8] c #A89BCC", -"9] c #D0C4F3", -"0] c #C4BAF2", -"a] c #BCB4E9", -"b] c #B6AEEA", -"c] c #C0B7F2", -"d] c #B9B4EF", -"e] c #D0C3FD", -"f] c #C7BDF7", -"g] c #B3AEED", -"h] c #BEB6ED", -"i] c #BDB6ED", -"j] c #B2ABE3", -"k] c #B2A3E7", -"l] c #A89FE0", -"m] c #A398D4", -"n] c #9C92D8", -"o] c #948BD2", -"p] c #8D83CB", -"q] c #8D80C6", -"r] c #5B518A", -"s] c #0B0919", -"t] c #111C1A", -"u] c #DCECE6", -"v] c #BB90D1", -"w] c #B88FCD", -"x] c #EFE9D5", -"y] c #25241C", -"z] c #030303", -"A] c #010001", -"B] c #413F3E", -"C] c #585756", -"D] c #585854", -"E] c #51514B", -"F] c #3D3C3B", -"G] c #373533", -"H] c #3C3C37", -"I] c #373732", -"J] c #2B2A29", -"K] c #2D3D37", -"L] c #EAF0EE", -"M] c #BB8FD1", -"N] c #B081C8", -"O] c #BE99D1", -"P] c #ECE6C6", -"Q] c #0F100F", -"R] c #10100F", -"S] c #21201F", -"T] c #565652", -"U] c #716E67", -"V] c #75726D", -"W] c #6D6C69", -"X] c #868583", -"Y] c #7A7876", -"Z] c #726C69", -"`] c #5A5A55", -" ^ c #51514D", -".^ c #D6F5E4", -"+^ c #FEFDE9", -"@^ c #3C3A27", -"#^ c #100F0F", -"$^ c #0D0D0C", -"%^ c #181717", -"&^ c #2C2C2A", -"*^ c #393836", -"=^ c #4B4A47", -"-^ c #625F5E", -";^ c #666460", -">^ c #4F4F4A", -",^ c #423F3F", -"'^ c #6E6B6A", -")^ c #A6A09C", -"!^ c #AFA9A6", -"~^ c #908D8C", -"{^ c #0B0B0B", -"]^ c #CCE5DB", -"^^ c #C7A7D8", -"/^ c #F1EAF1", -"(^ c #848056", -"_^ c #010003", -":^ c #444E53", -"<^ c #695E5B", -"[^ c #0D0510", -"}^ c #0F0914", -"|^ c #030006", -"1^ c #3A5850", -"2^ c #E9EBEE", -"3^ c #C89EDD", -"4^ c #BD91D2", -"5^ c #E4DCB9", -"6^ c #353A59", -"7^ c #30335A", -"8^ c #404278", -"9^ c #7979B8", -"0^ c #888AD6", -"a^ c #A4A3F2", -"b^ c #AFAEF8", -"c^ c #8280E2", -"d^ c #827EDC", -"e^ c #8983DC", -"f^ c #B8B2F7", -"g^ c #CCC7FF", -"h^ c #CAC2FF", -"i^ c #C2BAED", -"j^ c #D7BEF0", -"k^ c #DFC6FD", -"l^ c #E1C2EA", -"m^ c #D8B9DE", -"n^ c #CFB0D5", -"o^ c #D9B8D5", -"p^ c #D9B7D7", -"q^ c #D8B6D7", -"r^ c #D2B2D3", -"s^ c #DFBDD4", -"t^ c #E0BDDF", -"u^ c #DFBADF", -"v^ c #D5BDCF", -"w^ c #CFB6D5", -"x^ c #CFB1D7", -"y^ c #D0B0D1", -"z^ c #CAB3D4", -"A^ c #D2B6E3", -"B^ c #CAB6E5", -"C^ c #DAC1EE", -"D^ c #D8BDE3", -"E^ c #C4B1D5", -"F^ c #C0ACD9", -"G^ c #BDAAD9", -"H^ c #AEA4D5", -"I^ c #9890CD", -"J^ c #958DD1", -"K^ c #9187C8", -"L^ c #9187C6", -"M^ c #A89CC6", -"N^ c #B1A0D1", -"O^ c #B8A3D2", -"P^ c #A897BC", -"Q^ c #B798BE", -"R^ c #BDA0C8", -"S^ c #BC9FC1", -"T^ c #BCA1C1", -"U^ c #A793B6", -"V^ c #A48DB2", -"W^ c #AB99B1", -"X^ c #B79CC1", -"Y^ c #BDA3CB", -"Z^ c #BAA2C3", -"`^ c #B89CC0", -" / c #BBA2BB", -"./ c #B9A2B3", -"+/ c #BB9CA8", -"@/ c #B994A1", -"#/ c #B498AB", -"$/ c #B398A8", -"%/ c #BA98A7", -"&/ c #BA98A3", -"*/ c #C49EA8", -"=/ c #C4A3B7", -"-/ c #D0AFBE", -";/ c #CEB2C3", -">/ c #C8ACC1", -",/ c #C5AECE", -"'/ c #AC9FC6", -")/ c #A6A1DA", -"!/ c #9B9AD7", -"~/ c #8985C0", -"{/ c #77739F", -"]/ c #9387B4", -"^/ c #A795BD", -"// c #B39EC3", -"(/ c #BAA2C6", -"_/ c #BDA0C7", -":/ c #B6A3BE", -"( c #F3EDDA", -",( c #1F1D14", -"'( c #020003", -")( c #021016", -"!( c #000A15", -"~( c #0B181F", -"{( c #040009", -"]( c #373D66", -"^( c #9BD0C9", -"/( c #F1EAF4", -"(( c #C7A4D7", -"_( c #E3DCB7", -":( c #222439", -"<( c #1F203F", -"[( c #504F74", -"}( c #8586B4", -"|( c #9595E0", -"1( c #A4A6F0", -"2( c #9291EA", -"3( c #8483E1", -"4( c #8C85D9", -"5( c #9E9BE7", -"6( c #A8A6F4", -"7( c #CCC5F8", -"8( c #ABA7EB", -"9( c #A49BE3", -"0( c #DAC2F2", -"a( c #E9CEFD", -"b( c #E3C5ED", -"c( c #DBBADF", -"d( c #DBB9DC", -"e( c #DFBEE6", -"f( c #E1BDDD", -"g( c #E1BED9", -"h( c #DDBDC6", -"i( c #E1BECE", -"j( c #DEBBD1", -"k( c #DCBCCA", -"l( c #DFBCD2", -"m( c #D5B8CE", -"n( c #D1B3CE", -"o( c #D3B3D2", -"p( c #CEB7C7", -"q( c #CFB4CD", -"r( c #E2BEE4", -"s( c #DFC1E6", -"t( c #DBC4EE", -"u( c #D0B8E6", -"v( c #D8BDE1", -"w( c #D2C1F3", -"x( c #D2C0ED", -"y( c #C2AFD5", -"z( c #AFA0C5", -"A( c #9990BC", -"B( c #938CCB", -"C( c #7C77B2", -"D( c #8078BD", -"E( c #8E87C8", -"F( c #9E94C8", -"G( c #B8A8DA", -"H( c #AC9CC2", -"I( c #A99AC4", -"J( c #A394B8", -"K( c #9A8DB2", -"L( c #9E93BB", -"M( c #A193BD", -"N( c #AB9FC6", -"O( c #BEABD2", -"P( c #BCA9CD", -"Q( c #BDA6CD", -"R( c #BDA6CA", -"S( c #C1ABC6", -"T( c #C7ABD1", -"U( c #C2A9C2", -"V( c #BBA0B7", -"W( c #BC9AA7", -"X( c #BB9CA9", -"Y( c #C19FAB", -"Z( c #C49EA9", -"`( c #C09CA3", -" _ c #C099A3", -"._ c #C49EA0", -"+_ c #CCA8B6", -"@_ c #D2B1BD", -"#_ c #CCB0C7", -"$_ c #C7AACC", -"%_ c #A292BC", -"&_ c #A99FD4", -"*_ c #D3C5E9", -"=_ c #B0AAEB", -"-_ c #A8A4E6", -";_ c #B0ABD7", -">_ c #8E8BC3", -",_ c #877FBA", -"'_ c #8A7FBB", -")_ c #8C83B3", -"!_ c #7F7CA9", -"~_ c #7776A3", -"{_ c #6E6C9E", -"]_ c #8B84BC", -"^_ c #9A90C1", -"/_ c #9E90C1", -"(_ c #9F92BB", -"__ c #A690C1", -":_ c #A79AC2", -"<_ c #A39BBD", -"[_ c #A190C0", -"}_ c #A49EC5", -"|_ c #9186B8", -"1_ c #A192C7", -"2_ c #978BB9", -"3_ c #9185B6", -"4_ c #A394C1", -"5_ c #CEC4F2", -"6_ c #D2C2F6", -"7_ c #C0B8E7", -"8_ c #AAA3D2", -"9_ c #B2A8DE", -"0_ c #ACA1DE", -"a_ c #988ACF", -"b_ c #9A90D8", -"c_ c #9B90D4", -"d_ c #9086CE", -"e_ c #9083C5", -"f_ c #897DC1", -"g_ c #463E6A", -"h_ c #000D19", -"i_ c #4B7365", -"j_ c #EFEBF2", -"k_ c #C29ED3", -"l_ c #B992CC", -"m_ c #C6A8D5", -"n_ c #DAD4A9", -"o_ c #080908", -"p_ c #2B2B29", -"q_ c #5D5D58", -"r_ c #6B6B65", -"s_ c #64645F", -"t_ c #363533", -"u_ c #33322F", -"v_ c #363432", -"w_ c #343133", -"x_ c #312E30", -"y_ c #8AC0AC", -"z_ c #E1D8E5", -"A_ c #BD9ACE", -"B_ c #BE9CCF", -"C_ c #E5DFE7", -"D_ c #C4C089", -"E_ c #121110", -"F_ c #222121", -"G_ c #383635", -"H_ c #484745", -"I_ c #555550", -"J_ c #74746E", -"K_ c #7C7C76", -"L_ c #8E8B86", -"M_ c #B4B1AC", -"N_ c #6D6D68", -"O_ c #93C9B2", -"P_ c #FFFFFB", -"Q_ c #999669", -"R_ c #191817", -"S_ c #141313", -"T_ c #282825", -"U_ c #3B3B37", -"V_ c #5B5A57", -"W_ c #575654", -"X_ c #454542", -"Y_ c #4A4949", -"Z_ c #6D6A67", -"`_ c #938F8D", -" : c #9F9E9E", -".: c #9DCCBD", -"+: c #CAB0D8", -"@: c #C3A1D3", -"#: c #EDE7C9", -"$: c #08060A", -"%: c #363964", -"&: c #9293E2", -"*: c #838BD6", -"=: c #7180BB", -"-: c #E9F1ED", -";: c #CDADDC", -">: c #E4DDB8", -",: c #1C1A2C", -"': c #1D1B36", -"): c #4B4A6E", -"!: c #948FB2", -"~: c #AAA7D9", -"{: c #948DD8", -"]: c #A7A1EC", -"^: c #CCC2F6", -"/: c #E9DFFF", -"(: c #DED7FF", -"_: c #C6BCF4", -":: c #A79FE0", -"<: c #B6A9EA", -"[: c #D8C6F4", -"}: c #E1C6F0", -"|: c #E1C0E6", -"1: c #E3C1E7", -"2: c #E7C4E6", -"3: c #E2C0DC", -"4: c #DEBDD7", -"5: c #DFBCCE", -"6: c #D7B4C4", -"7: c #D7B7CB", -"8: c #DCBACC", -"9: c #DAB8CB", -"0: c #DAB8CD", -"a: c #D5B6CA", -"b: c #D4B4CE", -"c: c #D4B6D0", -"d: c #DCBBD4", -"e: c #DDBEDA", -"f: c #E3C2E9", -"g: c #E7CBEE", -"h: c #EED0F5", -"i: c #EED0F2", -"j: c #EECCF0", -"k: c #E0BEE0", -"l: c #C8AECF", -"m: c #C3AAC6", -"n: c #B69FC0", -"o: c #A995BE", -"p: c #B29EC5", -"q: c #9A8DBE", -"r: c #8B85C7", -"s: c #9A97CD", -"t: c #8079B9", -"u: c #6B689A", -"v: c #837CA9", -"w: c #A899BC", -"x: c #9E8CB0", -"y: c #A695BA", -"z: c #A897BD", -"A: c #A797C6", -"B: c #A092BA", -"C: c #B4A2CA", -"D: c #B8A3CA", -"E: c #BEA4CB", -"F: c #B29FC2", -"G: c #B3A0BB", -"H: c #B99EBC", -"I: c #C0A7CA", -"J: c #B69CBB", -"K: c #BAA3BB", -"L: c #BCA3BB", -"M: c #B69AB4", -"N: c #B8A0B2", -"O: c #C1A1AC", -"P: c #C4A1AA", -"Q: c #C5A4B1", -"R: c #C7A4B8", -"S: c #C1A0AE", -"T: c #C49A9C", -"U: c #D5B1BB", -"V: c #D7B6C8", -"W: c #C4ABB9", -"X: c #C6A8C2", -"Y: c #BCA2CB", -"Z: c #C3B0CF", -"`: c #8A82B7", -" < c #7E7CBE", -".< c #9F9BD5", -"+< c #BBB4F2", -"@< c #CAC3F7", -"#< c #B2A9E7", -"$< c #8C86C8", -"%< c #8C84C6", -"&< c #B3AAE0", -"*< c #AAA3D3", -"=< c #6E6DA3", -"-< c #928AC0", -";< c #948DB1", -">< c #978DB2", -",< c #988EB6", -"'< c #9C8BBB", -")< c #948AB3", -"!< c #9F90BC", -"~< c #9A8BB8", -"{< c #9086AF", -"]< c #9F92C0", -"^< c #A79ACB", -"/< c #9A92C6", -"(< c #A9A2D1", -"_< c #B4A9E2", -":< c #CBBCEE", -"<< c #C7BADF", -"[< c #D0C0F2", -"}< c #CCC2F3", -"|< c #B4A6DA", -"1< c #9C8EC3", -"2< c #9A90C7", -"3< c #958BCF", -"4< c #8C82C8", -"5< c #8A7FC6", -"6< c #8C85CB", -"7< c #998ED1", -"8< c #9489C6", -"9< c #897EBA", -"0< c #8A7DC0", -"a< c #2F2A4F", -"b< c #DCEEE6", -"c< c #BE9ACF", -"d< c #C4A5D3", -"e< c #F1ECD9", -"f< c #26251D", -"g< c #383834", -"h< c #575752", -"i< c #666661", -"j< c #74746F", -"k< c #373536", -"l< c #B9DFD0", -"m< c #CAAFD8", -"n< c #BF9BD0", -"o< c #BE9ACE", -"p< c #C9AED7", -"q< c #EFEACC", -"r< c #171716", -"s< c #363534", -"t< c #4C4B49", -"u< c #545352", -"v< c #514F4D", -"w< c #75756F", -"x< c #84807C", -"y< c #ACAAA7", -"z< c #A7A7A2", -"A< c #73736D", -"B< c #696963", -"C< c #D2F4E2", -"D< c #FCFBE0", -"E< c #505048", -"F< c #33332F", -"G< c #252423", -"H< c #1E1E1C", -"I< c #252422", -"J< c #3B3A39", -"K< c #52514F", -"L< c #484744", -"M< c #514F4E", -"N< c #697473", -"O< c #9FA399", -"P< c #C0BCAF", -"Q< c #CAC4B2", -"R< c #B8B29E", -"S< c #98927D", -"T< c #676565", -"U< c #888784", -"V< c #ABA9A7", -"W< c #A9A6A4", -"X< c #B0ACA8", -"Y< c #A19E9B", -"Z< c #1A1A19", -"`< c #190F1F", -" [ c #43364A", -".[ c #4A3C53", -"+[ c #46384D", -"@[ c #46384C", -"#[ c #45384C", -"$[ c #45384D", -"%[ c #332739", -"&[ c #0F0615", -"*[ c #08010F", -"=[ c #43354A", -"-[ c #46384E", -";[ c #47394E", -">[ c #44364A", -",[ c #19101F", -"'[ c #26161B", -")[ c #3D3044", -"![ c #140B1A", -"~[ c #BFE1D4", -"{[ c #C6A7D4", -"][ c #C5A5D4", -"^[ c #EFEACE", -"/[ c #090709", -"([ c #21203A", -"_[ c #9CA5E2", -":[ c #9DA6F9", -"<[ c #9098F1", -"[[ c #9099EF", -"}[ c #757ECA", -"|[ c #BFE4DC", -"1[ c #DDC3EA", -"2[ c #E7E1BA", -"3[ c #1F1D32", -"4[ c #2E2C3F", -"5[ c #595671", -"6[ c #9990B2", -"7[ c #C3B4E1", -"8[ c #E7D3F7", -"9[ c #F1DAFD", -"0[ c #F4D8FC", -"a[ c #F2D4FB", -"b[ c #EBCFF6", -"c[ c #F4D4F1", -"d[ c #EAC8F6", -"e[ c #E7C7EB", -"f[ c #E7C7E8", -"g[ c #D6B5DD", -"h[ c #D5B5DB", -"i[ c #CDAEDA", -"j[ c #D9B6D8", -"k[ c #DBBACF", -"l[ c #D7B3C6", -"m[ c #CCADC9", -"n[ c #C5AABE", -"o[ c #CAAFC2", -"p[ c #DEB9CA", -"q[ c #E0BACB", -"r[ c #DDB6BF", -"s[ c #DBB9CB", -"t[ c #DCBED2", -"u[ c #D1B6CB", -"v[ c #E4C7ED", -"w[ c #F6CFFC", -"x[ c #EECCFB", -"y[ c #E6C5EA", -"z[ c #DCBDD3", -"A[ c #DDBDCB", -"B[ c #D3B3C2", -"C[ c #CFACBC", -"D[ c #C8B1C0", -"E[ c #C6ABCC", -"F[ c #C0ABD4", -"G[ c #BAA3CF", -"H[ c #BCB1D2", -"I[ c #D8EADC", -"J[ c #CEC4BC", -"K[ c #8881B6", -"L[ c #7571A8", -"M[ c #7B72AE", -"N[ c #827EC1", -"O[ c #8981B6", -"P[ c #A093C3", -"Q[ c #AC9BC8", -"R[ c #A999C0", -"S[ c #9E94B7", -"T[ c #978EB6", -"U[ c #A091BA", -"V[ c #A895BD", -"W[ c #AB94B7", -"X[ c #B09CBF", -"Y[ c #B8A2C3", -"Z[ c #B8A2B9", -"`[ c #B7A1C3", -" } c #B59FBB", -".} c #B199BA", -"+} c #B99FBB", -"@} c #AE98B8", -"#} c #B098B5", -"$} c #BCA1BB", -"%} c #BEA2AF", -"&} c #C5A6B2", -"*} c #C7A4B3", -"=} c #C6A7B8", -"-} c #C19BA9", -";} c #CEA9B7", -">} c #D1B1C5", -",} c #C3A9C1", -"'} c #C7ACC3", -")} c #C7A9C5", -"!} c #C6AACA", -"~} c #B5A1BC", -"{} c #A192BC", -"]} c #BDADDE", -"^} c #C5B8E6", -"/} c #AEA4D0", -"(} c #C3B9EE", -"_} c #BAB1DC", -":} c #DDC3F2", -"<} c #DDC7EC", -"[} c #D6C2EC", -"}} c #8F84B9", -"|} c #7F77A9", -"1} c #8780C2", -"2} c #847ABA", -"3} c #857EB5", -"4} c #988DC2", -"5} c #9790C1", -"6} c #9B91BA", -"7} c #A292C3", -"8} c #A699CA", -"9} c #A599CA", -"0} c #B0A2CB", -"a} c #B1ABDA", -"b} c #DACAF0", -"c} c #C5BBF0", -"d} c #D4C6F3", -"e} c #BDB3DB", -"f} c #CCBCF4", -"g} c #BBB1EC", -"h} c #A79FD4", -"i} c #9289BA", -"j} c #998EC4", -"k} c #9186CD", -"l} c #7E78BC", -"m} c #8B7DC3", -"n} c #9183C7", -"o} c #9286C6", -"p} c #998CCE", -"q} c #9A89C2", -"r} c #8E7FBC", -"s} c #867AB0", -"t} c #251D32", -"u} c #9FD2BF", -"v} c #E3D1EC", -"w} c #C5A6D5", -"x} c #C5A9D3", -"y} c #E6E1E6", -"z} c #8B895E", -"A} c #3A3A38", -"B} c #555551", -"C} c #666660", -"D} c #3E4640", -"E} c #E8F1ED", -"F} c #CCAFD9", -"G} c #CFAFDE", -"H} c #C3A3D3", -"I} c #C7ABD6", -"J} c #F4F0EC", -"K} c #575536", -"L} c #0F0F0E", -"M} c #2D2C2C", -"N} c #434140", -"O} c #62625D", -"P} c #6D6D67", -"Q} c #70706A", -"R} c #706D66", -"S} c #676762", -"T} c #6D7B73", -"U} c #F8FEF8", -"V} c #E6E4AD", -"W} c #373735", -"X} c #272725", -"Y} c #272625", -"Z} c #2A2927", -"`} c #333130", -" | c #4E4C4A", -".| c #627069", -"+| c #C2D4C4", -"@| c #F5F3EA", -"#| c #E7D7EF", -"$| c #DCC3E9", -"%| c #DBC1E8", -"&| c #DBC1E7", -"*| c #E0C9EB", -"=| c #F9F5F1", -"-| c #EBE6CF", -";| c #BFB997", -">| c #8A8787", -",| c #9C9998", -"'| c #9C9796", -")| c #96908C", -"!| c #9C9793", -"~| c #97918D", -"{| c #192927", -"]| c #D9EADD", -"^| c #D1B8DA", -"/| c #D4B9DF", -"(| c #CCB0D8", -"_| c #C5AAD2", -":| c #C5AAD1", -"<| c #CAAED7", -"[| c #D4B9DE", -"}| c #CBAFD7", -"|| c #C8ACD5", -"1| c #CAAFD5", -"2| c #DACBD3", -"3| c #D2CBB6", -"4| c #A69F82", -"5| c #1B1320", -"6| c #0C0511", -"7| c #243C35", -"8| c #E1EDE1", -"9| c #D1B7DA", -"0| c #D4B8DE", -"a| c #C9ADD5", -"b| c #C4A8D0", -"c| c #D5BADE", -"d| c #CFB3DA", -"e| c #D2B8DA", -"f| c #B9B389", -"g| c #C8ABD5", -"h| c #CBB0D7", -"i| c #D9C7D9", -"j| c #DFD8C9", -"k| c #C4BE9D", -"l| c #484433", -"m| c #C9E7DB", -"n| c #CAACD8", -"o| c #C8ABD6", -"p| c #F3EFE5", -"q| c #393826", -"r| c #030304", -"s| c #5F659C", -"t| c #A4AEF8", -"u| c #979EF9", -"v| c #8B97F5", -"w| c #8C8BEB", -"x| c #928BDA", -"y| c #9A91D5", -"z| c #A4C6CC", -"A| c #FBF9FC", -"B| c #ECE7B8", -"C| c #413E4D", -"D| c #46404B", -"E| c #6E6476", -"F| c #A394B2", -"G| c #D9BDE1", -"H| c #E7CEF6", -"I| c #E2F0E7", -"J| c #D2B8DB", -"K| c #D5BBE0", -"L| c #D5BADF", -"M| c #CBAED7", -"N| c #D8BFDD", -"O| c #E2D9CB", -"P| c #DDCBB8", -"Q| c #D9B5C0", -"R| c #DDB3C3", -"S| c #D9AFB9", -"T| c #DBB6CB", -"U| c #EDCAE9", -"V| c #F4D1F0", -"W| c #E7C7E6", -"X| c #E4C0DF", -"Y| c #CFABBC", -"Z| c #D1AEBD", -"`| c #DAB6C4", -" 1 c #E7BAC5", -".1 c #DCB9D2", -"+1 c #D2B6D5", -"@1 c #C1A8CC", -"#1 c #C2A7C6", -"$1 c #B6DCD2", -"%1 c #EEECEF", -"&1 c #F7F5DE", -"*1 c #928BB6", -"=1 c #595A88", -"-1 c #57568A", -";1 c #505382", -">1 c #4E5485", -",1 c #55588D", -"'1 c #646598", -")1 c #8E85B6", -"!1 c #9B8DB2", -"~1 c #908BA2", -"{1 c #DEEDE1", -"]1 c #D6BDDE", -"^1 c #CAAED6", -"/1 c #C5A9D1", -"(1 c #D7BCE0", -"_1 c #DBC2E2", -":1 c #E6DCBC", -"<1 c #AF9CB6", -"[1 c #A491AD", -"}1 c #B59EAD", -"|1 c #BCA4B9", -"11 c #C3DFD7", -"21 c #D5BADD", -"31 c #CAADD6", -"41 c #C7ABD3", -"51 c #D6BBE0", -"61 c #DFC6E5", -"71 c #F6F0D5", -"81 c #BAA7AF", -"91 c #C6ABCB", -"01 c #CAAACB", -"a1 c #C0A5BE", -"b1 c #BAA2B3", -"c1 c #C3A2C7", -"d1 c #BEDBD4", -"e1 c #DCC4E2", -"f1 c #C7ABD4", -"g1 c #C4AAD1", -"h1 c #DAC2E1", -"i1 c #F5F2DC", -"j1 c #86849C", -"k1 c #636396", -"l1 c #69719D", -"m1 c #E2EEE4", -"n1 c #D0B7DA", -"o1 c #C8ADD4", -"p1 c #C9B0D2", -"q1 c #E3DCCE", -"r1 c #D4C6E2", -"s1 c #DBCAF6", -"t1 c #B3A9CE", -"u1 c #C4B7E7", -"v1 c #D5C4F7", -"w1 c #B7B0E0", -"x1 c #ACA8DD", -"y1 c #A39BD4", -"z1 c #938AC2", -"A1 c #8785B8", -"B1 c #E0EFE5", -"C1 c #DBC2E1", -"D1 c #C6AAD3", -"E1 c #D6BBE1", -"F1 c #DDC5E4", -"G1 c #D3CAB7", -"H1 c #4A426F", -"I1 c #44695D", -"J1 c #F2F1F4", -"K1 c #CCB0DA", -"L1 c #C3A5D2", -"M1 c #CDB5D9", -"N1 c #DFD9AF", -"O1 c #484843", -"P1 c #6E6E69", -"Q1 c #393835", -"R1 c #73A691", -"S1 c #F7F5F6", -"T1 c #CAB0D3", -"U1 c #ECE4EF", -"V1 c #C6ABD4", -"W1 c #E6E2E8", -"X1 c #CBC890", -"Y1 c #222120", -"Z1 c #353532", -"`1 c #474645", -" 2 c #5D5D57", -".2 c #72726D", -"+2 c #62625C", -"@2 c #62625E", -"#2 c #96CCB6", -"$2 c #FFFFFA", -"%2 c #97946D", -"&2 c #292827", -"*2 c #302F2D", -"=2 c #42423E", -"-2 c #494944", -";2 c #7A7877", -">2 c #AAC7B8", -",2 c #ECE9E9", -"'2 c #E3CFEC", -")2 c #FBF8F3", -"!2 c #E8E3C3", -"~2 c #A39B81", -"{2 c #5C5060", -"]2 c #5C5061", -"^2 c #60636C", -"/2 c #AFC3B5", -"(2 c #ECF2E6", -"_2 c #E9DAF0", -":2 c #E6D7EE", -"<2 c #E9E3D0", -"[2 c #B2AF92", -"}2 c #757270", -"|2 c #7C7A79", -"12 c #9A9695", -"22 c #8F8B85", -"32 c #9A9494", -"42 c #CEE3D4", -"52 c #DEC6E4", -"62 c #F1E8EA", -"72 c #DCC5E7", -"82 c #C6A7D5", -"92 c #C5A6D4", -"02 c #D8BEE5", -"a2 c #F1E8E8", -"b2 c #DABEE3", -"c2 c #D6B8E3", -"d2 c #D8B9E4", -"e2 c #D9BCE5", -"f2 c #E5D3E9", -"g2 c #DEC6EA", -"h2 c #E1CBEC", -"i2 c #F8F5EF", -"j2 c #DFD9B9", -"k2 c #5C583E", -"l2 c #0A0410", -"m2 c #1F342F", -"n2 c #D8E8D9", -"o2 c #F2E9EC", -"p2 c #C5A7D4", -"q2 c #F4EDF5", -"r2 c #E5D3E5", -"s2 c #D9BCE3", -"t2 c #DFC9E0", -"u2 c #ADA77D", -"v2 c #DABFE3", -"w2 c #D6B7E3", -"x2 c #D9BDE4", -"y2 c #EBDEEA", -"z2 c #E6D5EE", -"A2 c #E2CDED", -"B2 c #F8F5F5", -"C2 c #E9E4CB", -"D2 c #807D56", -"E2 c #0E0913", -"F2 c #08020E", -"G2 c #BFE4D6", -"H2 c #D3B8E0", -"I2 c #C8AED6", -"J2 c #E6E1E8", -"K2 c #C2BF8A", -"L2 c #19191A", -"M2 c #1D2019", -"N2 c #31355A", -"O2 c #A4AFF9", -"P2 c #9BA1F6", -"Q2 c #929CF9", -"R2 c #8B8EEE", -"S2 c #9B92EB", -"T2 c #B4A4EA", -"U2 c #C9AFEB", -"V2 c #CAADE5", -"W2 c #C0ABCF", -"X2 c #FBFEFB", -"Y2 c #F0EBBC", -"Z2 c #615766", -"`2 c #564E5C", -" 3 c #75687E", -".3 c #A595B4", -"+3 c #CEC0E1", -"@3 c #F0DAF6", -"#3 c #E2F1E8", -"$3 c #E0C8E6", -"%3 c #F3EAEC", -"&3 c #F2E9E9", -"*3 c #DBC0E4", -"=3 c #D7B9E4", -"-3 c #D7B8E4", -";3 c #DBC0E5", -">3 c #F2E8EE", -",3 c #DEC8E9", -"'3 c #EAE5E4", -")3 c #E5DABE", -"!3 c #DBB8D2", -"~3 c #E0BED5", -"{3 c #E3BBC8", -"]3 c #DBB4BC", -"^3 c #D8B6CA", -"/3 c #D8B3C7", -"(3 c #D4AEBC", -"_3 c #CEA8AF", -":3 c #DAAFBA", -"<3 c #D7B2C5", -"[3 c #D3B2BD", -"}3 c #D3B1C3", -"|3 c #C3A3B6", -"13 c #AA93A9", -"23 c #B89FB8", -"33 c #BEA5C0", -"43 c #DEEEE6", -"53 c #D1BDDC", -"63 c #E7E3E8", -"73 c #D1C6AD", -"83 c #8E7E9D", -"93 c #67667C", -"03 c #494D79", -"a3 c #4D5284", -"b3 c #4E5285", -"c3 c #55588C", -"d3 c #686792", -"e3 c #A493BA", -"f3 c #9389A4", -"g3 c #D9EBDD", -"h3 c #EAD9E7", -"i3 c #F4EDF4", -"j3 c #F5EFF2", -"k3 c #EFE4E4", -"l3 c #DFD5B1", -"m3 c #9C8895", -"n3 c #9B8998", -"o3 c #AF96A0", -"p3 c #B39EAE", -"q3 c #C1D9D1", -"r3 c #DFC7E5", -"s3 c #F2EAEE", -"t3 c #D9BFE6", -"u3 c #C8A9D7", -"v3 c #C2A4D1", -"w3 c #C9ADD7", -"x3 c #F1EBF4", -"y3 c #F8F4E7", -"z3 c #F4EEC9", -"A3 c #AF959D", -"B3 c #B298AA", -"C3 c #B79DAD", -"D3 c #B698A7", -"E3 c #BB98A1", -"F3 c #B8939E", -"G3 c #B7D5C5", -"H3 c #F5EFED", -"I3 c #DCC2E9", -"J3 c #D5B7E4", -"K3 c #CCACDB", -"L3 c #F7F2F4", -"M3 c #FAF7DB", -"N3 c #ACA5B2", -"O3 c #7D78A6", -"P3 c #666E96", -"Q3 c #DBEAE0", -"R3 c #DCC3E5", -"S3 c #E2CDE7", -"T3 c #F1E9F1", -"U3 c #CCB4D8", -"V3 c #ECE5D2", -"W3 c #B4AAC7", -"X3 c #9088B1", -"Y3 c #968EB9", -"Z3 c #A29BCB", -"`3 c #AEA6D6", -" 4 c #A9A5DA", -".4 c #ACA2D8", -"+4 c #998EC6", -"@4 c #948ABE", -"#4 c #DBF1E2", -"$4 c #F6F0EF", -"%4 c #F6F0F3", -"&4 c #F5EFE5", -"*4 c #C9C3A9", -"=4 c #7C6FA1", -"-4 c #7C71A1", -";4 c #26203C", -">4 c #DAF1E6", -",4 c #DAC0E6", -"'4 c #C7AAD5", -")4 c #CBB2D7", -"!4 c #F2EEDD", -"~4 c #323225", -"{4 c #373634", -"]4 c #747472", -"^4 c #BFEBD6", -"/4 c #FAF6E6", -"(4 c #BA9FC7", -"_4 c #E6ECEB", -":4 c #CEB4DB", -"<4 c #CEB8D9", -"[4 c #F0EBCF", -"}4 c #141414", -"|4 c #30302E", -"14 c #60605B", -"24 c #FCFADD", -"34 c #4F4E48", -"44 c #272624", -"54 c #262624", -"64 c #686862", -"74 c #71716B", -"84 c #4A4848", -"94 c #5F6C66", -"04 c #CEDDD5", -"a4 c #D5BFE0", -"b4 c #E6D6EE", -"c4 c #F0EACF", -"d4 c #747362", -"e4 c #3D3B3D", -"f4 c #2E2C2C", -"g4 c #2F2E2C", -"h4 c #2E2D2B", -"i4 c #555553", -"j4 c #90B8A8", -"k4 c #F5F3F3", -"l4 c #E3D0EC", -"m4 c #EEE9E9", -"n4 c #C8C596", -"o4 c #7F7B7B", -"p4 c #787774", -"q4 c #848381", -"r4 c #8D8D88", -"s4 c #979393", -"t4 c #1A111F", -"u4 c #241B2A", -"v4 c #CDE5DD", -"w4 c #CBB1D8", -"x4 c #F4EEF4", -"y4 c #75724F", -"z4 c #483A4E", -"A4 c #4D3E54", -"B4 c #4D3E53", -"C4 c #4B3D52", -"D4 c #403347", -"E4 c #647877", -"F4 c #D3E7D8", -"G4 c #FBF8FA", -"H4 c #E2D0EC", -"I4 c #EBE6E4", -"J4 c #BDBA87", -"K4 c #0D0812", -"L4 c #44364B", -"M4 c #D9E9E4", -"N4 c #CBB2D8", -"O4 c #F4EFF5", -"P4 c #C0BC85", -"Q4 c #3B2F41", -"R4 c #493B50", -"S4 c #413447", -"T4 c #120C17", -"U4 c #050009", -"V4 c #F4EEF3", -"W4 c #787551", -"X4 c #4C4055", -"Y4 c #4C3E54", -"Z4 c #4C3E53", -"`4 c #4A3C51", -" 5 c #332939", -".5 c #556768", -"+5 c #C6DBCB", -"@5 c #F9F7F6", -"#5 c #ECE8EA", -"$5 c #D6D2A7", -"%5 c #1F1C21", -"&5 c #0A0510", -"*5 c #99CDBA", -"=5 c #E8DBEF", -"-5 c #CAAFD7", -";5 c #CBB5D6", -">5 c #E6E1DC", -",5 c #747255", -"'5 c #1A191A", -")5 c #08060B", -"!5 c #08030C", -"~5 c #6B6FA6", -"{5 c #A1A8F3", -"]5 c #9096F0", -"^5 c #9193F0", -"/5 c #A69EE9", -"(5 c #C4B2F0", -"_5 c #CFB8F0", -":5 c #E4C3EB", -"<5 c #E4BBEC", -"[5 c #DCB1E1", -"}5 c #D9BFE8", -"|5 c #ECFDF1", -"15 c #EEEABA", -"25 c #7D6F81", -"35 c #695F70", -"45 c #7F7387", -"55 c #B49DB9", -"65 c #C4B7D4", -"75 c #E0C2EF", -"85 c #DCBEEC", -"95 c #D4C3EE", -"05 c #BEAFDA", -"a5 c #D2E8E2", -"b5 c #AB9C90", -"c5 c #998092", -"d5 c #9C8195", -"e5 c #A48796", -"f5 c #9D8193", -"g5 c #987D90", -"h5 c #987A8B", -"i5 c #A2ACAF", -"j5 c #E6EDE9", -"k5 c #DFC9E9", -"l5 c #D2BBDD", -"m5 c #E7E2DA", -"n5 c #CCB29F", -"o5 c #C2A1AC", -"p5 c #D1ABB8", -"q5 c #D7ADB7", -"r5 c #D8A9B1", -"s5 c #D6AAB1", -"t5 c #C8A0A8", -"u5 c #D5A9AC", -"v5 c #CDA9AF", -"w5 c #CAA3AA", -"x5 c #AE94A3", -"y5 c #B094A9", -"z5 c #C19AA4", -"A5 c #C2A3B3", -"B5 c #AEBFC3", -"C5 c #CFB8DA", -"D5 c #EEE9C9", -"E5 c #736576", -"F5 c #706279", -"G5 c #67647C", -"H5 c #494B7B", -"I5 c #474D7F", -"J5 c #494F7F", -"K5 c #4D5180", -"L5 c #A18EB3", -"M5 c #B19BBD", -"N5 c #9A8BA8", -"O5 c #A78FA9", -"P5 c #A7C0B9", -"Q5 c #F3EFF5", -"R5 c #CEB3DB", -"S5 c #F3EDEE", -"T5 c #9C9084", -"U5 c #76667B", -"V5 c #746675", -"W5 c #8A7387", -"X5 c #978090", -"Y5 c #A88CA8", -"Z5 c #B49BB5", -"`5 c #CCACC8", -" 6 c #CAABB8", -".6 c #BAA1B3", -"+6 c #DEEEE9", -"@6 c #E5DDB6", -"#6 c #867074", -"$6 c #847072", -"%6 c #877279", -"&6 c #947D86", -"*6 c #A68C99", -"=6 c #AF919A", -"-6 c #B68F9D", -";6 c #B28E98", -">6 c #B892A0", -",6 c #AE8A98", -"'6 c #C0E0D3", -")6 c #F7F2F9", -"!6 c #E2CBED", -"~6 c #F4EEDE", -"{6 c #928881", -"]6 c #685E75", -"^6 c #776B86", -"/6 c #918AA8", -"(6 c #AAA0C3", -"_6 c #938CAE", -":6 c #9C91C6", -"<6 c #A298C9", -"[6 c #C9EBE2", -"}6 c #DDC4E9", -"|6 c #D3B8E2", -"16 c #CCB0D9", -"26 c #DCD1E2", -"36 c #DED9AF", -"46 c #4B4A76", -"56 c #625F8B", -"66 c #918BBC", -"76 c #ACA8D4", -"86 c #A09BCC", -"96 c #9D90C0", -"06 c #948AB7", -"a6 c #998CBA", -"b6 c #9A89B7", -"c6 c #B3D5CF", -"d6 c #F7F2F8", -"e6 c #F5EEE0", -"f6 c #7B7487", -"g6 c #564F7E", -"h6 c #5E5683", -"i6 c #69618E", -"j6 c #70688F", -"k6 c #776B9A", -"l6 c #4A4565", -"m6 c #96CEB8", -"n6 c #F3EDF6", -"o6 c #CBB6D7", -"p6 c #E7E3E7", -"q6 c #969365", -"r6 c #181816", -"s6 c #333330", -"t6 c #666663", -"u6 c #575653", -"v6 c #49534C", -"w6 c #F1FDF3", -"x6 c #E9E6B3", -"y6 c #504554", -"z6 c #B9E1D2", -"A6 c #DEC8E8", -"B6 c #CAB2D7", -"C6 c #CCB7D8", -"D6 c #EEEBEA", -"E6 c #696745", -"F6 c #2C2B2A", -"G6 c #5A5957", -"H6 c #7E7E79", -"I6 c #7A7A74", -"J6 c #5B5B56", -"K6 c #5F7469", -"L6 c #FAFEF9", -"M6 c #DFDCA3", -"N6 c #464542", -"O6 c #272526", -"P6 c #20201E", -"Q6 c #494847", -"R6 c #777771", -"S6 c #7B7873", -"T6 c #87847F", -"U6 c #6A6A64", -"V6 c #576E63", -"W6 c #D9E1DD", -"X6 c #D5C2DF", -"Y6 c #E2CFEB", -"Z6 c #EAE4C2", -"`6 c #595656", -" 7 c #383735", -".7 c #2F2D2F", -"+7 c #201F20", -"@7 c #2A2929", -"#7 c #212020", -"$7 c #242323", -"%7 c #272525", -"&7 c #2D2C2B", -"*7 c #383835", -"=7 c #5D8575", -"-7 c #F1F3F3", -";7 c #E4D5ED", -">7 c #EBE8EB", -",7 c #D7D4A2", -"'7 c #7C7978", -")7 c #6C6B69", -"!7 c #6D6B69", -"~7 c #827E7C", -"{7 c #A3A09F", -"]7 c #08020D", -"^7 c #B3DDCD", -"/7 c #CFB9DB", -"(7 c #F7F4F1", -"_7 c #4B492C", -":7 c #020401", -"<7 c #09040C", -"[7 c #AADAC4", -"}7 c #F5F0F7", -"|7 c #D5C5DE", -"17 c #E7E4E8", -"27 c #CDCA94", -"37 c #0F0B12", -"47 c #06010B", -"57 c #08030D", -"67 c #C5E6D8", -"77 c #CFB9DA", -"87 c #F7F5F5", -"97 c #565433", -"07 c #040007", -"a7 c #476D60", -"b7 c #E5EFE9", -"c7 c #E3D2EC", -"d7 c #E2D7E7", -"e7 c #DDD9BA", -"f7 c #2F2C2B", -"g7 c #3D6155", -"h7 c #F3F3F4", -"i7 c #D1BBDC", -"j7 c #C8B0D4", -"k7 c #CFBCD8", -"l7 c #E6E1DA", -"m7 c #9A976C", -"n7 c #383945", -"o7 c #8A91C4", -"p7 c #9195E0", -"q7 c #8C8FE9", -"r7 c #9A93EB", -"s7 c #BCABEC", -"t7 c #DBB9EC", -"u7 c #E5BEEF", -"v7 c #EBBEEE", -"w7 c #E0BBDE", -"x7 c #DEAFDF", -"y7 c #E9C6ED", -"z7 c #F2DEF8", -"A7 c #E0D9E5", -"B7 c #C7B3C4", -"C7 c #8E839A", -"D7 c #7E7283", -"E7 c #88778C", -"F7 c #A695A4", -"G7 c #C8A9C2", -"H7 c #D4B3D9", -"I7 c #BEA5CA", -"J7 c #C0A9D1", -"K7 c #D6BADD", -"L7 c #C1E4DA", -"M7 c #75665B", -"N7 c #5B494E", -"O7 c #655157", -"P7 c #735C62", -"Q7 c #7A6268", -"R7 c #80656A", -"S7 c #886F7D", -"T7 c #8A7386", -"U7 c #92798C", -"V7 c #8E7D83", -"W7 c #E0EEE8", -"X7 c #DEC9E8", -"Y7 c #D1BFDC", -"Z7 c #E8E3DE", -"`7 c #B5A18D", -" 8 c #B58E97", -".8 c #CB9EA2", -"+8 c #D6A7AD", -"@8 c #CCA4A0", -"#8 c #D2A2A6", -"$8 c #DBA8AB", -"%8 c #CEA4AB", -"&8 c #CCA4AE", -"*8 c #D1A9A8", -"=8 c #D4A1A7", -"-8 c #CCA2A7", -";8 c #B89CA9", -">8 c #C7E8DC", -",8 c #D6BEE2", -"'8 c #CFBADA", -")8 c #EDE9E7", -"!8 c #787163", -"~8 c #514956", -"{8 c #6C6077", -"]8 c #4F4F72", -"^8 c #464A78", -"/8 c #525484", -"(8 c #4B4E7F", -"_8 c #5C5B83", -":8 c #A592B3", -"<8 c #AB98B8", -"[8 c #9384A4", -"}8 c #84798E", -"|8 c #D9F1E5", -"18 c #F0EDEC", -"28 c #78725C", -"38 c #4B4148", -"48 c #52464E", -"58 c #6A5A68", -"68 c #9C869B", -"78 c #A790AE", -"88 c #BDA4C1", -"98 c #D7BAD7", -"08 c #C7ABB7", -"a8 c #AC929A", -"b8 c #A3C7BB", -"c8 c #F4EFF6", -"d8 c #CEB9DA", -"e8 c #E0DAB0", -"f8 c #534545", -"g8 c #56474D", -"h8 c #635356", -"i8 c #77666B", -"j8 c #8E7C80", -"k8 c #A98C94", -"l8 c #B898A7", -"m8 c #B58F9B", -"n8 c #B291A6", -"o8 c #AD93A4", -"p8 c #A293A3", -"q8 c #FAFEFA", -"r8 c #FCF9F0", -"s8 c #8C8379", -"t8 c #4F4658", -"u8 c #4F465A", -"v8 c #5D566B", -"w8 c #71667E", -"x8 c #837692", -"y8 c #AB9BBE", -"z8 c #8E89AC", -"A8 c #7671A6", -"B8 c #C5EFDD", -"C8 c #F8F5F0", -"D8 c #E7E2E2", -"E8 c #DBC5E6", -"F8 c #D3BEDD", -"G8 c #E8E4E6", -"H8 c #A9A77F", -"I8 c #3A3C62", -"J8 c #646192", -"K8 c #837CB7", -"L8 c #8D87BA", -"M8 c #998FB8", -"N8 c #9C8CBE", -"O8 c #8B81AF", -"P8 c #9587B4", -"Q8 c #9286B0", -"R8 c #85769E", -"S8 c #E1F8EA", -"T8 c #FCFAFC", -"U8 c #AFA984", -"V8 c #413858", -"W8 c #393454", -"X8 c #3B375E", -"Y8 c #444064", -"Z8 c #5F5780", -"`8 c #796E98", -" 9 c #8677AA", -".9 c #8B7FB0", -"+9 c #282535", -"@9 c #395C50", -"#9 c #F4F5F5", -"$9 c #D4C1DF", -"%9 c #CCB6D7", -"&9 c #D5C4DD", -"*9 c #E4DFB5", -"=9 c #141413", -"-9 c #272724", -";9 c #6F6F6B", -">9 c #7DB29D", -",9 c #9D9B69", -"'9 c #2C2C2B", -")9 c #669683", -"!9 c #F4F1F6", -"~9 c #D2BEDC", -"{9 c #CDB9D7", -"]9 c #E0D6E4", -"^9 c #D2CE9C", -"/9 c #111110", -"(9 c #1F1F1D", -"_9 c #42423F", -":9 c #595856", -"<9 c #696964", -"[9 c #797876", -"}9 c #98D0B9", -"|9 c #FFFEF9", -"19 c #898665", -"29 c #3D3C3A", -"39 c #736F6A", -"49 c #7F7C77", -"59 c #77736E", -"69 c #827E78", -"79 c #696D67", -"89 c #D5E5DE", -"99 c #D6C5DF", -"09 c #E1CEEA", -"a9 c #F4EFD8", -"b9 c #63625D", -"c9 c #424140", -"d9 c #1B1A1A", -"e9 c #1E1D1D", -"f9 c #292728", -"g9 c #272627", -"h9 c #343432", -"i9 c #78AC97", -"j9 c #F5F2F5", -"k9 c #DBCCE3", -"l9 c #E9E6E8", -"m9 c #C1BE8D", -"n9 c #474644", -"o9 c #4C4A48", -"p9 c #7B7876", -"q9 c #908C8B", -"r9 c #AFDACB", -"s9 c #D2BFDC", -"t9 c #D3BFDC", -"u9 c #4B4A2C", -"v9 c #1F342D", -"w9 c #EBF4EE", -"x9 c #D3C0DC", -"y9 c #D1C0DA", -"z9 c #E9E5E6", -"A9 c #999667", -"B9 c #06030A", -"C9 c #C1E4D6", -"D9 c #F8F5F4", -"E9 c #504F30", -"F9 c #F7F5F0", -"G9 c #010200", -"H9 c #334C44", -"I9 c #E6F1EC", -"J9 c #E2D0EB", -"K9 c #D8C7E1", -"L9 c #E7E3BE", -"M9 c #141216", -"N9 c #CDECDE", -"O9 c #D1BBDD", -"P9 c #CCB7D7", -"Q9 c #D1C0D9", -"R9 c #E4E1E4", -"S9 c #E0DECA", -"T9 c #BEBBB0", -"U9 c #8D8AC4", -"V9 c #A697D7", -"W9 c #C9A6E6", -"X9 c #D7B2E2", -"Y9 c #E5BAEC", -"Z9 c #E5B7E5", -"`9 c #DAB3D3", -" 0 c #D8AFCF", -".0 c #EFCEFD", -"+0 c #F0E3FE", -"@0 c #FBE5FB", -"#0 c #EFCFEF", -"$0 c #CCB1D0", -"%0 c #A68FAD", -"&0 c #89748A", -"*0 c #887286", -"=0 c #AB8C9A", -"-0 c #CEA4B3", -";0 c #D1B1C8", -">0 c #D0AED3", -",0 c #D6BCE8", -"'0 c #CFB3D7", -")0 c #BFE3D8", -"!0 c #58523B", -"~0 c #322527", -"{0 c #3F3235", -"]0 c #5A474D", -"^0 c #785E66", -"/0 c #8B717C", -"(0 c #8C7484", -"_0 c #91747D", -":0 c #8F6D70", -"<0 c #7F6369", -"[0 c #90B5A4", -"}0 c #F5F1F6", -"|0 c #D4C3DD", -"10 c #F0EBCE", -"20 c #8E706E", -"30 c #AD8483", -"40 c #C19494", -"50 c #D1A0A0", -"60 c #D0A5AC", -"70 c #CEA7B0", -"80 c #BCA3B2", -"90 c #CBA9B8", -"00 c #D5A9B0", -"a0 c #D9AAB6", -"b0 c #C4A3AA", -"c0 c #BBA8B3", -"d0 c #EFF5F1", -"e0 c #D8C7DF", -"f0 c #EDE6F0", -"g0 c #D3C0DD", -"h0 c #DDD2E3", -"i0 c #D6D2A2", -"j0 c #332E36", -"k0 c #554A5D", -"l0 c #514E67", -"m0 c #7D7BA9", -"n0 c #65658E", -"o0 c #7E7DB5", -"p0 c #5C5C89", -"q0 c #4A4E7C", -"r0 c #52537C", -"s0 c #716C87", -"t0 c #8B7D99", -"u0 c #9FD1C1", -"v0 c #F5F1F7", -"w0 c #D5C3DE", -"x0 c #E2DBE6", -"y0 c #D2CE9A", -"z0 c #262027", -"A0 c #2F282D", -"B0 c #564958", -"C0 c #847580", -"D0 c #AC92AC", -"E0 c #C3ACBC", -"F0 c #E5C6E2", -"G0 c #DAB9D9", -"H0 c #B398A0", -"I0 c #9E898B", -"J0 c #EDF4F0", -"K0 c #D2BEDB", -"L0 c #F3EFDC", -"M0 c #3A3330", -"N0 c #32282B", -"O0 c #4B3C40", -"P0 c #69575D", -"Q0 c #8A7377", -"R0 c #A68790", -"S0 c #B2919A", -"T0 c #B58F98", -"U0 c #B696AA", -"V0 c #B49AAC", -"W0 c #A69EA4", -"X0 c #FCFEFB", -"Y0 c #EAE6B3", -"Z0 c #4D424A", -"`0 c #3B323B", -" a c #352D38", -".a c #4A414F", -"+a c #645A6D", -"@a c #897896", -"#a c #A191B0", -"$a c #716E94", -"%a c #464A73", -"&a c #C2EDDA", -"*a c #FCF9EF", -"=a c #C7B4CD", -"-a c #F2EFF4", -";a c #E1CDEA", -">a c #D5C4DE", -",a c #E8E4DA", -"'a c #63605A", -")a c #36375A", -"!a c #464875", -"~a c #505481", -"{a c #736EA0", -"]a c #847BAE", -"^a c #8981AA", -"/a c #8B80AF", -"(a c #8E84AB", -"_a c #81769A", -":a c #C2EEDB", -"b c #09070A", -",b c #C2E6D6", -"'b c #F8F6F4", -")b c #504F2F", -"!b c #100A15", -"~b c #021015", -"{b c #04141A", -"]b c #619280", -"^b c #F4F3F5", -"/b c #DDCFE4", -"(b c #E9E6EA", -"_b c #C5C28C", -":b c #121014", -"c c #A18CA1", -",c c #C9B2C6", -"'c c #D3B7CF", -")c c #C7ADB8", -"!c c #D0B2C4", -"~c c #CBB3C1", -"{c c #BCA9B8", -"]c c #E5F4EB", -"^c c #969265", -"/c c #241C1D", -"(c c #423337", -"_c c #6C575D", -":c c #8D7276", -"d c #F5F3F5", -",d c #E8E4BE", -"'d c #393837", -")d c #9F9F9D", -"!d c #07010E", -"~d c #B0DBCB", -"{d c #010301", -"]d c #B0DCCB", -"^d c #F6F3E0", -"/d c #1F1E13", -"(d c #0C050F", -"_d c #C2E5D6", -":d c #050208", -"e c #DBBCD9", -",e c #DAB6C8", -"'e c #D8B5C7", -")e c #D9BBCF", -"!e c #D3CFDB", -"~e c #FAFAFA", -"{e c #DACDE0", -"]e c #E5E1B6", -"^e c #1E181B", -"/e c #3D3135", -"(e c #6D5A61", -"_e c #947B88", -":e c #A88E9A", -"f c #3C3A3C", -",f c #3B383A", -"'f c #545653", -")f c #E1F3E9", -"!f c #D7CADD", -"~f c #EAE7E5", -"{f c #797754", -"]f c #222220", -"^f c #696864", -"/f c #8F8E8C", -"(f c #B1DCCB", -"_f c #B2DECD", -":f c #D9CDE0", -"g c #DDD8AB", -",g c #1E1B1F", -"'g c #413A45", -")g c #968498", -"!g c #DDBEDC", -"~g c #E5D2E1", -"{g c #CEACAD", -"]g c #D2B0B9", -"^g c #E0BEC6", -"/g c #C6EEDB", -"(g c #FEFDF4", -"_g c #F5F3EF", -":g c #F5F2E3", -"h c #DED4E2", -",h c #F9F7F3", -"'h c #6D6B51", -")h c #151414", -"!h c #3E3C3A", -"~h c #464344", -"{h c #3E3D3C", -"]h c #BDE6D4", -"^h c #ECE2F1", -"/h c #DFD7E3", -"(h c #DDD9AB", -"_h c #5B5857", -":h c #73716F", -"i c #C1B7D8", -",i c #7C799B", -"'i c #9490C2", -")i c #8282B8", -"!i c #51577D", -"~i c #464770", -"{i c #636A8C", -"]i c #EFF7F1", -"^i c #F4F1DB", -"/i c #2E2C28", -"(i c #322D32", -"_i c #665967", -":i c #A693AA", -"j c #605F5E", -",j c #5A5958", -"'j c #595654", -")j c #888582", -"!j c #72706B", -"~j c #7E7B76", -"{j c #817D78", -"]j c #A2C4B4", -"^j c #F8F6E5", -"/j c #414035", -"(j c #151413", -"_j c #1A1A1A", -":j c #403D3E", -"k c #F7F1C3", -",k c #9A7D83", -"'k c #7B6974", -")k c #62545F", -"!k c #AFDDCA", -"~k c #EFE9F3", -"{k c #E1D9E5", -"]k c #CAC68E", -"^k c #2F292D", -"/k c #4E454D", -"(k c #71676D", -"_k c #91879A", -":k c #E6D1F0", -"l c #5E8576", -",l c #F7F7F7", -"'l c #E3DCE5", -")l c #DDD6E0", -"!l c #DFDCAE", -"~l c #31302E", -"{l c #464644", -"]l c #676761", -"^l c #ACE0C9", -"/l c #6B694E", -"(l c #50504C", -"_l c #4D4B46", -":l c #585653", -"m c #F0B7B2", -",m c #D8F1E1", -"'m c #EAE4EC", -")m c #F2EBF4", -"!m c #FCFAF6", -"~m c #A29D6C", -"{m c #16100E", -"]m c #160F0F", -"^m c #382A27", -"/m c #73584F", -"(m c #9E7873", -"_m c #B98E86", -":m c #BF928E", -"n c #7D789F", -",n c #74729B", -"'n c #6A6A9C", -")n c #D0F0E0", -"!n c #DDD4E3", -"~n c #F6F4E6", -"{n c #3A3928", -"]n c #50504B", -"^n c #D1F4E1", -"/n c #FCFADE", -"(n c #525248", -"_n c #3F3F3B", -":n c #424541", -"o c #A49095", -",o c #AD90A9", -"'o c #C4E5D5", -")o c #F2F0EB", -"!o c #756E6C", -"~o c #6C696B", -"{o c #766C6E", -"]o c #8F7A7C", -"^o c #B49196", -"/o c #D8AEA4", -"(o c #EABBAF", -"_o c #F6C0B5", -":o c #EBC7B2", -"p c #343C66", -",p c #3D4777", -"'p c #434D84", -")p c #B8E9D7", -"!p c #57596B", -"~p c #2D3154", -"{p c #2E3153", -"]p c #40416B", -"^p c #565685", -"/p c #6E6C91", -"(p c #787299", -"_p c #7D779C", -":p c #7F79A2", -"

q c #281F22", -",q c #1B1417", -"'q c #405A50", -")q c #E1F1E8", -"!q c #E1CEEB", -"~q c #CFBCD9", -"{q c #E8E5E8", -"]q c #A9A474", -"^q c #614A4C", -"/q c #96757E", -"(q c #AC8F9D", -"_q c #C3A5AE", -":q c #AD97A9", -"r c #5F5F70", -",r c #4F4D72", -"'r c #353754", -")r c #2F3353", -"!r c #3B4064", -"~r c #91C5B6", -"{r c #D3C1DD", -"]r c #EDE9C9", -"^r c #2F303D", -"/r c #2C2F52", -"(r c #3B416B", -"_r c #434976", -":r c #B8E8D5", -"s c #C8A4D5", -",s c #AF94C6", -"'s c #B599C9", -")s c #C5A4C7", -"!s c #B095B5", -"~s c #9B7F9B", -"{s c #88708E", -"]s c #867085", -"^s c #7E6771", -"/s c #735A62", -"(s c #634D52", -"_s c #514044", -":s c #413236", -"t c #2B2C4D", -",t c #272744", -"'t c #292B4A", -")t c #333559", -"!t c #444771", -"~t c #474C79", -"{t c #444672", -"]t c #3F436C", -"^t c #424576", -"/t c #434879", -"(t c #646396", -"_t c #C4EEDD", -":t c #736F89", -"u c #E1DCAF", -",u c #0B0C16", -"'u c #201D2E", -")u c #544965", -"!u c #9379A1", -"~u c #C49ECE", -"{u c #C9EDE2", -"]u c #FBF5D0", -"^u c #CFA9DF", -"/u c #C19FD5", -"(u c #C4A0C9", -"_u c #C7A1D1", -":u c #DAAEDB", -"v c #E8E5B2", -",v c #4A4C6C", -"'v c #393B55", -")v c #2A2D46", -"!v c #24263E", -"~v c #97CFBB", -"{v c #F6F2F7", -"]v c #CCC891", -"^v c #12131D", -"/v c #24253C", -"(v c #363756", -"_v c #BAE9D6", -":v c #FEFCEA", -"w c #D6C6DE", -",w c #C8B0D5", -"'w c #D0B9DC", -")w c #F7F3E4", -"!w c #2D2D1B", -"~w c #AED9CA", -"{w c #F7F4F0", -"]w c #131510", -"^w c #0C0711", -"/w c #9BD0BA", -"(w c #D4C2DE", -"_w c #E7E2DE", -":w c #676448", -"x c #302E32", -",x c #584E58", -"'x c #716B72", -")x c #837D8B", -"!x c #A090B1", -"~x c #AAA0C1", -"{x c #A99FC0", -"]x c #9F94AE", -"^x c #A59ABC", -"/x c #A79BBF", -"(x c #B6E0D6", -"_x c #E0CEEA", -":x c #101218", -"y c #706E46", -",y c #3C3C3B", -"'y c #6A6967", -")y c #62615E", -"!y c #6A6A65", -"~y c #85837C", -"{y c #908C86", -"]y c #878684", -"^y c #83837D", -"/y c #CBB0D8", -"(y c #DAC1E7", -"_y c #F0EBC7", -":y c #222221", -"z c #DDC3E8", -",z c #D6B9E3", -"'z c #E6E0E2", -")z c #6E6C4D", -"!z c #262427", -"~z c #444141", -"{z c #8E849F", -"]z c #968B9F", -"^z c #AA98BB", -"/z c #A797BA", -"(z c #B2A2CA", -"_z c #A69CBD", -":z c #9BA5B3", -"A c #CBC88F", -",A c #191A19", -"'A c #3D3D3C", -")A c #636060", -"!A c #6B6866", -"~A c #868682", -"{A c #94928E", -"]A c #787872", -"^A c #80807C", -"/A c #4D534D", -"(A c #E1ECE6", -"_A c #C09BD1", -":A c #C19BD4", -"B c #F9FDF8", -",B c #E5DEB5", -"'B c #85768B", -")B c #74677B", -"!B c #63566A", -"~B c #605466", -"{B c #64586C", -"]B c #675D71", -"^B c #6D6277", -"/B c #6D6378", -"(B c #675D73", -"_B c #98C4B8", -":B c #F2ECF5", -"C c #555352", -",C c #393935", -"'C c #282725", -")C c #373633", -"!C c #97CFB8", -"~C c #B486CB", -"{C c #B086C1", -"]C c #F3F0F4", -"^C c #B6B37A", -"/C c #575552", -"(C c #827F7B", -"_C c #7D7A74", -":C c #8F8C87", -"D c #241E1D", -",D c #4B3F41", -"'D c #63595D", -")D c #6F6469", -"!D c #7B6F76", -"~D c #9A817F", -"{D c #957979", -"]D c #917C7F", -"^D c #977B81", -"/D c #8F7C7E", -"(D c #927D83", -"_D c #918083", -":D c #958184", -"E c #505050", -",E c #232644", -"'E c #1F2542", -")E c #2C3358", -"!E c #37406C", -"~E c #404977", -"{E c #545986", -"]E c #8580AE", -"^E c #6D6D93", -"/E c #908AC0", -"(E c #616961", -"_E c #E8EFED", -":E c #B583CD", -"F c #F6BBBC", -",F c #FBC2C2", -"'F c #FDC3C1", -")F c #F9C5BE", -"!F c #F2BBBE", -"~F c #E9B5BB", -"{F c #CDE6DC", -"]F c #BF94D4", -"^F c #F0E8F4", -"/F c #CBC48E", -"(F c #2D2224", -"_F c #2A1F1F", -":F c #514041", -"G c #5B5C86", -",G c #616194", -"'G c #51557D", -")G c #4A4D79", -"!G c #464673", -"~G c #60608F", -"{G c #545762", -"]G c #272943", -"^G c #303149", -"/G c #3B3C5C", -"(G c #42456A", -"_G c #3F426D", -":G c #414570", -"H c #1D1621", -",H c #2D232D", -"'H c #564857", -")H c #8C7787", -"!H c #BA99B8", -"~H c #C6A7C1", -"{H c #CFE8E0", -"]H c #BE9BD0", -"^H c #E3DAB5", -"/H c #6D5D64", -"(H c #7D6A77", -"_H c #A18597", -":H c #B699AC", -"I c #B080C8", -",I c #BE8DD3", -"'I c #F3EDD7", -")I c #27262A", -"!I c #262740", -"~I c #2D2D43", -"{I c #3D3C5B", -"]I c #424261", -"^I c #57577C", -"/I c #7870AF", -"(I c #7A7AB1", -"_I c #7E77AF", -":I c #737199", -"J c #B080C9", -",J c #F3EEF1", -"'J c #525132", -")J c #2E3229", -"!J c #31352C", -"~J c #2C3028", -"{J c #20211E", -"]J c #110E14", -"^J c #7DB09C", -"/J c #FBFAFA", -"(J c #A8A56E", -"_J c #09040D", -":J c #0A040F", -"K c #505261", -",K c #464C55", -"'K c #5B5E6D", -")K c #DCEBE5", -"!K c #AE7FC7", -"~K c #E8E1E1", -"{K c #5D5B43", -"]K c #353136", -"^K c #665D6B", -"/K c #7F7788", -"(K c #A89ABB", -"_K c #D4C8EA", -":K c #C5B9DD", -"L c #EEF0F1", -",L c #AF7DC8", -"'L c #F4EEE4", -")L c #35341E", -"!L c #757473", -"~L c #928F8C", -"{L c #918B88", -"]L c #A19F9B", -"^L c #AFACA6", -"/L c #8C8987", -"(L c #908C87", -"_L c #928E8A", -":L c #8F8B8A", -"M c #C7A6C8", -",M c #C4A6CD", -"'M c #B17FCA", -")M c #B27ACD", -"!M c #B589CB", -"~M c #E7DAED", -"{M c #F4EFCE", -"]M c #8D8073", -"^M c #8C768E", -"/M c #AE92AE", -"(M c #C4A5B4", -"_M c #DDAEAE", -":M c #EEB6B6", -"N c #C2A49E", -",N c #BDA19A", -"'N c #C0E3D6", -")N c #B17FCB", -"!N c #F2ECEE", -"~N c #64613E", -"{N c #06060E", -"]N c #10101D", -"^N c #2A293E", -"/N c #363852", -"(N c #494B6B", -"_N c #6A698F", -":N c #8280A7", -"O c #A97BC2", -",O c #A16EBD", -"'O c #B188C7", -")O c #DDD4C9", -"!O c #BEB3A8", -"~O c #A780B5", -"{O c #827864", -"]O c #395950", -"^O c #E4E8EA", -"/O c #BB8CD2", -"(O c #AD7DC6", -"_O c #E4DDE8", -":O c #C3BF88", -"P c #7F7686", -",P c #7D7484", -"'P c #7C7384", -")P c #787485", -"!P c #706E7E", -"~P c #6D6C7F", -"{P c #716E80", -"]P c #716D7D", -"^P c #77717F", -"/P c #85A09E", -"(P c #C8C8BF", -"_P c #C0A3D0", -":P c #AC80C4", -"

Q c #494D81", -",Q c #5C5F8C", -"'Q c #65668B", -")Q c #7774A9", -"!Q c #78A493", -"~Q c #F8F5F9", -"{Q c #F9F5FA", -"]Q c #CAC68C", -"^Q c #040403", -"/Q c #5F5F5A", -"(Q c #65655F", -"_Q c #70706C", -":Q c #9CCDB8", -"R c #7EAD98", -",R c #ECF1E8", -"'R c #C7A2DA", -")R c #C198D7", -"!R c #D9C4DE", -"~R c #E1D7D5", -"{R c #B087C0", -"]R c #B693C2", -"^R c #E4DBD9", -"/R c #F5F1F3", -"(R c #CEB0DF", -"_R c #F8F4F2", -":R c #DFD8B5", -"S c #D3CD9F", -",S c #31324E", -"'S c #43446D", -")S c #525481", -"!S c #5C5C87", -"~S c #535684", -"{S c #555A87", -"]S c #686799", -"^S c #656591", -"/S c #4D4E7C", -"(S c #40456E", -"_S c #343B5E", -":S c #CCF0DD", -"T c #6F70A7", -",T c #7B76C6", -"'T c #8A82BD", -")T c #9386B5", -"!T c #8E7CA3", -"~T c #796688", -"{T c #68526E", -"]T c #59445D", -"^T c #554056", -"/T c #62505D", -"(T c #80657A", -"_T c #987C97", -":T c #B392B1", -"U c #83829F", -",U c #9C95B3", -"'U c #9B8D9D", -")U c #B8A1B6", -"!U c #C9ADC7", -"~U c #B6A4B9", -"{U c #AB97AD", -"]U c #C8E5D2", -"^U c #C8C592", -"/U c #2C282E", -"(U c #1A161E", -"_U c #1D1A20", -":U c #363038", -"V c #C8C5C0", -",V c #C0BDB7", -"'V c #B7B4AE", -")V c #B1AEA9", -"!V c #A8A4A2", -"~V c #A09C97", -"{V c #989492", -"]V c #9E9A98", -"^V c #ABA9A6", -"/V c #969592", -"(V c #8B8B88", -"_V c #312D2F", -":V c #4B3F4F", -"W c #626477", -",W c #6A677D", -"'W c #6E6A7F", -")W c #6B6A79", -"!W c #6D6C7E", -"~W c #616373", -"{W c #595D6C", -"]W c #605F72", -"^W c #6A6881", -"/W c #807994", -"(W c #6B6573", -"_W c #44424D", -":W c #2E2A33", -"X c #1F2036", -",X c #333454", -"'X c #565581", -")X c #636399", -"!X c #505781", -"~X c #6B6898", -"{X c #646593", -"]X c #4E4E4B", -"^X c #393936", -"/X c #333331", -"(X c #3C3A39", -"_X c #5F5F59", -":X c #5D5955", -"Y c #706C81", -",Y c #626272", -"'Y c #5A5A6B", -")Y c #4E4C59", -"!Y c #3D3E4B", -"~Y c #36353F", -"{Y c #27272F", -"]Y c #1F1F27", -"^Y c #1B1B22", -"/Y c #1F2027", -"(Y c #282831", -"_Y c #333540", -":Y c #40414E", -"Z c #47496F", -",Z c #5B5A84", -"'Z c #595986", -")Z c #4A4E7A", -"!Z c #585B84", -"~Z c #706D9C", -"{Z c #5B5E8F", -"]Z c #51547B", -"^Z c #676492", -"/Z c #5A5883", -"(Z c #3C3C5B", -"_Z c #232643", -":Z c #2A2B4E", -"` c #584C5F", -",` c #514854", -"'` c #504753", -")` c #4C4553", -"!` c #45414D", -"~` c #4B4550", -"{` c #4E4955", -"]` c #534B5A", -"^` c #5C5367", -"/` c #5C596A", -"(` c #625E73", -"_` c #716C80", -":` c #6A687E", -"<` c #6C6A88", -"[` c #706D83", -"}` c #6D6B83", -"|` c #63627B", -"1` c #5B5B71", -"2` c #505062", -"3` c #454656", -"4` c #3D3F4A", -"5` c #323640", -"6` c #323342", -"7` c #2F323D", -"8` c #333442", -"9` c #3B3D4A", -"0` c #414250", -"a` c #474856", -"b` c #515162", -"c` c #5F5E6D", -"d` c #616370", -"e` c #616472", -"f` c #646479", -"g` c #67677D", -"h` c #66667E", -"i` c #626478", -"j` c #64647C", -"k` c #616278", -"l` c #5B5F70", -"m` c #5E616F", -"n` c #5E5F73", -"o` c #515464", -"p` c #484B5B", -"q` c #464656", -"r` c #3F4052", -"s` c #534E66", -"t` c #736B8A", -"u` c #746C87", -"v` c #71698A", -"w` c #726F8D", -"x` c #757488", -"y` c #707388", -"z` c #9E9ABD", -"A` c #ACA9C8", -"B` c #9893B6", -"C` c #8A89A8", -"D` c #9B9AB4", -"E` c #807F94", -"F` c #777285", -"G` c #6A657D", -"H` c #5F5D6E", -"I` c #535060", -"J` c #4E4C5D", -"K` c #494A56", -"L` c #766F86", -"M` c #7A748B", -"N` c #9791A0", -"O` c #A49DB6", -"P` c #9A91AF", -"Q` c #9B92A9", -"R` c #888288", -"S` c #A998AC", -"T` c #BAA3C4", -"U` c #A693A5", -"V` c #AE979E", -"W` c #9E8B9A", -"X` c #948195", -"Y` c #817188", -"Z` c #827388", -"`` c #756E79", -" . c #96819E", -". . c #B49BB8", -"+ . c #C0A2C6", -"@ . c #C2ABCD", -"# . c #C1ACCC", -"$ . c #B4A2B8", -"% . c #918998", -"& . c #46486A", -"* . c #3B3D62", -"= . c #272D4C", -"- . c #212542", -"; . c #202240", -"> . c #242944", -", . c #3A3A61", -"' . c #3C4163", -") . c #444871", -"! . c #5C5E87", -"~ . c #60618B", -"{ . c #5A5A86", -"] . c #5B5E85", -"^ . c #55597D", -"/ . c #54557B", -"( . c #5E5B7D", -"_ . c #565472", -": . c #504E72", -"< . c #373754", -"[ . c #2C2D47", -"} . c #2D2F47", -"| . c #4C4B6C", -"1 . c #47486E", -"2 . c #54547B", -"3 . c #686694", -"4 . c #616288", -"5 . c #4F527D", -"6 . c #494974", -"7 . c #505280", -"8 . c #4F527B", -"9 . c #605F8A", -"0 . c #53577F", -"a . c #5F5F91", -"b . c #51517F", -"c . c #41456D", -"d . c #36385E", -"e . c #303359", -"f . c #474774", -"g . c #464972", -"h . c #51557E", -"i . c #686697", -"j . c #585C8B", -"k . c #565886", -"l . c #5D5D8E", -"m . c #F4F4F4", -"n . c #FCFCFC", -"o . c #232220", -"p . c #4D4D48", -"q . c #989893", -"r . c #8E8B85", -"s . c #97938E", -"t . c #96928D", -"u . c #A8A8A2", -"v . c #8D8B86", -"w . c #C4C3C1", -"x . c #C0BCBA", -"y . c #BCBAB9", -"z . c #CECBC6", -"A . c #C1BDB8", -"B . c #9D9897", -"C . c #A09C9B", -"D . c #817D7C", -"E . c #6F6A67", -"F . c #777674", -"G . c #767672", -"H . c #676463", -"I . c #71716C", -"J . c #6C6C68", -"K . c #403E3D", -"L . c #050B02", -"M . c #040802", -"N . c #000A14", -"O . c #1F2B31", -"P . c #070716", -"Q . c #8191D1", -"R . c #8182CF", -"S . c #AC9ED3", -"T . c #B49FCF", -"U . c #B69DC4", -"V . c #B996B7", -"W . c #BB95B5", -"X . c #C8A1BF", -"Y . c #D0AAC5", -"Z . c #D4B0C4", -"` . c #D3B0CA", -" .. c #D1ABBF", -"... c #D6AEC8", -"+.. c #D2B1CB", -"@.. c #C5A7CC", -"#.. c #BEA0BB", -"$.. c #CAA7C0", -"%.. c #C5A6BC", -"&.. c #C4A4C0", -"*.. c #C2A7C2", -"=.. c #BC9DB9", -"-.. c #A28AA4", -";.. c #A088A5", -">.. c #907E9A", -",.. c #96839F", -"'.. c #9E89A5", -").. c #A08CA3", -"!.. c #96889E", -"~.. c #887E91", -"{.. c #7F728C", -"].. c #76677D", -"^.. c #6B6170", -"/.. c #625869", -"(.. c #5D5466", -"_.. c #5F546C", -":.. c #5A5263", -"<.. c #59525E", -"[.. c #665B71", -"}.. c #655E6E", -"|.. c #6C6578", -"1.. c #6A667C", -"2.. c #6E6A7D", -"3.. c #63647C", -"4.. c #696981", -"5.. c #646584", -"6.. c #67677E", -"7.. c #646581", -"8.. c #5C5E7B", -"9.. c #5D5D75", -"0.. c #56576B", -"a.. c #4E5261", -"b.. c #474C55", -"c.. c #454959", -"d.. c #484960", -"e.. c #47495C", -"f.. c #474A5B", -"g.. c #4E5060", -"h.. c #525266", -"i.. c #535767", -"j.. c #5C5E6C", -"k.. c #606372", -"l.. c #606371", -"m.. c #5F6076", -"n.. c #5C6173", -"o.. c #64647E", -"p.. c #626277", -"q.. c #646478", -"r.. c #5E6074", -"s.. c #5E6072", -"t.. c #5C5C74", -"u.. c #59596D", -"v.. c #57576D", -"w.. c #5D5B70", -"x.. c #686476", -"y.. c #857D9C", -"z.. c #877E9F", -"A.. c #7C758F", -"B.. c #6F6E84", -"C.. c #737085", -"D.. c #8886A2", -"E.. c #B0A8D1", -"F.. c #AEA6CC", -"G.. c #9C94AE", -"H.. c #9892A6", -"I.. c #C3BDCE", -"J.. c #898793", -"K.. c #928A9F", -"L.. c #958DAF", -"M.. c #9893AF", -"N.. c #938F9E", -"O.. c #868198", -"P.. c #8F8AA5", -"Q.. c #9E95B0", -"R.. c #9E9AB5", -"S.. c #B9ADCA", -"T.. c #C1B8D3", -"U.. c #9E9EB8", -"V.. c #91889B", -"W.. c #9A8A99", -"X.. c #BBA2C3", -"Y.. c #B2A3C0", -"Z.. c #AF98B0", -"`.. c #AD9BB6", -" +. c #9386A5", -".+. c #9587A4", -"++. c #9A87A1", -"@+. c #A191A8", -"#+. c #AA9FBD", -"$+. c #A594B2", -"%+. c #AC9BB9", -"&+. c #B19DBD", -"*+. c #AF9FB8", -"=+. c #C1A9CC", -"-+. c #9B8B9A", -";+. c #43435C", -">+. c #4A4A76", -",+. c #4C4D73", -"'+. c #43466B", -")+. c #3B3F5E", -"!+. c #383A5B", -"~+. c #47496D", -"{+. c #454970", -"]+. c #46476B", -"^+. c #44496A", -"/+. c #45486F", -"(+. c #46496F", -"_+. c #494B71", -":+. c #3E446F", -"<+. c #41446B", -"[+. c #4F527E", -"}+. c #4B4E76", -"|+. c #4C4F7A", -"1+. c #515478", -"2+. c #6E6899", -"3+. c #5D5A7B", -"4+. c #444763", -"5+. c #434567", -"6+. c #484873", -"7+. c #4D4D71", -"8+. c #44466C", -"9+. c #4E517C", -"0+. c #55577D", -"a+. c #4D5079", -"b+. c #626192", -"c+. c #4B5179", -"d+. c #565885", -"e+. c #525680", -"f+. c #585A88", -"g+. c #6D6C9E", -"h+. c #515277", -"i+. c #3F416A", -"j+. c #373864", -"k+. c #4B4A78", -"l+. c #5E5D89", -"m+. c #6C6998", -"n+. c #65658F", -"o+. c #5A5B8B", -"p+. c #575889", -"q+. c #555984", -"r+. c #EEEEEE", -"s+. c #5C5C57", -"t+. c #7B7B76", -"u+. c #686864", -"v+. c #87847E", -"w+. c #90908A", -"x+. c #7E7A74", -"y+. c #93938D", -"z+. c #A9A9A4", -"A+. c #A9A8A5", -"B+. c #979792", -"C+. c #B8B5B3", -"D+. c #A9A9A3", -"E+. c #A8A8A4", -"F+. c #BDBCB9", -"G+. c #CDCCCA", -"H+. c #C5C5C0", -"I+. c #C3C3BE", -"J+. c #C1C1BC", -"K+. c #B4B2AB", -"L+. c #A7A49E", -"M+. c #CCCAC3", -"N+. c #A09C9A", -"O+. c #ABA8A3", -"P+. c #B7B2B1", -"Q+. c #B9B6B4", -"R+. c #8D8988", -"S+. c #8A8785", -"T+. c #7E7D79", -"U+. c #878683", -"V+. c #8E8D8A", -"W+. c #858382", -"X+. c #848481", -"Y+. c #8A8987", -"Z+. c #73736F", -"`+. c #7A7A75", -" @. c #686664", -".@. c #5E5E5D", -"+@. c #191919", -"@@. c #060D03", -"#@. c #03141B", -"$@. c #241613", -"%@. c #4C261C", -"&@. c #91A2E5", -"*@. c #838CE5", -"=@. c #C0AFEF", -"-@. c #C5B0E2", -";@. c #D4ADE3", -">@. c #D8ADD7", -",@. c #D2A9C9", -"'@. c #D7B1CE", -")@. c #E0B6CA", -"!@. c #E2BAD1", -"~@. c #DAB4CB", -"{@. c #D9B1D1", -"]@. c #D3B0CE", -"^@. c #CDABCA", -"/@. c #CEA9CA", -"(@. c #C7A4C6", -"_@. c #C2A0C1", -":@. c #CBA4CB", -"<@. c #C1A0C2", -"[@. c #C09EC2", -"}@. c #C2A2C5", -"|@. c #C0A3C6", -"1@. c #BA9DC5", -"2@. c #A993B3", -"3@. c #9D8DAD", -"4@. c #9C8AAB", -"5@. c #9B8BA7", -"6@. c #A58DAE", -"7@. c #A890AE", -"8@. c #A28CB1", -"9@. c #93849F", -"0@. c #867B8F", -"a@. c #827487", -"b@. c #7F718D", -"c@. c #7A6B7E", -"d@. c #6D6479", -"e@. c #6D6577", -"f@. c #6F6678", -"g@. c #71697D", -"h@. c #706B7D", -"i@. c #686577", -"j@. c #716C84", -"k@. c #736F82", -"l@. c #67677C", -"m@. c #6B6A83", -"n@. c #64647D", -"o@. c #616483", -"p@. c #6A6889", -"q@. c #64667C", -"r@. c #606378", -"s@. c #5F5F7A", -"t@. c #5E5F74", -"u@. c #5A5B6D", -"v@. c #565977", -"w@. c #4E536B", -"x@. c #4E5367", -"y@. c #54566C", -"z@. c #56576C", -"A@. c #595C75", -"B@. c #5B5D6E", -"C@. c #606077", -"D@. c #5E5F71", -"E@. c #5D5F72", -"F@. c #5F6175", -"G@. c #5C6071", -"H@. c #5A5F6C", -"I@. c #5E6174", -"J@. c #616179", -"K@. c #626279", -"L@. c #5F6071", -"M@. c #5E6173", -"N@. c #5F6078", -"O@. c #5A5E71", -"P@. c #585C6D", -"Q@. c #5C5D6E", -"R@. c #616176", -"S@. c #7B758C", -"T@. c #887FA2", -"U@. c #8E85AD", -"V@. c #827A96", -"W@. c #A9A5C4", -"X@. c #A9A0C7", -"Y@. c #A79FC7", -"Z@. c #A499B4", -"`@. c #A79ABB", -" #. c #8B868E", -".#. c #B0A8C1", -"+#. c #ADA7C5", -"@#. c #B4AACE", -"##. c #9A94AC", -"$#. c #AAA6B9", -"%#. c #C5BBD3", -"&#. c #BAB1CE", -"*#. c #A19BB9", -"=#. c #8C86A7", -"-#. c #BBB5CB", -";#. c #9494AB", -">#. c #ACA5CA", -",#. c #ACA4BA", -"'#. c #AB9DB2", -")#. c #B29CB8", -"!#. c #A997AC", -"~#. c #B09EBD", -"{#. c #B3A2C2", -"]#. c #ADA1BD", -"^#. c #A899BF", -"/#. c #AB9BBF", -"(#. c #A191B1", -"_#. c #A194B5", -":#. c #B0A3C2", -"<#. c #B8ABD0", -"[#. c #A397B6", -"}#. c #A295AE", -"|#. c #D1BFDA", -"1#. c #AB96AB", -"2#. c #484C6B", -"3#. c #494E6B", -"4#. c #4C4A71", -"5#. c #606389", -"6#. c #4F5378", -"7#. c #4B4F6F", -"8#. c #4A4F70", -"9#. c #4A4E71", -"0#. c #51537C", -"a#. c #4D5176", -"b#. c #494D75", -"c#. c #4B4C75", -"d#. c #474B73", -"e#. c #373E5E", -"f#. c #30345E", -"g#. c #2E375E", -"h#. c #343A5D", -"i#. c #40426D", -"j#. c #404169", -"k#. c #53577D", -"l#. c #58597F", -"m#. c #484C6E", -"n#. c #3F4467", -"o#. c #45486D", -"p#. c #505278", -"q#. c #515479", -"r#. c #42466D", -"s#. c #4F517E", -"t#. c #4E5276", -"u#. c #7777AB", -"v#. c #53567A", -"w#. c #656489", -"x#. c #757298", -"y#. c #9593C0", -"z#. c #58587B", -"A#. c #4E4F74", -"B#. c #7570A9", -"C#. c #7873AA", -"D#. c #525377", -"E#. c #383B63", -"F#. c #373B67", -"G#. c #43456E", -"H#. c #515680", -"I#. c #5D5D8C", -"J#. c #5C5C86", -"K#. c #565780", -"L#. c #4B5072", -"M#. c #535683", -"N#. c #E9E9E9", -"O#. c #F2F2F2", -"P#. c #71716D", -"Q#. c #726E68", -"R#. c #89857F", -"S#. c #93938E", -"T#. c #B1B0AE", -"U#. c #B6B5B2", -"V#. c #9E9D9B", -"W#. c #C5C5BF", -"X#. c #C0BEBB", -"Y#. c #A3A39E", -"Z#. c #BBBAB8", -"`#. c #CBCAC7", -" $. c #C7C7C2", -".$. c #B6B6B0", -"+$. c #9E9999", -"@$. c #98928E", -"#$. c #95928D", -"$$. c #A29E9D", -"%$. c #8F8A89", -"&$. c #92918F", -"*$. c #878583", -"=$. c #969593", -"-$. c #9D9C9A", -";$. c #898886", -">$. c #7F7E7B", -",$. c #80807B", -"'$. c #656563", -")$. c #20201F", -"!$. c #281915", -"~$. c #83574B", -"{$. c #1C0A06", -"]$. c #58669C", -"^$. c #8893EE", -"/$. c #B2AAF1", -"($. c #D5B4F2", -"_$. c #E0B7EA", -":$. c #E2B6E3", -"<$. c #E1AFDE", -"[$. c #E0B2D0", -"}$. c #E4BAD7", -"|$. c #EAC0D3", -"1$. c #E3C0DC", -"2$. c #D7B5CD", -"3$. c #D2B0CF", -"4$. c #C7A6C4", -"5$. c #CBA7CA", -"6$. c #CCA7CC", -"7$. c #C4A2C8", -"8$. c #BE9FC0", -"9$. c #BB99BB", -"0$. c #C09EC1", -"a$. c #BCA0C5", -"b$. c #B69EC3", -"c$. c #AB96B6", -"d$. c #A490B7", -"e$. c #A593B6", -"f$. c #9E8EAE", -"g$. c #9E8BAD", -"h$. c #9788A3", -"i$. c #888199", -"j$. c #897E9E", -"k$. c #887F96", -"l$. c #81798B", -"m$. c #8A7D93", -"n$. c #877A90", -"o$. c #80778A", -"p$. c #797288", -"q$. c #737082", -"r$. c #716E83", -"s$. c #716E87", -"t$. c #68687C", -"u$. c #6F6C82", -"v$. c #6C6B83", -"w$. c #656679", -"x$. c #606579", -"y$. c #5F6279", -"z$. c #666680", -"A$. c #656683", -"B$. c #5E607A", -"C$. c #5E5E76", -"D$. c #65657E", -"E$. c #6C6C83", -"F$. c #63647D", -"G$. c #5D5D7E", -"H$. c #535871", -"I$. c #585972", -"J$. c #595E70", -"K$. c #5B6073", -"L$. c #79768F", -"M$. c #646678", -"N$. c #65657D", -"O$. c #716F8C", -"P$. c #6E6E84", -"Q$. c #595C6D", -"R$. c #565970", -"S$. c #5B5F72", -"T$. c #5B5C74", -"U$. c #5F6177", -"V$. c #5F5F77", -"W$. c #5E6076", -"X$. c #5A5F73", -"Y$. c #595F6D", -"Z$. c #666678", -"`$. c #75728B", -" %. c #6D6D84", -".%. c #78768B", -"+%. c #858294", -"@%. c #918FA2", -"#%. c #A89EBD", -"$%. c #AFA7C6", -"%%. c #B9A8CA", -"&%. c #AB9AB6", -"*%. c #928698", -"=%. c #7E7A8A", -"-%. c #A69FBB", -";%. c #A293B0", -">%. c #A297B6", -",%. c #93889A", -"'%. c #837C88", -")%. c #A8A4B9", -"!%. c #C2BAD9", -"~%. c #CCC3E1", -"{%. c #B1AACE", -"]%. c #8C88A0", -"^%. c #B8B2CD", -"/%. c #ADA2BF", -"(%. c #B6A7C9", -"_%. c #B5A7C6", -":%. c #AFA0B9", -"<%. c #B9A1C1", -"[%. c #AD9FBB", -"}%. c #C0B8D0", -"|%. c #9B98B0", -"1%. c #9089AD", -"2%. c #8F88AD", -"3%. c #988FAF", -"4%. c #948DA4", -"5%. c #807C8D", -"6%. c #ACA3C3", -"7%. c #BCB1CF", -"8%. c #978E9C", -"9%. c #4D4D61", -"0%. c #5C5E7E", -"a%. c #66668D", -"b%. c #63648D", -"c%. c #5D5D85", -"d%. c #5D5E85", -"e%. c #51577F", -"f%. c #5D6087", -"g%. c #676797", -"h%. c #55597C", -"i%. c #4F5374", -"j%. c #3B3F62", -"k%. c #3A3B65", -"l%. c #373B60", -"m%. c #30355B", -"n%. c #353760", -"o%. c #3A3E62", -"p%. c #3E4065", -"q%. c #3E3F63", -"r%. c #3E3F67", -"s%. c #363963", -"t%. c #424469", -"u%. c #3A3D68", -"v%. c #3F4468", -"w%. c #3F4268", -"x%. c #51527D", -"y%. c #494C75", -"z%. c #57587E", -"A%. c #6D6C9B", -"B%. c #626285", -"C%. c #464B6C", -"D%. c #7A79A0", -"E%. c #6D6C86", -"F%. c #6D6993", -"G%. c #787CA5", -"H%. c #666688", -"I%. c #6E6C9D", -"J%. c #54557A", -"K%. c #3E4266", -"L%. c #3C3E64", -"M%. c #41436F", -"N%. c #474B6F", -"O%. c #4C4F7D", -"P%. c #575785", -"Q%. c #585986", -"R%. c #4A507A", -"S%. c #4A4F77", -"T%. c #E3E3E3", -"U%. c #ECECEC", -"V%. c #232323", -"W%. c #60605A", -"X%. c #787672", -"Y%. c #807D78", -"Z%. c #7E7A76", -"`%. c #908D86", -" &. c #9B9A99", -".&. c #BBBBB7", -"+&. c #ABABA6", -"@&. c #A6A29E", -"#&. c #BCBAB7", -"$&. c #BCBBB9", -"%&. c #B8B8B3", -"&&. c #BBBBB6", -"*&. c #C3C3BD", -"=&. c #ACACA8", -"-&. c #A1A09E", -";&. c #92918E", -">&. c #8B8A87", -",&. c #908F8C", -"'&. c #B8B7B5", -")&. c #A6A5A2", -"!&. c #898885", -"~&. c #757371", -"{&. c #3F3F3F", -"]&. c #383F64", -"^&. c #8798F6", -"/&. c #A6A1F8", -"(&. c #C8B6F5", -"_&. c #D5B9E9", -":&. c #E3B8EB", -"<&. c #E3B8E5", -"[&. c #E7B9E1", -"}&. c #F1C3DF", -"|&. c #EBC6DA", -"1&. c #E5C1D5", -"2&. c #D8B8DF", -"3&. c #C7AFD4", -"4&. c #CBAAD0", -"5&. c #CBA9CC", -"6&. c #C4A6CA", -"7&. c #C2A2C6", -"8&. c #C19FC6", -"9&. c #B79BBD", -"0&. c #B698BB", -"a&. c #BA9BC2", -"b&. c #BA9CC1", -"c&. c #B198C2", -"d&. c #A692B6", -"e&. c #9E8CB4", -"f&. c #9A8BB2", -"g&. c #9383A9", -"h&. c #9184A6", -"i&. c #9B8BAC", -"j&. c #9283A2", -"k&. c #867E94", -"l&. c #897D9F", -"m&. c #8C809E", -"n&. c #867D93", -"o&. c #867C93", -"p&. c #857D92", -"q&. c #867D92", -"r&. c #827B8F", -"s&. c #75718E", -"t&. c #767286", -"u&. c #757289", -"v&. c #6B6B85", -"w&. c #696983", -"x&. c #69697F", -"y&. c #67687D", -"z&. c #6A6A83", -"A&. c #807A9C", -"B&. c #847DA4", -"C&. c #616479", -"D&. c #5F627C", -"E&. c #706E8E", -"F&. c #6C6C89", -"G&. c #807DA0", -"H&. c #928DBA", -"I&. c #8C84A4", -"J&. c #797991", -"K&. c #60627E", -"L&. c #555B6C", -"M&. c #686883", -"N&. c #787495", -"O&. c #797695", -"P&. c #827D9E", -"Q&. c #7E7C95", -"R&. c #8A84A6", -"S&. c #7F7F9B", -"T&. c #565A71", -"U&. c #585A71", -"V&. c #565B6D", -"W&. c #595E6E", -"X&. c #5E6073", -"Y&. c #606274", -"Z&. c #5F6273", -"`&. c #5C6172", -" *. c #BCB6C4", -".*. c #898A91", -"+*. c #747282", -"@*. c #6C6D7E", -"#*. c #A19AB7", -"$*. c #D0C6E3", -"%*. c #CEC3E3", -"&*. c #C0B8C8", -"**. c #B4ACCF", -"=*. c #BAB3CB", -"-*. c #ABA2BD", -";*. c #A797AC", -">*. c #928994", -",*. c #C6BFD7", -"'*. c #918B98", -")*. c #A897AF", -"!*. c #978A9E", -"~*. c #868290", -"{*. c #9992B2", -"]*. c #9890B3", -"^*. c #AFA9D6", -"/*. c #A8A0C4", -"(*. c #998FAF", -"_*. c #A69FC7", -":*. c #D0C8DC", -"<*. c #ABA5B9", -"[*. c #9890AF", -"}*. c #B4A9D4", -"|*. c #AA9BBC", -"1*. c #B7A8CC", -"2*. c #B7B1D0", -"3*. c #B4ACC6", -"4*. c #8F89A2", -"5*. c #807D9B", -"6*. c #8E89A7", -"7*. c #9D92B2", -"8*. c #9F99BA", -"9*. c #A7A3BB", -"0*. c #B2A7C7", -"a*. c #8A8292", -"b*. c #3F4254", -"c*. c #464A6D", -"d*. c #505174", -"e*. c #4F5173", -"f*. c #535577", -"g*. c #64618B", -"h*. c #5F6187", -"i*. c #5A5B87", -"j*. c #63638C", -"k*. c #5C5E84", -"l*. c #61618A", -"m*. c #525579", -"n*. c #4D4F74", -"o*. c #45476E", -"p*. c #3A3B60", -"q*. c #3F3E62", -"r*. c #393A5D", -"s*. c #353962", -"t*. c #3C3E65", -"u*. c #3F4164", -"v*. c #3A3E63", -"w*. c #393C65", -"x*. c #373A63", -"y*. c #2B3052", -"z*. c #35385C", -"A*. c #41436A", -"B*. c #5D5C8C", -"C*. c #5B5B85", -"D*. c #64618C", -"E*. c #57577F", -"F*. c #55557C", -"G*. c #626289", -"H*. c #636387", -"I*. c #656488", -"J*. c #464A6A", -"K*. c #5C5E81", -"L*. c #5D5E87", -"M*. c #44476F", -"N*. c #494970", -"O*. c #57587B", -"P*. c #8A889D", -"Q*. c #8D8DAD", -"R*. c #69658B", -"S*. c #3C3F62", -"T*. c #303558", -"U*. c #3B3F6B", -"V*. c #4E527D", -"W*. c #44476E", -"X*. c #4C5077", -"Y*. c #484C72", -"Z*. c #DBDBDB", -"`*. c #E7E7E7", -" =. c #3D3D3A", -".=. c #6E6E68", -"+=. c #7A7871", -"@=. c #7A7772", -"#=. c #AAA9A7", -"$=. c #A6A4A2", -"%=. c #BCBCB8", -"&=. c #B6B4B2", -"*=. c #C4C4C0", -"==. c #D0CDC8", -"-=. c #9E9A95", -";=. c #B3AFAF", -">=. c #BAB6B4", -",=. c #A9A4A4", -"'=. c #928E8D", -")=. c #BEBDBB", -"!=. c #C3C2C0", -"~=. c #9C9B99", -"{=. c #8E8D8B", -"]=. c #0C1021", -"^=. c #93A6F5", -"/=. c #9093F5", -"(=. c #C2B4F5", -"_=. c #CEB7EC", -":=. c #DFB9ED", -"<=. c #E2BBDF", -"[=. c #E0BBD7", -"}=. c #F0C6E2", -"|=. c #EEC3DB", -"1=. c #DFBCD4", -"2=. c #D1B3D9", -"3=. c #C0B0D5", -"4=. c #C5ABD1", -"5=. c #CBABD3", -"6=. c #C4A7D5", -"7=. c #C1A7CE", -"8=. c #BB9FCC", -"9=. c #B79CC5", -"0=. c #B399C1", -"a=. c #AF93BA", -"b=. c #A991BD", -"c=. c #A791BB", -"d=. c #A08DB0", -"e=. c #9786AF", -"f=. c #9285AF", -"g=. c #8A7F9F", -"h=. c #897FA4", -"i=. c #897E9B", -"j=. c #867D95", -"k=. c #867E90", -"l=. c #897E93", -"m=. c #90809E", -"n=. c #7E788C", -"o=. c #7F798E", -"p=. c #8C7D9C", -"q=. c #867D90", -"r=. c #827991", -"s=. c #74728E", -"t=. c #6D6C80", -"u=. c #676684", -"v=. c #626577", -"w=. c #67677F", -"x=. c #6E6D86", -"y=. c #67687E", -"z=. c #76738D", -"A=. c #6A6886", -"B=. c #5E5F78", -"C=. c #7C789C", -"D=. c #767494", -"E=. c #847FA6", -"F=. c #958EC2", -"G=. c #A79BC4", -"H=. c #AEA4CC", -"I=. c #A19AC2", -"J=. c #8B86AB", -"K=. c #73728E", -"L=. c #7E7A94", -"M=. c #797892", -"N=. c #928AB3", -"O=. c #857FA8", -"P=. c #A098C2", -"Q=. c #9A94B8", -"R=. c #B7B1D1", -"S=. c #8D8AA9", -"T=. c #82809C", -"U=. c #6E7087", -"V=. c #72718E", -"W=. c #6B6B83", -"X=. c #5B5F7C", -"Y=. c #5E6176", -"Z=. c #606474", -"`=. c #5B6172", -" -. c #767692", -".-. c #A09DBF", -"+-. c #D0C7EA", -"@-. c #9F98AC", -"#-. c #9795B8", -"$-. c #8A86A7", -"%-. c #A4A2BB", -"&-. c #DACDDE", -"*-. c #D2CBDA", -"=-. c #CEC1D7", -"--. c #B7AFCE", -";-. c #B7AFD0", -">-. c #A297AC", -",-. c #AB9BA3", -"'-. c #C3ABC3", -")-. c #958D9C", -"!-. c #B8ADC5", -"~-. c #9D8FAB", -"{-. c #B39EBA", -"]-. c #898187", -"^-. c #85808E", -"/-. c #89829B", -"(-. c #A19ABD", -"_-. c #A5A0BB", -":-. c #A29BB5", -"<-. c #BEB5D9", -"[-. c #C3B9CB", -"}-. c #A9A2BC", -"|-. c #B1A6CB", -"1-. c #A79FC0", -"2-. c #9E97B1", -"3-. c #908CAA", -"4-. c #73717E", -"5-. c #727184", -"6-. c #8883A7", -"7-. c #9D94B3", -"8-. c #928BAB", -"9-. c #AAA1C5", -"0-. c #B0A7B9", -"a-. c #706E7D", -"b-. c #4B4D68", -"c-. c #585779", -"d-. c #4E5171", -"e-. c #54547E", -"f-. c #4A4E70", -"g-. c #424665", -"h-. c #4D4D6F", -"i-. c #4A4C6E", -"j-. c #5F5E84", -"k-. c #5C5C84", -"l-. c #57587C", -"m-. c #52527B", -"n-. c #474D6F", -"o-. c #3C3E61", -"p-. c #3B3B63", -"q-. c #414163", -"r-. c #4A4C70", -"s-. c #42446A", -"t-. c #424566", -"u-. c #3D4061", -"v-. c #3C3D5E", -"w-. c #3C3E5B", -"x-. c #444465", -"y-. c #3A3B5F", -"z-. c #313356", -"A-. c #2E3156", -"B-. c #373863", -"C-. c #404468", -"D-. c #56567D", -"E-. c #67638C", -"F-. c #656285", -"G-. c #545579", -"H-. c #68678B", -"I-. c #696892", -"J-. c #70719A", -"K-. c #595B79", -"L-. c #4B4B6D", -"M-. c #474B71", -"N-. c #393A60", -"O-. c #3E3F68", -"P-. c #555578", -"Q-. c #444766", -"R-. c #424466", -"S-. c #63608A", -"T-. c #64648B", -"U-. c #4A4B72", -"V-. c #404266", -"W-. c #474A6E", -"X-. c #464A6F", -"Y-. c #565683", -"Z-. c #484A74", -"`-. c #414569", -" ;. c #D4D4D4", -".;. c #E0E0E0", -"+;. c #484842", -"@;. c #B6B4B1", -"#;. c #C2C1BE", -"$;. c #BAB9B7", -"%;. c #B2B2AE", -"&;. c #C6C6C2", -"*;. c #BDBCBA", -"=;. c #B3B3AE", -"-;. c #8E8B8A", -";;. c #91908D", -">;. c #94918E", -",;. c #9F9F9C", -"';. c #B8B7B4", -");. c #959492", -"!;. c #0F0E0C", -"~;. c #8095D5", -"{;. c #808DF4", -"];. c #BEB2FB", -"^;. c #CDB8EF", -"/;. c #E1BCF1", -"(;. c #EBC1E7", -"_;. c #E3B9DC", -":;. c #DFBAD7", -"<;. c #DEB6D8", -"[;. c #D8B3D3", -"};. c #D1AED2", -"|;. c #C3ABDC", -"1;. c #B9A9D4", -"2;. c #BDA7D8", -"3;. c #C0AED5", -"4;. c #C4B2DD", -"5;. c #BAA0D0", -"6;. c #AE9CC8", -"7;. c #A895C5", -"8;. c #A493BD", -"9;. c #9989AA", -"0;. c #9989B2", -"a;. c #9586B0", -"b;. c #9789B1", -"c;. c #9386AB", -"d;. c #8B80A3", -"e;. c #877EA1", -"f;. c #867E9F", -"g;. c #877DA0", -"h;. c #827C91", -"i;. c #847A90", -"j;. c #8D7F97", -"k;. c #8B8094", -"l;. c #8A7F98", -"m;. c #777387", -"n;. c #77738D", -"o;. c #716E90", -"p;. c #767289", -"q;. c #6C6C86", -"r;. c #6A6A80", -"s;. c #6D6C83", -"t;. c #928BB4", -"u;. c #918AAE", -"v;. c #837E97", -"w;. c #8982A3", -"x;. c #6D6E8B", -"y;. c #797794", -"z;. c #71718D", -"A;. c #8B83B0", -"B;. c #7D7A9C", -"C;. c #8D86AF", -"D;. c #948CB7", -"E;. c #9B95CD", -"F;. c #A79CCD", -"G;. c #A49CCD", -"H;. c #BCB6DA", -"I;. c #A3A2BA", -"J;. c #7C7A9A", -"K;. c #9C98C4", -"L;. c #9C94C5", -"M;. c #948CBA", -"N;. c #CBBFE9", -"O;. c #9492B7", -"P;. c #968FB6", -"Q;. c #BFB6DB", -"R;. c #A49CBB", -"S;. c #B5AFD5", -"T;. c #C8C0E2", -"U;. c #A19CBE", -"V;. c #9891C7", -"W;. c #8983AD", -"X;. c #6B6B87", -"Y;. c #696A86", -"Z;. c #66687F", -"`;. c #706D8C", -" >. c #9F9ACC", -".>. c #D2C6F4", -"+>. c #9190B4", -"@>. c #9C96BF", -"#>. c #C2BAEB", -"$>. c #A9A1CE", -"%>. c #89829A", -"&>. c #A199B6", -"*>. c #A098B7", -"=>. c #9A95AA", -"->. c #A698B9", -";>. c #B5A5BC", -">>. c #C8B2CD", -",>. c #CABDCF", -"'>. c #8C8593", -")>. c #A69BB2", -"!>. c #BFA8C3", -"~>. c #9992A2", -"{>. c #978FB1", -"]>. c #A196BF", -"^>. c #A79EBF", -"/>. c #B0A1C2", -"(>. c #91889C", -"_>. c #8B8396", -":>. c #A398BE", -"<>. c #9690B2", -"[>. c #807C93", -"}>. c #A69EC0", -"|>. c #A39DBF", -"1>. c #9A93B7", -"2>. c #7F7B96", -"3>. c #6D6D83", -"4>. c #5D606E", -"5>. c #5F6375", -"6>. c #8480A0", -"7>. c #8583A3", -"8>. c #79788A", -"9>. c #4B4C5D", -"0>. c #434563", -"a>. c #454766", -"b>. c #3E415F", -"c>. c #353B58", -"d>. c #3D3D60", -"e>. c #404164", -"f>. c #424568", -"g>. c #484C6F", -"h>. c #414567", -"i>. c #494C6C", -"j>. c #494B6F", -"k>. c #494B70", -"l>. c #46496C", -"m>. c #424266", -"n>. c #3C3D63", -"o>. c #373C5E", -"p>. c #393C5E", -"q>. c #7574A1", -"r>. c #8281AB", -"s>. c #4F516C", -"t>. c #636484", -"u>. c #515273", -"v>. c #6F708D", -"w>. c #A7A0BC", -"x>. c #A7A0C1", -"y>. c #6F6C90", -"z>. c #636385", -"A>. c #4D4C76", -"B>. c #46486F", -"C>. c #48486D", -"D>. c #4F5075", -"E>. c #595A81", -"F>. c #5E5E81", -"G>. c #565A7B", -"H>. c #565579", -"I>. c #555677", -"J>. c #797A97", -"K>. c #696885", -"L>. c #424468", -"M>. c #3B3D60", -"N>. c #34375C", -"O>. c #3B3E5E", -"P>. c #363857", -"Q>. c #625E88", -"R>. c #535374", -"S>. c #56547F", -"T>. c #45456A", -"U>. c #49496A", -"V>. c #48496A", -"W>. c #3E4263", -"X>. c #484A71", -"Y>. c #4D4D77", -"Z>. c #CDCDCD", -"`>. c #DADADA", -" ,. c #96695D", -".,. c #060505", -"+,. c #8A8784", -"@,. c #ABA6A2", -"#,. c #AFAEAB", -"$,. c #BABAB6", -"%,. c #A4A3A1", -"&,. c #B0AFAC", -"*,. c #A4A19B", -"=,. c #8D8C8A", -"-,. c #807D7A", -";,. c #858482", -">,. c #7E7E7C", -",,. c #515C8B", -"',. c #8B98F3", -"),. c #A09EFB", -"!,. c #CEBBF5", -"~,. c #D1B4E2", -"{,. c #E7BCED", -"],. c #E2BCE1", -"^,. c #E7BDDF", -"/,. c #D8B6DA", -"(,. c #C7A8D4", -"_,. c #BAA6D2", -":,. c #ACA0D1", -"<,. c #B8A6D7", -"[,. c #BCA7D2", -"},. c #C2B1DF", -"|,. c #A999C8", -"1,. c #A08EC2", -"2,. c #9386B0", -"3,. c #8C7EAC", -"4,. c #877EA0", -"5,. c #877EA7", -"6,. c #9083A9", -"7,. c #9180B1", -"8,. c #867CA3", -"9,. c #867D9E", -"0,. c #867DA1", -"a,. c #837A9A", -"b,. c #827A93", -"c,. c #867EA1", -"d,. c #9085B0", -"e,. c #7C7790", -"f,. c #827A98", -"g,. c #7C779A", -"h,. c #686A8B", -"i,. c #676780", -"j,. c #65667A", -"k,. c #867E9E", -"l,. c #7D778C", -"m,. c #AB9FCB", -"n,. c #A79ECA", -"o,. c #B4ACD2", -"p,. c #A6A1C6", -"q,. c #9C95C0", -"r,. c #9991C6", -"s,. c #8B84B1", -"t,. c #938BB6", -"u,. c #978FBF", -"v,. c #958CBA", -"w,. c #938ABB", -"x,. c #A198C1", -"y,. c #BDB5DA", -"z,. c #BAB5D2", -"A,. c #938EAE", -"B,. c #8D88B0", -"C,. c #958FB6", -"D,. c #8E87B0", -"E,. c #9D94BC", -"F,. c #B1ABCB", -"G,. c #A9A2CD", -"H,. c #AFA9D4", -"I,. c #A5A3C1", -"J,. c #8884AC", -"K,. c #ADA5CB", -"L,. c #B7B0CF", -"M,. c #A9A4C8", -"N,. c #8A87AF", -"O,. c #8685B4", -"P,. c #8180A4", -"Q,. c #7E7CA0", -"R,. c #75768D", -"S,. c #505766", -"T,. c #5D6273", -"U,. c #9B94BB", -"V,. c #9792BC", -"W,. c #8C89AE", -"X,. c #B1AACD", -"Y,. c #9894B7", -"Z,. c #9896B0", -"`,. c #8B8C9E", -" '. c #9D99AF", -".'. c #D3C3DD", -"+'. c #D4C6E3", -"@'. c #B8B0CE", -"#'. c #B9AFCB", -"$'. c #B6ACC4", -"%'. c #B4A9BE", -"&'. c #BDAEC5", -"*'. c #ACA3B3", -"='. c #968799", -"-'. c #9E90A8", -";'. c #9B92A5", -">'. c #9B8EA3", -",'. c #A492A6", -"''. c #AD94B3", -")'. c #A899B4", -"!'. c #9C93B0", -"~'. c #9990B9", -"{'. c #978CB2", -"]'. c #9087A1", -"^'. c #84839C", -"/'. c #817D9A", -"('. c #7E7D9D", -"_'. c #72728B", -":'. c #767195", -"<'. c #8281AE", -"['. c #646674", -"}'. c #3B3F51", -"|'. c #28314B", -"1'. c #2C3353", -"2'. c #383C5A", -"3'. c #373B5B", -"4'. c #2E3354", -"5'. c #2D3155", -"6'. c #313252", -"7'. c #343559", -"8'. c #3B3B5D", -"9'. c #45456D", -"0'. c #3E425E", -"a'. c #393C5F", -"b'. c #434568", -"c'. c #48496D", -"d'. c #46486C", -"e'. c #505173", -"f'. c #5C5B7E", -"g'. c #69688B", -"h'. c #4A4A69", -"i'. c #5A5977", -"j'. c #5A5A7C", -"k'. c #5A597A", -"l'. c #6D698C", -"m'. c #9794B2", -"n'. c #A7A2CA", -"o'. c #A19BC3", -"p'. c #77739C", -"q'. c #696998", -"r'. c #635F8D", -"s'. c #615E81", -"t'. c #4E4E72", -"u'. c #494A6D", -"v'. c #535275", -"w'. c #484A68", -"x'. c #4D4F70", -"y'. c #505373", -"z'. c #444567", -"A'. c #515176", -"B'. c #6A6A8D", -"C'. c #5F5E81", -"D'. c #414364", -"E'. c #36365B", -"F'. c #393E63", -"G'. c #3F4166", -"H'. c #444565", -"I'. c #5F628B", -"J'. c #6E6994", -"K'. c #5B5A7A", -"L'. c #393C59", -"M'. c #30325A", -"N'. c #313157", -"O'. c #393A5C", -"P'. c #43456B", -"Q'. c #C6C6C6", -"R'. c #D5D5D5", -"S'. c #767670", -"T'. c #84847E", -"U'. c #8C8C87", -"V'. c #7E7874", -"W'. c #A8A7A4", -"X'. c #A9A8A6", -"Y'. c #B3B2B0", -"Z'. c #ACABA9", -"`'. c #C1BEBB", -" ). c #B6B3B0", -".). c #B7B1AE", -"+). c #A29F9E", -"@). c #928C89", -"#). c #91918B", -"$). c #A29F9C", -"%). c #A3A2A0", -"&). c #A7A7A1", -"*). c #979593", -"=). c #7A7978", -"-). c #706E6D", -";). c #232844", -">). c #91A3F7", -",). c #9093F6", -"'). c #C4B8FC", -")). c #CCB3F2", -"!). c #D5B0EB", -"~). c #DBB4E3", -"{). c #E2BBE1", -"]). c #D9B2DE", -"^). c #BEA6D8", -"/). c #BEA3CF", -"(). c #AB9CC8", -"_). c #B6A3D4", -":). c #AF9ECB", -"<). c #B099CB", -"[). c #B3A1D3", -"}). c #A997C8", -"|). c #9A8CBA", -"1). c #9787B9", -"2). c #9080AE", -"3). c #867DA7", -"4). c #8B7FA7", -"5). c #8C80B1", -"6). c #8279A3", -"7). c #7E779E", -"8). c #877DA1", -"9). c #7C789B", -"0). c #80799A", -"a). c #807A9A", -"b). c #8C84AF", -"c). c #8D85AE", -"d). c #8C83B1", -"e). c #6B6C8B", -"f). c #676784", -"g). c #69697E", -"h). c #61637F", -"i). c #606376", -"j). c #767186", -"k). c #9389AD", -"l). c #C5BDDD", -"m). c #DAC9EE", -"n). c #C9BFE8", -"o). c #BEB3DD", -"p). c #BDB3E6", -"q). c #A09CC7", -"r). c #978EC2", -"s). c #AAA0D1", -"t). c #A298C7", -"u). c #9A96BF", -"v). c #8882AF", -"w). c #9A94BB", -"x). c #8785AD", -"y). c #857FA3", -"z). c #8B83B4", -"A). c #9491BB", -"B). c #CDC0E0", -"C). c #D3CDEA", -"D). c #A7A0CF", -"E). c #908ABB", -"F). c #8D8ABA", -"G). c #918ABD", -"H). c #887FAE", -"I). c #817DA5", -"J). c #8C85B1", -"K). c #8A85B0", -"L). c #5F617B", -"M). c #696980", -"N). c #8C8AB4", -"O). c #8784AB", -"P). c #A39DC0", -"Q). c #7C7997", -"R). c #B6ADCD", -"S). c #BAB2D3", -"T). c #B4ADCE", -"U). c #ACA8C5", -"V). c #AAA7C8", -"W). c #9994B3", -"X). c #76747D", -"Y). c #B6AFCA", -"Z). c #9D94A9", -"`). c #A29EB1", -" !. c #B0AAC0", -".!. c #9D94AF", -"+!. c #877F90", -"@!. c #877E8F", -"#!. c #8A839D", -"$!. c #A899BA", -"%!. c #A295B2", -"&!. c #9C8FA8", -"*!. c #9E90AA", -"=!. c #A595B1", -"-!. c #9D8EA7", -";!. c #9F91AE", -">!. c #9893AB", -",!. c #9589AB", -"'!. c #948CA9", -")!. c #888095", -"!!. c #988FB2", -"~!. c #7E7B96", -"{!. c #827B9F", -"]!. c #7F7FA4", -"^!. c #7D7998", -"/!. c #5B5B69", -"(!. c #323652", -"_!. c #2B324E", -":!. c #2B2D4C", -"~. c #A294C5", -",~. c #AC9ACF", -"'~. c #AA97CA", -")~. c #A290C1", -"!~. c #9F8CBD", -"~~. c #9487B4", -"{~. c #9080AB", -"]~. c #897EA2", -"^~. c #827A9B", -"/~. c #857DA4", -"(~. c #887DA6", -"_~. c #867CA1", -":~. c #867CA2", -"<~. c #827B9C", -"[~. c #8882A7", -"}~. c #887DA7", -"|~. c #8980A4", -"1~. c #9084B4", -"2~. c #A89ED2", -"3~. c #968DBE", -"4~. c #696A84", -"5~. c #76758E", -"6~. c #6A6986", -"7~. c #62637F", -"8~. c #636480", -"9~. c #63637C", -"0~. c #75738C", -"a~. c #817C99", -"b~. c #ACA4C9", -"c~. c #ADA5D0", -"d~. c #A39CC2", -"e~. c #B7AFD5", -"f~. c #A19AC4", -"g~. c #B4AADC", -"h~. c #B0AAD0", -"i~. c #9B92B9", -"j~. c #8E87B2", -"k~. c #797693", -"l~. c #9790B5", -"m~. c #8883AE", -"n~. c #8D86B6", -"o~. c #8681A9", -"p~. c #7D779E", -"q~. c #857FAF", -"r~. c #7E7BA5", -"s~. c #7C7BA3", -"t~. c #7B7598", -"u~. c #837EA8", -"v~. c #9F96C8", -"w~. c #ABA3D4", -"x~. c #A09ACB", -"y~. c #8987BA", -"z~. c #8C86B8", -"A~. c #8883B2", -"B~. c #8683AF", -"C~. c #807BA5", -"D~. c #8B86B2", -"E~. c #7D7AA0", -"F~. c #807EA8", -"G~. c #6F6F89", -"H~. c #72718F", -"I~. c #B3ADC3", -"J~. c #A6A3B3", -"K~. c #6A6B85", -"L~. c #918EBB", -"M~. c #A9A2C0", -"N~. c #A7A0CB", -"O~. c #8483A0", -"P~. c #84839B", -"Q~. c #A19EAF", -"R~. c #A29FAF", -"S~. c #C3B7D2", -"T~. c #CAC2DB", -"U~. c #A29BAE", -"V~. c #A5A3A7", -"W~. c #ADA4B9", -"X~. c #C6B8CD", -"Y~. c #A8A3AD", -"Z~. c #7A7481", -"`~. c #807883", -" {. c #938699", -".{. c #867D91", -"+{. c #9991AC", -"@{. c #A298B5", -"#{. c #AB9EBD", -"${. c #A99BB8", -"%{. c #AE9FBF", -"&{. c #8B859E", -"*{. c #8C849F", -"={. c #8B859D", -"-{. c #837D93", -";{. c #7C7591", -">{. c #74718F", -",{. c #7B7AA3", -"'{. c #656577", -"){. c #414554", -"!{. c #32384F", -"~{. c #2F3352", -"{{. c #313253", -"]{. c #2E324D", -"^{. c #222946", -"/{. c #1C2445", -"({. c #212648", -"_{. c #1E2648", -":{. c #1F254D", -"<{. c #21284C", -"[{. c #252A4A", -"}{. c #202745", -"|{. c #2A304B", -"1{. c #202844", -"2{. c #1F2744", -"3{. c #192347", -"4{. c #23294B", -"5{. c #282B4C", -"6{. c #292D4D", -"7{. c #333355", -"8{. c #363955", -"9{. c #2F3351", -"0{. c #313351", -"a{. c #272B4E", -"b{. c #343458", -"c{. c #303350", -"d{. c #383959", -"e{. c #464664", -"f{. c #333552", -"g{. c #3F3D5E", -"h{. c #3B3C5D", -"i{. c #414164", -"j{. c #555476", -"k{. c #4A4A6D", -"l{. c #434364", -"m{. c #3F4260", -"n{. c #424465", -"o{. c #383A58", -"p{. c #39395A", -"q{. c #393A5A", -"r{. c #383957", -"s{. c #535471", -"t{. c #3F425F", -"u{. c #4B4B6A", -"v{. c #5B5977", -"w{. c #4E4D69", -"x{. c #5F5883", -"y{. c #716F9A", -"z{. c #8982AD", -"A{. c #76709C", -"B{. c #857FA7", -"C{. c #615F7F", -"D{. c #4C4B66", -"E{. c #323450", -"F{. c #2B3050", -"G{. c #2D304E", -"H{. c #2A2B4B", -"I{. c #B9B9B9", -"J{. c #8B8B86", -"K{. c #B9B9B4", -"L{. c #A7A6A2", -"M{. c #A4A3A0", -"N{. c #9A9897", -"O{. c #9B9592", -"P{. c #8A8A85", -"Q{. c #585655", -"R{. c #090906", -"S{. c #4F6091", -"T{. c #899BF5", -"U{. c #9B9BF3", -"V{. c #CAB8F7", -"W{. c #D2B7F4", -"X{. c #CDB3E6", -"Y{. c #D1B0E0", -"Z{. c #C8A9DB", -"`{. c #BDA4DA", -" ]. c #B69FD4", -".]. c #AF9BCE", -"+]. c #AF9BD1", -"@]. c #A794C9", -"#]. c #9A8FBB", -"$]. c #9E8EBA", -"%]. c #9E8CBA", -"&]. c #9988B4", -"*]. c #9B8CB8", -"=]. c #9383AC", -"-]. c #8E81AD", -";]. c #877CA3", -">]. c #81779D", -",]. c #7C769B", -"']. c #837A9E", -")]. c #7F769C", -"!]. c #817A9F", -"~]. c #7E75A3", -"{]. c #7C7599", -"]]. c #9789BC", -"^]. c #8884B4", -"/]. c #928CBC", -"(]. c #9E93C3", -"_]. c #A59DC4", -":]. c #8D85B1", -"<]. c #676783", -"[]. c #716E8E", -"}]. c #60617B", -"|]. c #63637B", -"1]. c #74728A", -"2]. c #827E9D", -"3]. c #7B7695", -"4]. c #B2A8D2", -"5]. c #C3B7E6", -"6]. c #A8A1D4", -"7]. c #B1ABD4", -"8]. c #8481A9", -"9]. c #A59FC5", -"0]. c #ABA1C4", -"a]. c #9692C4", -"b]. c #908AB2", -"c]. c #747191", -"d]. c #8881AB", -"e]. c #747496", -"f]. c #8882B2", -"g]. c #777392", -"h]. c #7B779E", -"i]. c #7E78AA", -"j]. c #737193", -"k]. c #837CAC", -"l]. c #9D95C6", -"m]. c #8981B0", -"n]. c #A79FD1", -"o]. c #A9A3D4", -"p]. c #8D87B5", -"q]. c #8F8CBA", -"r]. c #9E9AC1", -"s]. c #AEA8C4", -"t]. c #837CA7", -"u]. c #767496", -"v]. c #8482B1", -"w]. c #8881AF", -"x]. c #7B7AA2", -"y]. c #817DA8", -"z]. c #7B7597", -"A]. c #76738F", -"B]. c #BDB7C7", -"C]. c #B0AAB5", -"D]. c #656473", -"E]. c #767498", -"F]. c #7C7999", -"G]. c #8885AE", -"H]. c #9190AF", -"I]. c #9A99B6", -"J]. c #A49EB2", -"K]. c #9C98AC", -"L]. c #908D9B", -"M]. c #9893AE", -"N]. c #9996A2", -"O]. c #C5BCC8", -"P]. c #6D706C", -"Q]. c #76717D", -"R]. c #A89FB4", -"S]. c #757578", -"T]. c #5E5E61", -"U]. c #68666E", -"V]. c #7C7991", -"W]. c #576061", -"X]. c #747187", -"Y]. c #878097", -"Z]. c #8B8295", -"`]. c #968AA4", -" ^. c #988DA0", -".^. c #897E95", -"+^. c #847D99", -"@^. c #83778E", -"#^. c #7A778B", -"$^. c #676777", -"%^. c #747291", -"&^. c #5B5C67", -"*^. c #404159", -"=^. c #3E405D", -"-^. c #4A4A6F", -";^. c #494C6B", -">^. c #393D5B", -",^. c #2D3050", -"'^. c #222847", -")^. c #222743", -"!^. c #1C2545", -"~^. c #1C2345", -"{^. c #222644", -"]^. c #2F3050", -"^^. c #313551", -"/^. c #2D3150", -"(^. c #323452", -"_^. c #303450", -":^. c #212842", -"<^. c #1E2345", -"[^. c #1E2546", -"}^. c #192245", -"|^. c #1B2548", -"1^. c #1D2342", -"2^. c #23294C", -"3^. c #1E2348", -"4^. c #1C2244", -"5^. c #222648", -"6^. c #292D49", -"7^. c #45455F", -"8^. c #292B4D", -"9^. c #2D2D4C", -"0^. c #232646", -"a^. c #2D2D4E", -"b^. c #282B4B", -"c^. c #30314E", -"d^. c #353653", -"e^. c #2F314E", -"f^. c #333755", -"g^. c #363654", -"h^. c #363957", -"i^. c #3B3C5E", -"j^. c #3D3D5E", -"k^. c #353955", -"l^. c #3D3F59", -"m^. c #404160", -"n^. c #34374F", -"o^. c #3A3B57", -"p^. c #5B5A78", -"q^. c #817E99", -"r^. c #847F9C", -"s^. c #605B7D", -"t^. c #777192", -"u^. c #ADA5B9", -"v^. c #A19AB3", -"w^. c #8F87AC", -"x^. c #716E8C", -"y^. c #4D4F66", -"z^. c #3D3E58", -"A^. c #393A58", -"B^. c #3D3D5C", -"C^. c #393956", -"D^. c #B6B6B6", -"E^. c #C0C0C0", -"F^. c #3A3A39", -"G^. c #7D7C79", -"H^. c #949490", -"I^. c #85857F", -"J^. c #898580", -"K^. c #979491", -"L^. c #898983", -"M^. c #1B253A", -"N^. c #92A7F3", -"O^. c #8490ED", -"P^. c #AFA7F1", -"Q^. c #CCB7F3", -"R^. c #C9B1E9", -"S^. c #C9ADDE", -"T^. c #C2A6DA", -"U^. c #B7A3D4", -"V^. c #AC9CD0", -"W^. c #A897D0", -"X^. c #A998C9", -"Y^. c #9F93C7", -"Z^. c #A291C7", -"`^. c #9488BD", -" /. c #9081B5", -"./. c #9383B2", -"+/. c #8B7FA4", -"@/. c #8E7DAB", -"#/. c #8C81A5", -"$/. c #8B7DA3", -"%/. c #847AA3", -"&/. c #83789C", -"*/. c #7E7598", -"=/. c #797395", -"-/. c #767190", -";/. c #7C7496", -">/. c #84789E", -",/. c #978BBC", -"'/. c #767396", -")/. c #8D82B0", -"!/. c #A298C6", -"~/. c #A097C6", -"{/. c #9D94C4", -"]/. c #9E96C4", -"^/. c #978EB5", -"//. c #6E6C88", -"(/. c #646580", -"_/. c #727092", -":/. c #5E607C", -"(. c #292E4F", -",(. c #252745", -"'(. c #242643", -")(. c #4C4B64", -"!(. c #626688", -"~(. c #5B5E78", -"{(. c #47475E", -"](. c #5B5D79", -"^(. c #353854", -"/(. c #20253E", -"((. c #222543", -"_(. c #202545", -":(. c #262B4B", -"<(. c #1B2146", -"[(. c #1A2142", -"}(. c #1C2343", -"|(. c #232544", -"1(. c #40405E", -"2(. c #5A5A79", -"3(. c #6D6D7A", -"4(. c #3C3B52", -"5(. c #615E76", -"6(. c #585674", -"7(. c #41415D", -"8(. c #363753", -"9(. c #3C3F5A", -"0(. c #2A2C47", -"a(. c #2F2F4C", -"b(. c #30324C", -"c(. c #343552", -"d(. c #30314F", -"e(. c #2F2F4E", -"f(. c #2D2E4C", -"g(. c #333652", -"h(. c #323655", -"i(. c #333752", -"j(. c #3B3B5C", -"k(. c #444464", -"l(. c #373956", -"m(. c #3F3F5C", -"n(. c #35394D", -"o(. c #42435D", -"p(. c #7A749B", -"q(. c #6C6A8B", -"r(. c #706A90", -"s(. c #A095B5", -"t(. c #AA9FB3", -"u(. c #A295B1", -"v(. c #8D88A7", -"w(. c #8881A1", -"x(. c #6F698C", -"y(. c #514F6A", -"z(. c #545172", -"A(. c #383A54", -"B(. c #353855", -"C(. c #B2B2B2", -"D(. c #787873", -"E(. c #989794", -"F(. c #878782", -"G(. c #A8A6A4", -"H(. c #A1A09C", -"I(. c #A9A4A3", -"J(. c #999593", -"K(. c #82827C", -"L(. c #535050", -"M(. c #9CB3EF", -"N(. c #8894EF", -"O(. c #8F90F0", -"P(. c #C5B3EE", -"Q(. c #C4ADE4", -"R(. c #BAA5DC", -"S(. c #BEA2D9", -"T(. c #B5A2D2", -"U(. c #A899CC", -"V(. c #A293CA", -"W(. c #A497D4", -"X(. c #A394C5", -"Y(. c #A493C8", -"Z(. c #8C7FB0", -"`(. c #8D7CAF", -" _. c #857BA1", -"._. c #8A78AC", -"+_. c #8279A1", -"@_. c #887BA3", -"#_. c #83779E", -"$_. c #83789E", -"%_. c #81779C", -"&_. c #7B729B", -"*_. c #777198", -"=_. c #716C94", -"-_. c #766F94", -";_. c #787193", -">_. c #8782AD", -",_. c #8180A5", -"'_. c #8681AB", -")_. c #938BBC", -"!_. c #A397C8", -"~_. c #AAA2C7", -"{_. c #A29AC2", -"]_. c #928CB5", -"^_. c #7C78A1", -"/_. c #78749B", -"(_. c #686880", -"__. c #62627C", -":_. c #76728C", -"<_. c #BFB0D4", -"[_. c #CFBEDF", -"}_. c #C3B3D3", -"|_. c #D2BAE0", -"1_. c #B8B0C5", -"2_. c #8E89B1", -"3_. c #918EB5", -"4_. c #A098C9", -"5_. c #9891BC", -"6_. c #8E89AF", -"7_. c #9891BD", -"8_. c #8E8CB9", -"9_. c #7F77A3", -"0_. c #7C76A0", -"a_. c #807BA3", -"b_. c #807CA9", -"c_. c #7B74A1", -"d_. c #948BBD", -"e_. c #7F79A4", -"f_. c #8B87A8", -"g_. c #797D92", -"h_. c #4F5364", -"i_. c #4C516C", -"j_. c #4B4E63", -"k_. c #595B76", -"l_. c #686889", -"m_. c #616281", -"n_. c #7771A0", -"o_. c #706D91", -"p_. c #5C5E75", -"q_. c #424A59", -"r_. c #565A75", -"s_. c #7D7AA6", -"t_. c #7A79AB", -"u_. c #747397", -"v_. c #747298", -"w_. c #ADA7C1", -"x_. c #ACAABB", -"y_. c #ADA2BD", -"z_. c #C7BDCE", -"A_. c #B8B7B8", -"B_. c #938DA5", -"C_. c #A7A2BA", -"D_. c #9896B2", -"E_. c #9693A4", -"F_. c #9B9B99", -"G_. c #5D6262", -"H_. c #494D54", -"I_. c #444958", -"J_. c #484D5C", -"K_. c #444B52", -"L_. c #4C5153", -"M_. c #4C5151", -"N_. c #787886", -"O_. c #63646A", -"P_. c #998FA9", -"Q_. c #B5AEB6", -"R_. c #878495", -"S_. c #8C8C8E", -"T_. c #4C5157", -"U_. c #878393", -"V_. c #8E899B", -"W_. c #B2B1B1", -"X_. c #877C8A", -"Y_. c #918697", -"Z_. c #9790AA", -"`_. c #8F8DA4", -" :. c #C6BBC6", -".:. c #B7B1BB", -"+:. c #8F8C9A", -"@:. c #494B56", -"#:. c #2E2E4B", -"$:. c #353657", -"%:. c #484765", -"&:. c #5D5B7A", -"*:. c #585971", -"=:. c #4C4C6E", -"-:. c #4F4E6D", -";:. c #565674", -">:. c #4E4B66", -",:. c #3C3C5D", -"':. c #242745", -"):. c #5E5D86", -"!:. c #797499", -"~:. c #807F91", -"{:. c #47485F", -"]:. c #31344B", -"^:. c #1B223F", -"/:. c #1A203C", -"(:. c #1F2640", -"_:. c #2A2D49", -"::. c #272A42", -"<:. c #252744", -"[:. c #302F4B", -"}:. c #2F3048", -"|:. c #75728E", -"1:. c #545364", -"2:. c #555671", -"3:. c #565575", -"4:. c #575379", -"5:. c #737095", -"6:. c #67678A", -"7:. c #363A50", -"8:. c #353651", -"9:. c #313350", -"0:. c #2C2D49", -"a:. c #31324C", -"b:. c #323250", -"c:. c #30314A", -"d:. c #393C58", -"e:. c #2D3147", -"f:. c #343550", -"g:. c #33384F", -"h:. c #555474", -"i:. c #4E4D68", -"j:. c #44455F", -"k:. c #393955", -"l:. c #5A5573", -"m:. c #68648E", -"n:. c #77729A", -"o:. c #998FB2", -"p:. c #B1A3B1", -"q:. c #B1A0B1", -"r:. c #AA9EB0", -"s:. c #9F97B0", -"t:. c #797788", -"u:. c #656288", -"v:. c #535371", -"w:. c #484863", -"x:. c #3E4057", -"y:. c #AFAFAF", -"z:. c #969595", -"A:. c #91918C", -"B:. c #91908C", -"C:. c #84817E", -"D:. c #979692", -"E:. c #9C9A98", -"F:. c #9C9896", -"G:. c #9A9796", -"H:. c #969591", -"I:. c #94908F", -"J:. c #86817D", -"K:. c #92928C", -"L:. c #7B7B75", -"M:. c #3E4D76", -"N:. c #8B9EED", -"O:. c #8589EA", -"P:. c #9D99E4", -"Q:. c #C0ADE2", -"R:. c #B5A5DB", -"S:. c #A898D4", -"T:. c #A595CF", -"U:. c #9F91C7", -"V:. c #9D8FCE", -"W:. c #A49BD0", -"X:. c #998DC0", -"Y:. c #9D90C7", -"Z:. c #9385B8", -"`:. c #8679A7", -" <. c #8674A8", -".<. c #8275A0", -"+<. c #8176A5", -"@<. c #8075A0", -"#<. c #81739E", -"$<. c #7E7498", -"%<. c #7E72A0", -"&<. c #766D9A", -"*<. c #736E90", -"=<. c #777197", -"-<. c #777299", -";<. c #7A769F", -"><. c #827DAF", -",<. c #8982B8", -"'<. c #8B84AD", -")<. c #908CBC", -"!<. c #9891C2", -"~<. c #ADA3C8", -"{<. c #B0A2C5", -"]<. c #A99ECB", -"^<. c #8B83B1", -"/<. c #7F79A1", -"(<. c #7C7697", -"_<. c #6F6C88", -":<. c #756E8F", -"<<. c #958BAC", -"[<. c #C0B0CE", -"}<. c #A09AC1", -"|<. c #B2A3D4", -"1<. c #C5B7D4", -"2<. c #817CA4", -"3<. c #9187B6", -"4<. c #9894C4", -"5<. c #9C94BF", -"6<. c #A8A1CB", -"7<. c #A5A0CB", -"8<. c #908AB5", -"9<. c #837DA2", -"0<. c #78729D", -"a<. c #76709A", -"b<. c #7B76A2", -"c<. c #757297", -"d<. c #78749F", -"e<. c #8281A9", -"f<. c #595C6C", -"g<. c #BEB3C2", -"h<. c #C9C8D4", -"i<. c #6D6E83", -"j<. c #494C61", -"k<. c #42495B", -"l<. c #464C63", -"m<. c #464B62", -"n<. c #555573", -"o<. c #42495A", -"p<. c #494E64", -"q<. c #444B5D", -"r<. c #414759", -"s<. c #384353", -"t<. c #545768", -"u<. c #6B6989", -"v<. c #7B76A6", -"w<. c #75719D", -"x<. c #4E5260", -"y<. c #64627A", -"z<. c #9C96A6", -"A<. c #CEC1C9", -"B<. c #C5B7CD", -"C<. c #BEB2C5", -"D<. c #A5A2BA", -"E<. c #858299", -"F<. c #A9A1BB", -"G<. c #ABA4C2", -"H<. c #B4ACC7", -"I<. c #717195", -"J<. c #505465", -"K<. c #69698A", -"L<. c #595B6D", -"M<. c #6E6E7C", -"N<. c #898896", -"O<. c #9190A6", -"P<. c #948E9F", -"Q<. c #A59FAA", -"R<. c #7F7B83", -"S<. c #8A8796", -"T<. c #484C51", -"U<. c #555763", -"V<. c #69637A", -"W<. c #5E5D6F", -"X<. c #888395", -"Y<. c #B6B3B3", -"Z<. c #867B7B", -"`<. c #8D8796", -" [. c #A19BAA", -".[. c #AFADBE", -"+[. c #AEA7AC", -"@[. c #B6B0B6", -"#[. c #757774", -"$[. c #444361", -"%[. c #464861", -"&[. c #444463", -"*[. c #3D3D5A", -"=[. c #5C5B78", -"-[. c #616080", -";[. c #6C6D86", -">[. c #636284", -",[. c #494966", -"'[. c #3B3B58", -")[. c #2B2D47", -"![. c #2D3049", -"~[. c #272B3E", -"{[. c #585A75", -"][. c #5C5975", -"^[. c #75738B", -"/[. c #8A85A9", -"([. c #3D3F53", -"_[. c #373955", -":[. c #434261", -"<[. c #353752", -"[[. c #5B547E", -"}[. c #5E5B81", -"|[. c #59557B", -"1[. c #41435A", -"2[. c #52506F", -"3[. c #8A8895", -"4[. c #827E9A", -"5[. c #58576F", -"6[. c #4F4F6E", -"7[. c #585676", -"8[. c #5B5A73", -"9[. c #535271", -"0[. c #66638A", -"a[. c #454560", -"b[. c #3E3F5A", -"c[. c #595878", -"d[. c #494968", -"e[. c #3D4059", -"f[. c #5F5C80", -"g[. c #726F8C", -"h[. c #4E4E60", -"i[. c #52506E", -"j[. c #4F4E6C", -"k[. c #4C4860", -"l[. c #35384D", -"m[. c #3E3F58", -"n[. c #64667D", -"o[. c #4F5169", -"p[. c #645E81", -"q[. c #7F7A9D", -"r[. c #A292AD", -"s[. c #A392AD", -"t[. c #A498AD", -"u[. c #A492AD", -"v[. c #A296AD", -"w[. c #8B849F", -"x[. c #7D759D", -"y[. c #817AA1", -"z[. c #6F698E", -"A[. c #565370", -"B[. c #ABABAB", -"C[. c #AAAAAA", -"D[. c #777574", -"E[. c #757472", -"F[. c #81807E", -"G[. c #90908B", -"H[. c #AAA8A6", -"I[. c #938F8E", -"J[. c #908C8A", -"K[. c #817C7B", -"L[. c #817E79", -"M[. c #87837F", -"N[. c #807E76", -"O[. c #52524D", -"P[. c #504E4D", -"Q[. c #242320", -"R[. c #02030A", -"S[. c #90A3E8", -"T[. c #828DE3", -"U[. c #7C83DD", -"V[. c #AC9FDE", -"W[. c #B2A1D9", -"X[. c #A896D3", -"Y[. c #9F91CD", -"Z[. c #8D84C0", -"`[. c #9187C9", -" }. c #958CC4", -".}. c #9F93C9", -"+}. c #958DBE", -"@}. c #887FB4", -"#}. c #8678A8", -"$}. c #8073A5", -"%}. c #8273A4", -"&}. c #8173A3", -"*}. c #7B7299", -"=}. c #7D7499", -"-}. c #7D7498", -";}. c #746E97", -">}. c #746B96", -",}. c #736B94", -"'}. c #7C70A3", -")}. c #8F87B4", -"!}. c #8F86B6", -"~}. c #8581B3", -"{}. c #8B82B9", -"]}. c #8D86BC", -"^}. c #8E86BD", -"/}. c #9691C5", -"(}. c #9D96C2", -"_}. c #A299BD", -":}. c #A39ABD", -"<}. c #A39AC0", -"[}. c #9A92B8", -"}}. c #8D8AB0", -"|}. c #8A83B0", -"1}. c #7C76A1", -"2}. c #807A9F", -"3}. c #8E88B3", -"4}. c #8F88B5", -"5}. c #9A92BD", -"6}. c #A79EC7", -"7}. c #A69DC6", -"8}. c #8F88B6", -"9}. c #9A92C8", -"0}. c #908AAF", -"a}. c #9F97C3", -"b}. c #938EB7", -"c}. c #7874A2", -"d}. c #6E6C89", -"e}. c #6F6990", -"f}. c #6E6892", -"g}. c #716B93", -"h}. c #525463", -"i}. c #444A54", -"j}. c #5D5C74", -"k}. c #7D7C96", -"l}. c #807B92", -"m}. c #B4B0BF", -"n}. c #464D54", -"o}. c #4C5061", -"p}. c #64667F", -"q}. c #575B70", -"r}. c #424759", -"s}. c #3A4251", -"t}. c #3A4252", -"u}. c #36414F", -"v}. c #38404D", -"w}. c #384055", -"x}. c #384150", -"y}. c #41465B", -"z}. c #5E5D77", -"A}. c #62617F", -"B}. c #5C5C78", -"C}. c #676583", -"D}. c #B7B0BE", -"E}. c #C8C1C8", -"F}. c #94939D", -"G}. c #BAB2C1", -"H}. c #C6BEC6", -"I}. c #C0B7C4", -"J}. c #B0A8BF", -"K}. c #B1ADBE", -"L}. c #8884A1", -"M}. c #56596A", -"N}. c #4F4F6C", -"O}. c #4B4D65", -"P}. c #54536E", -"Q}. c #3E4352", -"R}. c #686773", -"S}. c #898798", -"T}. c #7D7D8E", -"U}. c #666575", -"V}. c #5C5B5B", -"W}. c #5B555C", -"X}. c #807987", -"Y}. c #747080", -"Z}. c #686779", -"`}. c #615C6A", -" |. c #555564", -".|. c #535564", -"+|. c #78748D", -"@|. c #928894", -"#|. c #767379", -"$|. c #9E97A5", -"%|. c #B9B3B9", -"&|. c #B2ACAF", -"*|. c #818183", -"=|. c #3F4259", -"-|. c #3F425D", -";|. c #41445D", -">|. c #4F4D6C", -",|. c #575676", -"'|. c #40415C", -")|. c #373A51", -"!|. c #323548", -"~|. c #37374A", -"{|. c #464661", -"]|. c #656381", -"^|. c #636586", -"/|. c #414353", -"(|. c #4D4B64", -"_|. c #837F9A", -":|. c #9D98AC", -"<|. c #82808F", -"[|. c #6E688A", -"}|. c #5D587B", -"||. c #3D3E56", -"1|. c #41405A", -"2|. c #6E6A93", -"3|. c #7D7A9F", -"4|. c #65648E", -"5|. c #4F5065", -"6|. c #6D6A7B", -"7|. c #A096AB", -"8|. c #9690A8", -"9|. c #5A5677", -"0|. c #736F86", -"a|. c #636186", -"b|. c #7C779F", -"c|. c #515067", -"d|. c #5B587C", -"e|. c #3B3C4D", -"f|. c #5C587E", -"g|. c #6C6C88", -"h|. c #857FA6", -"i|. c #A19AAD", -"j|. c #948CA1", -"k|. c #78728D", -"l|. c #676889", -"m|. c #6E6B89", -"n|. c #4B4E5D", -"o|. c #47475B", -"p|. c #494A61", -"q|. c #2E2F3F", -"r|. c #404358", -"s|. c #53536B", -"t|. c #67607D", -"u|. c #7E7897", -"v|. c #9D91A9", -"w|. c #A092A9", -"x|. c #8E88A3", -"y|. c #958AA8", -"z|. c #9A90A8", -"A|. c #8B839F", -"B|. c #8C85A6", -"C|. c #958BA7", -"D|. c #88849D", -"E|. c #A7A7A7", -"F|. c #000100", -"G|. c #A2A2A2", -"H|. c #181818", -"I|. c #323231", -"J|. c #817F7D", -"K|. c #9E9D9A", -"L|. c #A09F9D", -"M|. c #A19D9C", -"N|. c #8C8887", -"O|. c #888382", -"P|. c #7F7D7B", -"Q|. c #888882", -"R|. c #7D7B73", -"S|. c #3B3A37", -"T|. c #1D1D1D", -"U|. c #875A4E", -"V|. c #556595", -"W|. c #7F8DDA", -"X|. c #7A82D7", -"Y|. c #7D7DCA", -"Z|. c #A396CC", -"`|. c #9289C5", -" 1. c #9689C4", -".1. c #948CC6", -"+1. c #968DC5", -"@1. c #8A83BE", -"#1. c #8C86B6", -"$1. c #867EAE", -"%1. c #8A7AB2", -"&1. c #7D73A8", -"*1. c #7C6E9F", -"=1. c #7A6D9B", -"-1. c #786C98", -";1. c #786D9B", -">1. c #796E9D", -",1. c #736A96", -"'1. c #736C90", -")1. c #726A95", -"!1. c #6F678D", -"~1. c #6C6687", -"{1. c #8276A3", -"]1. c #8A82A8", -"^1. c #8D86B4", -"/1. c #938CBD", -"(1. c #958FC2", -"_1. c #8F88BC", -":1. c #9893BE", -"<1. c #9892C1", -"[1. c #8F88AE", -"}1. c #9A91B6", -"|1. c #9892B5", -"11. c #9792B2", -"21. c #A399C0", -"31. c #8C85B0", -"41. c #8982AF", -"51. c #948BBB", -"61. c #8984AF", -"71. c #9F97C0", -"81. c #958CB5", -"91. c #9892B6", -"01. c #958EB7", -"a1. c #8780B3", -"b1. c #817BA8", -"c1. c #A99EC4", -"d1. c #817D9C", -"e1. c #706F9B", -"f1. c #6A6893", -"g1. c #77719A", -"h1. c #938DB1", -"i1. c #AEA8B6", -"j1. c #727478", -"k1. c #797586", -"l1. c #B7B4C4", -"m1. c #6F6D8E", -"n1. c #5D616B", -"o1. c #404750", -"p1. c #73708B", -"q1. c #9A97B5", -"r1. c #757685", -"s1. c #4B4E67", -"t1. c #414658", -"u1. c #444A5C", -"v1. c #323A4F", -"w1. c #353C4C", -"x1. c #373E4C", -"y1. c #363C52", -"z1. c #3B4156", -"A1. c #3F4355", -"B1. c #474B5E", -"C1. c #494B5D", -"D1. c #5D5C77", -"E1. c #827D89", -"F1. c #9893A9", -"G1. c #717183", -"H1. c #BEBEB8", -"I1. c #BCBCBC", -"J1. c #BCAFBD", -"K1. c #B3A7BD", -"L1. c #717389", -"M1. c #3E4351", -"N1. c #2E313F", -"O1. c #2C2F3C", -"P1. c #30343F", -"Q1. c #757478", -"R1. c #8A8891", -"S1. c #60606E", -"T1. c #5E5E69", -"U1. c #929093", -"V1. c #494C4B", -"W1. c #9C91A0", -"X1. c #9C91A5", -"Y1. c #6E6C7E", -"Z1. c #605D69", -"`1. c #5A5A69", -" 2. c #6B6676", -".2. c #7F7485", -"+2. c #A89DAB", -"@2. c #6D6A70", -"#2. c #A29EA4", -"$2. c #97979A", -"%2. c #4F4F53", -"&2. c #36394E", -"*2. c #555572", -"=2. c #57557A", -"-2. c #464761", -";2. c #4E516C", -">2. c #5A5478", -",2. c #474767", -"'2. c #535277", -")2. c #585478", -"!2. c #6C6B91", -"~2. c #55527D", -"{2. c #4C4C68", -"]2. c #605F87", -"^2. c #68668C", -"/2. c #424357", -"(2. c #575674", -"_2. c #716F92", -":2. c #525172", -"<2. c #7F7A96", -"[2. c #9C95A4", -"}2. c #A19AAF", -"|2. c #9892AF", -"12. c #726D93", -"22. c #434555", -"32. c #3A3A55", -"42. c #585875", -"52. c #53526F", -"62. c #524F6B", -"72. c #50506B", -"82. c #625D83", -"92. c #7E7A97", -"02. c #726D84", -"a2. c #6D6A84", -"b2. c #77778D", -"c2. c #78739E", -"d2. c #847FA3", -"e2. c #7D7996", -"f2. c #928EA7", -"g2. c #8D879D", -"h2. c #8983A4", -"i2. c #A8A0AA", -"j2. c #A19CAA", -"k2. c #A69FAA", -"l2. c #A397A9", -"m2. c #A99DA9", -"n2. c #AA99AA", -"o2. c #9D93A9", -"p2. c #948EA9", -"q2. c #A595A8", -"r2. c #96939C", -"s2. c #8F89A0", -"t2. c #96929E", -"u2. c #7B768C", -"v2. c #515061", -"w2. c #343744", -"x2. c #4B4965", -"y2. c #5F5A80", -"z2. c #726C8C", -"A2. c #9487A6", -"B2. c #8E87A1", -"C2. c #867E9A", -"D2. c #8A7F9E", -"E2. c #9288A4", -"F2. c #A08CA4", -"G2. c #9C8AA3", -"H2. c #998EA3", -"I2. c #A3A3A3", -"J2. c #9B9B9B", -"K2. c #2A2A29", -"L2. c #696969", -"M2. c #8A8886", -"N2. c #A09F9C", -"O2. c #8A8885", -"P2. c #888786", -"Q2. c #8B8987", -"R2. c #6A6968", -"S2. c #6C6A69", -"T2. c #777773", -"U2. c #42433D", -"V2. c #3E3E3D", -"W2. c #1A1A18", -"X2. c #1D2237", -"Y2. c #7C8DD2", -"Z2. c #747ECE", -"`2. c #7273C9", -" 3. c #847EC1", -".3. c #8E86BF", -"+3. c #847AB5", -"@3. c #8377B0", -"#3. c #877DB9", -"$3. c #8078AF", -"%3. c #8479AF", -"&3. c #79709F", -"*3. c #786D9C", -"=3. c #706790", -"-3. c #6D658C", -";3. c #706689", -">3. c #6B658A", -",3. c #6F6691", -"'3. c #70678D", -")3. c #6B6487", -"!3. c #6B6291", -"~3. c #615D82", -"{3. c #6A668C", -"]3. c #80779E", -"^3. c #857FB5", -"/3. c #807CB1", -"(3. c #9993B1", -"_3. c #847FA7", -":3. c #787395", -"<3. c #7B7499", -"[3. c #A59BC0", -"}3. c #8C84AB", -"|3. c #837CA5", -"13. c #7D7798", -"23. c #8C89A3", -"33. c #7F799F", -"43. c #857FAD", -"53. c #AB9EC3", -"63. c #8E88AF", -"73. c #918AB1", -"83. c #8C83AE", -"93. c #978FB5", -"03. c #8D87A9", -"a3. c #736F99", -"b3. c #706B94", -"c3. c #686487", -"d3. c #666489", -"e3. c #625F7D", -"f3. c #8D87AC", -"g3. c #8C889B", -"h3. c #BDB4BF", -"i3. c #94939B", -"j3. c #A49CB3", -"k3. c #BAB3BE", -"l3. c #ABAEAF", -"m3. c #8F8FA1", -"n3. c #9290A6", -"o3. c #9991A7", -"p3. c #B0ABB8", -"q3. c #83809B", -"r3. c #656A74", -"s3. c #45475B", -"t3. c #333949", -"u3. c #2E3643", -"v3. c #2E3749", -"w3. c #323748", -"x3. c #343848", -"y3. c #303748", -"z3. c #303649", -"A3. c #2E3646", -"B3. c #363B4A", -"C3. c #373D4A", -"D3. c #38404E", -"E3. c #72707D", -"F3. c #9B96A3", -"G3. c #A9A0B6", -"H3. c #ACA6B2", -"I3. c #A99FB6", -"J3. c #B6ACB5", -"K3. c #ADA4B4", -"L3. c #8C899E", -"M3. c #6A6B84", -"N3. c #3D4150", -"O3. c #36394C", -"P3. c #2B2F36", -"Q3. c #3D3F4D", -"R3. c #605D68", -"S3. c #686670", -"T3. c #555860", -"U3. c #716E79", -"V3. c #9B939D", -"W3. c #565755", -"X3. c #625C65", -"Y3. c #938A9A", -"Z3. c #766E7D", -"`3. c #817389", -" 4. c #908A95", -".4. c #676674", -"+4. c #8C8594", -"@4. c #786A7B", -"#4. c #8A7E8B", -"$4. c #A8A8AA", -"%4. c #5A5B65", -"&4. c #303241", -"*4. c #504E6B", -"=4. c #60607F", -"-4. c #54527D", -";4. c #515476", -">4. c #353750", -",4. c #3B3B55", -"'4. c #50506D", -")4. c #474863", -"!4. c #414057", -"~4. c #514F6B", -"{4. c #4F4F67", -"]4. c #4C4D5D", -"^4. c #6D6A85", -"/4. c #67687F", -"(4. c #4A4866", -"_4. c #706D8E", -":4. c #6D6D78", -"<4. c #5D5C7B", -"[4. c #706D88", -"}4. c #86819C", -"|4. c #7D7BA5", -"14. c #747092", -"24. c #6A6A85", -"34. c #4A4762", -"44. c #474561", -"54. c #454360", -"64. c #595976", -"74. c #595978", -"84. c #555173", -"94. c #555576", -"04. c #726C8E", -"a4. c #87809B", -"b4. c #87859D", -"c4. c #726F94", -"d4. c #716D91", -"e4. c #595879", -"f4. c #6F6C87", -"g4. c #8D869F", -"h4. c #928AA7", -"i4. c #978DA5", -"j4. c #9C96A3", -"k4. c #A39DA7", -"l4. c #A49BA6", -"m4. c #9A90A3", -"n4. c #A699A6", -"o4. c #9F8EA4", -"p4. c #9A8FA4", -"q4. c #A496A4", -"r4. c #A298A4", -"s4. c #A193A3", -"t4. c #A097A3", -"u4. c #9B93A3", -"v4. c #888499", -"w4. c #77738E", -"x4. c #535175", -"y4. c #4A495F", -"z4. c #454558", -"A4. c #615B7B", -"B4. c #8F84A1", -"C4. c #9484A0", -"D4. c #8A81A0", -"E4. c #8F85A0", -"F4. c #978AA0", -"G4. c #978A9F", -"H4. c #88819A", -"I4. c #9F9FA0", -"J4. c #929292", -"K4. c #747370", -"L4. c #6F6F6E", -"M4. c #8C8C89", -"N4. c #706F6E", -"O4. c #757471", -"P4. c #312F2E", -"Q4. c #0C090B", -"R4. c #8393C5", -"S4. c #727FC5", -"T4. c #6D73C2", -"U4. c #6768BA", -"V4. c #837BB8", -"W4. c #7770AA", -"X4. c #7168A6", -"Y4. c #7A73AE", -"Z4. c #726CA3", -"`4. c #696399", -" 5. c #756B9F", -".5. c #716493", -"+5. c #6C648F", -"@5. c #67608C", -"#5. c #675F8E", -"$5. c #6A6182", -"%5. c #6F658F", -"&5. c #7A739E", -"*5. c #676382", -"=5. c #605A85", -"-5. c #665F8E", -";5. c #5E5B79", -">5. c #79739C", -",5. c #ABA1BF", -"'5. c #7E7BAD", -")5. c #79789A", -"!5. c #625D7E", -"~5. c #8C84AA", -"{5. c #9088A7", -"]5. c #AEA4BE", -"^5. c #9D98B8", -"/5. c #857EA3", -"(5. c #625D7D", -"_5. c #70698B", -":5. c #757095", -"<5. c #8980A1", -"[5. c #9991B6", -"}5. c #988DB8", -"|5. c #8B85AC", -"15. c #9D90B0", -"25. c #A79BB5", -"35. c #8D86AA", -"45. c #7F7996", -"55. c #8E87AB", -"65. c #6C6890", -"75. c #605E7C", -"85. c #5F5D86", -"95. c #62608B", -"05. c #5A5872", -"a5. c #605C77", -"b5. c #87839A", -"c5. c #938FAF", -"d5. c #B2A6B5", -"e5. c #B4ADB4", -"f5. c #818090", -"g5. c #AFA8B3", -"h5. c #B1B1B1", -"i5. c #B2A8B2", -"j5. c #B2B2A4", -"k5. c #B2ABB2", -"l5. c #B1AAAD", -"m5. c #B2A3B2", -"n5. c #393F4A", -"o5. c #404255", -"p5. c #393E53", -"q5. c #2D3441", -"r5. c #2B3340", -"s5. c #2C3341", -"t5. c #31374C", -"u5. c #373B50", -"v5. c #323943", -"w5. c #50505B", -"x5. c #6F6F79", -"y5. c #837E8C", -"z5. c #A7A0A8", -"A5. c #777483", -"B5. c #93909C", -"C5. c #A6A0A9", -"D5. c #AFA6AF", -"E5. c #85819D", -"F5. c #75738E", -"G5. c #74758C", -"H5. c #4D5059", -"I5. c #7B7A82", -"J5. c #6D6D79", -"K5. c #686778", -"L5. c #747388", -"M5. c #848488", -"N5. c #7C798B", -"O5. c #79778A", -"P5. c #5B5864", -"Q5. c #716D77", -"R5. c #988D99", -"S5. c #928D95", -"T5. c #89878B", -"U5. c #7E7B8B", -"V5. c #625E6A", -"W5. c #6A6378", -"X5. c #74697A", -"Y5. c #726C7A", -"Z5. c #8A878C", -"`5. c #434549", -" 6. c #524D67", -".6. c #464659", -"+6. c #424455", -"@6. c #464655", -"#6. c #333544", -"$6. c #313144", -"%6. c #313345", -"&6. c #32324C", -"*6. c #404163", -"=6. c #40405D", -"-6. c #2F314A", -";6. c #37374E", -">6. c #3B3B54", -",6. c #514F68", -"'6. c #686286", -")6. c #605E79", -"!6. c #8F8A9F", -"~6. c #827F94", -"{6. c #807CA0", -"]6. c #8886A0", -"^6. c #706D93", -"/6. c #747293", -"(6. c #9088A4", -"_6. c #57566C", -":6. c #20243A", -"<6. c #1D1F38", -"[6. c #23243B", -"}6. c #46445B", -"|6. c #575271", -"16. c #4F4F6A", -"26. c #5A556D", -"36. c #857D9B", -"46. c #978CA3", -"56. c #6C6689", -"66. c #6A6687", -"76. c #79778E", -"86. c #636076", -"96. c #5B5972", -"06. c #7B7784", -"a6. c #81788C", -"b6. c #7B768D", -"c6. c #56545E", -"d6. c #848390", -"e6. c #474751", -"f6. c #746F81", -"g6. c #968B9E", -"h6. c #9D8E9F", -"i6. c #948A9E", -"j6. c #9F929F", -"k6. c #968D9D", -"l6. c #79748D", -"m6. c #9A929F", -"n6. c #878288", -"o6. c #6A667F", -"p6. c #655F84", -"q6. c #68648B", -"r6. c #636278", -"s6. c #4A4760", -"t6. c #787198", -"u6. c #7E7893", -"v6. c #8C809B", -"w6. c #98849B", -"x6. c #9B899B", -"y6. c #91809B", -"z6. c #837D9B", -"A6. c #8A8A8A", -"B6. c #272726", -"C6. c #30302F", -"D6. c #2E2E2B", -"E6. c #1F1E1E", -"F6. c #050506", -"G6. c #2B324B", -"H6. c #707EBA", -"I6. c #6771B7", -"J6. c #6265B1", -"K6. c #6A68A7", -"L6. c #706AA3", -"M6. c #68619C", -"N6. c #6E659F", -"O6. c #706BA0", -"P6. c #635B90", -"Q6. c #615A8C", -"R6. c #615B8A", -"S6. c #635A89", -"T6. c #696093", -"U6. c #605B84", -"V6. c #5F597E", -"W6. c #635B85", -"X6. c #5F587D", -"Y6. c #635B84", -"Z6. c #6B6993", -"`6. c #5D567D", -" 7. c #5A5577", -".7. c #5C577F", -"+7. c #5E597E", -"@7. c #7A7591", -"#7. c #A89EB7", -"$7. c #A4A3B5", -"%7. c #7D77A2", -"&7. c #5B587E", -"*7. c #5B557C", -"=7. c #817C95", -"-7. c #928BA2", -";7. c #B4A6B4", -">7. c #7E7C8F", -",7. c #504E70", -"'7. c #5E5B7E", -")7. c #53506E", -"!7. c #9A8FAE", -"~7. c #9A8EAF", -"{7. c #9C8FAE", -"]7. c #A69AAF", -"^7. c #A297AB", -"/7. c #5E5C78", -"(7. c #736C89", -"_7. c #6D6B8B", -":7. c #6B678A", -"<7. c #4E4D65", -"[7. c #565570", -"}7. c #3D3E4E", -"|7. c #555269", -"17. c #7B778E", -"27. c #9B92AC", -"37. c #6C6D80", -"47. c #746F80", -"57. c #9F98AA", -"67. c #9E99A8", -"77. c #8780A0", -"87. c #86809F", -"97. c #99939F", -"07. c #A9A3A9", -"a7. c #9D99A1", -"b7. c #605B7A", -"c7. c #8C8C9D", -"d7. c #4A4C61", -"e7. c #2E3644", -"f7. c #2D303F", -"g7. c #2C313E", -"h7. c #2B3142", -"i7. c #323646", -"j7. c #3A3D4C", -"k7. c #5A5A67", -"l7. c #85828E", -"m7. c #58566B", -"n7. c #97929D", -"o7. c #888488", -"p7. c #838088", -"q7. c #8C8792", -"r7. c #949197", -"s7. c #A5A5A5", -"t7. c #8E8AA1", -"u7. c #69667E", -"v7. c #A398A7", -"w7. c #97919E", -"x7. c #726F85", -"y7. c #8D889F", -"z7. c #827B90", -"A7. c #86828F", -"B7. c #837F87", -"C7. c #777583", -"D7. c #696572", -"E7. c #87828E", -"F7. c #908E90", -"G7. c #5F5F61", -"H7. c #908793", -"I7. c #7E7C83", -"J7. c #6D6B6E", -"K7. c #747174", -"L7. c #9A9497", -"M7. c #948E98", -"N7. c #666071", -"O7. c #686175", -"P7. c #79758D", -"Q7. c #5A5B68", -"R7. c #4E4F64", -"S7. c #646175", -"T7. c #777680", -"U7. c #797284", -"V7. c #9B939E", -"W7. c #5A5B6E", -"X7. c #282A39", -"Y7. c #272840", -"Z7. c #262640", -"`7. c #262A44", -" 8. c #2C2E41", -".8. c #383950", -"+8. c #40405A", -"@8. c #666679", -"#8. c #56596E", -"$8. c #595774", -"%8. c #46455D", -"&8. c #474860", -"*8. c #33364A", -"=8. c #514F67", -"-8. c #868291", -";8. c #8B869D", -">8. c #898597", -",8. c #787490", -"'8. c #847C9B", -")8. c #716F87", -"!8. c #2A2A3C", -"~8. c #2A2D43", -"{8. c #555571", -"]8. c #1E202F", -"^8. c #282940", -"/8. c #3F4056", -"(8. c #48465F", -"_8. c #6D6888", -":8. c #847E98", -"<8. c #5A5674", -"[8. c #5A586F", -"}8. c #6A6679", -"|8. c #86808E", -"18. c #3D3F49", -"28. c #303040", -"38. c #454256", -"48. c #787481", -"58. c #504D5F", -"68. c #625E7D", -"78. c #5B5A6E", -"88. c #414150", -"98. c #918996", -"08. c #8F8496", -"a8. c #968696", -"b8. c #908596", -"c8. c #68657A", -"d8. c #515164", -"e8. c #393949", -"f8. c #585373", -"g8. c #746E88", -"h8. c #726B85", -"i8. c #76718A", -"j8. c #5C5A79", -"k8. c #6C668A", -"l8. c #77718B", -"m8. c #877D94", -"n8. c #8E7F93", -"o8. c #907E93", -"p8. c #6E6886", -"q8. c #949494", -"r8. c #828282", -"s8. c #7082AF", -"t8. c #656DAF", -"u8. c #5D61A7", -"v8. c #5B5B9F", -"w8. c #6A639A", -"x8. c #655C99", -"y8. c #605993", -"z8. c #625D93", -"A8. c #595189", -"B8. c #585184", -"C8. c #5B5485", -"D8. c #5E5682", -"E8. c #5D5684", -"F8. c #5E5985", -"G8. c #5D547E", -"H8. c #585378", -"I8. c #5C5478", -"J8. c #5C577C", -"K8. c #746F9A", -"L8. c #6B688F", -"M8. c #56507A", -"N8. c #544F6F", -"O8. c #514E6C", -"P8. c #585271", -"Q8. c #6E6894", -"R8. c #918AA2", -"S8. c #8C8A96", -"T8. c #656386", -"U8. c #5E5782", -"V8. c #524F75", -"W8. c #5B5579", -"X8. c #6F6D88", -"Y8. c #827D8C", -"Z8. c #8E8C96", -"`8. c #6A677C", -" 9. c #48475E", -".9. c #4F4C6E", -"+9. c #7E7797", -"@9. c #867EA0", -"#9. c #827E9F", -"$9. c #A292A6", -"%9. c #918D99", -"&9. c #65617D", -"*9. c #5A5878", -"=9. c #535170", -"-9. c #47475C", -";9. c #47495E", -">9. c #333947", -",9. c #373A47", -"'9. c #4C4A5E", -")9. c #69647D", -"!9. c #848197", -"~9. c #847F8B", -"{9. c #9897A2", -"]9. c #7D7791", -"^9. c #87819A", -"/9. c #A398A3", -"(9. c #9996A3", -"_9. c #83819E", -":9. c #736E95", -"<9. c #857FA1", -"[9. c #9C91A1", -"}9. c #998EA2", -"|9. c #998EA1", -"19. c #9E9DA1", -"29. c #66677A", -"39. c #4D4D5F", -"49. c #3E4153", -"59. c #2F3546", -"69. c #29313A", -"79. c #2A3140", -"89. c #383B4B", -"99. c #4B4A5F", -"09. c #444459", -"a9. c #343A45", -"b9. c #474752", -"c9. c #908B8F", -"d9. c #948D97", -"e9. c #857F81", -"f9. c #9E999E", -"g9. c #998F9E", -"h9. c #9B939F", -"i9. c #878492", -"j9. c #898392", -"k9. c #88829A", -"l9. c #656279", -"m9. c #68657C", -"n9. c #89809A", -"o9. c #686576", -"p9. c #4E4B56", -"q9. c #52525C", -"r9. c #4E4E59", -"s9. c #484849", -"t9. c #474646", -"u9. c #58555E", -"v9. c #878091", -"w9. c #666271", -"x9. c #6A6176", -"y9. c #7C7680", -"z9. c #6A6876", -"A9. c #6E6876", -"B9. c #696677", -"C9. c #625C74", -"D9. c #757585", -"E9. c #8D8899", -"F9. c #737183", -"G9. c #8B8892", -"H9. c #969499", -"I9. c #9A9692", -"J9. c #999395", -"K9. c #8A888A", -"L9. c #58556C", -"M9. c #49485F", -"N9. c #20213A", -"O9. c #1B1E35", -"P9. c #45455E", -"Q9. c #474460", -"R9. c #504C6C", -"S9. c #676478", -"T9. c #4C4B62", -"U9. c #575767", -"V9. c #413E55", -"W9. c #35364D", -"X9. c #292A3E", -"Y9. c #39384A", -"Z9. c #656178", -"`9. c #605C79", -" 0. c #908195", -".0. c #8D8696", -"+0. c #73708A", -"@0. c #53526A", -"#0. c #48476B", -"$0. c #2F2F43", -"%0. c #4F4B6A", -"&0. c #383851", -"*0. c #514C6E", -"=0. c #5E5A77", -"-0. c #767188", -";0. c #68637E", -">0. c #514C65", -",0. c #6B6880", -"'0. c #68667E", -")0. c #6B6786", -"!0. c #7C7987", -"~0. c #737277", -"{0. c #62606A", -"]0. c #706D84", -"^0. c #817F88", -"/0. c #5F5D68", -"(0. c #7F7B85", -"_0. c #757481", -":0. c #585765", -"<0. c #484856", -"[0. c #575367", -"}0. c #646170", -"|0. c #645F74", -"10. c #887D8E", -"20. c #686679", -"30. c #5F5B79", -"40. c #6C6782", -"50. c #7D738D", -"60. c #716A82", -"70. c #7F798D", -"80. c #7E748D", -"90. c #7D738C", -"00. c #7F738B", -"a0. c #7C748A", -"b0. c #867D8B", -"c0. c #7C768B", -"d0. c #726B87", -"e0. c #6E6B88", -"f0. c #797979", -"g0. c #9AACB4", -"h0. c #303953", -"i0. c #5F6CA5", -"j0. c #5D63A1", -"k0. c #55569B", -"l0. c #5A578D", -"m0. c #5D588D", -"n0. c #565188", -"o0. c #58548A", -"p0. c #575084", -"q0. c #524B7D", -"r0. c #504A79", -"s0. c #564E7A", -"t0. c #574E7B", -"u0. c #575181", -"v0. c #514B73", -"w0. c #514B6F", -"x0. c #524B75", -"y0. c #58567D", -"z0. c #6E668C", -"A0. c #7C7597", -"B0. c #746F88", -"C0. c #5E597B", -"D0. c #535072", -"E0. c #4C4969", -"F0. c #524C77", -"G0. c #4B4970", -"H0. c #625F82", -"I0. c #605E82", -"J0. c #504C77", -"K0. c #484561", -"L0. c #515077", -"M0. c #565577", -"N0. c #49495E", -"O0. c #5D596F", -"P0. c #555471", -"Q0. c #41415C", -"R0. c #3D3D58", -"S0. c #3A3B58", -"T0. c #48455F", -"U0. c #575376", -"V0. c #807A98", -"W0. c #807B98", -"X0. c #797492", -"Y0. c #656180", -"Z0. c #646180", -"`0. c #53526D", -" a. c #5C5875", -".a. c #424359", -"+a. c #333848", -"@a. c #424257", -"#a. c #3A3C4D", -"$a. c #45445B", -"%a. c #48475D", -"&a. c #4B4A5C", -"*a. c #908893", -"=a. c #8A8A8F", -"-a. c #847D92", -";a. c #807C94", -">a. c #635F7E", -",a. c #77728F", -"'a. c #968A9B", -")a. c #7F7C94", -"!a. c #6D688B", -"~a. c #7C7689", -"{a. c #817C8F", -"]a. c #978999", -"^a. c #988999", -"/a. c #767681", -"(a. c #292F35", -"_a. c #282E37", -":a. c #252A35", -"b. c #6A6577", -",b. c #49475A", -"'b. c #252638", -")b. c #313141", -"!b. c #1D202C", -"~b. c #151929", -"{b. c #202233", -"]b. c #2C2D3F", -"^b. c #303145", -"/b. c #252A36", -"(b. c #363543", -"_b. c #393749", -":b. c #454260", -"c. c #858091", -",c. c #6C6680", -"'c. c #4D4D63", -")c. c #222A2F", -"!c. c #202732", -"~c. c #222635", -"{c. c #222733", -"]c. c #2B2E39", -"^c. c #363748", -"/c. c #3B3D4F", -"(c. c #4C4C59", -"_c. c #373D42", -":c. c #353943", -"d. c #2B2B41", -",d. c #202337", -"'d. c #242539", -")d. c #2E2E42", -"!d. c #3B3952", -"~d. c #5A566D", -"{d. c #676275", -"]d. c #6D637A", -"^d. c #76697D", -"/d. c #74687A", -"(d. c #756A7C", -"_d. c #79697C", -":d. c #796D7C", -"e. c #3F3F50", -",e. c #30333C", -"'e. c #40404E", -")e. c #6F6C73", -"!e. c #756F78", -"~e. c #807981", -"{e. c #827B85", -"]e. c #868686", -"^e. c #7A7584", -"/e. c #615D75", -"(e. c #656077", -"_e. c #5F5B75", -":e. c #575570", -"f. c #706473", -",f. c #716373", -"'f. c #716272", -")f. c #6A6072", -"!f. c #545161", -"~f. c #5E5A69", -"{f. c #717171", -"]f. c #606060", -"^f. c #5D6787", -"/f. c #4B5082", -"(f. c #47497F", -"_f. c #454278", -":f. c #443F76", -"g. c #706B78", -",g. c #51505E", -"'g. c #625D6E", -")g. c #4C4B5F", -"!g. c #44434F", -"~g. c #7C747C", -"{g. c #726F73", -"]g. c #625E6E", -"^g. c #666464", -"/g. c #726C6F", -"(g. c #756C77", -"_g. c #6E6A72", -":g. c #6E6C74", -"h. c #3D3961", -",h. c #3C3861", -"'h. c #3D3861", -")h. c #3C385E", -"!h. c #3C385B", -"~h. c #3C3859", -"{h. c #3C3857", -"]h. c #3B3857", -"^h. c #393857", -"/h. c #433E60", -"(h. c #4C476A", -"_h. c #55516B", -":h. c #685E79", -"i. c #6C6670", -",i. c #524D5D", -"'i. c #635D67", -")i. c #6E6D6F", -"!i. c #67646C", -"~i. c #343540", -"{i. c #3D3D4B", -"]i. c #1F212A", -"^i. c #292B38", -"/i. c #30303A", -"(i. c #3E3D45", -"_i. c #313240", -":i. c #1C1E30", -"j. c #514C69", -",j. c #3E3B59", -"'j. c #32314D", -")j. c #32304C", -"!j. c #32304E", -"~j. c #37355A", -"{j. c #2E2E49", -"]j. c #3E395B", -"^j. c #343251", -"/j. c #353351", -"(j. c #353250", -"_j. c #414256", -":j. c #545066", -"k. c #1F2030", -",k. c #2D2D3E", -"'k. c #2B2B3D", -")k. c #3B3855", -"!k. c #575264", -"~k. c #434056", -"{k. c #323243", -"]k. c #343348", -"^k. c #2E2E3E", -"/k. c #434158", -"(k. c #5E5A65", -"_k. c #5F5C63", -":k. c #565565", -"l. c #353453", -",l. c #302F4C", -"'l. c #3F3E58", -")l. c #62616F", -"!l. c #6F6F6F", -"~l. c #6A706D", -"{l. c #5E6171", -"]l. c #404156", -"^l. c #5A5770", -"/l. c #53546A", -"(l. c #5C5C6E", -"_l. c #4E4D6B", -":l. c #4A4968", -"m. c #4F5058", -",m. c #535358", -"'m. c #454456", -")m. c #424247", -"!m. c #262730", -"~m. c #1D1D29", -"{m. c #39394A", -"]m. c #323143", -"^m. c #252436", -"/m. c #1D1D2D", -"(m. c #141425", -"_m. c #0B0C1B", -":m. c #161626", -"n. c #363744", -",n. c #2E2E3F", -"'n. c #333345", -")n. c #323140", -"!n. c #393946", -"~n. c #3C3B4C", -"{n. c #2D2D36", -"]n. c #4B4952", -"^n. c #4B4859", -"/n. c #373946", -"(n. c #1B1F24", -"_n. c #21242B", -":n. c #212529", -"o. c #060717", -",o. c #050715", -"'o. c #0B0B19", -")o. c #070914", -"!o. c #060817", -"~o. c #060816", -"{o. c #0C0D1A", -"]o. c #0A0C19", -"^o. c #080A17", -"/o. c #050814", -"(o. c #0E101C", -"_o. c #171823", -":o. c #1D1D2A", -"p. c #484854", -",p. c #1E2125", -"'p. c #20222A", -")p. c #3D3B48", -"!p. c #4B4B50", -"~p. c #3F3D4C", -"{p. c #353546", -"]p. c #37354B", -"^p. c #2F2F41", -"/p. c #24262F", -"(p. c #31303D", -"_p. c #413E4E", -":p. c #504C53", -"q. c #191925", -",q. c #1B1B27", -"'q. c #23212F", -")q. c #3D3D3D", -"!q. c #424962", -"~q. c #3A3D61", -"{q. c #33325F", -"]q. c #322E57", -"^q. c #2F2C55", -"/q. c #2F2B52", -"(q. c #2E2950", -"_q. c #2D294C", -":q. c #2B284A", -"r. c #37363C", -",r. c #454449", -"'r. c #4D4A4D", -")r. c #49434D", -"!r. c #32313A", -"~r. c #424044", -"{r. c #4F4A4F", -"]r. c #514F51", -"^r. c #4C484E", -"/r. c #43404D", -"(r. c #48454C", -"_r. c #393941", -":r. c #444148", -"s. c #28253F", -",s. c #252338", -"'s. c #29273E", -")s. c #27253D", -"!s. c #403E55", -"~s. c #2A2943", -"{s. c #2B2743", -"]s. c #2C2941", -"^s. c #413D4C", -"/s. c #4E4C53", -"(s. c #3D3C47", -"_s. c #29273A", -":s. c #1B1C2B", -"t. c #38373C", -",t. c #403E40", -"'t. c #353338", -")t. c #36343B", -"!t. c #413E42", -"~t. c #3A3A3C", -"{t. c #37363B", -"]t. c #26262C", -"^t. c #12121A", -"/t. c #1D1C28", -"(t. c #292735", -"_t. c #35323D", -":t. c #37333D", -"u. c #383542", -",u. c #403D42", -"'u. c #403F43", -")u. c #383642", -"!u. c #3E3B46", -"~u. c #424045", -"{u. c #2F2E30", -"]u. c #48444B", -"^u. c #49484B", -"/u. c #4D484A", -"(u. c #49464B", -"_u. c #444248", -":u. c #3F3E46", -"v. c #272544", -",v. c #2A2548", -"'v. c #272443", -")v. c #262340", -"!v. c #24213D", -"~v. c #292740", -"{v. c #423E4D", -"]v. c #464251", -"^v. c #434250", -"/v. c #282541", -"(v. c #23223A", -"_v. c #222036", -":v. c #25233D", -"w. c #2C2A31", -",w. c #2B2A32", -"'w. c #15161F", -")w. c #1A1A24", -"!w. c #232228", -"~w. c #14131D", -"{w. c #08080D", -"]w. c #08080E", -"^w. c #17161A", -"/w. c #2C2A2E", -"(w. c #222029", -"_w. c #0F0F14", -":w. c #262529", -"x. c #36333B", -",x. c #26272C", -"'x. c #2A2931", -")x. c #2B2936", -"!x. c #24242F", -"~x. c #35313C", -"{x. c #1A1A21", -"]x. c #28272C", -"^x. c #35333A", -"/x. c #25242A", -"(x. c #26262D", -"_x. c #141514", -":x. c #202021", -"y. c #18172A", -",y. c #111222", -"'y. c #171628", -")y. c #121223", -"!y. c #121221", -"~y. c #141422", -"{y. c #131323", -"]y. c #171627", -"^y. c #10111F", -"/y. c #1D1B2E", -"(y. c #181824", -"_y. c #222032", -":y. c #1E1E31", -"z. c #16141D", -",z. c #0B0B12", -"'z. c #050509", -")z. c #030306", -"!z. c #000102", -"~z. c #252842", -"{z. c #20203F", -"]z. c #201E3B", -"^z. c #1E1D39", -"/z. c #201D36", -"(z. c #1E1C37", -"_z. c #29263B", -":z. c #373342", -"A. c #15141B", -",A. c #131317", -"'A. c #111014", -")A. c #1F1D21", -"!A. c #1E1D20", -"~A. c #0E0E16", -"{A. c #0F0E18", -"]A. c #0E0D18", -"^A. c #0B0A11", -"/A. c #040507", -"(A. c #050508", -"_A. c #030407", -":A. c #06050A", -"B. c #1D1B1E", -",B. c #221F22", -"'B. c #1B191F", -")B. c #0F0E16", -"!B. c #09090C", -"~B. c #08080A", -"{B. c #131217", -"]B. c #1A181C", -"^B. c #1B1A1C", -"/B. c #131219", -"(B. c #0D0D14", -"_B. c #111015", -":B. c #090810", -"C. c #060607", -",C. c #0A090B", -"'C. c #0D0B0D", -")C. c #0A090C", -"!C. c #0A090D", -"~C. c #07060B", -"{C. c #191B30", -"]C. c #14152D", -"^C. c #16152C", -"/C. c #15132A", -"(C. c #16142A", -"_C. c #292631", -":C. c #2E2D32", -"D. c #11101C", -",D. c #06060F", -"'D. c #0C0B14", -")D. c #0E0D19", -"!D. c #13121C", -"~D. c #0E0D17", -"{D. c #030408", -"]D. c #030405", -"^D. c #0E0D13", -"/D. c #0A0A11", -"(D. c #09090E", -"_D. c #0F0E13", -":D. c #06060A", -"E. c #4B4B4B", -",E. c #DEDEDE", -"'E. c #FBFBFB", -")E. c #AEAEAF", -"!E. c #525153", -"~E. c #676668", -"{E. c #3F3D40", -"]E. c #060024", -"^E. c #1D1D1C", -"/E. c #001D23", -"(E. c #090000", -"_E. c #DDDDDD", -":E. c #FDFDFD", -"F. c #062B86", -",F. c #BFCFC1", -"'F. c #BDBFC4", -")F. c #D0AD68", -"!F. c #CCBFB7", -"~F. c #C7CFCA", -"{F. c #C19762", -"]F. c #190040", -"^F. c #060D79", -"/F. c #BDDDD6", -"(F. c #B56B12", -"_F. c #0668A6", -":F. c #7F1D0E", -"G. c #838283", -",G. c #B7B7B8", -"'G. c #6C6C6D", -")G. c #1366AE", -"!G. c #DCDEBD", -"~G. c #060529", -"{G. c #1D1717", -"]G. c #1779B6", -"^G. c #EAEAD0", -"/G. c #945542", -"(G. c #4FA6CF", -"_G. c #60A8D1", -":G. c #469BC7", -"H. c #84BBCA", -",H. c #C9A56C", -"'H. c #2F000D", -")H. c #3D85B3", -"!H. c #D1DDD7", -"~H. c #D9CB9F", -"{H. c #672300", -"]H. c #29659D", -"^H. c #B38949", -"/H. c #001761", -"(H. c #9FC9CF", -"_H. c #DFDFCB", -":H. c #BF8947", -"I. c #064588", -",I. c #B1B9BF", -"'I. c #D2DDD9", -")I. c #DACBBB", -"!I. c #B7A171", -"~I. c #250040", -"{I. c #3C5764", -"]I. c #4C2D0F", -"^I. c #C3DDD0", -"/I. c #A7590E", -"(I. c #57A7CD", -"_I. c #DDC17D", -":I. c #1D0000", -"J. c #89430F", -",J. c #894310", -"'J. c #CB9543", -")J. c #013D7F", -"!J. c #2A2A2A", -"~J. c #717172", -"{J. c #B8B8B8", -"]J. c #CACACB", -"^J. c #380000", -"/J. c #003B6F", -"(J. c #AFCBBF", -"_J. c #AF958D", -":J. c #959397", -"K. c #002C7F", -",K. c #727272", -"'K. c #005393", -")K. c #CBD7B3", -"!K. c #3B89AF", -"~K. c #BDA369", -"{K. c #1F0035", -"]K. c #010100", -"^K. c #002373", -"/K. c #B3D5CB", -"(K. c #AD6F1F", -"_K. c #D3A369", -":K. c #7BB19D", -"L. c #CBBDAF", -",L. c #B3AFA1", -"'L. c #A18F5B", -")L. c #170000", -"!L. c #838383", -"~L. c #B0B0B0", -"{L. c #808080", -"]L. c #777777", -"^L. c #5391B5", -"/L. c #CFD1BD", -"(L. c #000153", -"_L. c #002B57", -":L. c #7B8163", -"M. c #D0D0D0", -",M. c #5395B5", -"'M. c #CBBF8F", -")M. c #571700", -"!M. c #A4A4A4", -"~M. c #979797", -"{M. c #3F204D", -"]M. c #89B5B3", -"^M. c #BBBDBD", -"/M. c #D1C79B", -"(M. c #5F2B00", -"_M. c #004387", -":M. c #B7BF99", -" $ + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + , + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + , + + + + + + + + + + + ' + + + + + + + + + + + + ) + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = - ! ~ { ' > + + + + # + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , , @ + + + + + + + + ] ^ + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + , + + + + + + + + + + + ' + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + ) > + + # + + + + + + + + + + ] + + + + + + + + + + + + $ ^ + + + + + , + + + + + + + + + , , + + + + + + + + + + + + + + + + = ( _ _ ! : , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + @ + + + @ + + + + ) + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + # + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + [ } ! ~ | ' $ @ + + + + + + + + + + + + + + + + + + + + + + + # # + + + + + + + + + + + + + + + + + + + + : 1 2 + + + + + + + + + + + = + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + . ", -" . + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + ) + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + / + + + + + $ [ - ^ 4 $ # + + + , + + + + + + + + + + + + ) + + + + + + + / / @ @ + + + + + + , + + + + + + , + + + + 5 | : + + + + + + + + + + + + + + + + + + + + + + ; 6 > + + + + + + + + + = | + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + , + + + ) + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + $ = = ) + + # + + + + + + + + + + + + + + + + + + + + + + + < / + + + + + + + + ] + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + ! 7 > + + + + + + + , = + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + , $ + + + + + + + + + | + + + + + : 8 $ + + + + + + + + + + + + + + 3 9 + + + + + + + + + + ) + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + , + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + $ ) , , + + + + + + + + + + + + 9 , + + + + + + + + + ) + + + + + + + + + + + + # # + + + + + + + + + + + + + + + + + + + + + + + + + + + % + + + + + + ( 0 + + + + + + + + + + + + + / + + + + + + + $ + + + + + + + + + + + + + + + + + + , $ + + + + + + + + + | + + + + + : 8 $ + + + + + + + + + + + + + + 3 9 + + + + + + + + + + ) + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + ) + : , + + + + = a ' + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + , + + + + @ + + + + + + + + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # # + + b { = + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + & + + + + @ + + + & + + + + + + , , + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + : , + + + + = a ' + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + . ", -" . + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + # + @ + < $ + + + + + + + + + + + + = + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + # + + + + + + + + + + + + + + + @ + + + + + + + + $ + + , + + + + + + c + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + # + @ + < $ + + + + + + + + + + + + = + ] + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + # + + + 2 + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + @ + @ + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + # + + + 2 + + + + + + + + + + + + + + + + + , + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + , , + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + d : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # { d + + + + + + + + + + + + + + + + + + + + + + + + + + # ) + e ) + + + + + + + + + + + + + + + + + + + + : % + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , , + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + d : + + + + + + + + + . ", -" . + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + > $ ) + + + + $ ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) = $ + + + + + + + + b + + + + + + + + ] + , # + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ] + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + , f + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' : + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + # + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < / + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , f + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + , + + + + + + + + + + + + . ", -" . $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + & + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + @ + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + $ , + + + + + + + + + + + + + + @ < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + , ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + < / + + + @ + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + & + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + @ + + + + . ", -" . + + + + + + + + + + + + + + + + + + # + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + $ $ + + + + + + + + , # + + + + + + + + + + + + + + + + + + # = $ + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + < + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + $ $ + + + + + + + + , # + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + % $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + @ # + + + + + + + + + + + + + + + + $ + + ) + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + g + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + % $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + @ # + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = : + + + + + + + + + + + , + g + + + + + + + + + + c + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h + + + + + . ", -" . + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + , + + + + + + + + + + + # + + + + + | i | 5 + + + + + + + + + ' g + + ' + + + + + + # + + + + + + + + + + + + + + + + + + + + + + , + + + + + @ + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + $ + + : + + + + + + + + + + ) ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + , + + + + + + + + + + + # + + + + + | i | 5 + + . ", -" . + + + + / + + + + + + < + + $ b = + + + + + + + + + $ + + + + + + + + + + + < : $ + + + + + + + + + + + + + + + + + + + + + + + + + : } - + + + + + + + + + + + + + + + + + + + + j + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + # - + + + + + + + + + + + + + + + + + + + b % + + + + + + , $ , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + / + + + + + + < + + $ b = + + + + + + + + + $ + + + + + + + + + + + < : $ + + + + + + + + + + + + + + + + + + + + + + + + + : } - + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + ~ { + + + + + + + + + + + + + + ) + + + + + + + ^ ^ + + $ $ + + + + + + + + $ + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , k + + + + + + + @ + + + + + + + + + + + $ + + + + + + + + + + + + + + + + b h + + + + + , = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + ^ + < , + + + + + + + + + + + + + > + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + ~ { + + + + + + + + + + + + + + ) + + + + + + + ^ ^ + + $ $ + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > > + + + + + , + + + + + + + + < + + , + + + + , + + + + : + + + + + + + # > + + + + @ + + + + + + + j + + + + + + + + + + + + + + + + + + + + + + + + + + # # + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + , + + l + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > > + + + + + , + + + + + + + + < + + , + + + + , + + + + : + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + + + + $ + m m + m m m m m m m m m m n m + + + + + , o + + + + + + + + + + + + + + + # < + + + + + + + + + + + b + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + # + + + g @ + + + + + + + ] + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + , + + < + + + + + + + + + @ + + + + + # + + + + + + + + + + + c + + + + + + + + + + + + + + + , + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + + + + $ + + + + + + , + + + + + + + + + + + + + + , o + + . ", -" . + = + + + + + + + + + + + + + + + + + + + + + @ ) + + < + + + + + + + + + ) + < + + + p p + q r s t u v w x y z A B C D E F G H I + + + + + # J + + + 2 + + + + + + + + + ] # + + : + + + + + + + ) + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + b + + + + + + + + + + + + + @ + + + + + + + + + , ) + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + + + + + + + + + + + + @ + + + + + # + + + + < % + + + + + & + + + + + > + + + + + + + + + + + + + + + + , + + + + + = + + + + + + + + + + + + + + + + + + + + + @ ) + + < + + + + + + + + + ) + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # . ", -" . + + + + + + + + + + + $ + + + + + + + + + K c + + + + + + + + + + # + + + , / 3 + + m L M N O P Q R R R S T U V W Q X Y Z ` . .. +. @. #. J J J J J J J J + + + + + + + @ + + = $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + # # + + + + + + @ + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + K c + + + + + + + + + + # + + + , / 3 + + + + + + + + + + + + + + + + @ + + + + < + + + + + + + + ) . ", -" . + + + + + + + + + + + $. 2 + + + + + + + = %. + + 3 + + + + + + + } $ + + + + + m &. *. =. -. ;. >. ,. '. ). !. s ~. {. '. ]. ]. '. ^. /. (. _. :. <. [. }. |. 1. 2. 3. 4. 5. J J J J J J + + + + + + + + + + + + + + + + + , + + + + ) + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + @ + + + # + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + $. 2 + + + + + + + = %. + + 3 + + + + + + + } $ + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + . ", -" . + + + + + + + + + + $ ) 0 + + + + + + + + + + + + + + + + + + + + + + + m + 6. 7. 8. 9. 0. a. a. b. c. d. e. f. g. h. i. j. k. l. m. n. o. p. q. m. r. s. t. u. v. v. w. x. y. z. J J J J J J J + + + + + + + + + + + + + @ + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + * = + + + + + + + + + + + + + + + + + + + + + + + + $ ) 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + < + + + + + + + + + + + + + + + + + + + + + : + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A. B. C. D. E. F. C. 0. G. H. ^. '. I. J. K. L. f. M. N. O. g. P. ]. !. Q. m. R. S. T. U. V. W. V. S U L. X. Y. J J J J J J + + # # + + + + + + + + + + + + + + + Z. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + { + + + + + + + + + + + + + & `. ( + + + + + o 0 $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . , $ + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + m m .+ ++ @+ #+ D. E. F. $+ %+ &+ *+ ]. >. /. Q. =+ -+ ;+ l. >+ ,+ '+ )+ >. k. U. !+ j. ~+ {+ o. _. ]+ ~+ V K. U O ^+ /+ J J J J J J J < + , + + + @ K + + + + + + + + + + , + + + + + + + + + @ + + + + + , + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + # g + + + + # + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + (+ (+ + + + _+ :+ <+ 8 + + + @ + + + , $ + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < . ", -" . + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + m m [+ }+ |+ 1+ 2+ 3+ 4+ $+ $+ 5+ ,+ ,+ 6+ ^. l. 7+ 8+ 9+ &+ 0+ 5+ a+ 9+ }+ >+ b+ {. o. N. c+ d+ e+ f+ {+ l. g+ ~+ h+ c+ V i+ j+ 4. J J J J J J + + + + : + / + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + = $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' * + + + + k+ + + + + + + + = + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + $ + + + + $ + + + + + + + + + + + + + + + + + + + + + + h + + + . ", -" . + + + + + + + $ - + + + + + + + + + + + + + + + + + + + + + + m l+ m+ n+ 4+ o+ p+ q+ r+ r+ &+ 5+ G. s+ {. t+ ;+ u+ $+ |+ %+ v+ q+ w+ E. a+ x+ s+ s+ 9+ y+ z+ k. A+ k. B+ C+ D+ D+ E+ F+ Q. V G+ H+ I+ J+ J J J J J J | d + + / + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ! : + + + + $ $ + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K+ L+ M+ N+ O+ P+ Q+ R+ S+ T+ U+ V+ W+ X+ Y+ Z+ `+ @ .@ +@ @@ #@ $@ %@ &@ *@ =@ -@ ;@ >@ ,@ K+ + + + + + + + + + + + + + + + + + + + + + @ + / + + + + + + + %. + + + + + + + + + + + $ + + + < + + + @ + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ $ '@ )@ !@ $+ ~@ {@ ~@ 1+ q+ ]@ 5+ a+ ^@ /@ (@ (@ %+ @+ %+ _@ ~@ r+ {@ :@ %+ <@ <@ C. x+ a. 9+ [@ }@ k. V |@ !. Q. '+ '+ 1@ -. R. 2@ 3@ 4@ [. 5@ J J J J J + + g / < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + 6@ 7@ 8@ 9@ 0@ a@ b@ c@ d@ e@ f@ g@ h@ i@ j@ k@ l@ m@ n@ o@ p@ q@ r@ s@ t@ u@ v@ w@ x@ y@ z@ A@ B@ C@ D@ E@ F@ G@ H@ I@ J@ K@ L@ M@ + + + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K < + + + + + + + . ", -" . + + + + + + + + + + + = + + + + + + + + + + + + + + + + + m N@ }+ O@ P@ Q@ O@ q+ r+ v+ 5+ 5+ $+ $+ E. 9+ R@ r+ S@ r r+ 1+ 1+ Q@ q+ v+ v+ &+ T@ x+ a+ 0. 0. a. 1@ l. O T m. U@ Q. T j. =. -. a. s+ j. V@ W@ 8. J J J J J + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ # + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + # + + + + + + * ! $ + $ , + + + + + + + + + + + + + + + X@ Y@ Z@ `@ # .# +# @# ## $# %# &# *# =# -# ;# ># ,# '# )# !# ~# {# ]# ^# /# (# _# :# <# [# }# |# 1# 2# 3# 4# 5# 6# 7# 8# 9# 0# a# b# c# d# e# f# g# h# i# j# k# + + + + + + + + + + + + + + + + + + + + + + + + + + + & # + + + + + + + @ + + + + + + + @ . ", -" . + + + + + + + + + + + # + + # + + + + + + + + + + + + + m l# m# }+ n# Q@ o# p# n+ 7. 5+ &+ &+ E. @+ <@ E. q# &+ r# E. p+ p+ {@ ~@ p+ F. 5+ }+ s# a+ }+ s# 0. t# u# I. v# W. w# ~+ x# g+ B+ y# z# A# B# !. O C# A+ D# E# J J J J + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + % # + ^ + + + + + + + + + + + + F# G# H# I# J# K# L# M# N# O# P# Q# R# S# T# U# V# W# X# Y# Z# `# $ .$ +$ @$ #$ $$ %$ &$ *$ =$ -$ ;$ >$ ,$ '$ )$ !$ ~$ {$ ]$ ^$ /$ ($ ^$ _$ :$ <$ [$ }$ |$ 1$ 2$ 3$ 4$ 5$ 6$ c# 7$ 8$ 9$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / j + , + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + , ) + + & + + + + + + m 0$ a$ &+ b$ c$ Q@ O@ w+ %+ 5+ }+ C. }+ @+ $+ &+ F. @+ F. 5+ D. 1+ d$ ~@ {@ q+ r @+ <@ x+ T@ a+ e$ =+ f$ f+ {. x# c+ O g$ J. h$ _. j. N. >. {+ U@ i$ V W. j$ k$ J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + @ + + + + + @ + + + @ + + + + + + + + + + + $ @ + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + < # + + + + + l$ m$ n$ o$ p$ g@ q$ r$ s$ t$ u$ v$ w$ x$ y$ z$ A$ B$ C$ D$ E$ F$ G$ H$ I$ J$ K$ L$ M$ N$ O$ P$ Q$ R$ S$ T$ U$ V$ W$ X$ Y$ Z$ `$ % .% +% @% #% $% %% &% *% =% -% ;% >% ,% '% )% !% ~% {% ]% ^% c# /% (% _% :% <% + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + @ + + + + + + . ", -" . + + + + + + + + + + + + + + + + + # + + + + + + + + + [% )@ }% %+ |% o# o# O@ v+ @+ [+ '+ x+ 9+ C. %+ &+ 1% }+ E. $+ 5+ {@ r+ r+ {@ r+ 2% %+ $+ <@ @+ F. ^@ a. 3% 1@ {. U@ l. N. J. U j. |@ j. m. q. !. 4% 5% L. L. 6% 7% ]@ J J J J + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + 8% 9% 0% a% b% c% +# d% e% f% g% h% i% j% k% l% m% n% o% p% q% r% s% t% u% v% w% x% y% z% A% B% C% D% E% F% G% H% I% J% K% L% M% N% O% P% Q% R% S% T% U% V% W% X% Y% Z% `% & .& +& @& #& $& %& && *& =& -& ;& >& ,& '& )& !& ~& {& + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + $ + + . ", -" . + + + + + + + + + + + + + + + + + + + @ + + + + + + ]& ^& T@ n+ D. /& p# p# 1+ (& '+ . 0. x+ _& 5+ 5+ $+ @+ F. {@ S@ &+ @+ :& 2% v+ <& $+ F. <@ &+ @+ E. *+ ^@ -. [& _& }& ]+ W. d+ !+ j. _. x# |& 1& m. _. f. W. V 7% J. V. 2& J J J + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + $ @ + + + + + + + + + + + + + + + 3& 4& 5& 6& 7& 8& 9& 0& a& b& c& d& e& f& g& h& i& j& k& l& m& n& o& p& q& r& s& t& u& v& E$ w& x& y& z& A& B& C& D& E& F& G& H& I& J& K& L& M& N& O& P& Q& R& S& T& U& V& W& X& Y& Z& `& * .* +* @* #* $* %* &* ** =* ;& -* ;* >* ,* '* )* !* ~* {* + + + + + + + + + + + + 3 + + + + + + + + + + g + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + m 5. ]* <@ ^* /* n+ (* _* :* ~@ @+ _& (@ 9+ 2% @+ q# 3+ #+ <* 5+ {@ M T@ 5+ @+ r M x+ 5+ @+ @+ F. <@ F. T@ ^@ [* }* G. =+ 2@ V |* 1* 2* 3* f. -. s+ 4* P. 5* 6* j. i+ O 7* 8* 5. J J + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + * : + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9* 0* a* b* c* d* e* f* d% g* h* i* j* k* l* m* n* o* p* q* r* s* t* u* v* w* x* y* z* A* B* C* D* E* F* G* H* I* J* K* L* M* N* O* P* Q* R* S* T* U* V* W* X* Y* Z* `* = .= += @= #= $= %= &= *= == -= ;= >= ,= '= )= != ~= {= ]= ^= /= (= _= := <= [= }= |= 1= 2= 3= + + + + + + + + ^ + + + + + + + + + + + 9 + + + + + 9 + . ", -" . + + + + + + + + + + + + + + + + + + + + @ + + + m 4= 5= 6= p# !@ 7= (* 8= Q@ ~@ %+ r $+ }+ @+ <& R@ d$ %+ $+ C. 9= D. @+ F. }+ :& d$ <@ a+ ^@ a+ F. T@ s [+ [& 0= a= a. ^& b= c= T@ T@ }+ d= e= s -. b+ e+ f= g= B+ k. 6% _. K. h= i= J J + + + + + + + + + + + + + + + + + + + Z. @ + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + < + + + + @ j= k= l= k= m= n= o= + + + + + + + + + + + + + + + + p= q= r= s= t= u= v= w= x= y= z= A= B= C= D= E= F= G= H= I= J= K= @= L= M= N= O= P= Q= R= S= T= U= V= W= X= Y= Z= `= - .- +- @- #- $- %- &- *- =- -- ;- >- ,- '- )- !- ~- {- ]- ^- /- (- _- :- <- [- }- |- 1- 2- 3- 4- 5- 6- 7- 8- 9- 0- a- b- c- d- e- f- g- h- i- j- k- l- m- := n- o- + + + + + ) + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + j= p- q- r- l= l= s- s- s- s- s- s- t- u- + + v- w- a+ x- y- z- A- z- B- C- D- E- F- G- H- I- $+ }+ J- @+ s# [+ x+ %+ I- K- K- L- M- N- O- P- Q- R- S- T- 3% U- V- W- =. [+ X- {. @+ a+ a+ 0. -. Y- Z- ,+ ^. `- ; h+ w# .; /. !+ +; @; J J + + 9 + + + + + + + + + + + + + + + + + , + + + + + #; 9 + + + + + + + + + + + $; 9 + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + %; &; *; =; -; ;; >; ,; '; ); !; ~; + + {; ]; ^; + + + + > + + /; (; _; :; <; [; }; |; 1; 2; 3; <# 4; 5; 6; 7; 8; 9; 0; a; b; c; d; e; f; g; h; i; j; k; l; m; n; o; p; q; r; s; t; u; v; w; x; y; z; A; B; C; D; E; F; G; H; I; J; K; L; u% M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z; `; > .> +> @> #> $> %> &> *> => -> ;> != >> ,> '> )> !> ~> {> ]> ^> /> >% (> + + + + + + + + + + + + + + + + + , + + + + + . ", -" . + + + + + + + + _> :> <> [> }> |> 1> 1> |> 2> 3> 4> 5> 6> 7> J 8> 9> v+ 0> :> 4> a> b> |> 1> 1> |> ;; <> c> d> e> f> g> g> h> i> C. 0. j> k> l> ;; |> |> 2> ;; l> :> m> n> o> p> -+ q> [& 3% 0. a+ E. v+ &+ T@ s# 0. (@ a+ e. t+ e$ 6+ K. d+ r> V. s> t> u> J + + + + + + + + + + + + + + + + + + + + + + + + + + # , + + + + + + + + + + + 3 3 + + + + + + + + + + + # + + + + + + + + + + + + < < + + + + + + + + + + + + + + + + + + + + = + + + + + v> w> x> y> z> A> B> C> D> E> F> G> H> I> J> K> L> M> 7> N> O> O> + P> 8# Q> R> S> T> U> V> W> X> Y> Z> `> , ., +, @, #, R; $, %, &, *, =, -, ;, >, ,, ', ), !, ~, {, ], ^, /, (, _, :, <, [, }, |, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, X$ N, O, P, Q, R, S, T, U, V, + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + W, X, Y, Z, `, ' .' +' @' #' $' %' &' *' =' -' ;' >' ,' '' X, )' !' ~' ' .' .' ' {' ]' ^' /' (' (* (& &+ _' T@ [+ 0. :' <' [' }' |' |' }' 1' 1' 2' 3' 3% 4' i> 5' 6' 7' 8' C. C. @+ &+ 5+ 5+ &+ T@ C. C. /@ b+ ^@ /@ W |@ j. (. 9' 0' a' b' J + # + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + c' d' e' f' g' h' i' j' k' l' m' n' o' p' q' r' s' t' u' v' w' x' y' z' A' B' C' D' E' F' G' H' I' J' K' L' M' N' O' P' Q' R' S' T' U' V' W' X' Y' Z' `' ) .) +) @) #) $) %) &) *) =) -) ;) >) ,) ') )) !) ~) {) ]) ^) /) () _) :) <) <) [) }) |) 1) 2) 3) 4) 5) 6) 7) 8) 9) 0) a) b) c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) V& s) t) u) v) w) x) y) z) %, A) B) C) D) E) F) G) H) I) J) + + + + + + + + + + + + + + + + + + . ", -" . & + + + + + + + K) L) M) N) O) P) Q) R) S) T) U) V) W) X) Y) Z) `) ! g> .! +! @! #! $! P) %! &! *! =! -! ;! >! ,! '! )! !! ~! {! ]! U- ^! /! (! _! :! :! ~ ,~ '~ )~ !~ ~~ {~ ]~ ^~ /~ (~ _~ :~ <~ [~ }~ |~ 1~ 2~ 3~ 4~ 5~ 6~ 7~ 8~ 9~ 0~ a~ b~ c~ d~ e~ f~ g~ h~ i~ j~ k~ l~ m~ n~ o~ p~ q~ r~ s~ t~ u~ v~ 6~ w~ x~ y~ z~ A~ B~ C~ D~ E~ F~ + + + + + + + + + + + + + + = + . ", -" . + + + + + + + + + O> =' d! G~ H~ I~ J~ K~ L~ M~ N~ N~ O~ b$ P~ Q~ R~ S~ T~ U~ .+ V~ W~ X~ Y~ Z~ `~ { .{ +{ @{ #{ ${ %{ &{ *{ C+ h. ={ e$ -{ ;{ >{ ,{ '{ ){ !{ ~{ {{ T~ ]{ ^{ /{ ({ _{ e$ $+ v+ $+ 5+ }+ <@ C. T@ &+ $+ e$ g$ f. V. G+ W. W. :{ R H+ c+ <{ b' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [{ }{ |{ 1{ 2{ Y) 3{ g! g! g! 4{ 5{ 6{ g! g! 7{ 8{ 9{ 0{ a{ b{ c{ d{ e{ f{ g{ h{ i{ j{ k{ l{ m{ n{ o{ p{ q{ r{ s{ t{ u{ v{ w{ x{ y{ z{ A{ B{ C{ D{ E{ F{ G{ H{ I{ J{ K{ L{ M{ N{ O{ P{ Q{ R{ S{ T{ U{ V{ W{ X{ Y{ Z{ `{ ] .] +] @] #] $] %] &] *] =] -] ;] >] ,] '] )] !] ~] {] ]] ^] /] q) (] _] :] <] [] }] |] 1] 2] 2] d~ 3] 4] 5] 6] L= 7] 8] 9] 0] a] m, b] c] d] e] f] g] h] i] j] k] l] m] n] o] p] q] r] s] + + + + + + + + + + + + + + . ", -" . $ + + + + + + + + O> =' d! t] u] v] n! w] x] y] z] A] B] C] D] E] F] G] H] I] J] K] L] M] N] O] P] Q] R] { {{ S] ${ T] U] V] W] X] Y] Z] `] ^ .^ +^ @^ #^ $^ %^ &^ *^ =^ -^ e= Z] ;^ >^ ,^ n# ,^ 5+ F. &+ T@ <@ 5+ $+ 3+ '^ j. V. )^ !^ d+ W. V H+ U ~^ {^ + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + , + + + + + + @ + : , + + + + + + + + + + + + + + + + + + + + + + + + + + # # ]^ ^^ /^ (^ Y) g! _^ _^ g! 3{ :^ <^ [^ }^ |^ |^ 1^ 2^ 3^ 4^ 5^ 6^ 7^ 8^ 9^ 0^ a^ b^ c^ d^ e^ )& f^ g^ h^ i^ j^ k^ l^ m^ I* n^ o^ p^ q^ r^ s^ t^ u^ v^ w^ x^ y^ z^ A^ B^ C^ D^ E^ F^ G^ H^ I^ J^ K^ L^ M^ N^ O^ P^ Q^ R^ S^ T^ U^ V^ W^ X^ Y^ Z^ `^ / ./ +/ @/ #/ $/ %/ &/ */ =/ -/ ;/ >/ ,/ '/ )/ 3- !/ ~/ {/ ]/ ^/ // (/ _/ :/ + + + + . ", -" . + + + + + + l/ $ + ~; N> w' m/ n/ o/ K~ p/ q/ r/ s/ p t/ F. u/ v/ w/ x/ y/ z/ A/ B/ C/ D/ E/ X~ F/ G/ H/ I/ .{ J/ K/ $+ L/ M/ N/ O/ g. h. P/ Q/ R/ S/ T/ U/ V/ W/ X/ Y/ Z/ `/ y+ ( .( +( C. @+ d$ p+ $+ E. (@ }+ &+ @+ F. n# @( c+ 6! #( 6! $( %( S P j$ &( *( J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & * + + + + + + + + + # + , , + + + + + + + + + + + > + + + + + + + + = : + + + + @ + + + + + + + + + + + + 2 =( -( ;( >( ,( g! N~ N~ '( e! d! )( !( =' ~( w' {( ]( ^( /( (( _( :( <( [( }( |( 1( 2( 3( 4( 5( 6( 7( 8( 9( 0( a( b( c( d( e( f( g( h( i( j( k( l( m( n( o( p( q( r( s( t( u( v( w( x( y( z( A( B( C( D( E( F( G( H( I( J( K( L( M( N( k) O( P( Q( R( S( T( U( V( W( X( Y( Z( `( _ ._ +_ @_ #_ $_ %_ &_ *_ =_ -_ ;_ >_ ,_ '_ )_ !_ ~_ {_ ]_ ^_ /_ (_ __ :_ <_ [_ }_ |_ 1_ 2_ 3_ 4_ U; 5_ 6_ 7_ 8_ 9_ 0_ 3~ a_ b_ c_ d_ e_ f_ g_ + + + + + + + + + + + . ", -" . + + + + + @ g + + + h_ N> =' i_ j_ k_ l_ m_ n_ o_ p_ q_ 1@ r_ s_ g> t_ u_ v_ w_ x_ y_ z_ A_ B_ C_ D_ E_ F_ &^ G_ H_ I_ J_ K_ L_ M_ Y J_ N_ O_ P_ Q_ J] R_ S_ T_ U_ ^ T@ !! V_ ]! W_ a. T@ }+ v+ $+ }+ s# &+ X_ F. @+ Y_ Z_ `_ H+ W. d+ h$ :. S $( V |@ : b' + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + ) + > + + + + @ + + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + ) + + + + .: +: @: #: $: N~ N~ _^ 3{ d! =' N> O> O> O> %: &: *: =: -: ;: >: ,: ': ): !: ~: {: ]: ^: /: (: _: :: <: [: }: |: 1: 2: 3: 4: 5: 6: 7: 8: 9: 0: a: b: c: d: e: f: g: h: i: j: k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: X: Y: Z: `: < .< +< @< #< $< %< &< *< =< -< ;< >< ,< '< )< !< ~< {< ]< ^< /< (< _< :< << [< }< |< 1< 2< 3< 4< 5< 6< 7< 8< 9< 0< a< , + + + + + 9 + @ . ", -" . + + + + + + ' + : [ + ~; O> 7> b< ;: c< d< e< f< z] g< h< i< j< `) !@ (* 7= S~ y/ k< l< m< n< o< p< q< R] r< s< t< u< v< ]! w< x< y< z< A< B< C< D< E< F< G< H< I< J< K< a+ =^ L< @+ s# F. ^@ (@ a+ E. M< N< O< P< Q< R< S< T< U< V< W< Q (. X< $( 6! R ~+ Y< Z< + + `< [ .[ +[ +[ +[ @[ +[ +[ #[ #[ +[ $[ %[ &[ *[ + + + , + + + + + + + + + `< =[ -[ +[ +[ +[ +[ ;[ ;[ +[ >[ ,[ + + + + + + + + + + + + + '[ [ -[ +[ +[ +[ @[ +[ +[ #[ ;[ +[ +[ #[ )[ ![ *[ + + + + + + + + + + + + + + ~[ {[ ][ ^[ /[ A] A] '( Y) =' O> ~; , ([ _[ :[ <[ [[ }[ |[ 1[ 2[ 3[ 4[ 5[ 6[ 7[ 8[ 9[ 0[ a[ b[ c[ d[ e[ f[ g[ h[ i[ j[ k[ l[ m[ n[ o[ p[ q[ r[ s[ t[ u[ v[ w[ x[ y[ z[ A[ B[ C[ D[ E[ F[ G[ H[ I[ J[ K[ L[ M[ N[ O[ P[ Q[ R[ S[ T[ U[ V[ W[ X[ Y[ Z[ `[ } .} +} @} #} $} %} &} *} =} -} ;} >} ,} '} )} !} ~} {} ]} ^} /} (} _} :} <} [} }} |} 1} 2} 3} 4} 5} 6} 7} 8} 9} 0} a} b} c} d} e} f} z, g} h} i} j} k} l} m} n} o} p} q} r} s} t} + + + + # + + . ", -" . + + + + + + + + 2 0 + + + O> u} v} w} x} y} z} 6. A} B} C} N_ F. t_ (* t_ (* !@ D} E} F} G} H} I} J} K} L} M} N} p> O} P} Q} R} S} ~. b+ T} U} V} x+ W} X} Y} Z} `} | >' }+ &+ F. }+ j. b+ s# .| +| @| #| $| %| &| %| *| =| -| ;| >| ,| '| )| O !| ~| S s. 5@ + {| ]| ^| /| (| _| :| <| [| }| || || || 1| 2| 3| 4| 5| 6| o= + + + + + + + + + 7| 8| 9| 0| a| b| b| a| c| d| <| e| f| + ~; + + + + + + + + + + {| ]| ^| /| (| _| :| <| [| }| || g| g| || h| i| j| k| l| 6| o= + $ + + + + + + + # + m| n| o| p| q| r| N~ g! {( N> ~; + s| t| u| v| w| x| y| z| A| B| C| D| E| F| G| H| I| J| K| (| _| :| <| L| }| || g| || || M| N| O| P| Q| R| S| T| U| V| W| X| m( Y| Z| `| 1 .1 +1 @1 #1 !] $1 %1 &1 *1 =1 -1 ;1 >1 ,1 '1 )1 !1 ~1 {1 ]1 c| ^1 /1 /1 ^1 (1 _1 :1 <1 [1 }1 |1 11 J| 21 31 /1 b| 41 51 61 71 81 91 01 a1 b1 c1 d1 e1 }| f1 g1 a| h1 i1 j1 k1 l1 m1 n1 d| L| o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 A1 B1 C1 M| D1 /1 31 E1 F1 G1 H1 ~; + + + + + . ", -" . + + + + + + + + + + , + + ~; I1 J1 K1 L1 M1 N1 L} X} O1 P1 /+ @+ Q1 Q1 (* 7= p# R1 S1 T1 U1 p< V1 W1 X1 V/ Y1 Z1 `1 2 K_ .2 +2 @2 G. 9+ #2 $2 %2 7. K/ &2 *2 =2 -2 D] >^ $+ E. M 5+ ^. ;2 >2 ,2 '2 )2 !2 ~2 {2 ]2 ^2 /2 (2 _2 :2 <2 [2 }2 g+ |2 12 22 j$ 32 |* + {| 42 52 62 72 82 92 02 a2 b2 c2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 ~; ~; + + + + + + m2 n2 52 o2 02 p2 p2 02 q2 r2 s2 t2 u2 =' N> O> ~; + + # + + + + + {| 42 52 62 72 m_ p2 02 a2 v2 w2 w2 w2 c2 x2 y2 z2 A2 B2 C2 D2 E2 F2 + + + + + + + + + G2 H2 I2 J2 K2 L2 r| 3{ M2 N> N2 O2 P2 Q2 R2 S2 T2 U2 V2 W2 X2 Y2 Z2 `2 3 .3 +3 @3 #3 $3 %3 72 m_ p2 02 &3 *3 =3 -3 -3 =3 ;3 >3 *| ,3 '3 )3 !3 ~3 {3 ]3 ^3 /3 (3 _3 :3 <3 [3 }3 |3 13 23 33 43 53 63 73 83 93 03 a3 b3 c3 d3 e3 f3 g3 h3 i3 02 {[ 92 02 j3 k3 l3 m3 n3 o3 p3 q3 r3 s3 t3 u3 v3 w3 x3 y3 z3 A3 B3 C3 D3 E3 F3 G3 H3 I3 J3 K3 t3 L3 M3 N3 O3 P3 Q3 R3 S3 T3 K1 p2 U3 V3 W3 X3 Y3 Z3 `3 4 .4 +4 @4 #4 $4 I3 J3 K3 t3 %4 &4 *4 =4 -4 ;4 ~; + + = . ", -" . + + + + + + + + + + @ j + + ~; >4 ,4 '4 )4 !4 ~4 J/ {4 ]4 ~! u/ ^* t_ u_ t_ Q1 ^4 /4 (4 _4 :4 x} <4 [4 }4 R_ |4 R~ 14 *{ *+ 5= 3% a. }+ .^ 24 34 ,! 44 54 )! h< 64 74 r_ ^@ 84 O@ D. 94 04 a4 b4 c4 d4 x+ J< e4 f4 g4 h4 i4 j4 k4 l4 m4 n4 o4 ~! p4 q4 r4 d+ s4 J + t4 [ u4 v4 w4 w4 x4 y4 z4 A4 A4 B4 C4 D4 E4 F4 G4 H4 I4 J4 K4 N> O> + + + + + + t4 L4 u4 M4 N4 w4 O4 P4 Q4 R4 S4 T4 d! U4 =' N> ~; + + # + + + + + t4 [ u4 v4 w4 w4 V4 W4 z4 X4 A4 Y4 Z4 `4 5 .5 +5 @5 l4 #5 $5 %5 &5 ~; ~; + + + + + + *5 =5 -5 ;5 >5 ,5 '5 )5 !5 ~5 {5 ]5 ^5 /5 (5 _5 :5 <5 [5 }5 |5 15 25 35 45 55 65 75 85 95 05 a5 N4 N4 V4 b5 c5 d5 e5 e5 f5 g5 h5 i5 j5 k5 l5 m5 n5 o5 p5 q5 r5 s5 t5 u5 v5 w5 x5 y5 z5 A5 B5 63 )4 C5 D5 E5 F5 G5 H5 I5 J5 K5 L5 M5 N5 O5 P5 Q5 R5 w4 S5 T5 U5 V5 W5 X5 Y5 Z5 `5 6 .6 +6 ,4 '4 N4 @6 #6 $6 %6 &6 *6 =6 -6 ;6 >6 ,6 '6 )6 !6 ~6 {6 ]6 ^6 /6 (6 _6 :6 <6 [6 }6 |6 16 26 36 46 56 66 76 86 96 @4 06 a6 b6 c6 d6 !6 e6 f6 g6 h6 i6 j6 k6 l6 ~; + + . ", -" . + + + + + + + + + + + + + + O> m6 n6 <4 o6 p6 q6 r6 s6 *2 t6 u6 (* (* u_ F. v6 w6 x6 y6 z6 A6 B6 C6 D6 E6 R] F6 $+ h> G6 H6 I6 J6 e$ K6 L6 M6 N6 O6 P6 J] Q6 R6 S6 4! T6 U6 Q~ D. V6 W6 X6 Y6 Z6 `6 7 .7 +7 @7 #7 $7 %7 &7 *7 =7 -7 ;7 >7 ,7 O. '7 )7 !7 ~7 {7 C/ + + O> ]7 ^7 /7 /7 (7 _7 N~ N~ '( :7 3{ <7 3{ 3{ [7 }7 |7 17 27 37 47 N> ~; + + + + + N> 57 67 /7 77 87 97 N~ _^ '( g! e! 07 w' N> O> + + + + + + + + + O> ]7 ^7 77 77 (7 _7 N~ N~ '( g! 3{ 3{ 3{ 3{ 3{ a7 b7 c7 d7 e7 f7 ]7 N> O> + + + + + g7 h7 i7 j7 k7 l7 m7 n7 o7 p7 q7 r7 s7 t7 u7 v7 w7 x7 y7 z7 A7 B7 C7 D7 E7 F7 G7 H7 I7 J7 K7 L7 /7 /7 (7 M7 N7 O7 P7 Q7 R7 S7 T7 U7 V7 W7 X7 Y7 Z7 `7 8 .8 +8 @8 #8 $8 %8 &8 *8 =8 -8 ;8 >8 X6 ,8 '8 )8 !8 ~8 {8 ]8 ^8 /8 (8 _8 :8 <8 [8 }8 |8 X7 i7 18 28 38 48 58 68 78 88 98 08 a8 b8 c8 <4 d8 e8 f8 g8 h8 i8 j8 k8 l8 m8 n8 o8 p8 q8 r8 s8 t8 u8 v8 w8 x8 y8 z8 A8 B8 C8 D8 E8 F8 G8 H8 I8 J8 K8 L8 M8 N8 O8 P8 Q8 R8 S8 T8 U8 V8 W8 X8 Y8 Z8 `8 9 .9 +9 + . ", -" . + + + > + + + + + + + + + + ~; @9 #9 $9 %9 &9 *9 =9 -9 P6 ;9 d. 5+ (* (* ^* >9 P_ ,9 '9 )9 !9 ~9 {9 ]9 ^9 /9 (9 _9 N6 :9 <9 r_ [9 -. }9 |9 19 29 0$ ){ W} F. &{ 39 49 59 69 b= 79 89 99 09 a9 b9 c9 +{ d9 d9 e9 L f9 g9 J] h9 *2 i9 j9 k9 l9 m9 H_ n9 o9 p9 q9 :9 + + O> ]7 r9 s9 t9 C8 u9 p p N~ g! 3{ 3{ 3{ 3{ v9 w9 x9 y9 z9 A9 B9 w' N> ~; + + + + N> 57 C9 t9 t9 D9 E9 p p N~ g! e! Y) w' N> O> + + + + + + # + + O> ]7 r9 t9 ~9 F9 u9 p p G9 g! 3{ e! e! 3{ 3{ g! H9 I9 J9 K9 L9 M9 2{ N> O> + + + + ~; N9 09 O9 P9 Q9 R9 S9 T9 U9 V9 W9 X9 Y9 Z9 `9 0 .0 +0 @0 #0 $0 %0 &0 *0 =0 -0 ;0 >0 ,0 '0 )0 t9 s9 F9 !0 ~0 {0 ]0 ^0 /0 (0 _0 :0 <0 [0 }0 ~9 |0 10 20 30 40 50 60 70 80 90 00 a0 b0 c0 d0 e0 f0 g0 h0 i0 j0 k0 l0 m0 n0 o0 p0 q0 r0 s0 t0 u0 v0 w0 x0 y0 z0 A0 B0 C0 D0 E0 F0 G0 H0 I0 J0 s9 K0 L0 M0 N0 O0 P0 Q0 R0 S0 T0 U0 V0 W0 X0 Y0 Z0 `0 a .a +a @a #a $a %a &a *a =a -a ;a >a ,a 'a )a !a ~a {a ]a ^a /a (a _a :a @b #b $b $b %b _7 p N~ 3{ Y) 07 07 Y) &b *b $b =b -b ;b >b |^ w' N> ~; + + + O> @b ,b $b $b 'b )b A] N~ g! !b ~b =' O> ~; + + + + + 3 + + + O> {b #b $b $b %b _7 p N~ 3{ Y) d! d! d! Y) |^ 3{ ]b ^b /b (b _b :b + + + ~; }b |b 1b 2b 3b 4b 5b 5b 6b 7b 8b 9b 0b ab bb cb db eb fb gb hb ib jb kb lb mb nb ob pb qb rb $b $b %b sb tb ub vb wb xb yb zb Ab Bb Cb Db $b Eb Fb Gb Hb Ib Jb Kb Lb Mb Nb Ob Pb Qb Rb @5 Sb Tb oa Ub Vb Wb Xb Yb Zb `b c .c +c @c #c $c %c &c oa *c ra =c -c ;c >c ,c 'c )c !c ~c {c ]c oa Eb l9 ^c /c (c _c :c Bc Cc Dc Eb Ec Fc Z< #{ &+ Gc >' n+ Q1 Hc Ic Jc Ua 44 Y1 Kc aa ba Lc Mc Nc V/ Oc ${ H_ 7. Pc 9> Qc Rc Sc n9 Tc Uc #+ t< Vc Wc Xc Yc Zc `c d .d *c Wa +d @d Y/ #d $d %d $7 &d *d #+ Q@ o+ o# =d -d ;d >d Dc -b ,d F6 #{ 'd q4 )d + + + !d ~d Dc Dc %b _7 p {d Y) w' =' =' w' !5 ]d Dc =b Dc ^d /d _^ (d =' O> + + + + !d _d Dc Dc 'b )b p _^ |^ w' N> O> ~; + + + + + + + + + + + !d ~d Dc Dc %b _7 p _^ Y) w' =' =' =' =' w' d! :d O> + + + N> 2d 3d Wa 4d ba 5d 6d 7d 8d 4b 4b 9d 0d ad bd cd dd ed fd gd hd id jd kd ld md nd od pd qd Dc qa %b rd sd td ud vd wd xd yd zd Ad Bd Cd Dc Dd Ed Fd Gd Hd Id Jd Kd Ld Md Nd Od Pd Qd Rd Sd Td aa Dc Ec Ud Vd Wd Xd Yd Zd `d e .e +e @e #e $e aa Dc %e &e *e =e -e ;e >e ,e 'e )e !e ~e aa |7 {e ]e ^e /e (e _e :e ' P} `e f K. .f +f @f #f $f u_ sa %f &f 44 T~ *f =f -f 1+ ;f >f ,f o# 'f )f Fe !f ~f {f ]f J] ^f /f + + + + (f {e {e %b u9 p g! d! N> O> O> O> 7> _f :f Lc Fe ~; + + + + |f {e {e 1f )b p '( d! N> O> + + + + + + + + + + + + @ + (f {e {e %b u9 2f g! d! N> O> O> O> O> N> 3f w' 4f 5f {e +f 6f >b |^ U4 N> ~; + + O> 7f 8f 9f 0f af ge Dc bf 5b cf df df ef ef ff gf hf if jf kf lf mf nf of pf qf rf sf tf uf {e {e %b vf wf xf yf zf Af Bf Cf Df Ef Ff Cd {e Gf Hf If Jf Kf Lf Mf Nf Of Pf Qf Rf Sf Tf Uf Vf Wf 5f Xf Yf Zf `f g .g +g @g #g $g %g &g *g =g -g ;g {e +f >g ,g 'g )g !g ~g {g ]g ^g /g (g _g Fe @f :g Og Pg Qg ,! G< Rg Sg Tg Ug Vg Se Wg Xg Yg &2 Zg 2 P} C} `g h .h +h _& @h #h $h %h e$ &h *h =h -h ;h Se >h ,h 'h Pe V/ )h @{ ${ !h ;f 1+ {@ r+ q+ q+ ;f ~h {h ]h ^h Yf /h (h r< Rg _h :h ~; + + $ ~; + + |h 1h [h 2h 3h 4h z] A] 5h Y) =' O> + ^ + + 6h [h [h 7h )b p g! {( N> + + + + + + + + + + + + # + + 9h Ee >h 0h ah bh _^ Y) =' O> + ch dh eh fh gh hh G4 ih jh kh 2h 26 Yf Ge lh mh ff nh oh ph qh rh sh th uh vh wh xh yh zh Ah Bh [h [h }h Ch Dh Eh Fh Gh Hh Ih Jh Kh Lh Mh Nh [h Oh Ph Qh Rh Sh Th Uh Vh Wh Xh Yh Zh `h i .i +i @i #i $i [h %i &i *i =i -i ;i >i ,i 'i )i !i ~i {i ]i Oh [h ^i /i (i _i :i Pi Qi Ri Si Ti Ui Vi Wi 3% 14 h> Xi Yi Zi `i F6 j ,! .j +j @j #j $j %j &j #^ ]f *j Ze *{ =j -j ;j 5+ >j ,j 'j )j !j ~j {j ({ s> $( ]j Ti $j Ri ^j /j (j _j e9 Y} {4 1+ :j r+ d$ p+ {@ q+ q+ O> + + + + + + 7j 8j 9j 0j aj bj N~ cj =' O> + = + + 6h Ri Ri dj ej p g! {( N> + + + + ) + < + + + + + + + + + + + + + + ~; hj Tg Ri ij jj kj r| g! {( N> lj mj nj oj pj qj rj sj tj uj vj wj xj xj yj zj Aj Bj Cj Dj Ej Fj Gj Hj Ij Mb Jj Kj Lj H: Mj Nj Oj Ri Ri gj Pj Qj Rj Sj Tj Uj Vj Wj Xj Yj Zj `j k 0j .k +k @k #k $k %k &k *k =k -k ;k w6 >k ,k 'k )k !k ~k {k Ti ]k ^k /k (k _k :k l ,l 'l )l #l !l t/ sa ~l {l ]l ^l di /l (l _l :l , + + + + + @ + + $ + + < + + ul 'l 'l gj u9 A] g! {( N> + + + + + + + !d vl 3l wl Ec xl 5j _^ Y) yl zl Al Bl Cl Dl El Fl Gl Hl Il Jl Kl Ll Ml Nl pl Ol Pl Ql @l Rl Sl Tl Ul Vl Wl Xl Yl Zl `l m .m _d 3l 3l +m @m #m $m %m &m *m =m -m ;m >m ,m 'm )m !m ~m {m ]m ^m /m (m _m :m n ,n 'n . ", -" . + + + + + + + + + + + + + + + + + ~; )n H~ !n #j ~n {n P6 ya ]n U- ^n /n (n $+ _n X_ Q6 6= :n p ,p 'p )p pc !p ~p {p ]p ^p /p (p _p :p

}p #f |p 1p 2p 3p Z< 4p 5p 6p U} 7p q_ 8p {h _n *j @+ H_ 9p 0p '8 1p ap bp /9 Pe cp dp ep fp gp za hp ip jp kp lp mp np J. =h op pp ~9 ;5 |p qp }4 rp sp tp up G. vp wp &+ &+ -. a+ E. $+ x+ xp yp zp s9 ~9 Ap Bp /9 B/ Cp Dp O> + @ Ep ~9 Fp X7 Gp Hp Ip Hp Jp Kp Lp J9 Mp Np Op Pp Qp Rp p p N~ 3{ {( Sp + + + + + C9 ~9 ~9 D9 ej p g! {( N> + + @ + + + + + + + + + + + + Ep ~9 ~9 F9 u9 A] g! {( N> + # + + < < + < Tp |p ;5 ~9 Up 5j Vp Wp Xp Yp Zp `p q .q +q @q #q $q %q &q *q =q -q ;q >q ,q 'q )q !q O9 ~q {q ]q ^q /q (q _q :q r ,r 'r )r !r p0 ~r #f $9 {r ]r ^r /r (r _r :r pc + + Mr Gr Fr Nr Or Pr Qr Pr Rr Sr Tr Ur Vr Wr Xr Yr Zr `r A] N~ }f d! =' O> + + + + + C9 s s 'b ej p g! {( N> + + + , + + , # + + + + + + + Mr s s C8 u9 A] g! {( N> + + + + + + + + .s |0 |q 2b +s @s #s $s %s &s *s =s -s ;s >s ,s 's )s !s ~s {s ]s ^s /s (s _s :s a Dc Qs Rs Ss Ts Us Vs Ws Xs Ys Zs `s t .t +t @t #t $t %t &t *t =t -t ;t >t ,t 't )t !t ~t {t ]t ^t /t (t _t be :t + + Ep ~9 ~9 F9 .u +u @u #u $u |^ Y) %u Hr Wa &u *u =u r| N~ g! 07 =' O> + + + + + + -u K0 K0 D9 ej p g! {( N> + + + + + + + + + + + + , < + Ep K0 K0 F9 u9 A] g! {( N> + + + + + + + + ;u ~9 Ot 09 >u ,u 'u )u !u ~u {u ]u ^u /u (u _u :u v ,v 'v )v !v ~v {v w0 Tu ]v ^v /v (v _v :v *w =w &( -w Ba >+ _& &+ ;w >w ,w 'w )w !w z] Ma Ua {( N> + + ~w .w .w {w u9 N~ g! ]w ^w 3{ /w v0 (w _w :w x ,x 'x )x !x ~x {x ]x ^x /x (x _x Ot Dv Uu :x !7 &y ~j Jt Zv *y *y #( =y -y Re K1 <| ;y >y =9 ,y ,j 'y )y ,+ !y ~y {y ]y ^y H6 -. @+ <@ C9 /y 82 (y _y M~ b' .{ :y {( N> + , + + + + + + + 3y <| <| 4y ej p g! {( N> + + + + + + 5y 6y ~; O> O> ~; + + + + + + + , + + 7y 8y <| 9y 0y ay by cy dy ey fy gy hy iy jy ky ly G; my ny oy py qy ry sy ty uy vy wy xy yy zy 9y Ay By Cy Dy Ey Fy Gy Hy Iy Jy <| <| Ky Ly My Ny Oy Py Qy Ry Sy Ty Uy Vy Wy Xy Yy Zy `y z .z +z @z #z $z %z &z *z =z -z ;z ;z ;z ;z =z *z >z ,z <| 'z )z !z ~z R- {z ]z ^z /z i, (z _z :z A ,A 'A )A !A .2 C} r_ ~A ]y {A ]A ^A }& <@ /A (A _A :A + + 1A _A _A 2A 3A p _^ |^ d! {( d! 4A 5A _A _A 6A 7A '( Y) =' O> ) + + + + + + 8A _A _A 9A )b A] p g! {( N> + + + + + {; 0A #A N> N> N> N> ~; + + 1A _A _A 2A u9 A] g! {( N> + + + + $ + + aA bA cA dA eA fA gA hA iA jA kA lA mA nA oA pA qA rA sA tA uA vA wA xA yA zA AA BA CA DA EA FA GA HA IA JA KA LA MA NA OA PA QA _A _A l! RA SA TA UA VA WA XA YA ZA `A B .B +B @B #B $B %B &B *B =B -B ;B >B ,B 'B )B !B ~B {B ]B ^B /B (B _B :B ;A C Z/ ,C 'C ${ )C *^ !@ 6= 0. Ax !C $C ~C &C ff {C ]C ^C X} #{ z. /C (C _C :C *y + + iC dC dC jC 3A p g! d! =' N> N> kC lC dC %C mC nC z] g! {( N> + + # # + + + oC dC dC pC )b n p g! qC N> + + + + + rC U} sC =' U4 U4 =' O> + + iC dC dC jC 3A A] g! {( N> + @ < + + + + tC uC vC wC xC yC zC AC BC CC DC EC FC GC HC IC JC KC LC MC NC OC PC QC RC SC TC UC VC WC XC YC ZC `C D .D +D @D #D $D %D &D *D dC dC =D -D ;D >D ,D 'D )D !D ~D {D ]D ^D /D (D _D :D E ,E 'E )E !E ~E {E C ]E ^E /E . ", -" . + + + + + + + + + + + + + + + + + + + m (E _E :E + + + + + + oC FE FE JE )b p g! {( 8h + + + + + KE LE ME {( Y) Y) U4 N> ~; ) zE FE FE BE 3A A] g! {( NE + + + + + + OE PE QE RE SE TE UE VE WE XE YE ZE `E F .F +F @F #F $F %F &F *F =F -F ;F >F ,F 'F )F !F ~F {F ]F ^F /F (F _F :F G ,G 'G )G !G ~G :a be {G ]G ^G /G (G _G :G OG + + zE AE AE BE 3A PG IE g! {( N> + + QG RG AE + + + + + + oC FE FE JE ej VG WG XG YG 7> + + + # + ZG `G H 07 e! |^ d! N> ~; + zE FE .H BE +H VG WG @H #H 7> + + + + + $H %H &H *H =H -H ;H >H ,H 'H )H !H ~H {H ~C ]H ^H /H (H _H :H I ,I 'I )I !I ~I {I ]I ^I /I K[ (I _I :I !d o= + `I S) S) J .J +J @J Q] + + + u] #J $J S) %J &J A] g! *J =J -J + + + !d + ;J >J S) ,J 'J )J !J ~J {J ]J !d + + + ^J 4i /J (J |^ g! 3{ d! _J :J !d `I S) S) BE .J J GJ HJ IJ JJ KJ LJ MJ NJ OJ PJ QJ RJ SJ TJ UJ VJ WJ XJ YJ ZJ `J K .K +K @K #K $K %K &K *K =K -K ;K >K ,K 'K )K S) !K ~K {K ]K ^K /K (K _K :K L ,L L 'L )L J &. {{ !@ !L ~L {L f ]L ^L 3@ /L (L _L f j$ U :L M ,M `E 'M )M !M ~M {M ]M ^M /M (M _M :M N ,N 'N +N )N !N ~N {N ]N ^N /N (N _N :N B} *{ *{ Ba S} (@ ~. s# zN AN vN vN BN CN DN (j EN FN GN HN IN JN KN LN *y MN NN ON PN 6% h$ QN RN SN TN UN VN WN XN YN ZN `N O .O +O @O ;y #O $O %O &O Wi &2 R_ r< X} { w' N> + *O =O -O ;O >O ,O 'O )O !O ~O {O B9 N> ~; + + ]O ^O /O (O _O :O P ,P 'P )P !P ~P {P ]P ^P /P (P .. _P :P fO

O aP :P bP cP dP eP fP 83 gP hP iP jP kP lP mP nP oP pP qP rP sP tP uP vP wP xP xP yP zP AP BP wN CP DP EP FP GP HP IP JP KP LP MP NP OP PP QP RP 'O SP eJ TP UP VP WP XP YP ZP `P Q .Q +Q @Q #Q $Q %Q (g jN &Q *Q =Q -Q ;Q >Q ,Q WK 'Q )Q . ", -" . + + + + + + + + + + + + + + @ + + + + + + Jr !Q ~Q {Q ]Q ^Q ^Q R] .+ 2E /Q H_ >+ *L Q} }* (Q p4 ]! _Q :Q {Q Ur R ,R 'R )R !R ~R {R }> ]R ^R /R (R _R :R S ,S 'S )S !S ~S {S ]S ^S /S (S _S :S T ,T 'T )T !T ~T {T ]T ^T /T (T _T :T U ,U 'U )U !U ~U {U ]U ^U /U (U _U :U V ,V 'V )V !V ~V t> w# {V |@ =y ]V ^V /V (V 5@ B] _V :V =' d! e! _^ A] p p N~ g! Y) U4 N> O> ~; N> {( 3{ pL 5V 6V 7V N~ g! e! 8V e! 9V 0V {( aV 3{ _^ A] p N~ g! bV cV e! e! g! g! N~ A] p p N~ 3{ U4 N> N> =' d! cV _^ A] A] N~ g! 3{ dV eV {a fV gV hV iV jV kV lV mV nV oV pV qV rV sV tV uV vV wV xV yV zV AV BV CV DV EV FV GV HV IV JV KV LV MV NV OV PV QV RV SV TV UV VV WV KT XV YV ZV `V W .W +W @W #W $W %W &W *W =W -W ;W >W ,W 'W )W !W ~W {W ]W ^W /W (W _W :W X ,X 'X )X !X yU ,Q ~X {X . ", -" . + + + + + + + + + + + + + + + + + + + + + ^ ~; ya ]X ^X 54 .j /X (X U6 _X :X 69 49 f V w' d! e! nX N~ N~ A] N~ _^ g! |^ {( [b O> oX pX =' d! g! N~ A] N~ N~ g! g! qX |^ d! w' {( Y) 3{ _^ N~ A] A] N~ _^ 3o g! 3{ 3{ g! g! '( _^ N~ N~ N~ g! Y) =' O> N> w' d! 3{ '( N~ A] A] N~ rX sX tX uX vX wX xX yX zX AX BX CX DX EX FX GX HX IX JX KX LX MX NX OX PX QX RX SX TX UX VX WX XX YX ZX `X Y .Y +Y @Y #Y $Y %Y &Y *Y =Y !W -Y ;Y >Y ,Y 'Y )Y !Y ~Y {Y ]Y ^Y /Y (Y _Y :Y Z ,Z 'Z =1 )Z !Z ~Z {Z ]Z ^Z /Z (Z _Z :Z =' {( 07 GZ ^w 3{ 3{ 3{ e! Y) d! w' N> ~; + + O> =' d! |^ g! g! g! 3{ e! Y) d! w' =' =' {( Y) |^ 3{ g! g! g! e! |^ |^ |^ |^ |^ |^ e! 3{ 3{ g! e! Y) w' N> O> O> =' {( Y) |^ 3{ g! g! g! e! HZ IZ JZ KZ LZ MZ NZ OZ PZ QZ RZ SZ TZ UZ VZ WZ XZ YZ ZZ `Z ` .` +` @` #` $` %` &` *` =` -` ;` >` ,` '` )` !` ~` {` ]` ^` /` (` _` :` <` [` }` }Y |` 1` 2` 3` 4` 5` 6` 7` 8` 9` 0` a` b` c` d` e` f` g` h` i` j` k` l` m` n` o` p` q` r` s` t` u` v` w` x` y` z` A` B` C` D` E` F` G` H` I` J` K` L` M` N` O` P` Q` R` S` T` U` V` W` X` Y` Z` `` .. .+ .@ .# .$ .% .& .* .7I = .- .; .> ., .~i ' .) .zB lx ! .~ .{ .] .9I ^ ./ .( ._ .: .< .[ .} .| .1 .2 .3 .4 .5 .6 .7 .8 .9 .0 .a .b .c .d .e .f .g .h .i .j .[G k .l .m . ", -" n .# + + + + + + + + + # + + + + + + + + + ) + + ~; o .Ax D] p ..h 64 (Q U6 J6 L/ A< YU Lt ^y q .r .s .t .z< u .*y v .tE fZ w .6X uS qS rS 0C x .v tS 6% 8! y .6% z .A .eE c+ R W B .C .QN v# D .E .F .G .H .I .S} BZ Ke J .@2 ,j )y o> K .J J J + + + % ~; O> N> L .w' w' U4 U4 U4 w' w' =' N> O> + + + + O> N> w' {( M .07 d! d! w' =' N> O> N> [b =' w' U4 {( {( {( U4 )( N .w' w' w' w' w' U4 {( {( w' =' N> O> + ~; O> N> =' w' U4 {( O .{( P .Q .R .S .T .U .V .W .X .Y .Z .` . .....+..`{ @..#..$..%..&..*..=..-..;..>..,..'..)..!..~..{..]..^../..(.._..:..<..[..}..|..1..2..3..4..;W 5..6..7..8..9..0..a..b..c..d..e..f..g..h..o` i..j..k..l..m..n..6Y o..p..i` q..r..s..t..u..v..w..x..y..z..A..B..C..D..E..F..G..H..I..J..K..L..M..N..O..P..Q..R..S..T..U..V..W..X..Y..Z..`.. +..+.++.@+.#+.$+.%+.&+.*+.=+.-+.;+.>+.1Z ,+.'+.)+.!+.~+.{+.]+.^+./+.(+._+.gx :+.<+.[+.}+.|+.1+.2+.3+.4+.5+.6+.7+.8+.9+.0+.a+.b+.c+.d+.~a e+.lx f+.g+.IK h+.i+.j+.k+.l+.m+.n+.;G o+.p+.q+.r+. ", -" ln + + + + + + + + + + + + + , + + + + + + + + + + m <* h< Ve `] s+.t+.]l /Q u+.64 v+.(L fE w+.x+.y+.z+.^+ A+.B+.C+.D+.E+.F+.G+.H+.H+.I+.J+.K+.L+.M+.6% V@ N+.h$ #( NN O+.P+.Q+.V. i$ i$ R+.S+._{ T+.U+.V+.W+.X+.Y+.M/ Z+.`+.Dr )y @..@.+@.J J J + + # < # + O> O> O> O> O> O> O> O> O> @@.~; + + + + + + ~; #@.N> $@.%@.L .N> N> pn ~; + ~; O> O> O> N> N> N> N> O> O> O> O> O> O> O> O> N> N> N> O> O> ~; + + + + O> O> O> N> N> N> N> &@.*@.=@.-@.;@.>@.,@.'@.)@.!@.~@.{@.]@.^@./@.(@._@.:@.<@.[@.}@.|@.1@.2@.3@.4@.5@.6@.7@.8@.9@.0@.a@.b@.c@.PH d@.e@.f@.g@.h@.i@.j@.k@.l@.m@.n@.o@.p@.q@.r@.s@.t@.u@.v@.w@.x@.y@.z@.A@.B@.C@.D@.E@.F@.G@.H@.s..I@.J@.K@.L@.t@.M@.N@.O@.P@.Q@.R@.S@.T@.U@.V@.GT W@.X@.Y@.Z@.`@. #..#.+#.@#.##.$#.%#.&#.*#.=#.-#.;#.>#.,#.'#.)#.!#.~#.{#.]#.^#./#.(#._#.:#.<#.[#.}#.|#.1#.qB 2#.3#.4#.5#.6#.7#.8#.9#._+.0#.a#.b#.c#.d#.e#.f#.g#.h#.i#.j#.k#.l#.m#.n#.o#.p#.q#.r#.s#.*X t#.u#.v#.w#.x#.y#.z#.A#.B#.C#.D#.E#.F#.G#.H#.I#.^Z J#.K#.L#.M#.N#. ", -" O#.+ + + # + + + + + + + + + + + + + + + + + + ) # + NG >' P#.M/ _X &{ 0Z P~ ga ]l Q#.R#.T6 eS aC S#.QI T#.U#.V#.W#.X#.Y#.Z#.`#. $.rS qS .$..$.^L Da +$.V. U L. w# @$.#$.T #( c+ J. $.EG ,$.]! 4' '$.)$.m J J J + + + + + + + + # + + + + + + + + + + + + + + + + ~; !$.~$.{$.~; ~; & + + + + + + + + + + + + + + + + + + + + + + + + + # < + + + + + + + ]$.^$./$.($._$.:$.<$.[$.}$.|$.1$.2$.3$.KX 4$.5$.6$.7$.8$.9$.0$.a$.b$.c$.d$.e$.f$.f$.g$.h$.i$.j$.k$.l$.m$.n$.o$.p$.q$.r$.s$.t$.u$.v$.w$.x$.y$.z$.A$.k` N@.B$.C$.D$.E$.F$.G$.H$.I$.J$.K$.L$.M$.N$.O$.P$.N@.Q$.R$.C$.S$.T$.U$.V$.W$.J$.X$.Y$.F@.Z$.`$. %..%.+%.@%.#%.$%.%%.&%.*%.=%.-%.;%.>%.,%.'%.)%.!%.~%.{%.]%.z8 ^%./%.(%._%.:%.<%.[%.}%.|%.1%.2%.3%.4%.5%.6%.7%.8%.9%.0%.a%.b%.c%.d%.e%.f%.g%.h%.i%._+.j%.k%.l%.m%.n%.o%.p%.q%.r%.s%.Kk JW t%.u%.v%.w%.a+.x%.y%.z%.A%.B%.C%.D%.E%.NB o#.F%.G%.H%.I%.J%.K%.L%.M%.N%.O%.P%.Q%.R%.S%.T%. ", -" U%.+ + 2 + + + + + + e + + + + + + + + + + + + , 1 + m V%.Pc C} W%.*{ Q} =L `] ]l P} X%.T6 Y%.Z%.`%.[X &..&.+&.u .@&.#&..&.$&.-V %&.&&.aX *&.=&.-&.S T h$ G+ V. I. V K. _L c= c+ Ar O d+ ;&.>&.,&.0C T#.'&.-&.)&.!&.~&.,+ /@ {&.J J J J + + + + + + + + + + + + + # + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + ]&.^&./&.(&._&.:&.<&.[&.}&.|&.1&.2&.3&.4&.5&.6&.7&.8&.9&.0&.a&.b&.c&.d&.e&.f&.g&.h&.i&.j&.k&.l&.m&.n&.o&.p&.q&.r&.s&.t&.u&.v&.w&.x&.y&.z&.z$.A&.B&.v&.C&.D&.E&.F&.G&.H&.I&.J&.K&.K&.L&.M&.N&.O&.P&.Q&.R&.S&.l` J$.X$.T&.U&.V&.W&.X&.Y&.Z&.`&. *..*.+*.@*.#*.$*.%*.&*.**.=*.-*.;*.>*.,*.'*.)*.!*.~*.{*.]*.^*./*.(*._*.:*.<*.[*.}*.|*.1*.2*.3*.4*.5*.6*.7*.8*.9*.0*.a*.b*.c*.d*.e*.f*.g*.h*.i*.j*.k*.l*.m*.n*.o*.p*.q*.r*.s*.t*.o%.o%.u*.v*.w*.x*.y*.z*.A*.B*.C*.D*.E*.F*.G*.H*.I*.J*.K*.L*.M*.N*.O*.P*.Q*.R*.d*.S*.T*.U*.V*.W*.8v X*.Y*.Z*. ", -" `*.+ + + + @ # + + + + + + + + + + + + + + + + + + + + + =./Q +2 ]l 74 .=.C} 9+ *L +=.@=.K_ R#.=w 7' #=.$=.%=.&=.X#.oZ .&.$&.$&.*=.*&.0X ==.-=.;=.7% >=.G+ 7% t. Q ,=.vG @$.|@ '=.>&.(. dX >&.&( 7' )=.!=.T#.~=.{=.Ar >+ s# _& b' J J J J + + + + + + + + + + + + + , + + + + + + + + + + + + + + + < + + + + + + + + + < + + + + + + + + + ~ } + + , + + + + + + + + + + + ]=.^=./=.(=._=.:=.<=.[=.}=.|=.1=.2=.3=.4=.5=.6=.7=.8=.9=.0=.a=.b=.c=.d=.e=.f=.g=.h=.j$.i=.j=.k=.l=.m=.n=.o=.p=.q=.r=.s=.t=.u=.u=.v=.w=.x=.y=.E%.z=.A=.B=.O&.C=.D=.E=.F=.G=.H=.I=.J=.K=.v&.L=.M=.N=.O=.P=.Q=.R=.S=.T=.U=.V=.W=.X=.Y=.Z=.`=. -..-.+-.@-.#-.$-.%-.&-.*-.=-.--.;-.>-.,-.'-.)-.!-.~-.{-.]-.^-./-.(-._-.:-.<-.cf [-.}-.|-.1-.2-.3-.4-.5-.6-.7-.8-.9-.0-.a-.b-.c-.d-.e-.f-.g-.h-.i-.j-.k-.l-.m-.n-.'+.o-.p-.q-.r-.s-.t-.u-.v-.w-.x-.y-.z-.A-.B-.C-.e-.D-.E-.F-.G-.H-.I-.J-.K-.L-.M-.N-.O-.P-.Q-.R-.S-.T-.U-.V-.W-.X-.Y-.U-.Z-.`-. ;. ", -" .;.+ + + + + + + + , # + + + + + + + + + + + + + + + + + m +;.s_ *L *{ R6 8C S} (Q a= Zc g= T6 fE @;.Cr 0C #;.$;.%;.6Q &;.-V *;.sZ =;.A .Da an U 7% j$ W. G+ j$ G+ W f V. T -;.;;.(. >;.QI Cr ,;.';.9Q T#.);.zr HG 3% <@ !;.J J J J + + + + , + + + + + + + + < < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + ~;.{;.];.^;./;.(;._;.:;.<;.[;.};.|;.1;.2;.3;.4;.5;.6;.7;.8;.9;.0;.a;.b;.c;.d;.e;.f;.g;.h;.i;.j;.k;.l;.m;.n;.o;.p;.p;.q;.5Y r;.6..s;.t;.u;.v;.w;.x;.y;.z;.A;.B;.C;.D;.E;.F;.G;.H;.I;.J;.K;.L;.M;.N;.O;.P;.Q;.R;.S;.T;.U;.V;.W;.X;.Y;.Z;.`;. >..>.+>.@>.#>.$>.%>.&>.*>.Ub $*.=>.->.;>.>>.,>.'>.)>.!>.~>.{>.]>.^>./>.(>._>.:>.<>.[>.}>.|>.1>.2>.3>.4>.5>.6>.7>.8>.9>.0>.a>.b>.c>.d>.e>.f>.g>.h>.i>.j>.k>.l>.m>.n>.o>.p>.q>.r>.s>.t>.u>.v>.w>.x>.y>.z>.A>.B>.u*.C>.D>.E>.F>.G>.H>.I>.J>.K>.F>.L>.M>.N>.`D O>.P>.Q>.R>.S>.T>.U>.V>.W>.6 .X>.Y>.Z>. ", -" `>.+ + + + + + + + < ,.+ + + + + + + + + + + + + + + + + + .,._& {. 74 Ba +,.Yv Ba Lt Y%.XU L_ @,.d+ ;&.#,.$&.8X =;.+&.$,.%,.#;.w .sZ &,.*,.bX K. k. w# V. 6! O j. |@ |@ V d+ K. =,.69 -,.;,.[C #=.%,.!=.~=.X] >,.-. i4 e9 J J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + % + + + + + + + + + + + + + + + + + + + & + + + + + + + + # ,,.',.),.!,.~,.{,.],.^,./,.G* (,._,.:,.T .<,.[,.},.E* |,.1,.2,.3,.4,.5,.6,.7,.8,.9,.0,.a,.a,.b,.c,.d,.e,.f,.g,.h,.m@.i,.m@.j,.k,.l,.m,.n,.{x o,.p,.q,.r,.s,.t,.i} u,.v,.w,.x,.y,.z,.A,.B,.C,.D,.E,.F,.G,.H,.I,.J,.K,.L,.M,.N,.O,.P,.Q,.R,.S,.T,.U,.V,.W,.X,.M,.Y,.Z,.`,. '..'.+'.@'.#'.$'.%'.&'.*'.='.-'.;'.Q` >'.,'.''.)'.!'.~'.{'.]'.^'./'.('._'.:'.<'.['.}'.|'.1'.2'.tU 3'.4'.5'.6'.7'.8'.9'.0'.a'.u-.b'.c'.d'.e'.f'.g'.h'.i'.j'.k'.l'.m'.n'.o'.p'.q'.r'.s'.t'.u'.v'.w'.x'.y'.z'.A'.B'.C'.D'.E'.F'.G'.P-.H'.I'.J'.K'.L'.at M'.N'.O'.P'.>+.Q'. ", -" R'.+ + $ + ) + + + + + + + + + + + + + + + + + + + + + + + m )h 9+ ]A S'.T'.U'.np 4% V'.49 s .s .K. Br W'.X'.W'.%,.Y'.Z'.>=.`'. )..).+).:. 6! k. K. j. k. k. s .@).c= J. (. O d+ #).$).w# %).&).*).Ar Ar =).-).,+ 2% ]& J J J J J + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + ;).>).,).').)).!).~).{).]).^)./)..- ().Q[ _).:).<).[).}).|).1).2).e;.3).4).5).6).7).e;.8).9).0).ht a).b).c).d).e).f).g).m@.4..h).i).j).k).l).m).n).o).p).q).r).s).t).u).B,.5} v).w).x).s=.y).xv z).A).B).C).D).E).F).G).H).I).J).K).N$.L).e).M).N).O).P).Q).R).S).T).U).V).W).X).Y).Z).`). !..!.+!.@!.#!.$!.%!.&!.*!.=!.-!.;!.>!.,!.'!.)!.!!.~!.{!.]!.^!./!.(!._!.:!.~.N^ ,~.'~.)~.I( !~.~~.{~.]~.^~./~.(~.3).-n _~.:~.<~.[~.}~.|~.1~.2~.3~.4~.5~.6~.7~.8~.9~.0~.a~.b~.c~.d~.e~.f~.g~.h~.i~.j~.k~.l~.m~.n~.o~.p~.q~.r~.s~.t~.z).u~.v~.w~.x~.y~.z~.A~.B~.C~.D~.E~.z8 F~.G~.6..H~.I~.J~.K~.L~.M~.N~.O~.P~.Q~.R~.S~.T~.U~.V~.W~.X~.Y~.Z~.`~. {..{.+{.@{.#{.${.%{.&{.*{.={.-{.;{.>{.,{.'{.){.!{.~{.{{.]{.^{./{.({._{.:{.<{.[{.}{.[{.|{.1{.2{.3{.4{.5{.6{.7{.8{.9{.0{.a{.b{.c{.d{.e{.f{.g{.h{.i{.e{.j{.k{.r!.l{.m{.n{.o{.p{.q{.r{.s{.t{.u{.v{.w{.x{.y{.z{.A{.B{.C{.D{.d{.E{.F{.G{.H{.I{. p ", -" Q'.+ + + + + + + + + + + + + + + + + + + + + + < $ + + + + + + + YI mS !y 74 J{.~y *A v+.69 Zv c+ 7' sZ [C K{.0C L{.M{.N{.j$ O eE O{.NN @).W!.@$.@$.T V. J. R 6! {7 6! 6% {V =,.P{.I ..=.1@ '+ *+ R6 Q{.lX R{.J J J J J J + + + + + + + + + + # + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + S{.T{.U{.V{.W{.X{.Y{.Z{.`{. ]..].N^ +].@].#].$].%].&].*].=].-].;].>].,].'].)].!].'].~].{].]].^]./].(]._].:].<].7~.[].}].|].1].2].3].4].5].6].7].8].9].0].a].b].c].d].A~.e].f].A~.g].h].i].j].k].l].m].n].o].p].q].r].s].t].u].v].w].x].y].z].A].B].C].D].E].F].G].H].I].J].K].L].M].N].O].P].Q].R].S].T].U].V].W].X].Y].Z].`]. ^..^.+^.@^.#^.$^.%^.&^.*^.=^.-^.;^.>^.,^.'^.)^.!^.~^.{^.]^.^^./^.(^._^.:^.<^.[^.}^.|^.1^.2^.3^.4^.5^.6^.7^.{^.8^.9^.0^.a^.b^.c^.d^.E{.e^.f^.g^.h^.i^.j^.k^.l^.m^.n^.o^.p^.q^.r^.s^.t^.u^.v^.w^.'].x^.y^.z^.A^.B^.C^.D^. p I ", -" E^.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + m F^.5= G^.H^.#).I^.g= J^.T W'.*;.#=.w .Br O T (. V. t. O T K. #( Da U d+ (. O c+ j. (. i$ R K^.L^.8C A< *{ S'.[& ^& (@ 9+ +@.b' J J J J J J + + + + + + + + ) b + ) + + + + + + + + + + + + + + @ + + + @ + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + M^.N^.O^.P^.Q^.R^.S^.T^.U^.V^.W^.X^.Y^.Z^.`^. /../.+/.@/.#/.$/.%/.&/.*/.=/.-/.;/.>/.,/.'/.)/.!/.~/.{/.]/.^/.//.(/._/.:/.(.,(.'(.)(.!(.~(.{(.](.^(./(.((._(.:(.<(.[(.}(.|(.1(.2(.3(.4(.5(.6(.7(.8(.9(.0(.a(.b(.c(.d(.e(.f(.g(.h(.i(.j(.k(.l(.m(.n(.o(.p(.q(.r(.s(.t(.u(.v(.w(.x(.y(.z(.A(.B(.C(. p ", -" I{.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + m X/ O1 D(.E(.F(.F(.*h 1l k. G(.&=.&,.$=.H(.R L. G+ I(.$( ~=.U V J. (. h+ _. W k. d+ J(.&( K(.S'.P} *L b+ s+ ~. s+ L(.Ta {^ J J J J J J + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + b + + + + + + + + + + + + + + + + M(.N(.O(.P(.Q(.R(.S(.T(.U(.V(.W(.X(.Y(.Z(.`(. _.._.+_.@_.#_.$_.%_.&_.*_.=_.-_.;_.>_.,_.'_.)_.!_.~_.{_.]_.^_./_.(_.__.:_.<_.[_.}_.|_.1_.2_.3_.4_.5_.6_.7_.8_.9_.0_.a_.b_.c_.d_.e_.f_.g_.h_.i_.j_.k_.l_.m_.n_.o_.__.p_.q_.r_.s_.$E t_.u_.v_.w_.x_.y_.z_.A_.B_.C_.D_.E_.F_.G_.H_.I_.J_.K_.L_.M_.N_.O_.P_.Q_.R_.S_.T_.U_.M` V_.W_.X_.Y_.Z_.`_. :..:.+:.@:.#:.$:.%:.&:.*:.=:.-:.;:.>:.,:.':.*(.L+ ):.!:.~:.{:.]:.^:./:.(:._:.Dk ::.<:.[:.}:.|:.1:.2:.dY 3:.4:.5:.6:.7:.8:.9:.0:.a:.b:.c:.d:.e:.f:.g:.h:.i:.R>.j:.k:.l:.m:.n:.o:.p:.q:.r:.s:.t:.u:.v:.w:.x:.y:. ", -" C(.+ + + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + m m A/ z:.=L A:.B:.G .C:.D:.E:.F:.G:.B .i$ B .H:.kE =y IN i$ =y c+ c= I:.i$ i$ J:.s> AS *L A< K:.L:.gZ 5= /@ s+ )! e9 b' J J J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , * ] + + + + + + + + + + + + + + + + + + + + + + + + + / @ + + M:.N:.O:.P:.Q:.R:.S:.T:.U:.V:.W:.X:.Y:.Z:.`:. <..<.+<.@<.#<.$<.%<.&<.*<.=<.-<.;<.><.,<.'<.)<.!<.~<.{<.]<.^<./<.(<._<.:<.<<.[<.}<.|<.1<.2<.3<.4<.5<.6<.7<.8<.9<.0<.a<.b<.c<.d<.e<.f<.g<.h<.i<.j<.k<.l<.m<.n<.o<.p<.q<.r<.s<.t<.u<.v<.w<.x<.y<.z<.A<.B<.C<.D<.E<.F<.G<.H<.I<.J<.K<.6r L<.M<.N<.O<.P<.Q<.R<.S<.T<.U<.V<.y&.W<.X<.Y<.Z<.`<. [..[.+[.@[.#[.$[.%[.&[.*[.=[.-[._N ;[.>[.,[.'[.)[.![.~[.{[.][.^[./[.([._[.:[.<[.[[.}[.|[.1[.2[.3[.4[.5[.6[.7[.8[.9[.0[.a[.b[.c[.av j!.d[.e[.f[.g[.h[.i[.j[.k[.l[.m[.n[.o[.p[.q[._6 r[.s[.t[.u[.v[.w[.x[.y[.z[.A[.B[. ", -" C[.+ + + + + + + + + + + + + + + + + + $ + 0 / + + + + + + + + + + + + + + m sa 4V D[.E[.F[.G[.yS yS v# iE _. tZ QN H[.C .I[.3! J[.tZ _. K[.N. R+.~7 L[.M[.N[.&L w- M/ O[.5' P[.-l Q[.i= J J J J J J J + < + + + + , + + + + + + + + + + + + + + + # + + + $ + + + + + + + + + , + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + R[.S[.T[.U[.V[.W[.X[.Y[.Z[.`[. }..}.+}.@}.#}.$}.%}.&}.*}.=}.-}.;}.>}.,}.'}.)}.!}.~}.{}.]}.^}./}.(}._}.:}.<}.[}.}}.|}.w/.1}.2}.3}.4}.5}.6}.7}.8}.9}.0}.a}.b}.c}.d}.e}.f}.g}.h}.i}.j}.k}.l}.m}.n}.o}.p}.q}.r}.s}.t}.u}.v}.w}.x}.y}.qB z}.A}.B}.C}.D}.E}.F}.G}.H}.I}.J}.K}.L}.M}.N}.O}.P}.Q}.R}.S}.T}.U}.V}.W}.X}.Y}.Z}.`}. |..|.+|.@|.Y< #|.$|.%|.&|.*|.=|.-|.;|.>|.,|.'|.)|.!|.~|.{|.z^.j{.]|.h,.^|./|.(|._|.:|.<|.[|.}|.||.1|.2|.3|.4|.5|.6|.7|.8|./!.9|.0|.a|.b|.c|.d|.e|.f|.&S g|.-/.h|.i|.j|.k|.l|.m|.n|.o|.p|.q|.r|.s|.t|.u|.v|.w|.x|.y|.z|.A|.B|.C|.D|.E|. F|. ", -" G|.+ + + + & + + + + + + + + + + + + + d 2 + + + + + + + + + + + + + + + + + { m H|.I|.=+ J|.Y] ;,.);.K|.%).L|.M|.{V Tt $$.I[.N|.R+.~+ O|.`_ P|.Q|.W- R|.R6 S'.^& jX S|.Z1 T|.M~ J J J J J J J + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + U|.+ + + + + + + + + + + V|.W|.X|.Y|.Z|.`|. 1..1.+1.@1.#1.$1.%1.&1.*1.=1.-1.;1.>1.,1.'1.)1.!1.~1.{1.]1.^1./1.(1._1.:1.<1.[1.}1.|1.11.q,.21.w^.31.41.7_.51.61.71.81.91.01.a1.b1.c1.d1.e1.f1.g1.l/.h1.i1.j1.k1.l1.m1.n1.o1.p1.q1.r1.s1.t1.u1.v1.w1.w1.x1.y1.z1.A1.B1.C1.D1.E1.F1.G1.Xd H1.I1.J1.K1.L1.M1.N1.O1.P1.Q1.R1.S1.T1.U1.);.V1.W1.X1.Y1.Z1.`1.Gz 2..2.+2.@2.#2.$2.%2.&2.*2.=2.-2.;2.>2.,2.'2.)2.!2.~2.{2.]2.^2./2.(2._2.:2.<2.[2.}2.|2.12.22.32.{(.42.52.62.72.82.92.02.a2.b2.c2.d2.e2.f2.g2.h2.i2.j2.k2.l2.m2.n2.o2.p2.q2.r2.s2.t2.u2.v2.w2.x2.y2.z2.A2.B2.C2.D2.E2.F2.G2.H2.I2. ", -" J2.+ + + + + + + + + + + + + + + + # + + & + + + + + + + + + + + + + + + + + 2 + + + m K2.V}.L2.E[.M2.yS X'.);.;&.N2.=,.=,.O2.;,.]y P2.Q2.P2.gZ R2.S2.T2.P~ U2.V2.W2.z] J J J J J J J + + + + + + + + + + @ + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + = $ , , + + + + + + + @ 3 + + + + + + + + + + + + + + X2.Y2.Z2.`2. 3..3.+3.@3..3.#3.$3.%3.&3.*3.=3.-3.;3.>3.,3.'3.Uk )3.!3.~3.{3.]3.E,.^3./3.(3.O;._3.:3.<3.[3.}3.|3.13.23.33.43.7_.53.]>.63.73.83.93.03.a3.b3.F%.c3.2|.d3.e3.f3.g3.h3.i3.j3.k3.l3.m3.n3.o3.p3.q3.r3.s3.t3.u3.v3.w3.x3.y3.z3.A3.B3.C3.D3.E3.F3.G3.H3.I3.J3.K3.L3.M3.N3.O3.P3.Q3.R3.S3.T3.U3.V3.W3.X3.Y3.Z3.`3. 4.|Y .4.+4.@4.#4.$4.%4.Q3.&4.4z *4.=4.-4.;4.>4.,4.'4.)4.!4.~4.{4.]4.^4./4.(4._4.:4.<4.[4.}4.|4.14.24.34.44.54.64.74.84.94.04.a4.P_.b4.c4.d4.e4.f4.g4.h4.i4.j4.k4.l4.m4.n4.o4.p4.q4.r4.s4.t4.u4.v4.w4.x4.y4.z4.A4.B4.C4.D4.E4.F4.G4.H4.I4. ", -" J4.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , ) + + m m m 'C 8p K4.:h L4.M4.M4.:h N4.O4.)7 O/ 4' s+ ^& -. r# $+ P4.Q4.z] J + J J J J J J + @ @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e + + + + + + + + + + + + + + R4.S4.T4.U4.V4.W4.X4.Y4.Z4.`4. 5..5.+5.@5.#5.#5.$5.p[.%5.&5.*5.=5.-5.;5.c3.>5.,5.'5.aG )5.!5.~5.{5.]5.^5./5.(5._5.:5.<5.[5.}5.;< |5.15.25.35.45.55.65.75.85.95.05.a5.b5.c5.d5.e5.f5.g5.C(.h5.i5.j5.k5.l5.m5.$2.n5.o5.p5.q5.r5.s5.t5.u5.v5.w5.x5.b` y5.z5.A5.B5.C5.D5.E5.F5.G5.H5.'Y I5.J5.K5.L5.M5.N5.O5.P5.Q5.R5.YJ S5.T5.U5.V5.W5.X5.Y5.Z5.`5. 6..6.+6.@6.#6.$6.%6.8(.&6.^G *6.=6.-6.;6.>6.,6.//.'6.)6.!6.~6.{6.]6.^6./6.(6._6.:6.<6.[6.}6.|6.16.26.36.46.+^.56.66.76.86.96.06.a6.b6.c6.d6.e6.f6.g6.h6.i6.j6.k6.l6.m6.n6.o6.p6.q6.r6.s6.t6.u6.v6.w6.x6.y6.z6.J2. ", -" A6.+ + + + + + + + + + @ + + + + + + + + + + + + + @ + + + + + + + + + + + + + # + + + + $ + + m m m 5. B6.C6.)@ D# `} sp D6.eG E6.Z< F6.m m + < + + + = + + + + + @ + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + h + + + + + + + + + + + + + + + + + + + + + + < + + + + + $ + + + + + + + + + + G6.H6.I6.J6.K6.L6.M6.N6.O6.P6.Q6.R6.S6.T6.U6.V6.W6.X6.Y6.p~.Z6.`6. 7..7.+7.@7.#7.$7.%7.&7.*7.=7.-7.;7.=;.>7.,7.'7.e3.)7.36.!7.~7.{7.]7.^7.=/./7.(7._7.:7.<7.[7.}7.|7.17.27.37.47.8|.57.C[.67.77.87.F1.97.n2.07.a7.b7.c7.d7.e7.f7.g7.h7.i7.j7.k7.l7.m7.n7.o7.p7.q7.r7.s7.t7.u7.v7.w7.x7.y7.z7.A7.B7.C7.D7.E7.F7.G7.H7.I7.J7.K7.L7.M7.N7.O7.P7.Q7.R7.S7.T7.U7.V7.W7.X7.Y7.ND Z7.`7. 8..8.+8.@8.#8.$8.%8.&8.*8.=8.-8.;8.>8.,8..(.'8.)8.!8.~8.{8.]8.^8./8.(8._8.:8.X<.<8.[8.}8.|8.18.28.38.48.58.68.78.88.{P 98.08.a8.b8.c8.d8.e8.f8.g8.h8.i8.j8.k8.l8.m8.n8.o8..{.p8.q8. I ", -" r8.+ + + + + b ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %. + + , + + + + + + + + < + + + + + + + + + + + + + + + + , # $ + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s8.t8.u8.v8.w8.x8.y8.z8.A8.B8.C8.D8.E8.F8.G8.H8.I8.J8.K8.L8.M8.N8.O8.P8.Q8.R8.S8.T8.U8.V8.W8.X8.Y8.Z8.`8. 9.'|.1(.m[..9.+9.@9.#9.$9.%9.&9.=8.*9.=9.-9.l0 ;9.>9.,9.'9.)9.!9.~9.{9.]9.^9./9.(9._9.:9.<9.[9.}9.|9.19.29.39.49.59.h7.69.79.89.99.09.a9.b9.c9.d9.e9.>*.f9.g9.h9.i9.j9.k9.l9.m9.n9.o9.p9.q9.r9.s9.t9.u9.v9.w9.x9.y9.z9.A9.B9.C9.D9.E9.F9.G9.H9.I9.J9.K9.L9.M9.N9.O9.-X P9.Q9.R9.S9.T9.U9.V9.W9.X9.Y9.Z9.`9.b6. 0..0.+0.@0.#0.$0.%0.DW &0.*0.=0.p&.-0.;0.>0.,0.'0.)0.!0.~0.{0.]0.^0./0.(0._0.:0.<0.[0.}0.|0.10.20.30.40.50.60.70.80.90.00.a0.b0.c0.d0.e0.A6. ", -" f0.+ + @ + + + + + @ { g0.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / / + + + + + + + b + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h0.i0.j0.k0.l0.m0.n0.o0.p0.q0.r0.s0.t0.u0.v0.w0.x0.y0.z0.A0.B0.C0.D0.E0.F0.G0.H0.I0.J0.K0.L0.M0.N0.O0.P0.Q0.R0.S0.a[.T0.U0.V0.W0.X0.o=.Y0.Z0.`0. a..a.+a.@a.#a.$a.%a.&a.*a.=a.-a.;a.>a.,a.'a.)a.!a.X8.1..~a.{a.]a.^a./a.(a._a.:a.b.,b.'b.)b.!b.~b.{b.]b.^b./b.(b._b.:b.c.,c.'c.)c.!c.~c.{c.]c.^c./c.(c._c.:c.d.,d.*Q 'd.)d.!d.~d.{d.]d.^d./d.(d._d.:d.e.,e.'e.)e.!e.~e.:0.{e.]e.]e.e9.^e./e.(e._e.:e.f.,f.'f.)f.!f.~f.{f. ", -" ]f.= + + + + = + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + , + + + # # + + + + + + + + + + ] + + + + + + @ + + + + # + # + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ) + + + + + + + + + + + + + + + + + + + + + + ^f./f.(f._f.:f.g.,g.'g.)g.!g.~g.{g.]g.^g./g.(g._g.:g.h.,h.'h.)h.!h.~h.{h.]h.^h./h.(h._h.:h.i.,i.'i.)i.0b.!i.~i.{i.]i.^i./i.(i._i.]8.:i.)d.j.,j.'j.)j.!j.~j.{j.]j.^j./j.(j.of._j.:j.k.,k.'k.)k.!k.~k.{k.|j.]k.^k./k.(k._k.:k.l.,l.'l.)l.0b.!l.0b.~l.{l.]l.Id.^l./l.@a.(l._l.>6.:l.m.,m.'m.)m.!m.~m.{m.]m.^m./m.(m._m.:m.0U n.,n.'n.%b.)n.!n.~n.{n.]n.^n./n.(n._n.:n.o.,o.'o.)o.!o.~o.{o.]o.^o./o.-o.(o._o.:o.p._Y ,p.'p.kl.)p.!p.~p.{p.]p.^p./p.(p._p.)p.:p.q.,q.'q.)q. ", -" il + + + + + + + + + + + + + + < @ + + + + + + + + + + + + + + # < + + + + + + + + + + + + + + = b + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !q.~q.{q.mm.]q.^q./q.(q._q.:q.r.,r.'r.)r.!r.~r.{r.Wu ]r.^r./r.(r._r.:r.s.,s.'s.)s.!s.~s.{s.]s.^s./s.(s._s.:s.Mg.t.,t.'t.)t.!t.~t.{t.]t.^t.@o./t.(t._t.:t. + , + + + # + Z. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pt.qt.rt.st.tt.ut.vt.wt.xt.yt.zt.At.Kf. k.Bt.Ct.Dt.Et.Ft.Gt.Ht.It.Jt.|S Kt.Lt.Mt.Nt.Ot.Pt.Qt.Rt.St.We.Tt.Ut.Vt.Wt.Xt.Yt.Mn.ns.Mn.Zt.=m.`t. u.ps..u.+u.ns.@u.#u.Ss $u.%u.&u.*u.=u.-u.;u.lp.hk.>u.,u.'u.)u.vF $W !u.~u.{u.]u.^u.0W /u.(u._u.:u.v.,v.'v.)v.!v.~v.{v.]v.Xt.^v./v.(v._v.:v..f.r.Dv.Ev.[r.Fv.tp.Gv.Hv.S@ Iv.Jv.Kv.Lv.Mv.Nv.Ov.Pv.Qv.Rv.Sv.Tv.Uv.=p.Vv.Wv.Xv.Yv.Yv.w+ :j Zv.`v. w.e4 Xv..w.mp.+w.@w.#w.$w.%w.&w.*w.=w.-w.;w.>w.,w.,q.Pp.'w.;q.Gr.Hr.)w.!w.~w.yu.{w.]w.^w.au./w.(w._w.:w. + + + + + + + + + + + + + + + + + + + + , + + + + + + , + + > + + + + + + + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + iw.6I jw.kw.lw.'v.mw.nw.ow.~v.pw.qw.rw.sw.Et.tw.uw.vw.ww.x.%r.{&.,x.'x.Xq.)x.!x.~x.1r.{x.]x.>x.^x./x.(x._x.B. :x.q.1o.lx.mx.nx.ur.ox.px.qx.rx.sx.Eu.tx.ux.vx.wx.xx.yx.zx.Ax.Bx.zu.Cx.Dx.Nu.Ex.Fx.0w.Gx.Hx.+v.J) Ix.J) x' x' v.Jx.+v.J) Uu.x' cw.bw.0w.nx.Kx.Lx.+v.0w.Mx.Mx.Nx.bw.bw.Ox.Mx.Mx.Px.Mx.Px.Qx.Rx.Sx. K+ ", -" #w + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Z. + + + + + + + + + + + + + + + + + + + + + + + : + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + Tx.Ux.Vx.Wx.Xx.Yx.Zx.`x. y..y.+y.+y.@y.#y.$y.%y.&y.*y.=y.-y.;y.>y.zw.,y.'y.)y.:m.!y.~y.{y.]y.^y.Gi.wr./y.(y._y.:y.z.,z.'z.px.)z.J) Ox.Fx.Ox.Ix.Ix.bw.Ox.Px.!z.!z.Mx.Ix.Lx.bw.K+ Mx.Mx.Px.Px.Px.Rx.Px.Px.Px. ", -" 5Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mx.~z.{z.]z.^z./z.(z._z.:z.q.kz.lz.mz.nz.oz.Ps.pz.qz.rz.sz.tz.uz.vz.wz.vx.xz.yz.zz.Az.Bz.Cz.Tq My.lr..z.{x.Dz.Ez.Fz.Ky.Gz.=w.Hz.mg.Eu.Iz.Jz.Kz.^Y |r.Lz.Mz.Nz.Oz.Pz.Qz.Rz.Sz.Tz.Uz.Vz.Wz.Xz.Yz.Zz.`z. A..A.pu.+A.@A. W #A.$A.%A.&A.*A.=A.-A.;A.>A.,A.'A.'A.)A.!A.~A.-q.7t.Gr.Gr.{A.~w.ox.]A.^A.nx.ew./A.Lx.(A.Lx._A.:A.A.wu.PA.QA.RA.SA.+A.TA.UA.VA.WA.V%.XA.YA.ZA.;A.`A.ny. B..{ .B.Bx.+B.@B.#B.$B.+B.%B.&B.*B.=B.-B.;B.Wz.My.>B.,B.'B.)B.|w.!B.~B.'A.{B.]B.^B./B.(B.)B._B.,z.:B.=z.(B.3w.:B.C.,C.'C.)C.!C.!C.~C.Lx.Dx.Lx.!B.Kx. F|. F|. F|. p F|. ", -" + + + + + + + + $ + + + + + + > + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + J) {C.]C.^C./C.(C._C.:C.:o.A.CB.xC.yC.zC.fC.AC.BC.CC.Ty.DC.EC.FC.GC.rx.HC.IC.JC.KC.KC.LC.CN b' MC.NC.pC.gw.OC.PC.PC.QC.RC.SC.'z.TC.UC.VC.QC.WC.XC.hw. UC. p p I F|. p F|.I ", -" F|. $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + YC.ZC.`C. D..D.+D.2y.@D.6z.#D.$D.%D.&D.*D.=D.-D.nA.;D.>D.%D.vr.Ir.#q.Pu.6t.9t.,D.ct.Qu.6t.Qu.Ru.'D.at.Uu.Uu.Tu.)D.!D.~D.~A.'D.MB.jt.7w.kt.{D.0w.+v.nx.Dx.hw.]w.Kx.fC.%z.]D.hC.+z.^D.pr.zx. A.Qz.(B.-C.GC.Ju.zu./D.(D.AC._D.7w.(D.:D.AC.tx.KC.E. ", -" I + + + + + + + + q8.,E.ln 'E.`*.)E.kx.+ + + # + , + + $ = + + + # + + + + + + !E.~E.~E.~E.~E.~E.{E.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , c + + + + + + + + + + ]E.^E.O> + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + = + + + + + + + + + + + + + I p p I /E.(E. p /E.(E.p I F|. p p F|.p I p 4o.E|._E.:E.. . . . . . . . . . . . :E. = [ + + + + !E.|E.n .. . . . . 1E.+ + + + + + + + + + + + + 2E.3E.+ 4E.5E.O> + + + + + + + + + + + + $ + + + + + + + + + O> 6E.7E.8E.+ + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + F|. p 9E.0E.aE. 9E.0E.aE. bE.cE. dE. F|. p I n I )q.D^.ln . . . . . . . . . . . . . . . . . . ~e eE.4o. I ", -" # + + + + + fE.. . . . . . . . gE.+ + # + + + & * & = - hE.iE.jE.kE.Z>.lE.mE.. . . . . . . nE.+ + + + + + + + + + + + + oE.pE.qE.rE.sE.tE.+ + + + + + + + + + + + + + + + + + + + + + + uE.vE.wE.+ + + + + + xE.yE.zE.O> + + 4E.AE.BE.CE.+ + + + + + + , DE.EE.FE.GE.+ + + + + + O> HE.IE.JE.O> + + + + + + KE.LE.ME.NE.OE.PE. QE.RE.SE.TE.UE.VE. bE.WE.XE. bE.WE.XE.F|. F|. p KE.LE.ME. QE.RE.SE. KE.YE.ZE.`E. F.PE. I p p I #w .F.,l . . . . . ln `>.+F.@F.1c.]e.]e.1c.@F.+F.`>.ln . . . . . ,l C(.#w I ", -" + + + + + #F.O#.. . . . . . . . . $F.+ + + + + + + = - ! %F.. . . . . . . . . . . . . &F.+ + + + + + + + + + + + + oE.*F.=F.-F.;F.~; >F.,F.'F.)F.O> oE.pE.!F.~F.{F.]F.yE.zE.^F./F.(F._F.*F.:F. + >F.,F.'F.)F.O> + gF.hF.iF.O> + / + + + = KE.LE.ME.NE.OE.PE.jF.kF.lF.mF. KE.LE.ME.NE.OE.PE.nF.oF.lF.pF.qF. QE.RE.SE.TE.UE.rF.sF.tF.uF.aE. vF.wF.xF.yF.zF.sF.tF.uF.aE. jF.kF.lF.mF. KE.YE.AF.BF.CF. vF.wF.xF.yF.zF. I F|. KE.LE.ME. QE.RE.SE. KE.LE.ME.DF.EF. F|. F|. FF..;.. . . . ~e GF.HF.O~ O~ HF.Z>.'E.. . . . .;.FF. ", -" I + + + + + IF.. . . . . . . . . . JF.+ + + + + + + = ( _ KF.. . . . . . . . . . . . . LF.+ + + + + + + + + + + + + oE.*F.=F.O> O> xE.yE.MF.^F.NF.OF._F.*F.:F. 6E.7E.8E.$ oE.*F.:F. WF.XF.YF.ZF.`F. G.+ + .G.+G.@G.+ < + + + + KE.LE.#G.NE.OE.$G.RE.SE.TE.UE.rF.KE.YE.%G.&G.*G.=G. TE.UE.rF. QE.RE.-G.TE.UE.rF. 9E.0E.aE. QE.RE.SE. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE. I I p I KE.LE.ME. QE.RE.SE. KE.LE.ME. F|. F|.I I I q8.;G.. . . 'E.O!.em. em.O!.'E.. . . ;G.q8. ", -" + + + + + >G.. . . . . . . . . . ,G.+ + + + + + + [ } ! %F.. . . . . . . . . . . . . 'G.+ + + + + + + + + + + + + )G.!G.=F.~G.{G.xE.yE.zE.^F.NF.OF.oE.*F.:F. 6E.7E.8E.+ oE.*F.:F.(G.[F.7F.yE.zE.^F.NF.OF.4E._G.VF.CE.+ + + + + + + 4E.AE.VF.CE.O> xE.yE.zE.O> + + + + .G.+G.@G.+ + + + + + KE.LE.ME.:G.OE.$G.RE. 6E.7E.8E.+ oE.*F.:F. + + + + + 4E.AE.VF.CE.sG.F-.XF.YF.ZF.`F. G.+ + .G.+G.@G.+ + + + + + KE.tG.uG.vG. F.$G.RE.SE. KE.LE.ME. F|.QE.RE.SE.TE.UE.rF. QE.RE.wG.xG.yG.rF. 9E.0E.aE. I TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE. I TE.UE.rF. zG.AG.BG.CG. KE.LE.ME.F|. QE.RE.-G. KE.LE.ME.NE.OE.PE. DG.EG.FG. p p F|. cG.:E.. . :E.C[. F|. C[.:E.. . :E.GG. I ", -" + + + + + + HG.. . . . . . . . ~e IG.+ + + + + + + + $ = JG.KG.LG.MG.'E.. . . . . . . . . NG.+ + + + + + + + + + + + + OG.PG.!F.QG.RG.SG.TG.UG.'F.9F.VG.oE.pE.!F.WG.@G.XG.TG.UG.'F.9F.0F.oE.YG.=F.+ + ZG.|F.1F.`G. H..H.4E.+H.!F.6F.sE.7F.yE.zE.^F.NF.OF.O> HE.@H.#H.$H.%H.+ + + + + O> &H.*H.=H.O> + >F.,F.'F.)F.-H.$ ;H.>H.,H.'H.+ + + + + )H.!H.~H.{H.p ]H.WG.xF.^H. KE.LE.ME. p ]H.WG.lF.3G.rF. /H.(H._H.:H. sF.tF. + + + + + + + + + + + + + O> + + / + + + + gF.hF.iF.hH.+ + + + + F|. iH.jH.kH. F|. p I F|. F|. nB ;G.. . 0l *g. f0.0l . . ;G.nB F|. p I ", -" + + + + + + + lH.0l . . . . mE.mH.#F.+ + + + + + + + + $ + 9 + + + nH.. . . . . . . . :E.+ + + + + + + + + + + + + + + + + + + + + + # # + oE.oH.pH.= O> qH.rH.sH.tH.3E.+ + + + + + + + + $ + + uH.vH.wH.QG.RG.~; + + + + + + + + & + + + + @ + + + & xH.yH.zH.+ + + , , + O> AH.BH.CH.= + + + + + I F|. I I DH.EH.FH. p I I F|. I A] p F|. #w dG.. . :E.cH. F|. F|. cH.:E.. . }E.O~ I ", -" + + + + + + + + GH.KG.HH.Z*.IH.JH., + + + + + + + + + + + + + + + + KH.. . . . . . . . ln + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + # + + + + + + + + + + + + + + + @ + + + + + + + + $ + + , + + + + + + c + + + > + + + + + + + + + + + + + + + I p p F|. F|. F|. p p C(.. . . C[. I p p p C[.. . . C(. ", -" + + + + + + + + + , + + + + & + + + + + + + + + + + + + + + + LH.. . . . . . . . MH.+ + + + + + + + + + + + + + + + + + + + + + + + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + F|. n I p p p F|. F|. NH.,l . . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9E.0E.aE. I p p p I I I F|. I p p F|. I 4o.ln . . mH. I F|. @h.&I.ln . . . . . . n .U%.. . . . N#.;G.. . . . . . :E.Z*.*I. O!.. . ln NH. F|. ", -" + + + lH.=I.:E.. . . . . . . . . . -I.$ ;I.N#.. . . . . . . . . . . . . . . . . . . . T%.+ + + + + = + + + + + + + + >I.,I.'I.)I.!I.~I.yE.zE.O> + + + 2E.{I.]I.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + O> F.^I./I.+ + + + + + + + + + + (I._I.:I. I bE.WE.XE. p xE.yE.bI.'F.9F.0F.uH.cI.dI.iF.O> O> eI.fI.wH.gI.hI.+ + + # + xE.yE.bI.'F.iI.jI.oE.*F.:F.F.,F.'F.)F.O> 4E.+H.!F.6F.sE.7F.yE.zE.^F.NF.OF.4E.+H.!F.WG.@G.ZG.kI.lI.mI.nI..H.+ + + + + + >F.,F.'F.mF. oI.AF.pI.6H.QE.RE.. A6.;G.. . . 'E.HI.2j. &v.. . . . Hk. II.I2.}E.. . . :E.8I. P!.. . Z*. ", -" I + + + JF.. . . . . . . . . . . . JI.n .. . . . . . . . . . . . . . . . . . . . . . KI.' + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.LI.xE.yE.zE.O> < / + + + @ + xE.yE.zE.^F.NF.OF.oE.pE.RF.SF.TF.MI.yE.zE.^F.NF.OF.oE.*F.:F.F.^I./I.+ + + + + + + WF.XF.TI.ZF.UI.VI.KE.LE.GI.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME. KE.LE.ME. QE.RE.SE.TE.UE.rF.qI.rI.sI.tI.}H.uI.jF.2I.3I.F|. KE.LE.WI.XI.EI.FI. TE.UE.rF.KE.YE.%G.&G.*G.YI.RE.SE.TE.UE.rF.I I F|. I F|. >E.:E.. . HF. G|.n .. . mE.&I.@I. p #w . . . . NH. ZI.N#.. . . IH.p `I.. . n .Hk. I ", -" + + + J.. . . . . . . . . . . ln JI.. . . . . . . . . Z*..J.&I.m .. . . . . . . . . . I+ + + + + + + + + + + + + + + + +J.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.O> O> @J.#J.$J.%J.&J.+ + + + + xE.yE.zE.^F.NF.OF.oE.*F.=F.+ + xE.yE.zE.^F.NF.OF.oE.*F.:F. O> O> >F.^I./I.+ + + + + + + xE.yE.zE.O> KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. 1G.2G.lF.3G.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.yI.=J.-J.;J.>J. yI.=J.-J.;J.,J.QE.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.3I. KE.LE.WI.XI.EI.'J.)J.2G.lF.3G.rF.KE.LE.ME. QE.RE..,l . . . . . . . . {J.RH.. . . . . . . 'E.nE.+ + + *w.]J.. . . . . . . . . RH.+ + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.O> O> O> O> ^F.NF.OF.+ + + + + xE.yE.zE.^F.NF.OF.oE.*F.=F.+ + xE.yE.zE.^F.NF.OF.oE.*F.:F.F.^I./I.+ + + + + + + WF.XF.YF.ZF.UI.VI.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. QE.RE.SE.TE.UE.rF. 9E.0E.aE.I QE.RE.SE.TE.UE.rF. NE.OE.^J. NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.3I. /J.(J._J.:J... . ;E.p p ", -" + + + + + + |J.,l . . . . . . ~e 1J.RH.. . . . . . . 2J.+ + + > + + KG.. . . . . . . . IH.+ + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.uH.3J.4J.5J.eF.6J.|F.wH.'F.9F.0F.+ + + + # xE.yE.bI.'F.)F.O> oE.*F.=F.+ + XG.TG.UG.'F.9F.0F.7J.8J.!F.6F.sE.9J.TG.UG.'F.0J.OF.4E.+H.!F.WG.@G.+ aJ.bJ.mI.nI..H., + + + + + >F.,F.'F.mF. 8H.9H.AF.BF.CF.QE.RE.SE.TE.UE.rF. )H.cJ.tI.}H.2H.]H.WG.lF.3G.rF.sF.tF. + + + + + + + + + $ + + : + + + + + + + + + + ) ] + + + + + + + + + + + + + + + + + + + F|. I F|. I F|. A] F|. U%.. . pJ. qJ.. . rJ. 'E.. . . II. 2j.. . eE. 5I.. . U%. ", -" + + + + + + + E|.. . . . . . sJ.+ RH.. . . . . . tJ.+ + + # - + + nJ.. . . . . . . . D^.+ + + + + + + b % + + + + + + , $ , + + + + + + + + + + + + + + + + + + + + + + + xE.yE.zE.O> + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + I I I F|. F|. I p F|. p I I p I ;G.. . cH.F|.TH.. . @h. F|.~e . . . 4o. I ;G.. mH. cH.. . .I. ", -" + + + + + + + uJ.. . . . . 0l kx.+ RH.. . . . . m .#F.+ + + b h + + nJ.. . . . . . . . )E.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + ^ + < , + + + + + + + + + + + + + > + + + + + + , + + + + + + + + + + F|.I F|. I I p I p A] ~e . . vJ. ]e.. . wJ. p 0l . . . Hk. I m .. xJ. vJ.. . ~e ", -" + + + + + + + yJ.. . . . . _E.+ + RH.. . . . . gE.+ + + + = + + + nJ.. . . . . . . . 0I.+ + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + , + + l + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + > + + p F|. p I I A] p I I I ~e . . vJ. 5Z }J.. cG. p 0l . . . NH. F|. UH.. ZH.Qr. vJ.. . ~e ", -" + + + + + + + zJ.. . . . . Z>.+ + RH.. . . . . C(.+ g @ + + + + + nJ.. . . . . . . . 2J.+ + + + + + + + + @ + + + + + + + + + + + + , + + < + + + + + + + + + @ + + + + + # + + + + + + + + + + + c + + + + + + + + + + + + + + + , + + + + + + + + + + + # + + + + + + + /E.(E.I I I I I I F|. p F|. I ;G.. . cH. r8.n .}E.5Z p 0l . . . II. I I HI.mE.J4. cH.. . .I. p ", -" + + + + + + + AJ.. . . . . BJ.+ + RH.. . . . . CJ.+ + @ + + + + + nJ.. . . . . . . . DJ.+ + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + + + + + + + + + + + + @ + + + + + # + + + + < % + + + + + & + + + + + > + + + + + + + + + + + + + + + + , + + + + + = p 9E.0E.aE. EJ. FJ.cE. I U%.. . mJ. F|.p GG.n .;E. p 0l . . . II. J2.n .E|. mJ.. . U%. ", -" F|. N@ . . . . . E^. RH.. . . . . GJ. F|. F|. O~ . . . . . . . . A6. (I._I.:I. QE.RE.SE. HJ.IJ.JJ.aE. nF.KJ.LJ.MJ.NJ. bE.OJ.XE. F|. TE.UE.rF. QE.RE.PJ.QJ.RJ.SJ. nF.KJ.LJ.MJ.NJ. (I._I.:I. p F|. p /H.(H._H.:H. F|. JI.. . E^. vJ.MH.E^.#w p 0l . . . 4o. F|. p 0I.m .1c. +F.. . JI. ", -" 'E.. . . . HI. RH.. . . . . cG. F|. O~ . . . . . . . . OH. qI.rI.sI.tI.}H.uI.jF.kF.lF.mF. oI.AF.pI.6H.QE.RE.K.kF.lF.mF.F|. F|. +F.. . Z*.I NH.[E.,E.,K. 0l . . . Hk. ]f.R'.&I.em. Z*.. . +F. ", -" O#.. . . . _E. RH.. . . . . C(. O~ . . . . . . . . {f.A] F|. (I._I.:I. QE.RE.SE.TE.UE.rF.'K.)K.ME.!K.~K.{K.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. yI.zI.AI.BI.yF.zF.KE.YE.%G.&G.*G.YI.RE.SE.TE.UE.rF.KE.LE.WI.XI.EI.FI. I 9E.0E.aE. QE.RE.SE.TE.UE.rF. p ]K. ^K./K.(K. KE.LE.ME.NE.OE.3H.zI.AI.BI.yF.zF. (I._I.:I. QE.RE._K.:K.E. #w cG.m .. . . . . . . . . 4I.|d. F|. I I ]K. I sF.eJ.xF.BF.HK.IK.JK.KK.LK.cE. MK.NK.OK. F|. I I I I +F.. . 'E.lJ. F|. s7.. . h5. L2.'E.. . I1. ]K. ", -" I y:.4I.. . . . . . . . . O#.)q.O~ I2.-E.'E.. . . . ,l R'. ;.PK.. . . . . . . . . . . . . }J.B[. p p I F|. F|. F|. F|. I I F|. I Ui.0l . . +I.5Z I QK.. . ]e. L.,L.'L.)L. . p gE.PK.RH.RH.RH.dG..I. HF.. MH. 9E.0E.aE. QE.RE.SE.TE.UE.rF. 0H.-K.;K.F|.KE.LE.ME. 8L.4K.5K.6K.UI.VI.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE.I 0H.-K.;K. KE.LE.ME.NE.OE.yL.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE. (I._I.:I. 8L.4K.5K.6K.UI.VI. 9L.0L.6H. zL.AL.BL. jF.CL.DL.EL.%K.&K.(I.FL.GL.EI.FI.HL.CL.DL.EL.%K.&K. F|. 0H.-K.;K. KE.LE.ME.NE.OE.PE.p IL.JL.KL.LL.ML.YI.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.NL. /J.(J._J.:J.. gE.AK.eE.eE.eE.dG.O#. I I wJ.TH. lH.. N#. I sF.tF.M.-E. &I.PK. vJ..;. E|.. ,E.p p I p TE.UE.rF. zG.,M.'M.)M. 9E.0E.aE. 9E.0E.aE. F|. p F|. F|. p iH.jH.kH. F|. F|.F|. em.E^.;G.. . . . . . . . . . . . . . . . . . ;G.I1.em. I ", -" +I.. . . ,K. O~ . . . X. !M.;G.eG. Pm.]L. *I.~e r+. ~M.Z*. rJ.. ;. p p p p yI.1H.xF.lF.pF.{M.]M.^M./M.(M. _M.:M.M.eE.eE.eE.mE.. . PL.eE.eE.eE.eE.eE..PK.RH.RH.RH.`*.. D^. p I p p p I I F|. I I ]K. F|. I I F|. p II.q8.GK.JI.`*..I.0l ,l MH.U%.-E.+F.1E.NH. F|. p ", -"F|. II.R'.0l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . :E.O#.HI.N@ I I p p I F|. I I I p I I I I F|. p p F|. p I p I F|.", -" F|. I I p F|. p p p p F|. I p I p I p I p ", -" I F|. F|. p I p I I I I p F|. F|. I ]K. p F|. I F|. F|. p p p F|. F|. I p ", -" p p F|. I I p I I F|. F|. I I F|. ", -" I F|. F|. I I F|. F|. F|. F|. F|. p F|. p I F|. p ", -" I p F|. F|. I p p F|. I F|. p F|.I I F|. p F|. p p F|. F|. I I ", -" p p p F|. I F|. F|. F|. I I I I F|. p p p F|. F|. p ", -" F|. F|. p I F|. F|. F|. I F|. I F|.I F|. I p p I p F|. I ", -"p I p F|. I p p p p F|. p p p I F|. p I p F|. I p p F|. "}; diff --git a/resources/bitmaps/texture_browser.xpm b/resources/bitmaps/texture_browser.xpm deleted file mode 100644 index 21edf5e..0000000 --- a/resources/bitmaps/texture_browser.xpm +++ /dev/null @@ -1,83 +0,0 @@ -/* XPM */ -static char * texture_browser_xpm[] = { -"16 16 64 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #65F2FC", -"& c #66F2FC", -"* c #00C9F7", -"= c #8CFFFF", -"- c #8AFFFF", -"; c #69F1FD", -"> c #68F1FE", -", c #69F2FE", -"' c #69F1FE", -") c #00C7F7", -"! c #00C5FD", -"~ c #90FFFF", -"{ c #8EFFFF", -"] c #6CF1FF", -"^ c #00C5FF", -"/ c #00C1FF", -"( c #6BF0FF", -"_ c #00BDFF", -": c #69EFFF", -"< c #68EFFF", -"[ c #69EEFF", -"} c #00BBFF", -"| c #00B7FF", -"1 c #66EDFF", -"2 c #65EDFF", -"3 c #00B3FF", -"4 c #63ECFF", -"5 c #84FFFF", -"6 c #00B5FF", -"7 c #00ADFF", -"8 c #62EBFF", -"9 c #60EBFF", -"0 c #80FFFF", -"a c #82FFFF", -"b c #00AFFF", -"c c #00A9FF", -"d c #5FEAFF", -"e c #5DEAFF", -"f c #7CFFFF", -"g c #7EFFFF", -"h c #00A5FF", -"i c #5CE9FF", -"j c #5AE9FF", -"k c #5CE8FF", -"l c #7AFFFF", -"m c #00A3FF", -"n c #009FFF", -"o c #59E7FF", -"p c #5AE8FF", -"q c #76FFFF", -"r c #78FFFF", -"s c #009BFF", -"t c #56E6FF", -"u c #57E6FF", -"v c #72FFFF", -"w c #74FFFF", -"x c #0095FF", -"y c #0097FF", -" ", -" ...+.......... ", -" @##$$#$%%%&&%@ ", -" *==-===;>,,'') ", -" !~{~~~~]]]]]]^ ", -" /{{{{{{((((((/ ", -" _-===--:<<<<[} ", -" |#$##$#111211| ", -" 342444455#5556 ", -" 78999990aaa00b ", -" cddddeeffggggc ", -" hiijiikllllllm ", -" nooooopqqqqrqn ", -" stttuttvwvvwvs ", -" xxxxxxxxyxxxxx ", -" "}; diff --git a/resources/bitmaps/texture_lock.xpm b/resources/bitmaps/texture_lock.xpm deleted file mode 100644 index a7ebe72..0000000 --- a/resources/bitmaps/texture_lock.xpm +++ /dev/null @@ -1,37 +0,0 @@ -/* XPM */ -static char * texture_lock_xpm[] = { -"16 16 18 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #87FFFF", -"# c #89FFFF", -"$ c #8CFFFF", -"% c #8FFFFF", -"& c #8EFFFF", -"* c #8BFFFF", -"= c #85FFFF", -"- c #FFFF00", -"; c #83FFFF", -"> c #81FFFF", -", c #7FFFFF", -"' c #7BFFFF", -") c #77FFFF", -"! c #72FFFF", -"~ c #75FFFF", -" ", -" .............. ", -" .++++++@@@##@. ", -" .++++....$$$$. ", -" .+++......%%%. ", -" .+++..+&..&&&. ", -" .+++..+$..**$. ", -" .++........##. ", -" .=@.------.++. ", -" .;>.--..--.++. ", -" .,,.--..--.++. ", -" .''.------.++. ", -" .))........++. ", -" .!!!~!!++++++. ", -" .............. ", -" "}; diff --git a/resources/bitmaps/textures_popup.xpm b/resources/bitmaps/textures_popup.xpm deleted file mode 100644 index cb402f2..0000000 --- a/resources/bitmaps/textures_popup.xpm +++ /dev/null @@ -1,66 +0,0 @@ -/* XPM */ -static char * textures_popup_xpm[] = { -"16 15 48 1", -" c None", -". c #007B82", -"+ c #FFFF00", -"@ c #000000", -"# c #31C6C9", -"$ c #007A84", -"% c #FFFFFF", -"& c #37C6CA", -"* c #007A85", -"= c #40C6CB", -"- c #3DC6CB", -"; c #007A86", -"> c #007986", -", c #007987", -"' c #45C6CB", -") c #43C6CB", -"! c #007988", -"~ c #4AC5CC", -"{ c #4AC6CC", -"] c #007888", -"^ c #48C5CC", -"/ c #007688", -"( c #45C4CC", -"_ c #43C4CC", -": c #007488", -"< c #3DC4CC", -"[ c #40C4CC", -"} c #3AC3CC", -"| c #3DC3CC", -"1 c #007388", -"2 c #007288", -"3 c #37C2CC", -"4 c #34C3CC", -"5 c #34C2CC", -"6 c #007088", -"7 c #31C2CC", -"8 c #2DC2CC", -"9 c #007188", -"0 c #006F88", -"a c #26C1CC", -"b c #2AC1CC", -"c c #006E88", -"d c #006C88", -"e c #26C0CC", -"f c #006D88", -"g c #006B88", -"h c #006988", -"i c #006A88", -" .+ @#.. ", -" $%$@+&&&$$$ ", -"+*+*+=-=---=*@ ", -";+%>,,@'')'',@ ", -"!%++~{~~~{{!!@ ", -"%]%^^]^^^^]]]@ ", -"+/%(%(%_(////@ ", -":%@%<%[<:::::@ ", -"}}%|%}%}1:11:@ ", -"2%3%4%452222@ ", -"67%7%7%8999@ ", -" 000a%bbc0@ ", -" dddef@ @@@", -" g@ @gg", -" @hi"}; diff --git a/resources/bitmaps/undo.xpm b/resources/bitmaps/undo.xpm deleted file mode 100644 index 2758d4e..0000000 --- a/resources/bitmaps/undo.xpm +++ /dev/null @@ -1,34 +0,0 @@ -/* XPM */ -static char * undo_xpm[] = { -"16 16 15 1", -" c None", -". c #47E0FF", -"+ c #47E1FF", -"@ c #45DEFF", -"# c #43DBFF", -"$ c #44DCFF", -"% c #44DBFF", -"& c #42D9FF", -"* c #43DAFF", -"= c #41D6FF", -"- c #40D7FF", -"; c #40D6FF", -"> c #3FD4FF", -", c #3ED5FF", -"' c #3DD1FF", -" ", -" ", -" ", -" ", -" ", -" ..+. ", -" @ @@ @ ", -" #$ # % ", -" &*& & ", -" =--; - ", -" >>>>, > ", -" ' ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/view_cameratoggle.xpm b/resources/bitmaps/view_cameratoggle.xpm deleted file mode 100644 index a9cb932..0000000 --- a/resources/bitmaps/view_cameratoggle.xpm +++ /dev/null @@ -1,66 +0,0 @@ -/* XPM */ -static char * view_cameratoggle_xpm[] = { -"16 15 48 1", -" c None", -". c #CCCCCC", -"+ c #40E6F3", -"@ c #3FE6F4", -"# c #3FE6F3", -"$ c #3FE5F3", -"% c #41E5F6", -"& c #42E5F5", -"* c #42E5F6", -"= c #43E4F8", -"- c #44E4F9", -"; c #43E4F9", -"> c #44E5F9", -", c #44E4F8", -"' c #46E4FB", -") c #45E4FB", -"! c #46E3FB", -"~ c #45E3FC", -"{ c #46E3FC", -"] c #46E4FC", -"^ c #48E2FE", -"/ c #47E2FF", -"( c #48E3FE", -"_ c #48E2FF", -": c #48E3FF", -"< c #47E1FF", -"[ c #47E0FF", -"} c #FFFFFF", -"| c #45DEFF", -"1 c #46DEFF", -"2 c #FFFF00", -"3 c #43DBFF", -"4 c #44DCFF", -"5 c #44DBFF", -"6 c #42D9FF", -"7 c #43DAFF", -"8 c #41D6FF", -"9 c #40D7FF", -"0 c #40D6FF", -"a c #3FD4FF", -"b c #3ED5FF", -"c c #3DD2FF", -"d c #3CD2FF", -"e c #3BCFFF", -"f c #3BD0FF", -"g c #39CDFF", -"h c #3ACDFF", -"i c #37CAFF", -".+@#$# ", -"%%%%&*%% ", -"=-;=--=>;;;-, ", -"')!!~{'!!~]]{{ ", -"^^^/^(^_^(:(:^_ ", -"<[<[[[[<[[<[[}} ", -" ||111||1||2}}} ", -" 334335355}2}}3 ", -" 6766666}22}} ", -" 899090}22}}9 ", -" aaaab}22}}a ", -" ccdc222}}c ", -" eeee}}}}f ", -" gg}}}}h ", -" i}}i "}; diff --git a/resources/bitmaps/view_cameraupdate.xpm b/resources/bitmaps/view_cameraupdate.xpm deleted file mode 100644 index b5b0787..0000000 --- a/resources/bitmaps/view_cameraupdate.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * view_cameraupdate_xpm[] = { -"16 15 43 1", -" c None", -". c #D4FFFF", -"+ c #40E6FF", -"@ c #3FE6FF", -"# c #94FFFF", -"$ c #41E5FF", -"% c #42E5FF", -"& c #95FFFF", -"* c #43E4FF", -"= c #44E4FF", -"- c #44E5FF", -"; c #97FFFF", -"> c #45E4FF", -", c #46E3FF", -"' c #45E3FF", -") c #46E4FF", -"! c #FFFFFF", -"~ c #48E2FF", -"{ c #47E2FF", -"] c #48E3FF", -"^ c #47E0FF", -"/ c #47E1FF", -"( c #45DEFF", -"_ c #46DEFF", -": c #96FCFF", -"< c #43DBFF", -"[ c #44DCFF", -"} c #95F8FF", -"| c #42D9FF", -"1 c #43DAFF", -"2 c #41D7FF", -"3 c #94F6FF", -"4 c #3FD4FF", -"5 c #94F4FF", -"6 c #3DD1FF", -"7 c #3DD2FF", -"8 c #93F1FF", -"9 c #3BD0FF", -"0 c #93F0FF", -"a c #39CDFF", -"b c #92EEFF", -"c c #38CAFF", -"d c #91ECFF", -".+@# ", -"$$$$%%$$& ", -"*=**==*-** ", -";>,,',),,! ", -" ~~{~]~~!! ", -" ^/^^^!!!! ", -" ((__!!!!: ", -" <<[!!!! ", -" }|1!!!} | ", -" !! 23 ", -" 45 ", -" 6777676 ", -" 8898000", -" ab ", -" cd "}; diff --git a/resources/bitmaps/view_change.xpm b/resources/bitmaps/view_change.xpm deleted file mode 100644 index acc7ddc..0000000 --- a/resources/bitmaps/view_change.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * view_change_xpm[] = { -"16 16 26 1", -" c None", -". c #41E5F6", -"+ c #42E5F6", -"@ c #43E4F9", -"# c #44E4F9", -"$ c #46E3FB", -"% c #45E3FC", -"& c #46E3FC", -"* c #47E2FF", -"= c #48E3FE", -"- c #48E2FE", -"; c #47E1FF", -"> c #47E0FF", -", c #45DEFF", -"' c #46DEFF", -") c #43DBFF", -"! c #42D9FF", -"~ c #40D7FF", -"{ c #41D7FF", -"] c #3ED4FF", -"^ c #3FD4FF", -"/ c #3DD2FF", -"( c #3BCFFF", -"_ c #39CDFF", -": c #37CAFF", -"< c #38CAFF", -" ", -" . + ", -" @ # ", -" $ % & ", -" * = - ", -" ; > ; > ", -" , ' , , ", -" ) ", -" !!!!! ! ", -" ~ { ", -" ] ^ ", -" / / ", -" ( ", -" _ ", -" :<<:< ", -" "}; diff --git a/resources/bitmaps/view_clipper.xpm b/resources/bitmaps/view_clipper.xpm deleted file mode 100644 index 6adc047..0000000 --- a/resources/bitmaps/view_clipper.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * view_clipper_xpm[] = { -"16 16 30 1", -" c None", -". c #00CDFF", -"+ c #00CBFF", -"@ c #00CBED", -"# c #00CBEB", -"$ c #00C9F3", -"% c #00C9FF", -"& c #00C9F7", -"* c #00C7F7", -"= c #00C5FD", -"- c #00C7FF", -"; c #00C5FF", -"> c #00C1FF", -", c #00C3FF", -"' c #00BDFF", -") c #00BBFF", -"! c #00B7FF", -"~ c #00B3FF", -"{ c #00B5FF", -"] c #00ADFF", -"^ c #00AFFF", -"/ c #00A9FF", -"( c #00A5FF", -"_ c #00A3FF", -": c #009FFF", -"< c #009BFF", -"[ c #0097FF", -"} c #0095FF", -"| c #0091FF", -"1 c #008FFF", -" ..+", -" @@@#@@@@@@@@+++", -" $ %%%", -" & * ", -" = - ; ", -" > , > ", -" ' ) ", -" ! ! ! ", -" ~ ~ { ", -" ] ^ ", -" / / / ", -" ( ( _ ", -" : : ", -"<<< < ", -"[}}}}}}}}[}}}}} ", -"||1 "}; diff --git a/resources/bitmaps/view_cubicclipping.xpm b/resources/bitmaps/view_cubicclipping.xpm deleted file mode 100644 index 6e26d4b..0000000 --- a/resources/bitmaps/view_cubicclipping.xpm +++ /dev/null @@ -1,39 +0,0 @@ -/* XPM */ -static char * view_cubicclipping_xpm[] = { -"16 16 20 1", -" c None", -". c #41E5F6", -"+ c #C9FFFF", -"@ c #43E4F8", -"# c #CAFFFF", -"$ c #46E3FC", -"% c #48E3FE", -"& c #47E0FF", -"* c #47E1FF", -"= c #45DEFF", -"- c #44DBFF", -"; c #43D9FF", -"> c #C8FFFF", -", c #41D7FF", -"' c #3FD5FF", -") c #C7FFFF", -"! c #3DD2FF", -"~ c #3BD0FF", -"{ c #39CDFF", -"] c #38CAFF", -" ", -" . ", -" +++@ ", -" ###+##$# ", -" #########%## ", -" &*&&&&*&&*### ", -" +###++#+=++ ", -" +++++++-++ ", -" ++++++;++ ", -" >>>>>,>> ", -" >>>>'> ", -" )))!) ", -" ))~) ", -" ){) ", -" ] ", -" "}; diff --git a/resources/bitmaps/view_entity.xpm b/resources/bitmaps/view_entity.xpm deleted file mode 100644 index 64001ab..0000000 --- a/resources/bitmaps/view_entity.xpm +++ /dev/null @@ -1,65 +0,0 @@ -/* XPM */ -static char * view_entity_xpm[] = { -"16 15 47 1", -" c None", -". c #00FFFF", -"+ c #86FFFF", -"@ c #88FFFF", -"# c #11FFFF", -"$ c #8CFFFF", -"% c #8AFFFF", -"& c #15FFFF", -"* c #8EFFFF", -"= c #00C5FD", -"- c #00C7FD", -"; c #00C5FF", -"> c #90FFFF", -", c #19FFFF", -"' c #00FEFF", -") c #17FFFF", -"! c #00FAFF", -"~ c #00BDFF", -"{ c #00F8FF", -"] c #13FFFF", -"^ c #00F4FF", -"/ c #0FFFFF", -"( c #00F0FF", -"_ c #00B3FF", -": c #84FFFF", -"< c #00B5FF", -"[ c #0DFFFF", -"} c #00EAFF", -"| c #80FFFF", -"1 c #82FFFF", -"2 c #00ECFF", -"3 c #09FFFF", -"4 c #00E6FF", -"5 c #7EFFFF", -"6 c #00A9FF", -"7 c #7CFFFF", -"8 c #00ABFF", -"9 c #00E8FF", -"0 c #05FFFF", -"a c #00E2FF", -"b c #7AFFFF", -"c c #78FFFF", -"d c #03FFFF", -"e c #00DCFF", -"f c #76FFFF", -"g c #01FFFF", -"h c #00D8FF", -" ", -" ............ ", -" .+@@+@+++@@.# ", -" .$%$$$$%$$$.& ", -" .*=-=;=->->., ", -" .**********') ", -" !$~~~~~~%~%{] ", -" ^@++@+@@@+@^/ ", -" (+_:___<__:([ ", -" }||||||111|23 ", -" 4566768886590 ", -" abcbbbbbbbbad ", -" effffcffffceg ", -" hhhhhhhhhhhh. ", -" ............ "}; diff --git a/resources/bitmaps/white.xpm b/resources/bitmaps/white.xpm deleted file mode 100644 index 31b56ca..0000000 --- a/resources/bitmaps/white.xpm +++ /dev/null @@ -1,15 +0,0 @@ -/* XPM */ -static char *white[] = { -/* columns rows colors chars-per-pixel */ -"8 8 1 1 ", -" c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/window1.xpm b/resources/bitmaps/window1.xpm deleted file mode 100644 index ae11c6f..0000000 --- a/resources/bitmaps/window1.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window1[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXOOOXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXOXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXOXXXXXXX.", -".XXXOXXXOXXXXXXXXXXoXXXOXXXXXXX.", -".XXXXOXOXXXXXXXXXXXoXXXXOOOXXXX.", -".XXXXXOXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXOXOXXXOXXXOXXXoXXXXXXXXXXX.", -".XXXOXXXOXXOXXXOXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXOXOXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXOXXXXXoooooooooooo.", -".XXXOOOOOXXXXOXXXXXoXXXXXXXXXXX.", -".XXXXXXOXXXXXOXXXXXoXXXXXXXXXXX.", -".XXXXXOXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXOXXXXXXXXXXXXXoXXXOOOOOXXX.", -".XXXOOOOOXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window2.xpm b/resources/bitmaps/window2.xpm deleted file mode 100644 index 14a194e..0000000 --- a/resources/bitmaps/window2.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char *window2[] = { -/* columns rows colors chars-per-pixel */ -"32 32 4 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".X XXX.", -".X XXX.", -".X.XXXXXXXXXXXXXXXXXXXXXXXX.XXX.", -".X.XXXXXXXXXXXXXXXXXX X.", -".X.XXoXXXoXXXXXXXXXXX X.", -".X.XXXoXoXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXXoXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXoXoXXXoXXXoXXXX.XoooooX.X.", -".X.XXoXXXoXXoXXXoXXXX.XXXoXXX.X.", -".X.XXXXXXXXXXoXoXXXXX.XXXoXXX.X.", -".X.XXXXXXXXXXXoXXXXXX.XXXoXXX.X.", -".X.XXoooooXXXXoXXXXXX.XXXoXXX.X.", -".X.XXXXXoXXXXXoXXXXXX.XXXXXXX.X.", -".X.XXXXoXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXoXXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXoooooXXXXXXXXXXX.........X.", -".X.XXXXXXXX XXXXXXX.XXX.", -".X.XXXXXXXX XXXXXXX.XXX.", -".X.XXXXXXXX.XXXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XXoooXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X..........XXoooXX.........XXX.", -".XXXXXXXXXX.XXXXXXX.XXXXXXXXXXX.", -".XXXXXXXXXX.........XXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window3.xpm b/resources/bitmaps/window3.xpm deleted file mode 100644 index c1513c3..0000000 --- a/resources/bitmaps/window3.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window3[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXOOOXXXXXXoXXOXXXOXXXXXXXX.", -".XXXXOXXXXXXXXXoXXXOXOXXXXXXXXX.", -".XXXXOXXXXXXXXXoXXXXOXXXOXXXOXX.", -".XXXXOXXXXXXXXXoXXXOXOXXOXXXOXX.", -".XXXXXOOOXXXXXXoXXOXXXOXXOXOXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XOXXXOXXXXXXXXoXXOXXXOXXXXXXXX.", -".XOXXXOXXXXXXXXoXXXOXOXXXXXXXXX.", -".XXOXOXXOOOOOXXoXXXXOXXXOOOOOXX.", -".XXXOXXXXXXOXXXoXXXOXOXXXXXOXXX.", -".XXXOXXXXXOXXXXoXXOXXXOXXXOXXXX.", -".XXXOXXXXOXXXXXoXXXXXXXXXOXXXXX.", -".XXXXXXXOOOOOXXoXXXXXXXXOOOOOXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window4.xpm b/resources/bitmaps/window4.xpm deleted file mode 100644 index 3336ed5..0000000 --- a/resources/bitmaps/window4.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window4[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXOOOXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXOXXXOXXXXXXXXXX.", -".XXXXOOOXXXXoXXXXOXOXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXOXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXOXOXXXOXXXOXXX.", -".XXXXXXXXXXXoXXXOXXXOXXOXXXOXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXOXOXXXX.", -".ooooooooooooXXXXXXXXXXXXOXXXXX.", -".XXXXXXXXXXXoXXXOOOOOXXXXOXXXXX.", -".XXXXXXXXXXXoXXXXXXOXXXXXOXXXXX.", -".XXXXXXXXXXXoXXXXXOXXXXXXXXXXXX.", -".XXXOOOOOXXXoXXXXOXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXOOOOOXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/ws_icons.xcf b/resources/bitmaps/ws_icons.xcf deleted file mode 100644 index 858c27768ca76ac4ccec21313dc512ea52605c25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109114 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 L86P13 -Brush4Sided=4 -Brush5Sided=5 -Brush6Sided=6 -Brush7Sided=7 -Brush8Sided=8 -Brush9Sided=9 -BrushCone= -BrushPrism= -BrushRock= -BrushSphere= -BuildMenuCustomize= -CSGMakeHollow= -CSGMakeRoom= -CSGMerge=u -CSGSubtract=u -CameraAngleDown=z -CameraAngleUp=a -CameraBack=Down -CameraDown=c -CameraForward=Up -CameraFreeMoveBack=Down -CameraFreeMoveDown=c -CameraFreeMoveForward=Up -CameraFreeMoveLeft=Left -CameraFreeMoveRight=Right -CameraFreeMoveUp=d -CameraLeft=Left -CameraRight=Right -CameraSpeedDec=KP_Subtract -CameraSpeedInc=KP_Add -CameraStrafeLeft=comma -CameraStrafeRight=period -CameraUp=d -CapCurrentCurve=c -CenterView=End -CenterXYView=Tab -ChooseBrushColor= -ChooseCameraBackgroundColor= -ChooseCameraSelectedBrushColor= -ChooseClipperColor= -ChooseGridBackgroundColor= -ChooseGridBlockColor= -ChooseGridMajorColor= -ChooseGridMinorColor= -ChooseGridTextColor= -ChooseOrthoViewNameColor= -ChooseSelectedBrushColor= -ChooseSmallGridMajorColor= -ChooseSmallGridMinorColor= -ChooseTextureBackgroundColor= -ClearPatchOverlays=l -ClipSelected=Return -CloneSelection=space -CloneSelectionAndMakeUnique=space -ColorSchemeBlackAndGreen= -ColorSchemeOriginal= -ColorSchemeQER= -ColorSchemeYdnar= -ConnectSelection=k -Copy=c -CopyTag= -CubicClipZoomIn=bracketleft -CubicClipZoomOut=bracketright -CycleCapTexturePatch=n -DeleteSelection=BackSpace -DeleteTag= -DownFloor=Page_Down -DragEdges=e -DragFaces=f -DragVertices=v -EnableAlpha= -EntityColor=k -EntityList=l -Exit= -ExpandSelectionToEntities=e -ExportSelected= -FaceCopyTexture= -FacePasteTexture= -FilterAreaportals=3 -FilterBotClips=m -FilterCaulk=6 -FilterClips=7 -FilterClusterportals=9 -FilterDecals=d -FilterDetails=d -FilterEntities=2 -FilterFallback= -FilterHintsSkips=h -FilterLightgrid= -FilterLights=0 -FilterLiquids=5 -FilterMissing= -FilterModels=m -FilterPatches=p -FilterPaths=8 -FilterStructural=d -FilterTranslucent=4 -FilterTriggers=t -FilterWorldBrushes=1 -FindBrush= -FindReplaceTextures= -FitTexture=b -FixedSize= -FlipClip=Return -GridDown=bracketleft -GridUp=bracketright -GroupSelection= -HideSelected=h -HideUnselected= -ImportMap= -InvertCurve=i -InvertCurveTextureX=i -InvertCurveTextureY=i -InvertFilters= -InvertSelection=i -KillConnectSelection=k -LookThroughCamera= -LookThroughSelected= -MakeDetail=m -MakeOverlayPatch=y -MakeStructural=s -MapInfo=m -MatrixTranspose=m -MirrorSelectionX= -MirrorSelectionY= -MirrorSelectionZ= -MouseDrag=q -MouseRotate=r -MouseScale= -MouseTranslate=w -MoveSelectionDOWN=KP_Subtract -MoveSelectionUP=KP_Add -NaturalizePatch=n -NewMap= -NextLeakSpot=k -NextView=Tab -NormalizeColor= -OpenMap=o -ParentSelection= -Paste=v -PasteTag= -PasteToCamera=v -PatchBevel= -PatchCone= -PatchCylinder= -PatchDeleteFirstColumn= -PatchDeleteFirstRow=KP_Subtract -PatchDeleteLastColumn=KP_Subtract -PatchDeleteLastRow= -PatchDenseCylinder= -PatchEndCap= -PatchInsertAddColumn= -PatchInsertAddRow= -PatchInsertInsertColumn=KP_Add -PatchInsertInsertRow=KP_Add -PatchInspector=s -PatchSphere= -PatchSquareBevel= -PatchSquareCylinder= -PatchSquareEndcap= -PatchVeryDenseCylinder= -PatchXactCone= -PatchXactCylinder= -PatchXactSphere= -Preferences=p -PrevLeakSpot=l -ProjectSettings= -RedisperseCols=e -RedisperseRows=e -Redo=y -RefreshReferences= -RefreshShaders= -RegionOff= -RegionSetBrush= -RegionSetSelection=r -RegionSetXY= -RenameTag= -ResetFilters= -RotateSelectionX= -RotateSelectionY= -RotateSelectionZ= -SaveMap=s -SaveMapAs= -SaveRegion= -SelectAllOfType=a -SelectInside= -SelectNudgeDown=Down -SelectNudgeLeft=Left -SelectNudgeRight=Right -SelectNudgeUp=Up -SelectTouching= -SetGrid0.125= -SetGrid0.25= -SetGrid0.5= -SetGrid1=1 -SetGrid128=8 -SetGrid16=5 -SetGrid2=2 -SetGrid256=9 -SetGrid32=6 -SetGrid4=3 -SetGrid64=7 -SetGrid8=4 -ShaderInfo= -ShowAllTextures=a -ShowAngles= -ShowAxes= -ShowBlocks= -ShowCoordinates= -ShowHidden=h -ShowInUse=u -ShowNames= -ShowStats= -ShowUntagged= -ShowWindowOutline= -ShowWorkzone= -SimplePatchMesh=p -Sleep=p -SmoothCols=w -SmoothRows=w -SnapToGrid=g -SplitSelected=Return -SurfaceInspector=s -TexRotateClock=Page_Down -TexRotateCounter=Page_Up -TexScaleDown=Down -TexScaleLeft=Left -TexScaleRight=Right -TexScaleUp=Up -TexShiftDown=Down -TexShiftLeft=Left -TexShiftRight=Right -TexShiftUp=Up -TogTexLock=t -ToggleCamera=c -ToggleClipper=x -ToggleConsole=o -ToggleCrosshairs=x -ToggleCubicClip=backslash -ToggleEntityInspector=n -ToggleFrontView= -ToggleGrid=0 -ToggleGridSnap= -TogglePointfile= -ToggleShowShaderlistOnly= -ToggleShowShaders= -ToggleSideView= -ToggleSizePaint=j -ToggleTextures=t -ToggleView=v -UnSelectSelection=Escape -Undo=z -UngroupSelection= -UpFloor=Page_Up -ViewEntityInfo=n -ViewFront=KP_End -ViewSide=KP_Page_Down -ViewTop=KP_Home -Zoom100= -ZoomIn=Delete -ZoomOut=Insert diff --git a/resources/games/goldsrc.game b/resources/games/goldsrc.game deleted file mode 100644 index 22a3a2d..0000000 --- a/resources/games/goldsrc.game +++ /dev/null @@ -1,28 +0,0 @@ - - diff --git a/resources/games/platform.game b/resources/games/platform.game deleted file mode 100644 index 48d85a0..0000000 --- a/resources/games/platform.game +++ /dev/null @@ -1,26 +0,0 @@ - - diff --git a/resources/gl/lighting_DBS_XY_Z_arbfp1.cg b/resources/gl/lighting_DBS_XY_Z_arbfp1.cg deleted file mode 100644 index f535dbb..0000000 --- a/resources/gl/lighting_DBS_XY_Z_arbfp1.cg +++ /dev/null @@ -1,92 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -#include "utils.cg" - -struct cg_vertex2fragment -{ - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(cg_vertex2fragment IN, - uniform sampler2D diffusemap, - uniform sampler2D bumpmap, - uniform sampler2D specularmap, - uniform sampler2D attenuationmap_xy, - uniform sampler2D attenuationmap_z, - uniform float3 view_origin, - uniform float3 light_origin, - uniform float3 light_color, - uniform float bump_scale, - uniform float specular_exponent) -{ - cg_fragment2final OUT; - - // construct object-space-to-tangent-space 3x3 matrix - float3x3 rotation = float3x3(IN.tangent, IN.binormal, IN.normal); - - // compute view direction in tangent space - float3 V = normalize(mul(rotation, view_origin - IN.position.xyz)); - - // compute light direction in tangent space - float3 L = normalize(mul(rotation, (light_origin - IN.position.xyz))); - - // compute half angle in tangent space - float3 H = normalize(L + V); - - // compute normal in tangent space from bumpmap - float3 T = CG_Expand(tex2D(bumpmap, IN.tex_diffuse_bump.zw).xyz); - T.z *= bump_scale; - float3 N = normalize(T); - - // compute the diffuse term - float4 diffuse = tex2D(diffusemap, IN.tex_diffuse_bump.xy); - diffuse.rgb *= light_color * saturate(dot(N, L)); - - // compute the specular term - float3 specular = tex2D(specularmap, IN.tex_specular.xy).rgb * light_color * pow(saturate(dot(N, H)), specular_exponent); - - // compute attenuation - float3 attenuation_xy = tex2Dproj(attenuationmap_xy, float3(IN.tex_atten_xy_z.x, IN.tex_atten_xy_z.y, IN.tex_atten_xy_z.w)).rgb; - float3 attenuation_z = tex2D(attenuationmap_z, float2(IN.tex_atten_xy_z.z, 0)).rgb; - - // compute final color - OUT.color.rgba = diffuse; - OUT.color.rgb += specular; - OUT.color.rgb *= attenuation_xy; - OUT.color.rgb *= attenuation_z; - - return OUT; -} diff --git a/resources/gl/lighting_DBS_XY_Z_arbvp1.cg b/resources/gl/lighting_DBS_XY_Z_arbvp1.cg deleted file mode 100644 index 59a6fc7..0000000 --- a/resources/gl/lighting_DBS_XY_Z_arbvp1.cg +++ /dev/null @@ -1,78 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : POSITION; - float4 tex0 : ATTR8; - - float3 tangent : ATTR9; - float3 binormal : ATTR10; - float3 normal : ATTR11; -}; - -struct cg_vertex2fragment -{ - float4 hposition : POSITION; - - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.hposition = mul(glstate.matrix.mvp, IN.position); - - // assign position in object space - OUT.position = IN.position; - - // transform texcoords - OUT.tex_diffuse_bump.xy = mul(glstate.matrix.texture[0], IN.tex0).xy; - - // transform texcoords - OUT.tex_diffuse_bump.zw = mul(glstate.matrix.texture[1], IN.tex0).xy; - - // transform texcoords - OUT.tex_specular = mul(glstate.matrix.texture[2], IN.tex0); - - // transform vertex position into light space - OUT.tex_atten_xy_z = mul(glstate.matrix.texture[3], IN.position); - - // assign tangent space vectors - OUT.tangent = IN.tangent; - OUT.binormal = IN.binormal; - OUT.normal = IN.normal; - - return OUT; -} diff --git a/resources/gl/lighting_DBS_omni_fp.glp b/resources/gl/lighting_DBS_omni_fp.glp deleted file mode 100644 index 88dab8d..0000000 --- a/resources/gl/lighting_DBS_omni_fp.glp +++ /dev/null @@ -1,86 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbfp1.cg -# source file: ..\..\setup\data\tools\gl/utils.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.diffusemap -#semantic main.bumpmap -#semantic main.specularmap -#semantic main.attenuationmap_xy -#semantic main.attenuationmap_z -#semantic main.view_origin -#semantic main.light_origin -#semantic main.light_color -#semantic main.bump_scale -#semantic main.specular_exponent -#var float4 IN.position : $vin.TEX0 : TEX0 : 0 : 1 -#var float4 IN.tex_diffuse_bump : $vin.TEX1 : TEX1 : 0 : 1 -#var float4 IN.tex_specular : $vin.TEX2 : TEX2 : 0 : 1 -#var float4 IN.tex_atten_xy_z : $vin.TEX3 : TEX3 : 0 : 1 -#var float3 IN.tangent : $vin.TEX4 : TEX4 : 0 : 1 -#var float3 IN.binormal : $vin.TEX5 : TEX5 : 0 : 1 -#var float3 IN.normal : $vin.TEX6 : TEX6 : 0 : 1 -#var sampler2D diffusemap : : texunit 0 : 1 : 1 -#var sampler2D bumpmap : : texunit 1 : 2 : 1 -#var sampler2D specularmap : : texunit 2 : 3 : 1 -#var sampler2D attenuationmap_xy : : texunit 3 : 4 : 1 -#var sampler2D attenuationmap_z : : texunit 4 : 5 : 1 -#var float3 view_origin : : c[4] : 6 : 1 -#var float3 light_origin : : c[2] : 7 : 1 -#var float3 light_color : : c[3] : 8 : 1 -#var float bump_scale : : c[1] : 9 : 1 -#var float specular_exponent : : c[5] : 10 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0.5 2 0 -PARAM c[6] = { { 0.5, 2, 0 }, - program.local[1..5] }; -TEMP R0; -TEMP R1; -TEMP R2; -ADD R1.xyz, -fragment.texcoord[0], c[2]; -DP3 R0.z, fragment.texcoord[6], R1; -DP3 R0.x, fragment.texcoord[4], R1; -DP3 R0.y, fragment.texcoord[5], R1; -ADD R1.xyz, -fragment.texcoord[0], c[4]; -DP3 R0.w, R0, R0; -DP3 R2.z, fragment.texcoord[6], R1; -DP3 R2.x, fragment.texcoord[4], R1; -DP3 R2.y, fragment.texcoord[5], R1; -RSQ R0.w, R0.w; -MUL R1.xyz, R0.w, R0; -DP3 R1.w, R2, R2; -RSQ R0.w, R1.w; -MUL R2.xyz, R0.w, R2; -ADD R2.xyz, R1, R2; -DP3 R0.w, R2, R2; -RSQ R2.w, R0.w; -TEX R0.xyz, fragment.texcoord[1].zwzw, texture[1], 2D; -ADD R0.xyz, R0, -c[0].x; -MUL R0.xyz, R0, c[0].y; -MUL R0.z, R0, c[1].x; -DP3 R1.w, R0, R0; -RSQ R0.w, R1.w; -MUL R0.xyz, R0.w, R0; -MUL R2.xyz, R2.w, R2; -DP3_SAT R0.w, R0, R2; -DP3_SAT R0.x, R0, R1; -TEX R2.xyz, fragment.texcoord[2], texture[2], 2D; -MUL R1.xyz, R2, c[3]; -POW R0.w, R0.w, c[5].x; -MUL R2.xyz, R1, R0.w; -MUL R1.xyz, R0.x, c[3]; -TEX R0, fragment.texcoord[1], texture[0], 2D; -MAD R2.xyz, R0, R1, R2; -TXP R0.xyz, fragment.texcoord[3], texture[3], 2D; -MOV R1.y, c[0].z; -MOV R1.x, fragment.texcoord[3].z; -TEX R1.xyz, R1, texture[4], 2D; -MUL R0.xyz, R2, R0; -MUL result.color.xyz, R0, R1; -MOV result.color.w, R0; -END -# 41 instructions, 3 R-regs diff --git a/resources/gl/lighting_DBS_omni_fp.glsl b/resources/gl/lighting_DBS_omni_fp.glsl deleted file mode 100644 index 7f80fea..0000000 --- a/resources/gl/lighting_DBS_omni_fp.glsl +++ /dev/null @@ -1,73 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -uniform sampler2D u_diffusemap; -uniform sampler2D u_bumpmap; -uniform sampler2D u_specularmap; -uniform sampler2D u_attenuationmap_xy; -uniform sampler2D u_attenuationmap_z; -uniform vec3 u_view_origin; -uniform vec3 u_light_origin; -uniform vec3 u_light_color; -uniform float u_bump_scale; -uniform float u_specular_exponent; - -varying vec3 var_vertex; -varying vec4 var_tex_diffuse_bump; -varying vec2 var_tex_specular; -varying vec4 var_tex_atten_xy_z; -varying mat3 var_mat_os2ts; - -void main() -{ - // compute view direction in tangent space - vec3 V = normalize(var_mat_os2ts * (u_view_origin - var_vertex)); - - // compute light direction in tangent space - vec3 L = normalize(var_mat_os2ts * (u_light_origin - var_vertex)); - - // compute half angle in tangent space - vec3 H = normalize(L + V); - - // compute normal in tangent space from bumpmap - vec3 N = 2.0 * (texture2D(u_bumpmap, var_tex_diffuse_bump.pq).xyz - 0.5); - N.z *= u_bump_scale; - N = normalize(N); - - // compute the diffuse term - vec4 diffuse = texture2D(u_diffusemap, var_tex_diffuse_bump.st); - diffuse.rgb *= u_light_color * clamp(dot(N, L), 0.0, 1.0); - - // compute the specular term - vec3 specular = texture2D(u_specularmap, var_tex_specular).rgb * u_light_color * pow(clamp(dot(N, H), 0.0, 1.0), u_specular_exponent); - - // compute attenuation - vec3 attenuation_xy = texture2DProj(u_attenuationmap_xy, vec3(var_tex_atten_xy_z.x, var_tex_atten_xy_z.y, var_tex_atten_xy_z.w)).rgb; - vec3 attenuation_z = texture2D(u_attenuationmap_z, vec2(var_tex_atten_xy_z.z, 0)).rgb; - - // compute final color - gl_FragColor.rgba = diffuse; - gl_FragColor.rgb += specular; - gl_FragColor.rgb *= attenuation_xy; - gl_FragColor.rgb *= attenuation_z; -} - diff --git a/resources/gl/lighting_DBS_omni_vp.glp b/resources/gl/lighting_DBS_omni_vp.glp deleted file mode 100644 index b4472d7..0000000 --- a/resources/gl/lighting_DBS_omni_vp.glp +++ /dev/null @@ -1,410 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : c[8], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : c[12], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : c[16], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.POSITION : POSITION : 0 : 1 -#var float4 IN.tex0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float3 IN.tangent : $vin.ATTR9 : ATTR9 : 0 : 1 -#var float3 IN.binormal : $vin.ATTR10 : ATTR10 : 0 : 1 -#var float3 IN.normal : $vin.ATTR11 : ATTR11 : 0 : 1 -#var float4 main.hposition : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.position : $vout.TEX0 : TEX0 : -1 : 1 -#var float4 main.tex_diffuse_bump : $vout.TEX1 : TEX1 : -1 : 1 -#var float4 main.tex_specular : $vout.TEX2 : TEX2 : -1 : 1 -#var float4 main.tex_atten_xy_z : $vout.TEX3 : TEX3 : -1 : 1 -#var float3 main.tangent : $vout.TEX4 : TEX4 : -1 : 1 -#var float3 main.binormal : $vout.TEX5 : TEX5 : -1 : 1 -#var float3 main.normal : $vout.TEX6 : TEX6 : -1 : 1 -PARAM c[20] = { state.matrix.mvp, - state.matrix.texture[0], - state.matrix.texture[1], - state.matrix.texture[2], - state.matrix.texture[3] }; -TEMP R0; -DP4 result.position.w, vertex.position, c[3]; -DP4 result.position.z, vertex.position, c[2]; -DP4 result.position.y, vertex.position, c[1]; -DP4 result.position.x, vertex.position, c[0]; -DP4 R0.y, vertex.attrib[8], c[9]; -DP4 R0.x, vertex.attrib[8], c[8]; -MOV result.texcoord[0], vertex.position; -MOV result.texcoord[1].zw, R0.xyxy; -DP4 result.texcoord[1].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[1].x, vertex.attrib[8], c[4]; -DP4 result.texcoord[2].w, vertex.attrib[8], c[15]; -DP4 result.texcoord[2].z, vertex.attrib[8], c[14]; -DP4 result.texcoord[2].y, vertex.attrib[8], c[13]; -DP4 result.texcoord[2].x, vertex.attrib[8], c[12]; -DP4 result.texcoord[3].w, vertex.position, c[19]; -DP4 result.texcoord[3].z, vertex.position, c[18]; -DP4 result.texcoord[3].y, vertex.position, c[17]; -DP4 result.texcoord[3].x, vertex.position, c[16]; -MOV result.texcoord[4].xyz, vertex.attrib[9]; -MOV result.texcoord[5].xyz, vertex.attrib[10]; -MOV result.texcoord[6].xyz, vertex.attrib[11]; -END -# 21 instructions, 1 R-regs diff --git a/resources/gl/lighting_DBS_omni_vp.glsl b/resources/gl/lighting_DBS_omni_vp.glsl deleted file mode 100644 index 6900b5a..0000000 --- a/resources/gl/lighting_DBS_omni_vp.glsl +++ /dev/null @@ -1,58 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -attribute vec4 attr_TexCoord0; -attribute vec3 attr_Tangent; -attribute vec3 attr_Binormal; - -varying vec3 var_vertex; -varying vec4 var_tex_diffuse_bump; -varying vec2 var_tex_specular; -varying vec4 var_tex_atten_xy_z; -varying mat3 var_mat_os2ts; - -void main() -{ - // transform vertex position into homogenous clip-space - gl_Position = ftransform(); - - // assign position in object space - var_vertex = gl_Vertex.xyz; - - // transform texcoords into diffusemap texture space - var_tex_diffuse_bump.st = (gl_TextureMatrix[0] * attr_TexCoord0).st; - - // transform texcoords into bumpmap texture space - var_tex_diffuse_bump.pq = (gl_TextureMatrix[1] * attr_TexCoord0).st; - - // transform texcoords into specularmap texture space - var_tex_specular = (gl_TextureMatrix[2] * attr_TexCoord0).st; - - // calc light xy,z attenuation in light space - var_tex_atten_xy_z = gl_TextureMatrix[3] * gl_Vertex; - - - // construct object-space-to-tangent-space 3x3 matrix - var_mat_os2ts = mat3( attr_Tangent.x, attr_Binormal.x, gl_Normal.x, - attr_Tangent.y, attr_Binormal.y, gl_Normal.y, - attr_Tangent.z, attr_Binormal.z, gl_Normal.z ); -} diff --git a/resources/gl/utils.cg b/resources/gl/utils.cg deleted file mode 100644 index 63bfcb6..0000000 --- a/resources/gl/utils.cg +++ /dev/null @@ -1,36 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -// fresnel approximation -float fast_fresnel(float3 I, float3 N, float3 fresnel_values) -{ - float power = fresnel_values.x; - float scale = fresnel_values.y; - float bias = fresnel_values.z; - - return bias + pow(1.0 - dot(I, N), power) * scale; -} - -float3 CG_Expand(float3 v) -{ - return (v - 0.5) * 2; // expand a range-compressed vector -} diff --git a/resources/gl/zfill_arbfp1.cg b/resources/gl/zfill_arbfp1.cg deleted file mode 100644 index c80189c..0000000 --- a/resources/gl/zfill_arbfp1.cg +++ /dev/null @@ -1,47 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(in cg_vertex2fragment IN, - uniform sampler2D colormap) -{ - cg_fragment2final OUT; - - OUT.color.w = tex2D(colormap, IN.tex0.xy).a; - - OUT.color.xyz = 0; - - return OUT; -} diff --git a/resources/gl/zfill_arbvp1.cg b/resources/gl/zfill_arbvp1.cg deleted file mode 100644 index 4ffc6e2..0000000 --- a/resources/gl/zfill_arbvp1.cg +++ /dev/null @@ -1,49 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : ATTR0; - float4 texcoord0 : ATTR8; -}; - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.position = mul(glstate.matrix.mvp, IN.position); - - // transform texcoords into 1st texture space - OUT.tex0 = mul(glstate.matrix.texture[0], IN.texcoord0); - - return OUT; -} diff --git a/resources/gl/zfill_fp.glp b/resources/gl/zfill_fp.glp deleted file mode 100644 index 5eb8b12..0000000 --- a/resources/gl/zfill_fp.glp +++ /dev/null @@ -1,19 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbfp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.colormap -#var float4 IN.position : : : 0 : 0 -#var float4 IN.tex0 : $vin.TEX0 : TEX0 : 0 : 1 -#var sampler2D colormap : : texunit 0 : 1 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0 -PARAM c[1] = { { 0 } }; -MOV result.color.xyz, c[0].x; -TEX result.color.w, fragment.texcoord[0], texture[0], 2D; -END -# 2 instructions, 0 R-regs diff --git a/resources/gl/zfill_fp.glsl b/resources/gl/zfill_fp.glsl deleted file mode 100644 index 537db67..0000000 --- a/resources/gl/zfill_fp.glsl +++ /dev/null @@ -1,29 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -uniform sampler2D u_colormap; - -void main() -{ - gl_FragColor.a = texture2D(u_colormap, gl_TexCoord[0].st).a; - gl_FragColor.rgb = vec3(0.0, 0.0, 0.0); -} diff --git a/resources/gl/zfill_vp.glp b/resources/gl/zfill_vp.glp deleted file mode 100644 index f6eda0c..0000000 --- a/resources/gl/zfill_vp.glp +++ /dev/null @@ -1,384 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.ATTR0 : ATTR0 : 0 : 1 -#var float4 IN.texcoord0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float4 main.position : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.tex0 : $vout.TEX0 : TEX0 : -1 : 1 -PARAM c[8] = { state.matrix.mvp, - state.matrix.texture[0] }; -DP4 result.position.w, vertex.attrib[0], c[3]; -DP4 result.position.z, vertex.attrib[0], c[2]; -DP4 result.position.y, vertex.attrib[0], c[1]; -DP4 result.position.x, vertex.attrib[0], c[0]; -DP4 result.texcoord[0].w, vertex.attrib[8], c[7]; -DP4 result.texcoord[0].z, vertex.attrib[8], c[6]; -DP4 result.texcoord[0].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[0].x, vertex.attrib[8], c[4]; -END -# 8 instructions, 0 R-regs diff --git a/resources/gl/zfill_vp.glsl b/resources/gl/zfill_vp.glsl deleted file mode 100644 index 4c81280..0000000 --- a/resources/gl/zfill_vp.glsl +++ /dev/null @@ -1,35 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -attribute vec4 attr_TexCoord0; - -void main() -{ - // transform vertex position into homogenous clip-space - gl_Position = ftransform(); - - // transform texcoords - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - - // assign color - gl_FrontColor = gl_Color; -} diff --git a/resources/goldsrc.game/default_build_menu.xml b/resources/goldsrc.game/default_build_menu.xml deleted file mode 100644 index 3c1637e..0000000 --- a/resources/goldsrc.game/default_build_menu.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - -"[RadiantPath]vmap" -v -connect [MonitorAddress] -game platform -fs_basepath "[EnginePath]" -fs_game [GameName] - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" -[vmap] -light -custinfoparms -v -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis "[MapFile]" -[vmap] -light -custinfoparms -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - - - diff --git a/resources/platform.game/default_build_menu.xml b/resources/platform.game/default_build_menu.xml deleted file mode 100644 index 3c1637e..0000000 --- a/resources/platform.game/default_build_menu.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - -"[RadiantPath]vmap" -v -connect [MonitorAddress] -game platform -fs_basepath "[EnginePath]" -fs_game [GameName] - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" -[vmap] -light -custinfoparms -v -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis "[MapFile]" -[vmap] -light -custinfoparms -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - - - diff --git a/src/Makefile b/src/Makefile index 81c14ec..37a58f1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,221 +1,157 @@ -# WorldSpawn Makefile +# vmap Makefile -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GTK_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) +# ws libs vmap uses +LIBOBJS=../libs/libddslib.a \ + ../libs/libetclib.a \ + ../libs/libfilematch.a \ + ../libs/libl_net.a \ + ../libs/libmathlib.a \ + ../libs/libpicomodel.a GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -GLIB_LDLAGS=$(shell pkg-config --libs glib-2.0) +GLIB_LDFLAGS=$(shell pkg-config --libs glib-2.0) XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) XML_LDFLAGS=$(shell pkg-config --libs libxml-2.0) -GLEXT_CFLAGS=$(shell pkg-config --cflags gtkglext-1.0) -GLEXT_LDFLAGS=$(shell pkg-config --libs gtkglext-1.0) +MINIZIP_CFLAGS=$(shell pkg-config --cflags minizip) +MINIZIP_LDFLAGS=$(shell pkg-config --libs minizip) -PANGO_CFLAGS=$(shell pkg-config --cflags pango) -PANGO_LDFLAGS=$(shell pkg-config --libs pango) +JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) +JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) -PANGOFT2_CFLAGS=$(shell pkg-config --cflags pangoft2) -PANGOFT2_LDFLAGS=$(shell pkg-config --libs pangoft2) +PNG_CFLAGS=$(shell pkg-config --cflags libpng) +PNG_LDFLAGS=$(shell pkg-config --libs libpng) -WS_LIBS= ../libs/libcmdlib.a \ - ../libs/libcontainer.a \ - ../libs/libddslib.a \ - ../libs/libdebugging.a \ - ../libs/libetclib.a \ - ../libs/libgeneric.a \ - ../libs/libgtkutil.a \ - ../libs/libl_net.a \ - ../libs/libmath.a \ - ../libs/libmathlib.a \ - ../libs/libmodulesystem.a \ - ../libs/libos.a \ - ../libs/libpicomodel.a \ - ../libs/libprofile.a \ - ../libs/libscript.a \ - ../libs/libsignal.a \ - ../libs/libsplines.a \ - ../libs/libstream.a \ - ../libs/libstring.a \ - ../libs/libuilib.a \ - ../libs/libxmllib.a +VMAP_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(MINIZIP_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) -I../include -I../common -I../libs +VMAP_LDFLAGS=$(LDFLAGS) -lm -lpthread -L../lib $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(MINIZIP_LDFLAGS) $(JPEG_LDFLAGS) $(PNG_LDFLAGS) -WS_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(XML_CFLAGS) $(GLEXT_CFLAGS) -I../include -I../libs -DGTK_TARGET=2 $(WS_VERSION) -WS_LDFLAGS=$(LDFLAGS) -lm $(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(PANGO_LDFLAGS) $(PANGOFT2_LDFLAGS) $(GLEXT_LDFLAGS) -L../lib +DO_CC=$(CC) $(VMAP_CFLAGS) -o $@ -c $< -DO_CXX=$(CXX) $(WS_CFLAGS) -o $@ -c $< +.c.o: + $(DO_CC) -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - autosave.o \ +VMAP_OBJS = \ + ../common/cmdlib.o \ + ../common/imagelib.o \ + ../common/inout.o \ + ../common/jpeg.o \ + ../common/md4.o \ + ../common/mutex.o \ + ../common/polylib.o \ + ../common/scriplib.o \ + ../common/matlib.o \ + ../common/threads.o \ + ../common/vfs.o \ brush.o \ brush_primit.o \ - brushmanip.o \ - brushmodule.o \ - brushnode.o \ - brushtokens.o \ - brushxml.o \ - build.o \ - camwindow.o \ - commands.o \ - console.o \ - csg.o \ - dialog.o \ - eclass.o \ - eclass_def.o \ - eclass_doom3.o \ - eclass_fgd.o \ - eclass_xml.o \ - entity.o \ - entityinspector.o \ - entitylist.o \ - environment.o \ - error.o \ - feedback.o \ - filetypes.o \ - filters.o \ - findtexturedialog.o \ - glwidget.o \ - grid.o \ - groupdialog.o \ - gtkdlgs.o \ - gtkmisc.o \ + bsp.o \ + bsp_analyze.o \ + bsp_info.o \ + bsp_scale.o \ + bspfile_abstract.o \ + bspfile_ibsp.o \ + bspfile_rbsp.o \ + convert_ase.o \ + convert_bsp.o \ + convert_map.o \ + convert_obj.o \ + decals.o \ + exportents.o \ + facebsp.o \ + fixaas.o \ + fog.o \ help.o \ image.o \ + leakfile.o \ + light.o \ + light_bounce.o \ + light_trace.o \ + light_ydnar.o \ + lightmaps_ydnar.o \ main.o \ - mainframe.o \ - multimon.o \ map.o \ - mru.o \ - nullmodel.o \ - parse.o \ + mesh.o \ + model.o \ patch.o \ - patchdialog.o \ - patchmanip.o \ - patchmodule.o \ - plugin.o \ - pluginapi.o \ - pluginmanager.o \ - pluginmenu.o \ - plugintoolbar.o \ - points.o \ - preferencedictionary.o \ - preferences.o \ - qe3.o \ - qgl.o \ - referencecache.o \ - renderer.o \ - renderstate.o \ - scenegraph.o \ - select.o \ - selection.o \ - server.o \ + path_init.o \ + portals.o \ + prtfile.o \ shaders.o \ - sockets.o \ - stacktrace.o \ - surfacedialog.o \ - texmanip.o \ - textureentry.o \ - textures.o \ - texwindow.o \ - timer.o \ - treemodel.o \ - undo.o \ - url.o \ - view.o \ - watchbsp.o \ - winding.o \ - windowobservers.o \ - xmlstuff.o \ - xywindow.o + surface.o \ + surface_extra.o \ + surface_foliage.o \ + surface_fur.o \ + surface_meta.o \ + tjunction.o \ + tree.o \ + vis.o \ + visflow.o \ + writebsp.o # binary target -../build/worldspawn: $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(WS_LIBS) $(WS_LDFLAGS) +../vmap: $(VMAP_OBJS) + $(CXX) -o $@ $(VMAP_OBJS) $(LIBOBJS) $(VMAP_LDFLAGS) clean: - -rm -f *.o ../build/worldspawn + -rm -f ./../common/*.o + -rm -f ./*.o + -rm -f ../vmap # object files -autosave.o: autosave.cpp autosave.h -brush.o: brush.cpp brush.h -brush_primit.o: brush_primit.cpp brush_primit.h -brushmanip.o: brushmanip.cpp brushmanip.h -brushmodule.o: brushmodule.cpp brushmodule.h -brushnode.o: brushnode.cpp brushnode.h -brushtokens.o: brushtokens.cpp brushtokens.h -brushxml.o: brushxml.cpp brushxml.h -build.o: build.cpp build.h -camwindow.o: camwindow.cpp camwindow.h -commands.o: commands.cpp commands.h -console.o: console.cpp console.h -csg.o: csg.cpp csg.h -dialog.o: dialog.cpp dialog.h -eclass.o: eclass.cpp eclass.h -eclass_def.o: eclass_def.cpp eclass_def.h -eclass_doom3.o: eclass_doom3.cpp eclass_doom3.h -eclass_fgd.o: eclass_fgd.cpp eclass_fgd.h -eclass_xml.o: eclass_xml.cpp eclass_xml.h -entity.o: entity.cpp entity.h -entityinspector.o: entityinspector.cpp entityinspector.h -entitylist.o: entitylist.cpp entitylist.h -environment.o: environment.cpp environment.h -error.o: error.cpp error.h -feedback.o: feedback.cpp feedback.h -filetypes.o: filetypes.cpp filetypes.h -filters.o: filters.cpp filters.h -findtexturedialog.o: findtexturedialog.cpp findtexturedialog.h -glwidget.o: glwidget.cpp glwidget.h -grid.o: grid.cpp grid.h -groupdialog.o: groupdialog.cpp groupdialog.h -gtkdlgs.o: gtkdlgs.cpp gtkdlgs.h -gtkmisc.o: gtkmisc.cpp gtkmisc.h -help.o: help.cpp help.h -image.o: image.cpp image.h -main.o: main.cpp main.h -mainframe.o: mainframe.cpp mainframe.h -map.o: map.cpp map.h -mru.o: mru.cpp mru.h -nullmodel.o: nullmodel.cpp nullmodel.h -parse.o: parse.cpp parse.h -patch.o: patch.cpp patch.h -patchdialog.o: patchdialog.cpp patchdialog.h -patchmanip.o: patchmanip.cpp patchmanip.h -patchmodule.o: patchmodule.cpp patchmodule.h -plugin.o: plugin.cpp plugin.h -pluginapi.o: pluginapi.cpp pluginapi.h -pluginmanager.o: pluginmanager.cpp pluginmanager.h -pluginmenu.o: pluginmenu.cpp pluginmenu.h -plugintoolbar.o: plugintoolbar.cpp plugintoolbar.h -points.o: points.cpp points.h -preferencedictionary.o: preferencedictionary.cpp preferencedictionary.h -preferences.o: preferences.cpp preferences.h -qe3.o: qe3.cpp qe3.h -qgl.o: qgl.cpp qgl.h -referencecache.o: referencecache.cpp referencecache.h -renderer.o: renderer.cpp renderer.h -renderstate.o: renderstate.cpp renderstate.h -scenegraph.o: scenegraph.cpp scenegraph.h -select.o: select.cpp select.h -selection.o: selection.cpp selection.h -server.o: server.cpp server.h -shaders.o: shaders.cpp shaders.h -sockets.o: sockets.cpp sockets.h -stacktrace.o: stacktrace.cpp stacktrace.h -surfacedialog.o: surfacedialog.cpp surfacedialog.h -texmanip.o: texmanip.cpp texmanip.h -textureentry.o: textureentry.cpp textureentry.h -textures.o: textures.cpp textures.h -texwindow.o: texwindow.cpp texwindow.h -timer.o: timer.cpp timer.h -treemodel.o: treemodel.cpp treemodel.h -undo.o: undo.cpp undo.h -url.o: url.cpp url.h -view.o: view.cpp view.h -watchbsp.o: watchbsp.cpp watchbsp.h -winding.o: winding.cpp winding.h -windowobservers.o: windowobservers.cpp windowobservers.h -xmlstuff.o: xmlstuff.cpp xmlstuff.h -xywindow.o: xywindow.cpp xywindow.h +../common/cmdlib.o: ../common/cmdlib.c ../common/cmdlib.h +../common/imagelib.o: ../common/imagelib.c ../common/imagelib.h +../common/inout.o: ../common/inout.c ../common/inout.h +../common/jpeg.o: ../common/jpeg.c +../common/md4.o: ../common/md4.c ../common/md4.h +../common/mutex.o: ../common/mutex.c ../common/mutex.h +../common/polylib.o: ../common/polylib.c ../common/polylib.h +../common/scriplib.o: ../common/scriplib.c ../common/scriplib.h +../common/matlib.o: ../common/matlib.c ../common/matlib.h +../common/threads.o: ../common/threads.c +../common/vfs.o: ../common/vfs.c ../common/vfs.h +brush.o: brush.c +brush_primit.o: brush_primit.c +bsp.o: bsp.c +bsp_analyze.o: bsp_analyze.c +bsp_info.o: bsp_info.c +bsp_scale.o: bsp_scale.c +bspfile_abstract.o: bspfile_abstract.c +bspfile_ibsp.o: bspfile_ibsp.c +bspfile_rbsp.o: bspfile_rbsp.c +convert_ase.o: convert_ase.c +convert_bsp.o: convert_bsp.c +convert_map.o: convert_map.c +convert_obj.o: convert_obj.c +decals.o: decals.c +exportents.o: exportents.c +facebsp.o: facebsp.c +fixaas.o: fixaas.c +fog.o: fog.c +help.o: help.c +image.o: image.c +leakfile.o: leakfile.c +light.o: light.c +light_bounce.o: light_bounce.c +light_trace.o: light_trace.c +light_ydnar.o: light_ydnar.c +lightmaps_ydnar.o: lightmaps_ydnar.c +main.o: main.c +map.o: map.c +mesh.o: mesh.c +model.o: model.c +patch.o: patch.c +path_init.o: path_init.c +portals.o: portals.c +prtfile.o: prtfile.c +shaders.o: shaders.c +surface.o: surface.c +surface_extra.o: surface_extra.c +surface_foliage.o: surface_foliage.c +surface_fur.o: surface_fur.c +surface_meta.o: surface_meta.c +tjunction.o: tjunction.c +tree.o: tree.c +vis.o: vis.c +visflow.o: visflow.c +writebsp.o: writebsp.c diff --git a/src/autosave.cpp b/src/autosave.cpp deleted file mode 100644 index 29f7d90..0000000 --- a/src/autosave.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "autosave.h" -#include "globaldefs.h" - -#include "os/file.h" -#include "os/path.h" -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "scenelib.h" -#include "mapfile.h" - -#include "map.h" -#include "mainframe.h" -#include "qe3.h" -#include "preferences.h" - - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - - -bool DoesFileExist(const char *name, std::size_t &size) -{ - if (file_exists(name)) { - size += file_size(name); - return true; - } - return false; -} - -void Map_Snapshot() -{ - // we need to do the following - // 1. make sure the snapshot directory exists (create it if it doesn't) - // 2. find out what the lastest save is based on number - // 3. inc that and save the map - const char *path = Map_Name(g_map); - const char *name = path_get_filename_start(path); - - StringOutputStream snapshotsDir(256); - snapshotsDir << StringRange(path, name) << "snapshots"; - - if (file_exists(snapshotsDir.c_str()) || Q_mkdir(snapshotsDir.c_str())) { - std::size_t lSize = 0; - StringOutputStream strNewPath(256); - strNewPath << snapshotsDir.c_str() << '/' << name; - - StringOutputStream snapshotFilename(256); - - for (int nCount = 0;; ++nCount) { - // The original map's filename is "/." - // The snapshot's filename will be "/snapshots/.." - const char *end = path_get_filename_base_end(strNewPath.c_str()); - snapshotFilename << StringRange(strNewPath.c_str(), end) << '.' << nCount << end; - - if (!DoesFileExist(snapshotFilename.c_str(), lSize)) { - break; - } - - snapshotFilename.clear(); - } - - // save in the next available slot - Map_SaveFile(snapshotFilename.c_str()); - - if (lSize > 50 * 1024 * 1024) { // total size of saves > 50 mb - globalOutputStream() << "The snapshot files in " << snapshotsDir.c_str() - << " total more than 50 megabytes. You might consider cleaning up."; - } - } else { - StringOutputStream strMsg(256); - strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str(); - ui::alert(MainFrame_getWindow(), strMsg.c_str()); - } -} - -/* - =============== - QE_CheckAutoSave - - If five minutes have passed since making a change - and the map hasn't been saved, save it out. - =============== - */ - -bool g_AutoSave_Enabled = true; -int m_AutoSave_Frequency = 5; -bool g_SnapShots_Enabled = false; - -namespace { -time_t s_start = 0; -std::size_t s_changes = 0; -} - -void AutoSave_clear() -{ - s_changes = 0; -} - -scene::Node &Map_Node() -{ - return GlobalSceneGraph().root(); -} - -void QE_CheckAutoSave(void) -{ - if (!Map_Valid(g_map) || !ScreenUpdates_Enabled()) { - return; - } - - time_t now; - time(&now); - - if (s_start == 0 || s_changes == Node_getMapFile(Map_Node())->changes()) { - s_start = now; - } - - if ((now - s_start) > (60 * m_AutoSave_Frequency)) { - s_start = now; - s_changes = Node_getMapFile(Map_Node())->changes(); - - if (g_AutoSave_Enabled) { - const char *strMsg = g_SnapShots_Enabled ? "Autosaving snapshot..." : "Autosaving..."; - globalOutputStream() << strMsg << "\n"; - //Sys_Status(strMsg); - - // only snapshot if not working on a default map - if (g_SnapShots_Enabled && !Map_Unnamed(g_map)) { - Map_Snapshot(); - } else { - if (Map_Unnamed(g_map)) { - StringOutputStream autosave(256); - autosave << g_qeglobals.m_userGamePath.c_str() << "maps/"; - Q_mkdir(autosave.c_str()); - autosave << "autosave.map"; - Map_SaveFile(autosave.c_str()); - } else { - const char *name = Map_Name(g_map); - const char *extension = path_get_filename_base_end(name); - StringOutputStream autosave(256); - autosave << StringRange(name, extension) << ".autosave" << extension; - Map_SaveFile(autosave.c_str()); - } - } - } else { - globalOutputStream() << "Autosave skipped...\n"; - //Sys_Status ("Autosave skipped..."); - } - } -} - -void Autosave_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton autosave_enabled = page.appendCheckBox("Autosave", "Enable Autosave", g_AutoSave_Enabled); - ui::SpinButton autosave_frequency = page.appendSpinner("Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 1, - 60); - Widget_connectToggleDependency(autosave_frequency, autosave_enabled); - page.appendCheckBox("", "Save Snapshots", g_SnapShots_Enabled); -} - -void Autosave_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Autosave", "Autosave Preferences")); - Autosave_constructPreferences(page); -} - -void Autosave_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Autosave_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void Autosave_Construct() -{ - GlobalPreferenceSystem().registerPreference("Autosave", make_property_string(g_AutoSave_Enabled)); - GlobalPreferenceSystem().registerPreference("AutosaveMinutes", make_property_string(m_AutoSave_Frequency)); - GlobalPreferenceSystem().registerPreference("Snapshots", make_property_string(g_SnapShots_Enabled)); - - Autosave_registerPreferencesPage(); -} - -void Autosave_Destroy() -{ -} diff --git a/src/autosave.h b/src/autosave.h deleted file mode 100644 index e7dc00e..0000000 --- a/src/autosave.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_AUTOSAVE_H ) -#define INCLUDED_AUTOSAVE_H - -extern bool g_SnapShots_Enabled; - -void AutoSave_clear(); - -void QE_CheckAutoSave(void); - -void Map_Snapshot(); - -void Autosave_Construct(); - -void Autosave_Destroy(); - - -#endif diff --git a/tools/vmap/brush.c b/src/brush.c similarity index 100% rename from tools/vmap/brush.c rename to src/brush.c diff --git a/src/brush.cpp b/src/brush.cpp deleted file mode 100644 index ed3f3c8..0000000 --- a/src/brush.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brush.h" -#include "signal/signal.h" - -Signal0 g_brushTextureChangedCallbacks; - -void Brush_addTextureChangedCallback(const SignalHandler &handler) -{ - g_brushTextureChangedCallbacks.connectLast(handler); -} - -void Brush_textureChanged() -{ - g_brushTextureChangedCallbacks(); -} - -QuantiseFunc Face::m_quantise; -EBrushType Face::m_type; -EBrushType FacePlane::m_type; -bool g_brush_texturelock_enabled = true; - -EBrushType Brush::m_type; -double Brush::m_maxWorldCoord = 0; -Shader *Brush::m_state_point; -Shader *BrushClipPlane::m_state = 0; -Shader *BrushInstance::m_state_selpoint; -Counter *BrushInstance::m_counter = 0; - -FaceInstanceSet g_SelectedFaceInstances; - - -struct SListNode { - SListNode *m_next; -}; - -class ProximalVertex { -public: -const SListNode *m_vertices; - -ProximalVertex(const SListNode *next) - : m_vertices(next) -{ -} - -bool operator<(const ProximalVertex &other) const -{ - if (!(operator==(other))) { - return m_vertices < other.m_vertices; - } - return false; -} - -bool operator==(const ProximalVertex &other) const -{ - const SListNode *v = m_vertices; - std::size_t DEBUG_LOOP = 0; - do { - if (v == other.m_vertices) { - return true; - } - v = v->m_next; - //ASSERT_MESSAGE(DEBUG_LOOP < c_brush_maxFaces, "infinite loop"); - if (!(DEBUG_LOOP < c_brush_maxFaces)) { - break; - } - ++DEBUG_LOOP; - } while (v != m_vertices); - return false; -} -}; - -typedef Array ProximalVertexArray; - -std::size_t ProximalVertexArray_index(const ProximalVertexArray &array, const ProximalVertex &vertex) -{ - return vertex.m_vertices - array.data(); -} - - -inline bool Brush_isBounded(const Brush &brush) -{ - for (Brush::const_iterator i = brush.begin(); i != brush.end(); ++i) { - if (!(*i)->is_bounded()) { - return false; - } - } - return true; -} - -void Brush::buildBRep() -{ - bool degenerate = buildWindings(); - - std::size_t faces_size = 0; - std::size_t faceVerticesCount = 0; - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - if ((*i)->contributes()) { - ++faces_size; - } - faceVerticesCount += (*i)->getWinding().numpoints; - } - - if (degenerate || faces_size < 4 || faceVerticesCount != (faceVerticesCount >> 1) - << 1) { // sum of vertices for each face of a valid polyhedron is always even - m_uniqueVertexPoints.resize(0); - - vertex_clear(); - edge_clear(); - - m_edge_indices.resize(0); - m_edge_faces.resize(0); - - m_faceCentroidPoints.resize(0); - m_uniqueEdgePoints.resize(0); - m_uniqueVertexPoints.resize(0); - - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->getWinding().resize(0); - } - } else { - { - typedef std::vector FaceVertices; - FaceVertices faceVertices; - faceVertices.reserve(faceVerticesCount); - - { - for (std::size_t i = 0; i != m_faces.size(); ++i) { - for (std::size_t j = 0; j < m_faces[i]->getWinding().numpoints; ++j) { - faceVertices.push_back(FaceVertexId(i, j)); - } - } - } - - IndexBuffer uniqueEdgeIndices; - typedef VertexBuffer UniqueEdges; - UniqueEdges uniqueEdges; - - uniqueEdgeIndices.reserve(faceVertices.size()); - uniqueEdges.reserve(faceVertices.size()); - - { - ProximalVertexArray edgePairs; - edgePairs.resize(faceVertices.size()); - - { - for (std::size_t i = 0; i < faceVertices.size(); ++i) { - edgePairs[i].m_next = edgePairs.data() + absoluteIndex(next_edge(m_faces, faceVertices[i])); - } - } - - { - UniqueVertexBuffer inserter(uniqueEdges); - for (ProximalVertexArray::iterator i = edgePairs.begin(); i != edgePairs.end(); ++i) { - uniqueEdgeIndices.insert(inserter.insert(ProximalVertex(&(*i)))); - } - } - - { - edge_clear(); - m_select_edges.reserve(uniqueEdges.size()); - for (UniqueEdges::iterator i = uniqueEdges.begin(); i != uniqueEdges.end(); ++i) { - edge_push_back(faceVertices[ProximalVertexArray_index(edgePairs, *i)]); - } - } - - { - m_edge_faces.resize(uniqueEdges.size()); - for (std::size_t i = 0; i < uniqueEdges.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(edgePairs, uniqueEdges[i])]; - m_edge_faces[i] = EdgeFaces(faceVertex.getFace(), - m_faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent); - } - } - - { - m_uniqueEdgePoints.resize(uniqueEdges.size()); - for (std::size_t i = 0; i < uniqueEdges.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(edgePairs, uniqueEdges[i])]; - - const Winding &w = m_faces[faceVertex.getFace()]->getWinding(); - Vector3 edge = vector3_mid(w[faceVertex.getVertex()].vertex, - w[Winding_next(w, faceVertex.getVertex())].vertex); - m_uniqueEdgePoints[i] = pointvertex_for_windingpoint(edge, colour_vertex); - } - } - - } - - - IndexBuffer uniqueVertexIndices; - typedef VertexBuffer UniqueVertices; - UniqueVertices uniqueVertices; - - uniqueVertexIndices.reserve(faceVertices.size()); - uniqueVertices.reserve(faceVertices.size()); - - { - ProximalVertexArray vertexRings; - vertexRings.resize(faceVertices.size()); - - { - for (std::size_t i = 0; i < faceVertices.size(); ++i) { - vertexRings[i].m_next = - vertexRings.data() + absoluteIndex(next_vertex(m_faces, faceVertices[i])); - } - } - - { - UniqueVertexBuffer inserter(uniqueVertices); - for (ProximalVertexArray::iterator i = vertexRings.begin(); i != vertexRings.end(); ++i) { - uniqueVertexIndices.insert(inserter.insert(ProximalVertex(&(*i)))); - } - } - - { - vertex_clear(); - m_select_vertices.reserve(uniqueVertices.size()); - for (UniqueVertices::iterator i = uniqueVertices.begin(); i != uniqueVertices.end(); ++i) { - vertex_push_back(faceVertices[ProximalVertexArray_index(vertexRings, (*i))]); - } - } - - { - m_uniqueVertexPoints.resize(uniqueVertices.size()); - for (std::size_t i = 0; i < uniqueVertices.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(vertexRings, - uniqueVertices[i])]; - - const Winding &winding = m_faces[faceVertex.getFace()]->getWinding(); - m_uniqueVertexPoints[i] = pointvertex_for_windingpoint(winding[faceVertex.getVertex()].vertex, - colour_vertex); - } - } - } - - if ((uniqueVertices.size() + faces_size) - uniqueEdges.size() != 2) { - globalErrorStream() << "Final B-Rep: inconsistent vertex count\n"; - } - -#if BRUSH_CONNECTIVITY_DEBUG - if ( ( uniqueVertices.size() + faces_size ) - uniqueEdges.size() != 2 ) { - for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i ) - { - std::size_t faceIndex = std::distance( m_faces.begin(), i ); - - if ( !( *i )->contributes() ) { - globalOutputStream() << "face: " << Unsigned( faceIndex ) << " does not contribute\n"; - } - - Winding_printConnectivity( ( *i )->getWinding() ); - } - } -#endif - - // edge-index list for wireframe rendering - { - m_edge_indices.resize(uniqueEdgeIndices.size()); - - for (std::size_t i = 0, count = 0; i < m_faces.size(); ++i) { - const Winding &winding = m_faces[i]->getWinding(); - for (std::size_t j = 0; j < winding.numpoints; ++j) { - const RenderIndex edge_index = uniqueEdgeIndices[count + j]; - - m_edge_indices[edge_index].first = uniqueVertexIndices[count + j]; - m_edge_indices[edge_index].second = uniqueVertexIndices[count + Winding_next(winding, j)]; - } - count += winding.numpoints; - } - } - } - - { - m_faceCentroidPoints.resize(m_faces.size()); - for (std::size_t i = 0; i < m_faces.size(); ++i) { - m_faces[i]->construct_centroid(); - m_faceCentroidPoints[i] = pointvertex_for_windingpoint(m_faces[i]->centroid(), colour_vertex); - } - } - } -} - - -class FaceFilterWrapper : public Filter { -FaceFilter &m_filter; -bool m_active; -bool m_invert; -public: -FaceFilterWrapper(FaceFilter &filter, bool invert) : - m_filter(filter), - m_invert(invert) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Face &face) -{ - return m_invert ^ m_filter.filter(face); -} -}; - - -typedef std::list FaceFilters; -FaceFilters g_faceFilters; - -void add_face_filter(FaceFilter &filter, int mask, bool invert) -{ - g_faceFilters.push_back(FaceFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_faceFilters.back(), mask); -} - -bool face_filtered(Face &face) -{ - for (FaceFilters::iterator i = g_faceFilters.begin(); i != g_faceFilters.end(); ++i) { - if ((*i).active() && (*i).filter(face)) { - return true; - } - } - return false; -} - - -class BrushFilterWrapper : public Filter { -bool m_active; -bool m_invert; -BrushFilter &m_filter; -public: -BrushFilterWrapper(BrushFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Brush &brush) -{ - return m_invert ^ m_filter.filter(brush); -} -}; - - -typedef std::list BrushFilters; -BrushFilters g_brushFilters; - -void add_brush_filter(BrushFilter &filter, int mask, bool invert) -{ - g_brushFilters.push_back(BrushFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_brushFilters.back(), mask); -} - -bool brush_filtered(Brush &brush) -{ - for (BrushFilters::iterator i = g_brushFilters.begin(); i != g_brushFilters.end(); ++i) { - if ((*i).active() && (*i).filter(brush)) { - return true; - } - } - return false; -} diff --git a/src/brush.h b/src/brush.h deleted file mode 100644 index 118d97e..0000000 --- a/src/brush.h +++ /dev/null @@ -1,4075 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_H ) -#define INCLUDED_BRUSH_H - -/// \file -/// \brief The brush primitive. -/// -/// A collection of planes that define a convex polyhedron. -/// The Boundary-Representation of this primitive is a manifold polygonal mesh. -/// Each face polygon is represented by a list of vertices in a \c Winding. -/// Each vertex is associated with another face that is adjacent to the edge -/// formed by itself and the next vertex in the winding. This information can -/// be used to find edge-pairs and vertex-rings. - - -#include "debugging/debugging.h" - -#include "itexdef.h" -#include "iundo.h" -#include "iselection.h" -#include "irender.h" -#include "imap.h" -#include "ibrush.h" -#include "igl.h" -#include "ifilter.h" -#include "nameable.h" -#include "moduleobserver.h" - -#include - -#include "mathlib.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "editable.h" -#include "mapfile.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "render.h" -#include "texturelib.h" -#include "container/container.h" -#include "generic/bitfield.h" -#include "signal/signalfwd.h" - -#include "winding.h" -#include "brush_primit.h" - -const unsigned int BRUSH_DETAIL_FLAG = 27; -const unsigned int BRUSH_DETAIL_MASK = (1 << BRUSH_DETAIL_FLAG); - -#define BRUSH_CONNECTIVITY_DEBUG 0 -#define BRUSH_DEGENERATE_DEBUG 0 - -template -inline TextOuputStreamType &ostream_write(TextOuputStreamType &ostream, const Matrix4 &m) -{ - return ostream << "(" << m[0] << " " << m[1] << " " << m[2] << " " << m[3] << ", " - << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << ", " - << m[8] << " " << m[9] << " " << m[10] << " " << m[11] << ", " - << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << ")"; -} - -inline void print_vector3(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n"; -} - -inline void print_3x3(const Matrix4 &m) -{ - globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) " - << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) " - << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n"; -} - - -inline bool texdef_sane(const texdef_t &texdef) -{ - return fabs(texdef.shift[0]) < (1 << 16) - && fabs(texdef.shift[1]) < (1 << 16); -} - -inline void Winding_DrawWireframe(const Winding &winding) -{ - glVertexPointer(3, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->vertex); - glDrawArrays(GL_LINE_LOOP, 0, GLsizei(winding.numpoints)); -} - -inline void Winding_Draw(const Winding &winding, const Vector3 &normal, RenderStateFlags state) -{ - glVertexPointer(3, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->vertex); - - if ((state & RENDER_BUMP) != 0) { - Vector3 normals[c_brush_maxFaces]; - typedef Vector3 *Vector3Iter; - for (Vector3Iter i = normals, end = normals + winding.numpoints; i != end; ++i) { - *i = normal; - } - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(Vector3), normals); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(Vector3), normals); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->bitangent); - } - } else { - if (state & RENDER_LIGHTING) { - Vector3 normals[c_brush_maxFaces]; - typedef Vector3 *Vector3Iter; - for (Vector3Iter i = normals, last = normals + winding.numpoints; i != last; ++i) { - *i = normal; - } - glNormalPointer(GL_FLOAT, sizeof(Vector3), normals); - } - - if (state & RENDER_TEXTURE) { - glTexCoordPointer(2, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->texcoord); - } - } -#if 0 - if ( state & RENDER_FILL ) { - glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) ); - } - else - { - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); - } -#else - glDrawArrays(GL_POLYGON, 0, GLsizei(winding.numpoints)); -#endif - -#if 0 - const Winding& winding = winding; - - if ( state & RENDER_FILL ) { - glBegin( GL_POLYGON ); - } - else - { - glBegin( GL_LINE_LOOP ); - } - - if ( state & RENDER_LIGHTING ) { - glNormal3fv( normal ); - } - - for ( int i = 0; i < winding.numpoints; ++i ) - { - if ( state & RENDER_TEXTURE ) { - glTexCoord2fv( &winding.points[i][3] ); - } - glVertex3fv( winding.points[i] ); - } - glEnd(); -#endif -} - - -#include "shaderlib.h" - -typedef DoubleVector3 PlanePoints[3]; - -inline bool planepts_equal(const PlanePoints planepts, const PlanePoints other) -{ - return planepts[0] == other[0] && planepts[1] == other[1] && planepts[2] == other[2]; -} - -inline void planepts_assign(PlanePoints planepts, const PlanePoints other) -{ - planepts[0] = other[0]; - planepts[1] = other[1]; - planepts[2] = other[2]; -} - -inline void planepts_quantise(PlanePoints planepts, double snap) -{ - vector3_snap(planepts[0], snap); - vector3_snap(planepts[1], snap); - vector3_snap(planepts[2], snap); -} - -inline float vector3_max_component(const Vector3 &vec3) -{ - return std::max(fabsf(vec3[0]), std::max(fabsf(vec3[1]), fabsf(vec3[2]))); -} - -inline void edge_snap(Vector3 &edge, double snap) -{ - float scale = static_cast( ceil(fabs(snap / vector3_max_component(edge)))); - if (scale > 0.0f) { - vector3_scale(edge, scale); - } - vector3_snap(edge, snap); -} - -inline void planepts_snap(PlanePoints planepts, double snap) -{ - Vector3 edge01(vector3_subtracted(planepts[1], planepts[0])); - Vector3 edge12(vector3_subtracted(planepts[2], planepts[1])); - Vector3 edge20(vector3_subtracted(planepts[0], planepts[2])); - - double length_squared_01 = vector3_dot(edge01, edge01); - double length_squared_12 = vector3_dot(edge12, edge12); - double length_squared_20 = vector3_dot(edge20, edge20); - - vector3_snap(planepts[0], snap); - - if (length_squared_01 < length_squared_12) { - if (length_squared_12 < length_squared_20) { - edge_snap(edge01, snap); - edge_snap(edge12, snap); - planepts[1] = vector3_added(planepts[0], edge01); - planepts[2] = vector3_added(planepts[1], edge12); - } else { - edge_snap(edge20, snap); - edge_snap(edge01, snap); - planepts[1] = vector3_added(planepts[0], edge20); - planepts[2] = vector3_added(planepts[1], edge01); - } - } else { - if (length_squared_01 < length_squared_20) { - edge_snap(edge01, snap); - edge_snap(edge12, snap); - planepts[1] = vector3_added(planepts[0], edge01); - planepts[2] = vector3_added(planepts[1], edge12); - } else { - edge_snap(edge12, snap); - edge_snap(edge20, snap); - planepts[1] = vector3_added(planepts[0], edge12); - planepts[2] = vector3_added(planepts[1], edge20); - } - } -} - -inline PointVertex pointvertex_for_planept(const DoubleVector3 &point, const Colour4b &colour) -{ - return PointVertex( - Vertex3f( - static_cast( point.x()), - static_cast( point.y()), - static_cast( point.z()) - ), - colour - ); -} - -inline PointVertex pointvertex_for_windingpoint(const Vector3 &point, const Colour4b &colour) -{ - return PointVertex( - vertex3f_for_vector3(point), - colour - ); -} - -inline bool check_plane_is_integer(const PlanePoints &planePoints) -{ - return !float_is_integer(planePoints[0][0]) - || !float_is_integer(planePoints[0][1]) - || !float_is_integer(planePoints[0][2]) - || !float_is_integer(planePoints[1][0]) - || !float_is_integer(planePoints[1][1]) - || !float_is_integer(planePoints[1][2]) - || !float_is_integer(planePoints[2][0]) - || !float_is_integer(planePoints[2][1]) - || !float_is_integer(planePoints[2][2]); -} - -inline void brush_check_shader(const char *name) -{ - if (!shader_valid(name)) { - globalErrorStream() << "brush face has invalid texture name: '" << name << "'\n"; - } -} - -class FaceShaderObserver { -public: -virtual void realiseShader() = 0; - -virtual void unrealiseShader() = 0; -}; - -typedef ReferencePair FaceShaderObserverPair; - - -class ContentsFlagsValue { -public: -ContentsFlagsValue() -{ -} - -ContentsFlagsValue(int surfaceFlags, int contentFlags, int value, bool specified) : - m_surfaceFlags(surfaceFlags), - m_contentFlags(contentFlags), - m_value(value), - m_specified(specified) -{ -} - -int m_surfaceFlags; -int m_contentFlags; -int m_value; -bool m_specified; -}; - -inline void ContentsFlagsValue_assignMasked(ContentsFlagsValue &flags, const ContentsFlagsValue &other) -{ - bool detail = bitfield_enabled(flags.m_contentFlags, BRUSH_DETAIL_MASK); - flags = other; - if (detail) { - flags.m_contentFlags = bitfield_enable(flags.m_contentFlags, BRUSH_DETAIL_MASK); - } else { - flags.m_contentFlags = bitfield_disable(flags.m_contentFlags, BRUSH_DETAIL_MASK); - } -} - - -class FaceShader : public ModuleObserver { -public: -class SavedState { -public: -CopiedString m_shader; -ContentsFlagsValue m_flags; - -SavedState(const FaceShader &faceShader) -{ - m_shader = faceShader.getShader(); - m_flags = faceShader.m_flags; -} - -void exportState(FaceShader &faceShader) const -{ - faceShader.setShader(m_shader.c_str()); - faceShader.setFlags(m_flags); -} -}; - -CopiedString m_shader; -Shader *m_state; -ContentsFlagsValue m_flags; -FaceShaderObserverPair m_observers; -bool m_instanced; -bool m_realised; - -FaceShader(const char *shader, const ContentsFlagsValue &flags = ContentsFlagsValue(0, 0, 0, false)) : - m_shader(shader), - m_state(0), - m_flags(flags), - m_instanced(false), - m_realised(false) -{ - captureShader(); -} - -~FaceShader() -{ - releaseShader(); -} - -// copy-construction not supported -FaceShader(const FaceShader &other); - -void instanceAttach() -{ - m_instanced = true; - m_state->incrementUsed(); -} - -void instanceDetach() -{ - m_state->decrementUsed(); - m_instanced = false; -} - -void captureShader() -{ - ASSERT_MESSAGE(m_state == 0, "shader cannot be captured"); - brush_check_shader(m_shader.c_str()); - m_state = GlobalShaderCache().capture(m_shader.c_str()); - m_state->attach(*this); -} - -void releaseShader() -{ - ASSERT_MESSAGE(m_state != 0, "shader cannot be released"); - m_state->detach(*this); - GlobalShaderCache().release(m_shader.c_str()); - m_state = 0; -} - -void realise() -{ - ASSERT_MESSAGE(!m_realised, "FaceTexdef::realise: already realised"); - m_realised = true; - m_observers.forEach([](FaceShaderObserver &observer) { - observer.realiseShader(); - }); -} - -void unrealise() -{ - ASSERT_MESSAGE(m_realised, "FaceTexdef::unrealise: already unrealised"); - m_observers.forEach([](FaceShaderObserver &observer) { - observer.unrealiseShader(); - }); - m_realised = false; -} - -void attach(FaceShaderObserver &observer) -{ - m_observers.attach(observer); - if (m_realised) { - observer.realiseShader(); - } -} - -void detach(FaceShaderObserver &observer) -{ - if (m_realised) { - observer.unrealiseShader(); - } - m_observers.detach(observer); -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -void setShader(const char *name) -{ - if (m_instanced) { - m_state->decrementUsed(); - } - releaseShader(); - m_shader = name; - captureShader(); - if (m_instanced) { - m_state->incrementUsed(); - } -} - -ContentsFlagsValue getFlags() const -{ - ASSERT_MESSAGE(m_realised, "FaceShader::getFlags: flags not valid when unrealised"); - if (!m_flags.m_specified) { - return ContentsFlagsValue( - m_state->getTexture().surfaceFlags, - m_state->getTexture().contentFlags, - m_state->getTexture().value, - true - ); - } - return m_flags; -} - -void setFlags(const ContentsFlagsValue &flags) -{ - ASSERT_MESSAGE(m_realised, "FaceShader::setFlags: flags not valid when unrealised"); - ContentsFlagsValue_assignMasked(m_flags, flags); -} - -Shader *state() const -{ - return m_state; -} - -std::size_t width() const -{ - if (m_realised) { - return m_state->getTexture().width; - } - return 1; -} - -std::size_t height() const -{ - if (m_realised) { - return m_state->getTexture().height; - } - return 1; -} - -unsigned int shaderFlags() const -{ - if (m_realised) { - return m_state->getFlags(); - } - return 0; -} -}; - - -class FaceTexdef : public FaceShaderObserver { -// not copyable -FaceTexdef(const FaceTexdef &other); - -// not assignable -FaceTexdef &operator=(const FaceTexdef &other); - -public: -class SavedState { -public: -TextureProjection m_projection; - -SavedState(const FaceTexdef &faceTexdef) -{ - m_projection = faceTexdef.m_projection; -} - -void exportState(FaceTexdef &faceTexdef) const -{ - Texdef_Assign(faceTexdef.m_projection, m_projection); -} -}; - -FaceShader &m_shader; -TextureProjection m_projection; -bool m_projectionInitialised; -bool m_scaleApplied; - -FaceTexdef( - FaceShader &shader, - const TextureProjection &projection, - bool projectionInitialised = true - ) : - m_shader(shader), - m_projection(projection), - m_projectionInitialised(projectionInitialised), - m_scaleApplied(false) -{ - m_shader.attach(*this); -} - -~FaceTexdef() -{ - m_shader.detach(*this); -} - -void addScale() -{ - ASSERT_MESSAGE(!m_scaleApplied, "texture scale aready added"); - m_scaleApplied = true; - m_projection.m_brushprimit_texdef.addScale(m_shader.width(), m_shader.height()); -} - -void removeScale() -{ - ASSERT_MESSAGE(m_scaleApplied, "texture scale aready removed"); - m_scaleApplied = false; - m_projection.m_brushprimit_texdef.removeScale(m_shader.width(), m_shader.height()); -} - -void realiseShader() -{ - if (m_projectionInitialised && !m_scaleApplied) { - addScale(); - } -} - -void unrealiseShader() -{ - if (m_projectionInitialised && m_scaleApplied) { - removeScale(); - } -} - -void setTexdef(const TextureProjection &projection) -{ - removeScale(); - Texdef_Assign(m_projection, projection); - addScale(); -} - -void shift(float s, float t) -{ - ASSERT_MESSAGE(texdef_sane(m_projection.m_texdef), "FaceTexdef::shift: bad texdef"); - removeScale(); - Texdef_Shift(m_projection, s, t); - addScale(); -} - -void scale(float s, float t) -{ - removeScale(); - Texdef_Scale(m_projection, s, t); - addScale(); -} - -void rotate(float angle) -{ - removeScale(); - Texdef_Rotate(m_projection, angle); - addScale(); -} - -void fit(const Vector3 &normal, const Winding &winding, float s_repeat, float t_repeat) -{ - Texdef_FitTexture(m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat); -} -void align(const Plane3 &plane, const Vector3 &normal, const Winding &winding, int alignment) -{ - Texdef_AlignTexture(m_projection, plane, normal, winding, m_shader.width(), m_shader.height(), alignment); -} - -void emitTextureCoordinates(Winding &winding, const Vector3 &normal, const Matrix4 &localToWorld) -{ - Texdef_EmitTextureCoordinates(m_projection, m_shader.width(), m_shader.height(), winding, normal, localToWorld); -} - -void transform(const Plane3 &plane, const Matrix4 &matrix) -{ - removeScale(); - Texdef_transformLocked(m_projection, m_shader.width(), m_shader.height(), plane, matrix); - addScale(); -} - -TextureProjection normalised() const -{ - brushprimit_texdef_t tmp(m_projection.m_brushprimit_texdef); - tmp.removeScale(m_shader.width(), m_shader.height()); - return TextureProjection(m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t); -} - -void setBasis(const Vector3 &normal) -{ - Matrix4 basis; - Normal_GetTransform(normal, basis); - m_projection.m_basis_s = Vector3(basis.xx(), basis.yx(), basis.zx()); - m_projection.m_basis_t = Vector3(-basis.xy(), -basis.yy(), -basis.zy()); - - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE ) { - Vector3 s = m_projection.m_basis_s, t = m_projection.m_basis_t; - RotatePointAroundVector(m_projection.m_basis_s.data(), normal.data(), s.data(), m_projection.m_texdef.rotate); - RotatePointAroundVector(m_projection.m_basis_t.data(), normal.data(), t.data(), m_projection.m_texdef.rotate); - } -} -}; - -inline void planepts_print(const PlanePoints &planePoints, TextOutputStream &ostream) -{ - ostream << "( " << planePoints[0][0] << " " << planePoints[0][1] << " " << planePoints[0][2] << " ) " - << "( " << planePoints[1][0] << " " << planePoints[1][1] << " " << planePoints[1][2] << " ) " - << "( " << planePoints[2][0] << " " << planePoints[2][1] << " " << planePoints[2][2] << " )"; -} - - -inline Plane3 Plane3_applyTranslation(const Plane3 &plane, const Vector3 &translation) -{ - Plane3 tmp(plane3_translated(Plane3(plane.normal(), -plane.dist()), translation)); - return Plane3(tmp.normal(), -tmp.dist()); -} - -inline Plane3 Plane3_applyTransform(const Plane3 &plane, const Matrix4 &matrix) -{ - Plane3 tmp(plane3_transformed(Plane3(plane.normal(), -plane.dist()), matrix)); - return Plane3(tmp.normal(), -tmp.dist()); -} - -class FacePlane { -PlanePoints m_planepts; -Plane3 m_planeCached; -Plane3 m_plane; -public: -Vector3 m_funcStaticOrigin; - -static EBrushType m_type; - -static bool isDoom3Plane() -{ - return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4; -} - -class SavedState { -public: -PlanePoints m_planepts; -Plane3 m_plane; - -SavedState(const FacePlane &facePlane) -{ - if (facePlane.isDoom3Plane()) { - m_plane = facePlane.m_plane; - } else { - planepts_assign(m_planepts, facePlane.planePoints()); - } -} - -void exportState(FacePlane &facePlane) const -{ - if (facePlane.isDoom3Plane()) { - facePlane.m_plane = m_plane; - facePlane.updateTranslated(); - } else { - planepts_assign(facePlane.planePoints(), m_planepts); - facePlane.MakePlane(); - } -} -}; - -FacePlane() : m_funcStaticOrigin(0, 0, 0) -{ -} - -FacePlane(const FacePlane &other) : m_funcStaticOrigin(0, 0, 0) -{ - if (!isDoom3Plane()) { - planepts_assign(m_planepts, other.m_planepts); - MakePlane(); - } else { - m_plane = other.m_plane; - updateTranslated(); - } -} - -void MakePlane() -{ - if (!isDoom3Plane()) { -#if 0 - if ( check_plane_is_integer( m_planepts ) ) { - globalErrorStream() << "non-integer planepts: "; - planepts_print( m_planepts, globalErrorStream() ); - globalErrorStream() << "\n"; - } -#endif - m_planeCached = plane3_for_points(m_planepts); - } -} - -void reverse() -{ - if (!isDoom3Plane()) { - vector3_swap(m_planepts[0], m_planepts[2]); - MakePlane(); - } else { - m_planeCached = plane3_flipped(m_plane); - updateSource(); - } -} - -void transform(const Matrix4 &matrix, bool mirror) -{ - if (!isDoom3Plane()) { - -#if 0 - bool off = check_plane_is_integer( planePoints() ); -#endif - - matrix4_transform_point(matrix, m_planepts[0]); - matrix4_transform_point(matrix, m_planepts[1]); - matrix4_transform_point(matrix, m_planepts[2]); - - if (mirror) { - reverse(); - } - -#if 0 - if ( check_plane_is_integer( planePoints() ) ) { - if ( !off ) { - globalErrorStream() << "caused by transform\n"; - } - } -#endif - MakePlane(); - } else { - m_planeCached = Plane3_applyTransform(m_planeCached, matrix); - updateSource(); - } -} - -void offset(float offset) -{ - if (!isDoom3Plane()) { - Vector3 move(vector3_scaled(m_planeCached.normal(), -offset)); - - vector3_subtract(m_planepts[0], move); - vector3_subtract(m_planepts[1], move); - vector3_subtract(m_planepts[2], move); - - MakePlane(); - } else { - m_planeCached.d += offset; - updateSource(); - } -} - -void updateTranslated() -{ - m_planeCached = Plane3_applyTranslation(m_plane, m_funcStaticOrigin); -} - -void updateSource() -{ - m_plane = Plane3_applyTranslation(m_planeCached, vector3_negated(m_funcStaticOrigin)); -} - - -PlanePoints &planePoints() -{ - return m_planepts; -} - -const PlanePoints &planePoints() const -{ - return m_planepts; -} - -const Plane3 &plane3() const -{ - return m_planeCached; -} - -void setDoom3Plane(const Plane3 &plane) -{ - m_plane = plane; - updateTranslated(); -} - -const Plane3 &getDoom3Plane() const -{ - return m_plane; -} - -void copy(const FacePlane &other) -{ - if (!isDoom3Plane()) { - planepts_assign(m_planepts, other.m_planepts); - MakePlane(); - } else { - m_planeCached = other.m_plane; - updateSource(); - } -} - -void copy(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) -{ - if (!isDoom3Plane()) { - m_planepts[0] = p0; - m_planepts[1] = p1; - m_planepts[2] = p2; - MakePlane(); - } else { - m_planeCached = plane3_for_points(p2, p1, p0); - updateSource(); - } -} -}; - -inline void Winding_testSelect(Winding &winding, SelectionTest &test, SelectionIntersection &best) -{ - test.TestPolygon(VertexPointer(reinterpret_cast( &winding.points.data()->vertex ), - sizeof(WindingVertex)), winding.numpoints, best); -} - -const double GRID_MIN = 0.125; - -inline double quantiseInteger(double f) -{ - return float_to_integer(f); -} - -inline double quantiseFloating(double f) -{ - return float_snapped(f, 1.f / (1 << 16)); -} - -typedef double ( *QuantiseFunc )(double f); - -class Face; - -class FaceFilter { -public: -virtual bool filter(const Face &face) const = 0; -}; - -bool face_filtered(Face &face); - -void add_face_filter(FaceFilter &filter, int mask, bool invert = false); - -void Brush_addTextureChangedCallback(const SignalHandler &callback); - -void Brush_textureChanged(); - - -extern bool g_brush_texturelock_enabled; - -class FaceObserver { -public: -virtual void planeChanged() = 0; - -virtual void connectivityChanged() = 0; - -virtual void shaderChanged() = 0; - -virtual void evaluateTransform() = 0; -}; - -class Face : - public OpenGLRenderable, - public Filterable, - public Undoable, - public FaceShaderObserver { -std::size_t m_refcount; - -class SavedState : public UndoMemento { -public: -FacePlane::SavedState m_planeState; -FaceTexdef::SavedState m_texdefState; -FaceShader::SavedState m_shaderState; - -SavedState(const Face &face) : m_planeState(face.getPlane()), m_texdefState(face.getTexdef()), - m_shaderState(face.getShader()) -{ -} - -void exportState(Face &face) const -{ - m_planeState.exportState(face.getPlane()); - m_shaderState.exportState(face.getShader()); - m_texdefState.exportState(face.getTexdef()); -} - -void release() -{ - delete this; -} -}; - -public: -static QuantiseFunc m_quantise; -static EBrushType m_type; - -PlanePoints m_move_planepts; -PlanePoints m_move_planeptsTransformed; -private: -FacePlane m_plane; -FacePlane m_planeTransformed; -FaceShader m_shader; -FaceTexdef m_texdef; -TextureProjection m_texdefTransformed; - -Winding m_winding; -Vector3 m_centroid; -bool m_filtered; - -FaceObserver *m_observer; -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// assignment not supported -Face &operator=(const Face &other); - -// copy-construction not supported -Face(const Face &other); - -public: - -Face(FaceObserver *observer) : - m_refcount(0), - m_shader(texdef_name_default()), - m_texdef(m_shader, TextureProjection(), false), - m_filtered(false), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(Vector3(0, 0, 0), Vector3(64, 0, 0), Vector3(0, 64, 0)); - m_texdef.setBasis(m_plane.plane3().normal()); - planeChanged(); -} - -Face( - const Vector3 &p0, - const Vector3 &p1, - const Vector3 &p2, - const char *shader, - const TextureProjection &projection, - FaceObserver *observer - ) : - m_refcount(0), - m_shader(shader), - m_texdef(m_shader, projection), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(p0, p1, p2); - m_texdef.setBasis(m_plane.plane3().normal()); - planeChanged(); - updateFiltered(); -} - -Face(const Face &other, FaceObserver *observer) : - m_refcount(0), - m_shader(other.m_shader.getShader(), other.m_shader.m_flags), - m_texdef(m_shader, other.getTexdef().normalised()), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(other.m_plane); - planepts_assign(m_move_planepts, other.m_move_planepts); -// if (g_bp_globals.m_texdefTypeId != TEXDEFTYPEID_HALFLIFE) { -// m_texdef.setBasis(m_plane.plane3().normal()); -// } - planeChanged(); - updateFiltered(); -} - -~Face() -{ - m_shader.detach(*this); -} - -void planeChanged() -{ - revertTransform(); - m_observer->planeChanged(); -} - -void realiseShader() -{ - m_observer->shaderChanged(); -} - -void unrealiseShader() -{ -} - -void instanceAttach(MapFile *map) -{ - m_shader.instanceAttach(); - m_map = map; - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); -} - -void instanceDetach(MapFile *map) -{ - GlobalFilterSystem().unregisterFilterable(*this); - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - m_map = 0; - m_shader.instanceDetach(); -} - -void render(RenderStateFlags state) const -{ - Winding_Draw(m_winding, m_planeTransformed.plane3().normal(), state); -} - -void updateFiltered() -{ - m_filtered = face_filtered(*this); -} - -bool isFiltered() const -{ - return m_filtered; -} - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -// undoable -UndoMemento *exportState() const -{ - return new SavedState(*this); -} - -void importState(const UndoMemento *data) -{ - undoSave(); - - static_cast( data )->exportState(*this); - - planeChanged(); - m_observer->connectivityChanged(); - texdefChanged(); - m_observer->shaderChanged(); - updateFiltered(); -} - -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - if (--m_refcount == 0) { - delete this; - } -} - -void flipWinding() -{ - m_plane.reverse(); - planeChanged(); -} - -bool intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestPlane(Plane3(plane3().normal(), -plane3().dist()), localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_shader.state(), Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void transform(const Matrix4 &matrix, bool mirror) -{ - if (g_brush_texturelock_enabled) { - Texdef_transformLocked(m_texdefTransformed, m_shader.width(), m_shader.height(), m_plane.plane3(), matrix); - } - - m_planeTransformed.transform(matrix, mirror); - -#if 0 - ASSERT_MESSAGE( projectionaxis_for_normal( normal ) == projectionaxis_for_normal( plane3().normal() ), "bleh" ); -#endif - m_observer->planeChanged(); - - if (g_brush_texturelock_enabled) { - Brush_textureChanged(); - } -} - -void assign_planepts(const PlanePoints planepts) -{ - m_planeTransformed.copy(planepts[0], planepts[1], planepts[2]); - m_observer->planeChanged(); -} - -/// \brief Reverts the transformable state of the brush to identity. -void revertTransform() -{ - m_planeTransformed = m_plane; - planepts_assign(m_move_planeptsTransformed, m_move_planepts); - m_texdefTransformed = m_texdef.m_projection; -} - -void freezeTransform() -{ - undoSave(); - m_plane = m_planeTransformed; - planepts_assign(m_move_planepts, m_move_planeptsTransformed); - m_texdef.m_projection = m_texdefTransformed; -} - -void update_move_planepts_vertex(std::size_t index, PlanePoints planePoints) -{ - std::size_t numpoints = getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "update_move_planepts_vertex: invalid index"); - - std::size_t opposite = Winding_Opposite(getWinding(), index); - std::size_t adjacent = Winding_wrap(getWinding(), opposite + numpoints - 1); - planePoints[0] = getWinding()[opposite].vertex; - planePoints[1] = getWinding()[index].vertex; - planePoints[2] = getWinding()[adjacent].vertex; - // winding points are very inaccurate, so they must be quantised before using them to generate the face-plane - planepts_quantise(planePoints, GRID_MIN); -} - -void snapto(float snap) -{ - if (contributes()) { -#if 0 - ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane before snap to grid" ); - planepts_snap( m_plane.planePoints(), snap ); - ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane after snap to grid" ); -#else - PlanePoints planePoints; - update_move_planepts_vertex(0, planePoints); - vector3_snap(planePoints[0], snap); - vector3_snap(planePoints[1], snap); - vector3_snap(planePoints[2], snap); - assign_planepts(planePoints); - freezeTransform(); -#endif - SceneChangeNotify(); - if (!plane3_valid(m_plane.plane3())) { - globalErrorStream() << "WARNING: invalid plane after snap to grid\n"; - } - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - Winding_testSelect(m_winding, test, best); -} - -void testSelect_centroid(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(m_centroid, best); -} - -void shaderChanged() -{ - EmitTextureCoordinates(); - Brush_textureChanged(); - m_observer->shaderChanged(); - updateFiltered(); - planeChanged(); - SceneChangeNotify(); -} - -const char *GetShader() const -{ - return m_shader.getShader(); -} - -void SetShader(const char *name) -{ - undoSave(); - m_shader.setShader(name); - shaderChanged(); -} - -void revertTexdef() -{ - m_texdefTransformed = m_texdef.m_projection; -} - -void texdefChanged() -{ - revertTexdef(); - EmitTextureCoordinates(); - Brush_textureChanged(); -} - -void GetTexdef(TextureProjection &projection) const -{ - projection = m_texdef.normalised(); -} - -void SetTexdef(const TextureProjection &projection, bool ignorebasis) -{ - undoSave(); - m_texdef.setTexdef(projection); - if (ignorebasis) - m_texdef.setBasis(m_plane.plane3().normal()); - texdefChanged(); -} - -void GetFlags(ContentsFlagsValue &flags) const -{ - flags = m_shader.getFlags(); -} - -void SetFlags(const ContentsFlagsValue &flags) -{ - undoSave(); - m_shader.setFlags(flags); - m_observer->shaderChanged(); - updateFiltered(); -} - -void ShiftTexdef(float s, float t) -{ - undoSave(); - m_texdef.shift(s, t); - texdefChanged(); -} - -void ScaleTexdef(float s, float t) -{ - undoSave(); - m_texdef.scale(s, t); - texdefChanged(); -} - -void RotateTexdef(float angle) -{ - undoSave(); - m_texdef.rotate(angle); - texdefChanged(); -} - -void FitTexture(float s_repeat, float t_repeat) -{ - undoSave(); - m_texdef.fit(m_plane.plane3().normal(), m_winding, s_repeat, t_repeat); - texdefChanged(); -} - -void AlignTexture(int alignment) -{ - undoSave(); - m_texdef.align(m_plane.plane3(), m_plane.plane3().normal(), m_winding, alignment); - texdefChanged(); -} - -void EmitTextureCoordinates() -{ - Texdef_EmitTextureCoordinates(m_texdefTransformed, m_shader.width(), m_shader.height(), m_winding, - plane3().normal(), g_matrix4_identity); -} - - -const Vector3 ¢roid() const -{ - return m_centroid; -} - -void construct_centroid() -{ - Winding_Centroid(m_winding, plane3(), m_centroid); -} - -const Winding &getWinding() const -{ - return m_winding; -} - -Winding &getWinding() -{ - return m_winding; -} - -const Plane3 &plane3() const -{ - m_observer->evaluateTransform(); - return m_planeTransformed.plane3(); -} - -FacePlane &getPlane() -{ - return m_plane; -} - -const FacePlane &getPlane() const -{ - return m_plane; -} - -FaceTexdef &getTexdef() -{ - return m_texdef; -} - -const FaceTexdef &getTexdef() const -{ - return m_texdef; -} - -FaceShader &getShader() -{ - return m_shader; -} - -const FaceShader &getShader() const -{ - return m_shader; -} - -bool isDetail() const -{ - return (m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK) != 0; -} - -void setDetail(bool detail) -{ - undoSave(); - if (detail && !isDetail()) { - m_shader.m_flags.m_contentFlags |= BRUSH_DETAIL_MASK; - } else if (!detail && isDetail()) { - m_shader.m_flags.m_contentFlags &= ~BRUSH_DETAIL_MASK; - } - m_observer->shaderChanged(); -} - -bool contributes() const -{ - return m_winding.numpoints > 2; -} - -bool is_bounded() const -{ - for (Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i) { - if ((*i).adjacent == c_brush_maxFaces) { - return false; - } - } - return true; -} -}; - - -class FaceVertexId { -std::size_t m_face; -std::size_t m_vertex; - -public: -FaceVertexId(std::size_t face, std::size_t vertex) - : m_face(face), m_vertex(vertex) -{ -} - -std::size_t getFace() const -{ - return m_face; -} - -std::size_t getVertex() const -{ - return m_vertex; -} -}; - -typedef std::size_t faceIndex_t; - -struct EdgeRenderIndices { - RenderIndex first; - RenderIndex second; - - EdgeRenderIndices() - : first(0), second(0) - { - } - - EdgeRenderIndices(const RenderIndex _first, const RenderIndex _second) - : first(_first), second(_second) - { - } -}; - -struct EdgeFaces { - faceIndex_t first; - faceIndex_t second; - - EdgeFaces() - : first(c_brush_maxFaces), second(c_brush_maxFaces) - { - } - - EdgeFaces(const faceIndex_t _first, const faceIndex_t _second) - : first(_first), second(_second) - { - } -}; - -class RenderableWireframe : public OpenGLRenderable { -public: -void render(RenderStateFlags state) const -{ -#if 1 - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices->vertex); - glDrawElements(GL_LINES, GLsizei(m_size << 1), RenderIndexTypeID, m_faceVertex.data()); -#else - glBegin( GL_LINES ); - for ( std::size_t i = 0; i < m_size; ++i ) - { - glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x ); - glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x ); - } - glEnd(); -#endif -} - -Array m_faceVertex; -std::size_t m_size; -const PointVertex *m_vertices; -}; - -class Brush; - -typedef std::vector brush_vector_t; - -class BrushFilter { -public: -virtual bool filter(const Brush &brush) const = 0; -}; - -bool brush_filtered(Brush &brush); - -void add_brush_filter(BrushFilter &filter, int mask, bool invert = false); - - -/// \brief Returns true if 'self' takes priority when building brush b-rep. -inline bool plane3_inside(const Plane3 &self, const Plane3 &other, bool selfIsLater) -{ - if (vector3_equal_epsilon(self.normal(), other.normal(), 0.001)) { - // same plane? prefer the one with smaller index - if (self.dist() == other.dist()) { - return selfIsLater; - } - return self.dist() < other.dist(); - } - return true; -} - -typedef SmartPointer FaceSmartPointer; -typedef std::vector Faces; - -/// \brief Returns the unique-id of the edge adjacent to \p faceVertex in the edge-pair for the set of \p faces. -inline FaceVertexId next_edge(const Faces &faces, FaceVertexId faceVertex) -{ - std::size_t adjacent_face = faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent; - std::size_t adjacent_vertex = Winding_FindAdjacent(faces[adjacent_face]->getWinding(), faceVertex.getFace()); - - ASSERT_MESSAGE(adjacent_vertex != c_brush_maxFaces, "connectivity data invalid"); - if (adjacent_vertex == c_brush_maxFaces) { - return faceVertex; - } - - return FaceVertexId(adjacent_face, adjacent_vertex); -} - -/// \brief Returns the unique-id of the vertex adjacent to \p faceVertex in the vertex-ring for the set of \p faces. -inline FaceVertexId next_vertex(const Faces &faces, FaceVertexId faceVertex) -{ - FaceVertexId nextEdge = next_edge(faces, faceVertex); - return FaceVertexId(nextEdge.getFace(), - Winding_next(faces[nextEdge.getFace()]->getWinding(), nextEdge.getVertex())); -} - -class SelectableEdge { -Vector3 getEdge() const -{ - const Winding &winding = getFace().getWinding(); - return vector3_mid(winding[m_faceVertex.getVertex()].vertex, - winding[Winding_next(winding, m_faceVertex.getVertex())].vertex); -} - -public: -Faces &m_faces; -FaceVertexId m_faceVertex; - -SelectableEdge(Faces &faces, FaceVertexId faceVertex) - : m_faces(faces), m_faceVertex(faceVertex) -{ -} - -SelectableEdge &operator=(const SelectableEdge &other) -{ - m_faceVertex = other.m_faceVertex; - return *this; -} - -Face &getFace() const -{ - return *m_faces[m_faceVertex.getFace()]; -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(getEdge(), best); -} -}; - -class SelectableVertex { -Vector3 getVertex() const -{ - return getFace().getWinding()[m_faceVertex.getVertex()].vertex; -} - -public: -Faces &m_faces; -FaceVertexId m_faceVertex; - -SelectableVertex(Faces &faces, FaceVertexId faceVertex) - : m_faces(faces), m_faceVertex(faceVertex) -{ -} - -SelectableVertex &operator=(const SelectableVertex &other) -{ - m_faceVertex = other.m_faceVertex; - return *this; -} - -Face &getFace() const -{ - return *m_faces[m_faceVertex.getFace()]; -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(getVertex(), best); -} -}; - -class BrushObserver { -public: -virtual void reserve(std::size_t size) = 0; - -virtual void clear() = 0; - -virtual void push_back(Face &face) = 0; - -virtual void pop_back() = 0; - -virtual void erase(std::size_t index) = 0; - -virtual void connectivityChanged() = 0; - -virtual void edge_clear() = 0; - -virtual void edge_push_back(SelectableEdge &edge) = 0; - -virtual void vertex_clear() = 0; - -virtual void vertex_push_back(SelectableVertex &vertex) = 0; - -virtual void DEBUG_verify() const = 0; -}; - -class BrushVisitor { -public: -virtual void visit(Face &face) const = 0; -}; - -class Brush : - public TransformNode, - public Bounded, - public Cullable, - public Snappable, - public Undoable, - public FaceObserver, - public Filterable, - public Nameable, - public BrushDoom3 { -private: -scene::Node *m_node; -typedef UniqueSet Observers; -Observers m_observers; -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// state -Faces m_faces; -// ---- - -// cached data compiled from state -Array m_faceCentroidPoints; -RenderablePointArray m_render_faces; - -Array m_uniqueVertexPoints; -typedef std::vector SelectableVertices; -SelectableVertices m_select_vertices; -RenderablePointArray m_render_vertices; - -Array m_uniqueEdgePoints; -typedef std::vector SelectableEdges; -SelectableEdges m_select_edges; -RenderablePointArray m_render_edges; - -Array m_edge_indices; -Array m_edge_faces; - -AABB m_aabb_local; -// ---- - -Callback m_evaluateTransform; -Callback m_boundsChanged; - -mutable bool m_planeChanged; // b-rep evaluation required -mutable bool m_transformChanged; // transform evaluation required -// ---- - -public: -STRING_CONSTANT(Name, "Brush"); - -Callback m_lightsChanged; - -// static data -static Shader *m_state_point; -// ---- - -static EBrushType m_type; -static double m_maxWorldCoord; - -Brush(scene::Node &node, const Callback &evaluateTransform, const Callback &boundsChanged) : - m_node(&node), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged), - m_planeChanged(false), - m_transformChanged(false) -{ - planeChanged(); -} - -Brush(const Brush &other, scene::Node &node, const Callback &evaluateTransform, - const Callback &boundsChanged) : - m_node(&node), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged), - m_planeChanged(false), - m_transformChanged(false) -{ - copy(other); -} - -Brush(const Brush &other) : - TransformNode(other), - Bounded(other), - Cullable(other), - Snappable(), - Undoable(other), - FaceObserver(other), - Filterable(other), - Nameable(other), - BrushDoom3(other), - m_node(0), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_planeChanged(false), - m_transformChanged(false) -{ - copy(other); -} - -~Brush() -{ - ASSERT_MESSAGE(m_observers.empty(), "Brush::~Brush: observers still attached"); -} - -// assignment not supported -Brush &operator=(const Brush &other); - -void setDoom3GroupOrigin(const Vector3 &origin) -{ - //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n"; - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->getPlane().m_funcStaticOrigin = origin; - (*i)->getPlane().updateTranslated(); - (*i)->planeChanged(); - } - planeChanged(); -} - -void attach(BrushObserver &observer) -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - observer.push_back(*(*i)); - } - - for (SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i) { - observer.edge_push_back(*i); - } - - for (SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i) { - observer.vertex_push_back(*i); - } - - m_observers.insert(&observer); -} - -void detach(BrushObserver &observer) -{ - m_observers.erase(&observer); -} - -void forEachFace(const BrushVisitor &visitor) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - visitor.visit(*(*i)); - } -} - -void forEachFace_instanceAttach(MapFile *map) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->instanceAttach(map); - } -} - -void forEachFace_instanceDetach(MapFile *map) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->instanceDetach(map); - } -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_map = path_find_mapfile(path.begin(), path.end()); - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); - forEachFace_instanceAttach(m_map); - } else { - ASSERT_MESSAGE(path_find_mapfile(path.begin(), path.end()) == m_map, - "node is instanced across more than one file"); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - forEachFace_instanceDetach(m_map); - GlobalFilterSystem().unregisterFilterable(*this); - m_map = 0; - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - } -} - -// nameable -const char *name() const -{ - return "brush"; -} - -void attach(const NameCallback &callback) -{ -} - -void detach(const NameCallback &callback) -{ -} - -// filterable -void updateFiltered() -{ - if (m_node != 0) { - if (brush_filtered(*this)) { - m_node->enable(scene::Node::eFiltered); - } else { - m_node->disable(scene::Node::eFiltered); - } - } -} - -// observer -void planeChanged() -{ - m_planeChanged = true; - aabbChanged(); - m_lightsChanged(); -} - -void shaderChanged() -{ - updateFiltered(); - planeChanged(); -} - -void evaluateBRep() const -{ - if (m_planeChanged) { - m_planeChanged = false; - const_cast( this )->buildBRep(); - } -} - -void transformChanged() -{ - m_transformChanged = true; - planeChanged(); -} - -typedef MemberCaller TransformChangedCaller; - -void evaluateTransform() -{ - if (m_transformChanged) { - m_transformChanged = false; - revertTransform(); - m_evaluateTransform(); - } -} - -const Matrix4 &localToParent() const -{ - return g_matrix4_identity; -} - -void aabbChanged() -{ - m_boundsChanged(); -} - -const AABB &localAABB() const -{ - evaluateBRep(); - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -void renderComponents(SelectionSystem::EComponentMode mode, Renderer &renderer, const VolumeTest &volume, - const Matrix4 &localToWorld) const -{ - switch (mode) { - case SelectionSystem::eVertex: - renderer.addRenderable(m_render_vertices, localToWorld); - break; - case SelectionSystem::eEdge: - renderer.addRenderable(m_render_edges, localToWorld); - break; - case SelectionSystem::eFace: - renderer.addRenderable(m_render_faces, localToWorld); - break; - default: - break; - } -} - -void transform(const Matrix4 &matrix) -{ - bool mirror = matrix4_handedness(matrix) == MATRIX4_LEFTHANDED; - - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->transform(matrix, mirror); - } -} - -void snapto(float snap) -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->snapto(snap); - } -} - -void revertTransform() -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->revertTransform(); - } -} - -void freezeTransform() -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->freezeTransform(); - } -} - -/// \brief Returns the absolute index of the \p faceVertex. -std::size_t absoluteIndex(FaceVertexId faceVertex) -{ - std::size_t index = 0; - for (std::size_t i = 0; i < faceVertex.getFace(); ++i) { - index += m_faces[i]->getWinding().numpoints; - } - return index + faceVertex.getVertex(); -} - -void appendFaces(const Faces &other) -{ - clear(); - for (Faces::const_iterator i = other.begin(); i != other.end(); ++i) { - push_back(*i); - } -} - -/// \brief The undo memento for a brush stores only the list of face references - the faces are not copied. -class BrushUndoMemento : public UndoMemento { -public: -BrushUndoMemento(const Faces &faces) : m_faces(faces) -{ -} - -void release() -{ - delete this; -} - -Faces m_faces; -}; - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -UndoMemento *exportState() const -{ - return new BrushUndoMemento(m_faces); -} - -void importState(const UndoMemento *state) -{ - undoSave(); - appendFaces(static_cast( state )->m_faces); - planeChanged(); - - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->DEBUG_verify(); - } -} - -bool isDetail() -{ - return !m_faces.empty() && m_faces.front()->isDetail(); -} - -/// \brief Appends a copy of \p face to the end of the face list. -Face *addFace(const Face &face) -{ - if (m_faces.size() == c_brush_maxFaces) { - return 0; - } - undoSave(); - push_back(FaceSmartPointer(new Face(face, this))); - m_faces.back()->setDetail(isDetail()); - planeChanged(); - return m_faces.back(); -} - -/// \brief Appends a new face constructed from the parameters to the end of the face list. -Face *addPlane(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, const char *shader, - const TextureProjection &projection) -{ - if (m_faces.size() == c_brush_maxFaces) { - return 0; - } - undoSave(); - push_back(FaceSmartPointer(new Face(p0, p1, p2, shader, projection, this))); - m_faces.back()->setDetail(isDetail()); - planeChanged(); - return m_faces.back(); -} - -static void constructStatic(EBrushType type) -{ - m_type = type; - Face::m_type = type; - FacePlane::m_type = type; - - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE; - if (m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4) { - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES; - // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting - } else if (m_type == eBrushTypeHalfLife || m_type == eBrushTypeQuake3Valve) { - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE; - // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting - } - - Face::m_quantise = (m_type == eBrushTypeQuake) ? quantiseInteger : quantiseFloating; - - m_state_point = GlobalShaderCache().capture("$POINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$POINT"); -} - -std::size_t DEBUG_size() -{ - return m_faces.size(); -} - -typedef Faces::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_faces.begin(); -} - -const_iterator end() const -{ - return m_faces.end(); -} - -Face *back() -{ - return m_faces.back(); -} - -const Face *back() const -{ - return m_faces.back(); -} - -void reserve(std::size_t count) -{ - m_faces.reserve(count); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->reserve(count); - } -} - -void push_back(Faces::value_type face) -{ - m_faces.push_back(face); - if (m_instanceCounter.m_count != 0) { - m_faces.back()->instanceAttach(m_map); - } - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->push_back(*face); - (*i)->DEBUG_verify(); - } -} - -void pop_back() -{ - if (m_instanceCounter.m_count != 0) { - m_faces.back()->instanceDetach(m_map); - } - m_faces.pop_back(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->pop_back(); - (*i)->DEBUG_verify(); - } -} - -void erase(std::size_t index) -{ - if (m_instanceCounter.m_count != 0) { - m_faces[index]->instanceDetach(m_map); - } - m_faces.erase(m_faces.begin() + index); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->erase(index); - (*i)->DEBUG_verify(); - } -} - -void connectivityChanged() -{ - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->connectivityChanged(); - } -} - - -void clear() -{ - undoSave(); - if (m_instanceCounter.m_count != 0) { - forEachFace_instanceDetach(m_map); - } - m_faces.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->clear(); - (*i)->DEBUG_verify(); - } -} - -std::size_t size() const -{ - return m_faces.size(); -} - -bool empty() const -{ - return m_faces.empty(); -} - -/// \brief Returns true if any face of the brush contributes to the final B-Rep. -bool hasContributingFaces() const -{ - for (const_iterator i = begin(); i != end(); ++i) { - if ((*i)->contributes()) { - return true; - } - } - return false; -} - -/// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush. -/// Note: removal of empty faces is not performed during direct brush manipulations, because it would make a manipulation irreversible if it created an empty face. -void removeEmptyFaces() -{ - evaluateBRep(); - - { - std::size_t i = 0; - while (i < m_faces.size()) { - if (!m_faces[i]->contributes()) { - erase(i); - planeChanged(); - } else { - ++i; - } - } - } -} - -/// \brief Constructs \p winding from the intersection of \p plane with the other planes of the brush. -void windingForClipPlane(Winding &winding, const Plane3 &plane) const -{ - FixedWinding buffer[2]; - bool swap = false; - - // get a poly that covers an effectively infinite area - Winding_createInfinite(buffer[swap], plane, m_maxWorldCoord + 1); - - // chop the poly by all of the other faces - { - for (std::size_t i = 0; i < m_faces.size(); ++i) { - const Face &clip = *m_faces[i]; - - if (plane3_equal(clip.plane3(), plane) - || !plane3_valid(clip.plane3()) || !plane_unique(i) - || plane3_opposing(plane, clip.plane3())) { - continue; - } - - buffer[!swap].clear(); - -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "clip vs face: " << i << "\n"; -#endif - - { - // flip the plane, because we want to keep the back side - Plane3 clipPlane(vector3_negated(clip.plane3().normal()), -clip.plane3().dist()); - Winding_Clip(buffer[swap], plane, clipPlane, i, buffer[!swap]); - } - -#if BRUSH_CONNECTIVITY_DEBUG - for ( FixedWinding::Points::iterator k = buffer[!swap].points.begin(), j = buffer[!swap].points.end() - 1; k != buffer[!swap].points.end(); j = k, ++k ) - { - if ( vector3_length_squared( vector3_subtracted( ( *k ).vertex, ( *j ).vertex ) ) < 1 ) { - globalOutputStream() << "v: " << std::distance( buffer[!swap].points.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n"; - } - } -#endif - - //ASSERT_MESSAGE(buffer[!swap].numpoints != 1, "created single-point winding"); - - swap = !swap; - } - } - - Winding_forFixedWinding(winding, buffer[swap]); - -#if BRUSH_CONNECTIVITY_DEBUG - Winding_printConnectivity( winding ); - - for ( Winding::iterator i = winding.begin(), j = winding.end() - 1; i != winding.end(); j = i, ++i ) - { - if ( vector3_length_squared( vector3_subtracted( ( *i ).vertex, ( *j ).vertex ) ) < 1 ) { - globalOutputStream() << "v: " << std::distance( winding.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n"; - } - } -#endif -} - -void update_wireframe(RenderableWireframe &wire, const bool *faces_visible) const -{ - wire.m_faceVertex.resize(m_edge_indices.size()); - wire.m_vertices = m_uniqueVertexPoints.data(); - wire.m_size = 0; - for (std::size_t i = 0; i < m_edge_faces.size(); ++i) { - if (faces_visible[m_edge_faces[i].first] - || faces_visible[m_edge_faces[i].second]) { - wire.m_faceVertex[wire.m_size++] = m_edge_indices[i]; - } - } -} - - -void update_faces_wireframe(Array &wire, const bool *faces_visible) const -{ - std::size_t count = 0; - for (std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i) { - if (faces_visible[i]) { - ++count; - } - } - - wire.resize(count); - Array::iterator p = wire.begin(); - for (std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i) { - if (faces_visible[i]) { - *p++ = m_faceCentroidPoints[i]; - } - } -} - -/// \brief Makes this brush a deep-copy of the \p other. -void copy(const Brush &other) -{ - for (Faces::const_iterator i = other.m_faces.begin(); i != other.m_faces.end(); ++i) { - addFace(*(*i)); - } - planeChanged(); -} - -private: -void edge_push_back(FaceVertexId faceVertex) -{ - m_select_edges.push_back(SelectableEdge(m_faces, faceVertex)); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->edge_push_back(m_select_edges.back()); - } -} - -void edge_clear() -{ - m_select_edges.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->edge_clear(); - } -} - -void vertex_push_back(FaceVertexId faceVertex) -{ - m_select_vertices.push_back(SelectableVertex(m_faces, faceVertex)); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->vertex_push_back(m_select_vertices.back()); - } -} - -void vertex_clear() -{ - m_select_vertices.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->vertex_clear(); - } -} - -/// \brief Returns true if the face identified by \p index is preceded by another plane that takes priority over it. -bool plane_unique(std::size_t index) const -{ - // duplicate plane - for (std::size_t i = 0; i < m_faces.size(); ++i) { - if (index != i && !plane3_inside(m_faces[index]->plane3(), m_faces[i]->plane3(), index < i)) { - return false; - } - } - return true; -} - -/// \brief Removes edges that are smaller than the tolerance used when generating brush windings. -void removeDegenerateEdges() -{ - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Winding &winding = m_faces[i]->getWinding(); - for (Winding::iterator j = winding.begin(); j != winding.end();) { - std::size_t index = std::distance(winding.begin(), j); - std::size_t next = Winding_next(winding, index); - if (Edge_isDegenerate(winding[index].vertex, winding[next].vertex)) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate edge adjacent to " << winding[index].adjacent << "\n"; -#endif - Winding &other = m_faces[winding[index].adjacent]->getWinding(); - std::size_t adjacent = Winding_FindAdjacent(other, i); - if (adjacent != c_brush_maxFaces) { - other.erase(other.begin() + adjacent); - } - winding.erase(j); - } else { - ++j; - } - } - } -} - -/// \brief Invalidates faces that have only two vertices in their winding, while preserving edge-connectivity information. -void removeDegenerateFaces() -{ - // save adjacency info for degenerate faces - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Winding °en = m_faces[i]->getWinding(); - - if (degen.numpoints == 2) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate winding adjacent to " << degen[0].adjacent << ", " << degen[1].adjacent << "\n"; -#endif - // this is an "edge" face, where the plane touches the edge of the brush - { - Winding &winding = m_faces[degen[0].adjacent]->getWinding(); - std::size_t index = Winding_FindAdjacent(winding, i); - if (index != c_brush_maxFaces) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << degen[0].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[1].adjacent << "\n"; -#endif - winding[index].adjacent = degen[1].adjacent; - } - } - - { - Winding &winding = m_faces[degen[1].adjacent]->getWinding(); - std::size_t index = Winding_FindAdjacent(winding, i); - if (index != c_brush_maxFaces) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << degen[1].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[0].adjacent << "\n"; -#endif - winding[index].adjacent = degen[0].adjacent; - } - } - - degen.resize(0); - } - } -} - -/// \brief Removes edges that have the same adjacent-face as their immediate neighbour. -void removeDuplicateEdges() -{ - // verify face connectivity graph - for (std::size_t i = 0; i < m_faces.size(); ++i) { - //if(m_faces[i]->contributes()) - { - Winding &winding = m_faces[i]->getWinding(); - for (std::size_t j = 0; j != winding.numpoints;) { - std::size_t next = Winding_next(winding, j); - if (winding[j].adjacent == winding[next].adjacent) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": removed duplicate edge adjacent to face " << winding[j].adjacent << "\n"; -#endif - winding.erase(winding.begin() + next); - } else { - ++j; - } - } - } - } -} - -/// \brief Removes edges that do not have a matching pair in their adjacent-face. -void verifyConnectivityGraph() -{ - // verify face connectivity graph - for (std::size_t i = 0; i < m_faces.size(); ++i) { - //if(m_faces[i]->contributes()) - { - Winding &winding = m_faces[i]->getWinding(); - for (Winding::iterator j = winding.begin(); j != winding.end();) { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": adjacent to face " << ( *j ).adjacent << "\n"; -#endif - // remove unidirectional graph edges - if ((*j).adjacent == c_brush_maxFaces - || Winding_FindAdjacent(m_faces[(*j).adjacent]->getWinding(), i) == c_brush_maxFaces) { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": removing unidirectional connectivity graph edge adjacent to face " << ( *j ).adjacent << "\n"; -#endif - winding.erase(j); - } else { - ++j; - } - } - } - } -} - -/// \brief Returns true if the brush is a finite volume. A brush without a finite volume extends past the maximum world bounds and is not valid. -bool isBounded() -{ - for (const_iterator i = begin(); i != end(); ++i) { - if (!(*i)->is_bounded()) { - return false; - } - } - return true; -} - -/// \brief Constructs the polygon windings for each face of the brush. Also updates the brush bounding-box and face texture-coordinates. -bool buildWindings() -{ - - { - m_aabb_local = AABB(); - - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Face &f = *m_faces[i]; - - if (!plane3_valid(f.plane3()) || !plane_unique(i)) { - f.getWinding().resize(0); - } else { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "face: " << i << "\n"; -#endif - windingForClipPlane(f.getWinding(), f.plane3()); - - // update brush bounds - const Winding &winding = f.getWinding(); - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, (*i).vertex); - } - - // update texture coordinates - f.EmitTextureCoordinates(); - } - } - } - - bool degenerate = !isBounded(); - - if (!degenerate) { - // clean up connectivity information. - // these cleanups must be applied in a specific order. - removeDegenerateEdges(); - removeDegenerateFaces(); - removeDuplicateEdges(); - verifyConnectivityGraph(); - } - - return degenerate; -} - -/// \brief Constructs the face windings and updates anything that depends on them. -void buildBRep(); -}; - - -class FaceInstance; - -class FaceInstanceSet { -typedef SelectionList FaceInstances; -FaceInstances m_faceInstances; -public: -void insert(FaceInstance &faceInstance) -{ - m_faceInstances.append(faceInstance); -} - -void erase(FaceInstance &faceInstance) -{ - m_faceInstances.erase(faceInstance); -} - -template -void foreach(Functor functor) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - functor(*(*i)); - } -} - -bool empty() const -{ - return m_faceInstances.empty(); -} - -FaceInstance &last() const -{ - return m_faceInstances.back(); -} -}; - -extern FaceInstanceSet g_SelectedFaceInstances; - -typedef std::list VertexSelection; - -inline VertexSelection::iterator VertexSelection_find(VertexSelection &self, std::size_t value) -{ - return std::find(self.begin(), self.end(), value); -} - -inline VertexSelection::const_iterator VertexSelection_find(const VertexSelection &self, std::size_t value) -{ - return std::find(self.begin(), self.end(), value); -} - -inline VertexSelection::iterator VertexSelection_insert(VertexSelection &self, std::size_t value) -{ - VertexSelection::iterator i = VertexSelection_find(self, value); - if (i == self.end()) { - self.push_back(value); - return --self.end(); - } - return i; -} - -inline void VertexSelection_erase(VertexSelection &self, std::size_t value) -{ - VertexSelection::iterator i = VertexSelection_find(self, value); - if (i != self.end()) { - self.erase(i); - } -} - -inline bool triangle_reversed(std::size_t x, std::size_t y, std::size_t z) -{ - return !((x < y && y < z) || (z < x && x < y) || (y < z && z < x)); -} - -template -inline Vector3 -triangle_cross(const BasicVector3 &x, const BasicVector3 y, const BasicVector3 &z) -{ - return vector3_cross(y - x, z - x); -} - -template -inline bool -triangles_same_winding(const BasicVector3 &x1, const BasicVector3 y1, const BasicVector3 &z1, - const BasicVector3 &x2, const BasicVector3 y2, const BasicVector3 &z2) -{ - return vector3_dot(triangle_cross(x1, y1, z1), triangle_cross(x2, y2, z2)) > 0; -} - - -typedef const Plane3 *PlanePointer; -typedef PlanePointer *PlanesIterator; - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -class FaceInstance { -Face *m_face; -ObservedSelectable m_selectable; -ObservedSelectable m_selectableVertices; -ObservedSelectable m_selectableEdges; -SelectionChangeCallback m_selectionChanged; - -VertexSelection m_vertexSelection; -VertexSelection m_edgeSelection; - -public: -mutable VectorLightList m_lights; - -FaceInstance(Face &face, const SelectionChangeCallback &observer) : - m_face(&face), - m_selectable(SelectedChangedCaller(*this)), - m_selectableVertices(observer), - m_selectableEdges(observer), - m_selectionChanged(observer) -{ -} - -FaceInstance(const FaceInstance &other) : - m_face(other.m_face), - m_selectable(SelectedChangedCaller(*this)), - m_selectableVertices(other.m_selectableVertices), - m_selectableEdges(other.m_selectableEdges), - m_selectionChanged(other.m_selectionChanged) -{ -} - -FaceInstance &operator=(const FaceInstance &other) -{ - m_face = other.m_face; - return *this; -} - -Face &getFace() -{ - return *m_face; -} - -const Face &getFace() const -{ - return *m_face; -} - -void selectedChanged(const Selectable &selectable) -{ - if (selectable.isSelected()) { - g_SelectedFaceInstances.insert(*this); - } else { - g_SelectedFaceInstances.erase(*this); - } - m_selectionChanged(selectable); -} - -typedef MemberCaller SelectedChangedCaller; - -bool selectedVertices() const -{ - return !m_vertexSelection.empty(); -} - -bool selectedEdges() const -{ - return !m_edgeSelection.empty(); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - -bool selectedComponents() const -{ - return selectedVertices() || selectedEdges() || isSelected(); -} - -bool selectedComponents(SelectionSystem::EComponentMode mode) const -{ - switch (mode) { - case SelectionSystem::eVertex: - return selectedVertices(); - case SelectionSystem::eEdge: - return selectedEdges(); - case SelectionSystem::eFace: - return isSelected(); - default: - return false; - } -} - -void setSelected(SelectionSystem::EComponentMode mode, bool select) -{ - switch (mode) { - case SelectionSystem::eFace: - m_selectable.setSelected(select); - break; - case SelectionSystem::eVertex: - ASSERT_MESSAGE(!select, "select-all not supported"); - - m_vertexSelection.clear(); - m_selectableVertices.setSelected(false); - break; - case SelectionSystem::eEdge: - ASSERT_MESSAGE(!select, "select-all not supported"); - - m_edgeSelection.clear(); - m_selectableEdges.setSelected(false); - break; - default: - break; - } -} - -template -void SelectedVertices_foreach(Functor functor) const -{ - for (VertexSelection::const_iterator i = m_vertexSelection.begin(); i != m_vertexSelection.end(); ++i) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *i); - if (index != c_brush_maxFaces) { - functor(getFace().getWinding()[index].vertex); - } - } -} - -template -void SelectedEdges_foreach(Functor functor) const -{ - for (VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *i); - if (index != c_brush_maxFaces) { - const Winding &winding = getFace().getWinding(); - std::size_t adjacent = Winding_next(winding, index); - functor(vector3_mid(winding[index].vertex, winding[adjacent].vertex)); - } - } -} - -template -void SelectedFaces_foreach(Functor functor) const -{ - if (isSelected()) { - functor(centroid()); - } -} - -template -void SelectedComponents_foreach(Functor functor) const -{ - SelectedVertices_foreach(functor); - SelectedEdges_foreach(functor); - SelectedFaces_foreach(functor); -} - -void iterate_selected(AABB &aabb) const -{ - SelectedComponents_foreach([&](const Vector3 &point) { - aabb_extend_by_point_safe(aabb, point); - }); -} - -void iterate_selected(RenderablePointVector &points) const -{ - SelectedComponents_foreach([&](const Vector3 &point) { - const Colour4b colour_selected(0, 0, 255, 255); - points.push_back(pointvertex_for_windingpoint(point, colour_selected)); - }); -} - -bool intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return m_face->intersectVolume(volume, localToWorld); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (!m_face->isFiltered() && m_face->contributes() && intersectVolume(volume, localToWorld)) { - renderer.PushState(); - if (selectedComponents()) { - renderer.Highlight(Renderer::eFace); - } - m_face->render(renderer, localToWorld); - renderer.PopState(); - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - if (!m_face->isFiltered()) { - m_face->testSelect(test, best); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - testSelect(test, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } -} - -void testSelect_centroid(Selector &selector, SelectionTest &test) -{ - if (m_face->contributes() && !m_face->isFiltered()) { - SelectionIntersection best; - m_face->testSelect_centroid(test, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } - } -} - -void selectPlane(Selector &selector, const Line &line, PlanesIterator first, PlanesIterator last, - const PlaneCallback &selectedPlaneCallback) -{ - for (Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i) { - Vector3 v(vector3_subtracted(line_closest_point(line, (*i).vertex), (*i).vertex)); - double dot = vector3_dot(getFace().plane3().normal(), v); - if (dot <= 0) { - return; - } - } - - Selector_add(selector, m_selectable); - - selectedPlaneCallback(getFace().plane3()); -} - -void selectReversedPlane(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - if (selectedPlanes.contains(plane3_flipped(getFace().plane3()))) { - Selector_add(selector, m_selectable); - } -} - -void transformComponents(const Matrix4 &matrix) -{ - if (isSelected()) { - m_face->transform(matrix, false); - } - if (selectedVertices()) { - if (m_vertexSelection.size() == 1) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_vertexSelection.size() == 2) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_vertexSelection.size() >= 3) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } - } - if (selectedEdges()) { - if (m_edgeSelection.size() == 1) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_edgeSelection.size() >= 2) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } - } -} - -void snapto(float snap) -{ - m_face->snapto(snap); -} - -void snapComponents(float snap) -{ - if (isSelected()) { - snapto(snap); - } - if (selectedVertices()) { - vector3_snap(m_face->m_move_planepts[0], snap); - vector3_snap(m_face->m_move_planepts[1], snap); - vector3_snap(m_face->m_move_planepts[2], snap); - m_face->assign_planepts(m_face->m_move_planepts); - planepts_assign(m_face->m_move_planeptsTransformed, m_face->m_move_planepts); - m_face->freezeTransform(); - } - if (selectedEdges()) { - vector3_snap(m_face->m_move_planepts[0], snap); - vector3_snap(m_face->m_move_planepts[1], snap); - vector3_snap(m_face->m_move_planepts[2], snap); - m_face->assign_planepts(m_face->m_move_planepts); - planepts_assign(m_face->m_move_planeptsTransformed, m_face->m_move_planepts); - m_face->freezeTransform(); - } -} - -void update_move_planepts_vertex(std::size_t index) -{ - m_face->update_move_planepts_vertex(index, m_face->m_move_planepts); -} - -void update_move_planepts_vertex2(std::size_t index, std::size_t other) -{ - const std::size_t numpoints = m_face->getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "select_vertex: invalid index"); - - const std::size_t opposite = Winding_Opposite(m_face->getWinding(), index, other); - - if (triangle_reversed(index, other, opposite)) { - std::swap(index, other); - } - - ASSERT_MESSAGE( - triangles_same_winding( - m_face->getWinding()[opposite].vertex, - m_face->getWinding()[index].vertex, - m_face->getWinding()[other].vertex, - m_face->getWinding()[0].vertex, - m_face->getWinding()[1].vertex, - m_face->getWinding()[2].vertex - ), - "update_move_planepts_vertex2: error" - ); - - m_face->m_move_planepts[0] = m_face->getWinding()[opposite].vertex; - m_face->m_move_planepts[1] = m_face->getWinding()[index].vertex; - m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex; - planepts_quantise(m_face->m_move_planepts, GRID_MIN); // winding points are very inaccurate -} - -void update_selection_vertex() -{ - if (m_vertexSelection.size() == 0) { - m_selectableVertices.setSelected(false); - } else { - m_selectableVertices.setSelected(true); - - if (m_vertexSelection.size() == 1) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_vertexSelection.begin()); - - if (index != c_brush_maxFaces) { - update_move_planepts_vertex(index); - } - } else if (m_vertexSelection.size() == 2) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_vertexSelection.begin()); - std::size_t other = Winding_FindAdjacent(getFace().getWinding(), *(++m_vertexSelection.begin())); - - if (index != c_brush_maxFaces - && other != c_brush_maxFaces) { - update_move_planepts_vertex2(index, other); - } - } - } -} - -void select_vertex(std::size_t index, bool select) -{ - if (select) { - VertexSelection_insert(m_vertexSelection, getFace().getWinding()[index].adjacent); - } else { - VertexSelection_erase(m_vertexSelection, getFace().getWinding()[index].adjacent); - } - - SceneChangeNotify(); - update_selection_vertex(); -} - -bool selected_vertex(std::size_t index) const -{ - return VertexSelection_find(m_vertexSelection, getFace().getWinding()[index].adjacent) != - m_vertexSelection.end(); -} - -void update_move_planepts_edge(std::size_t index) -{ - std::size_t numpoints = m_face->getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "select_edge: invalid index"); - - std::size_t adjacent = Winding_next(m_face->getWinding(), index); - std::size_t opposite = Winding_Opposite(m_face->getWinding(), index); - m_face->m_move_planepts[0] = m_face->getWinding()[index].vertex; - m_face->m_move_planepts[1] = m_face->getWinding()[adjacent].vertex; - m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex; - planepts_quantise(m_face->m_move_planepts, GRID_MIN); // winding points are very inaccurate -} - -void update_selection_edge() -{ - if (m_edgeSelection.size() == 0) { - m_selectableEdges.setSelected(false); - } else { - m_selectableEdges.setSelected(true); - - if (m_edgeSelection.size() == 1) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_edgeSelection.begin()); - - if (index != c_brush_maxFaces) { - update_move_planepts_edge(index); - } - } - } -} - -void select_edge(std::size_t index, bool select) -{ - if (select) { - VertexSelection_insert(m_edgeSelection, getFace().getWinding()[index].adjacent); - } else { - VertexSelection_erase(m_edgeSelection, getFace().getWinding()[index].adjacent); - } - - SceneChangeNotify(); - update_selection_edge(); -} - -bool selected_edge(std::size_t index) const -{ - return VertexSelection_find(m_edgeSelection, getFace().getWinding()[index].adjacent) != m_edgeSelection.end(); -} - -const Vector3 ¢roid() const -{ - return m_face->centroid(); -} - -void connectivityChanged() -{ - // This occurs when a face is added or removed. - // The current vertex and edge selections no longer valid and must be cleared. - m_vertexSelection.clear(); - m_selectableVertices.setSelected(false); - m_edgeSelection.clear(); - m_selectableEdges.setSelected(false); -} -}; - -class BrushClipPlane : public OpenGLRenderable { -Plane3 m_plane; -Winding m_winding; -static Shader *m_state; -public: -static void constructStatic() -{ - m_state = GlobalShaderCache().capture("$CLIPPER_OVERLAY"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$CLIPPER_OVERLAY"); -} - -void setPlane(const Brush &brush, const Plane3 &plane) -{ - m_plane = plane; - if (plane3_valid(m_plane)) { - brush.windingForClipPlane(m_winding, m_plane); - } else { - m_winding.resize(0); - } -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_FILL) != 0) { - Winding_Draw(m_winding, m_plane.normal(), state); - } else { - Winding_DrawWireframe(m_winding); - - // also draw a line indicating the direction of the cut - Vector3 lineverts[2]; - Winding_Centroid(m_winding, m_plane, lineverts[0]); - lineverts[1] = vector3_added(lineverts[0], vector3_scaled(m_plane.normal(), Brush::m_maxWorldCoord * 4)); - - glVertexPointer(3, GL_FLOAT, sizeof(Vector3), &lineverts[0]); - glDrawArrays(GL_LINES, 0, GLsizei(2)); - } -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eWireframeOnly); - renderer.SetState(m_state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} -}; - -inline void Face_addLight(const FaceInstance &face, const Matrix4 &localToWorld, const RendererLight &light) -{ - const Plane3 &facePlane = face.getFace().plane3(); - const Vector3 &origin = light.aabb().origin; - Plane3 tmp(plane3_transformed(Plane3(facePlane.normal(), -facePlane.dist()), localToWorld)); - if (!plane3_test_point(tmp, origin) - || !plane3_test_point(tmp, vector3_added(origin, light.offset()))) { - face.m_lights.addLight(light); - } -} - - -typedef std::vector FaceInstances; - -class EdgeInstance : public Selectable { -FaceInstances &m_faceInstances; -SelectableEdge *m_edge; - -void select_edge(bool select) -{ - FaceVertexId faceVertex = m_edge->m_faceVertex; - m_faceInstances[faceVertex.getFace()].select_edge(faceVertex.getVertex(), select); - faceVertex = next_edge(m_edge->m_faces, faceVertex); - m_faceInstances[faceVertex.getFace()].select_edge(faceVertex.getVertex(), select); -} - -bool selected_edge() const -{ - FaceVertexId faceVertex = m_edge->m_faceVertex; - if (!m_faceInstances[faceVertex.getFace()].selected_edge(faceVertex.getVertex())) { - return false; - } - faceVertex = next_edge(m_edge->m_faces, faceVertex); - if (!m_faceInstances[faceVertex.getFace()].selected_edge(faceVertex.getVertex())) { - return false; - } - - return true; -} - -public: -EdgeInstance(FaceInstances &faceInstances, SelectableEdge &edge) - : m_faceInstances(faceInstances), m_edge(&edge) -{ -} - -EdgeInstance &operator=(const EdgeInstance &other) -{ - m_edge = other.m_edge; - return *this; -} - -void setSelected(bool select) -{ - select_edge(select); -} - -bool isSelected() const -{ - return selected_edge(); -} - - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - m_edge->testSelect(test, best); - if (best.valid()) { - Selector_add(selector, *this, best); - } -} -}; - -class VertexInstance : public Selectable { -FaceInstances &m_faceInstances; -SelectableVertex *m_vertex; - -void select_vertex(bool select) -{ - FaceVertexId faceVertex = m_vertex->m_faceVertex; - do { - m_faceInstances[faceVertex.getFace()].select_vertex(faceVertex.getVertex(), select); - faceVertex = next_vertex(m_vertex->m_faces, faceVertex); - } while (faceVertex.getFace() != m_vertex->m_faceVertex.getFace()); -} - -bool selected_vertex() const -{ - FaceVertexId faceVertex = m_vertex->m_faceVertex; - do { - if (!m_faceInstances[faceVertex.getFace()].selected_vertex(faceVertex.getVertex())) { - return false; - } - faceVertex = next_vertex(m_vertex->m_faces, faceVertex); - } while (faceVertex.getFace() != m_vertex->m_faceVertex.getFace()); - return true; -} - -public: -VertexInstance(FaceInstances &faceInstances, SelectableVertex &vertex) - : m_faceInstances(faceInstances), m_vertex(&vertex) -{ -} - -VertexInstance &operator=(const VertexInstance &other) -{ - m_vertex = other.m_vertex; - return *this; -} - -void setSelected(bool select) -{ - select_vertex(select); -} - -bool isSelected() const -{ - return selected_vertex(); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - m_vertex->testSelect(test, best); - if (best.valid()) { - Selector_add(selector, *this, best); - } -} -}; - -class BrushInstanceVisitor { -public: -virtual void visit(FaceInstance &face) const = 0; -}; - -class BrushInstance : - public BrushObserver, - public scene::Instance, - public Selectable, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable, - public PlaneSelectable, - public LightCullable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); - InstanceContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -Brush &m_brush; - -FaceInstances m_faceInstances; - -typedef std::vector EdgeInstances; -EdgeInstances m_edgeInstances; -typedef std::vector VertexInstances; -VertexInstances m_vertexInstances; - -ObservedSelectable m_selectable; - -mutable RenderableWireframe m_render_wireframe; -mutable RenderablePointVector m_render_selected; -mutable AABB m_aabb_component; -mutable Array m_faceCentroidPointsCulled; -RenderablePointArray m_render_faces_wireframe; -mutable bool m_viewChanged; // requires re-evaluation of view-dependent cached data - -BrushClipPlane m_clipPlane; - -static Shader *m_state_selpoint; - -const LightList *m_lightList; - -TransformModifier m_transform; - -BrushInstance(const BrushInstance &other); // NOT COPYABLE -BrushInstance &operator=(const BrushInstance &other); // NOT ASSIGNABLE -public: -static Counter *m_counter; - -typedef LazyStatic StaticTypeCasts; - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -STRING_CONSTANT(Name, "BrushInstance"); - -BrushInstance(const scene::Path &path, scene::Instance *parent, Brush &brush) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_brush(brush), - m_selectable(SelectedChangedCaller(*this)), - m_render_selected(GL_POINTS), - m_render_faces_wireframe(m_faceCentroidPointsCulled, GL_POINTS), - m_viewChanged(false), - m_transform(Brush::TransformChangedCaller(m_brush), ApplyTransformCaller(*this)) -{ - m_brush.instanceAttach(Instance::path()); - m_brush.attach(*this); - m_counter->increment(); - - m_lightList = &GlobalShaderCache().attach(*this); - m_brush.m_lightsChanged = LightsChangedCaller(*this); ///\todo Make this work with instancing. - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); -} - -~BrushInstance() -{ - Instance::setTransformChangedCallback(Callback()); - - m_brush.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); - - m_counter->decrement(); - m_brush.detach(*this); - m_brush.instanceDetach(Instance::path()); -} - -Brush &getBrush() -{ - return m_brush; -} - -const Brush &getBrush() const -{ - return m_brush; -} - -Bounded &get(NullType) -{ - return m_brush; -} - -Cullable &get(NullType) -{ - return m_brush; -} - -Transformable &get(NullType) -{ - return m_transform; -} - -void selectedChanged(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::ePrimitive)(selectable); - GlobalSelectionSystem().onSelectedChanged(*this, selectable); - - Instance::selectedChanged(); -} - -typedef MemberCaller SelectedChangedCaller; - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -const BrushInstanceVisitor &forEachFaceInstance(const BrushInstanceVisitor &visitor) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - visitor.visit(*i); - } - return visitor; -} - -static void constructStatic() -{ - m_state_selpoint = GlobalShaderCache().capture("$SELPOINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$SELPOINT"); -} - -void clear() -{ - m_faceInstances.clear(); -} - -void reserve(std::size_t size) -{ - m_faceInstances.reserve(size); -} - -void push_back(Face &face) -{ - m_faceInstances.push_back(FaceInstance(face, SelectedChangedComponentCaller(*this))); -} - -void pop_back() -{ - ASSERT_MESSAGE(!m_faceInstances.empty(), "erasing invalid element"); - m_faceInstances.pop_back(); -} - -void erase(std::size_t index) -{ - ASSERT_MESSAGE(index < m_faceInstances.size(), "erasing invalid element"); - m_faceInstances.erase(m_faceInstances.begin() + index); -} - -void connectivityChanged() -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).connectivityChanged(); - } -} - -void edge_clear() -{ - m_edgeInstances.clear(); -} - -void edge_push_back(SelectableEdge &edge) -{ - m_edgeInstances.push_back(EdgeInstance(m_faceInstances, edge)); -} - -void vertex_clear() -{ - m_vertexInstances.clear(); -} - -void vertex_push_back(SelectableVertex &vertex) -{ - m_vertexInstances.push_back(VertexInstance(m_faceInstances, vertex)); -} - -void DEBUG_verify() const -{ - ASSERT_MESSAGE(m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch"); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - -void setSelected(bool select) -{ - m_selectable.setSelected(select); -} - -void update_selected() const -{ - m_render_selected.clear(); - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - if ((*i).getFace().contributes()) { - (*i).iterate_selected(m_render_selected); - } - } -} - -void evaluateViewDependent(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (m_viewChanged) { - m_viewChanged = false; - - bool faces_visible[c_brush_maxFaces]; - { - bool *j = faces_visible; - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j) { - *j = (*i).intersectVolume(volume, localToWorld); - } - } - - m_brush.update_wireframe(m_render_wireframe, faces_visible); - m_brush.update_faces_wireframe(m_faceCentroidPointsCulled, faces_visible); - } -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - m_brush.evaluateBRep(); - - update_selected(); - if (!m_render_selected.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(m_state_selpoint, Renderer::eWireframeOnly); - renderer.SetState(m_state_selpoint, Renderer::eFullMaterials); - renderer.addRenderable(m_render_selected, localToWorld); - } -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - const Matrix4 &localToWorld = Instance::localToWorld(); - - renderer.SetState(m_brush.m_state_point, Renderer::eWireframeOnly); - renderer.SetState(m_brush.m_state_point, Renderer::eFullMaterials); - - if (volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - evaluateViewDependent(volume, localToWorld); - renderer.addRenderable(m_render_faces_wireframe, localToWorld); - } else { - m_brush.renderComponents(GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld); - } -} - -void renderClipPlane(Renderer &renderer, const VolumeTest &volume) const -{ - if (GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected()) { - m_clipPlane.render(renderer, volume, localToWorld()); - } -} - -void renderCommon(Renderer &renderer, const VolumeTest &volume) const -{ - bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent; - - if (componentMode && isSelected()) { - renderComponents(renderer, volume); - } - - if (parentSelected()) { - if (!componentMode) { - renderer.Highlight(Renderer::eFace); - } - renderer.Highlight(Renderer::ePrimitive); - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - //renderCommon(renderer, volume); - - m_lightList->evaluateLights(); - - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - renderer.setLights((*i).m_lights); - (*i).render(renderer, volume, localToWorld); - } - - renderComponentsSelected(renderer, volume, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - //renderCommon(renderer, volume); - - evaluateViewDependent(volume, localToWorld); - - if (m_render_wireframe.m_size != 0) { - renderer.addRenderable(m_render_wireframe, localToWorld); - } - - renderComponentsSelected(renderer, volume, localToWorld); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - renderClipPlane(renderer, volume); - - renderSolid(renderer, volume, localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - renderClipPlane(renderer, volume); - - renderWireframe(renderer, volume, localToWorld()); -} - -void viewChanged() const -{ - m_viewChanged = true; -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld()); - - SelectionIntersection best; - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect(test, best); - } - if (best.valid()) { - selector.addIntersection(best); - } -} - -bool isSelectedComponents() const -{ - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - if ((*i).selectedComponents()) { - return true; - } - } - return false; -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).setSelected(mode, select); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - test.BeginMesh(localToWorld()); - - switch (mode) { - case SelectionSystem::eVertex: { - for (VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - case SelectionSystem::eEdge: { - for (EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - case SelectionSystem::eFace: { - if (test.getVolume().fill()) { - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } else { - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect_centroid(selector, test); - } - } - } - break; - default: - break; - } -} - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - - PlanePointer brushPlanes[c_brush_maxFaces]; - PlanesIterator j = brushPlanes; - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - *j++ = &(*i)->plane3(); - } - - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).selectPlane(selector, Line(test.getNear(), test.getFar()), brushPlanes, j, selectedPlaneCallback); - } -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).selectReversedPlane(selector, selectedPlanes); - } -} - - -void transformComponents(const Matrix4 &matrix) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).transformComponents(matrix); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).iterate_selected(m_aabb_component); - } - - return m_aabb_component; -} - -void snapComponents(float snap) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).snapComponents(snap); - } -} - -void evaluateTransform() -{ - Matrix4 matrix(m_transform.calculateTransform()); - //globalOutputStream() << "matrix: " << matrix << "\n"; - - if (m_transform.getType() == TRANSFORM_PRIMITIVE) { - m_brush.transform(matrix); - } else { - transformComponents(matrix); - } -} - -void applyTransform() -{ - m_brush.revertTransform(); - evaluateTransform(); - m_brush.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void setClipPlane(const Plane3 &plane) -{ - m_clipPlane.setPlane(m_brush, plane); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - Face_addLight(*i, localToWorld, light); - } -} - -void clearLights() -{ - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).m_lights.clear(); - } -} -}; - -inline BrushInstance *Instance_getBrush(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - - -template -class BrushSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -BrushSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_functor(*brush); - } -} -}; - -template -inline const Functor &Scene_forEachSelectedBrush(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(BrushSelectedVisitor(functor)); - return functor; -} - -template -class BrushVisibleSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -BrushVisibleSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0 - && instance.path().top().get().visible()) { - m_functor(*brush); - } -} -}; - -template -inline const Functor &Scene_forEachVisibleSelectedBrush(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(BrushVisibleSelectedVisitor(functor)); - return functor; -} - -class BrushForEachFace { -const BrushInstanceVisitor &m_visitor; -public: -BrushForEachFace(const BrushInstanceVisitor &visitor) : m_visitor(visitor) -{ -} - -void operator()(BrushInstance &brush) const -{ - brush.forEachFaceInstance(m_visitor); -} -}; - -template -class FaceInstanceVisitFace : public BrushInstanceVisitor { -const Functor &functor; -public: -FaceInstanceVisitFace(const Functor &functor) - : functor(functor) -{ -} - -void visit(FaceInstance &face) const -{ - functor(face.getFace()); -} -}; - -template -inline const Functor &Brush_forEachFace(BrushInstance &brush, const Functor &functor) -{ - brush.forEachFaceInstance(FaceInstanceVisitFace(functor)); - return functor; -} - -template -class FaceVisitAll : public BrushVisitor { -const Functor &functor; -public: -FaceVisitAll(const Functor &functor) - : functor(functor) -{ -} - -void visit(Face &face) const -{ - functor(face); -} -}; - -template -inline const Functor &Brush_forEachFace(const Brush &brush, const Functor &functor) -{ - brush.forEachFace(FaceVisitAll(functor)); - return functor; -} - -template -inline const Functor &Brush_forEachFace(Brush &brush, const Functor &functor) -{ - brush.forEachFace(FaceVisitAll(functor)); - return functor; -} - -template -class FaceInstanceVisitAll : public BrushInstanceVisitor { -const Functor &functor; -public: -FaceInstanceVisitAll(const Functor &functor) - : functor(functor) -{ -} - -void visit(FaceInstance &face) const -{ - functor(face); -} -}; - -template -inline const Functor &Brush_ForEachFaceInstance(BrushInstance &brush, const Functor &functor) -{ - brush.forEachFaceInstance(FaceInstanceVisitAll(functor)); - return functor; -} - -template -inline const Functor &Scene_forEachBrush(scene::Graph &graph, const Functor &functor) -{ - graph.traverse(InstanceWalker >(functor)); - return functor; -} - -template -class InstanceIfVisible : public Functor { -public: -InstanceIfVisible(const Functor &functor) : Functor(functor) -{ -} - -void operator()(scene::Instance &instance) -{ - if (instance.path().top().get().visible()) { - Functor::operator()(instance); - } -} -}; - -template -class BrushVisibleWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -BrushVisibleWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_functor(*brush); - } - } - return true; -} -}; - -template -inline const Functor &Scene_forEachVisibleBrush(scene::Graph &graph, const Functor &functor) -{ - graph.traverse(BrushVisibleWalker(functor)); - return functor; -} - -template -inline const Functor &Scene_ForEachBrush_ForEachFace(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachBrush(graph, BrushForEachFace(FaceInstanceVisitFace(functor))); - return functor; -} - -// d1223m -template -inline const Functor &Scene_ForEachBrush_ForEachFaceInstance(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachBrush(graph, BrushForEachFace(FaceInstanceVisitAll(functor))); - return functor; -} - -template -inline const Functor &Scene_ForEachSelectedBrush_ForEachFace(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachSelectedBrush(BrushForEachFace(FaceInstanceVisitFace(functor))); - return functor; -} - -template -inline const Functor &Scene_ForEachSelectedBrush_ForEachFaceInstance(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachSelectedBrush(BrushForEachFace(FaceInstanceVisitAll(functor))); - return functor; -} - -template -class FaceVisitorWrapper { -const Functor &functor; -public: -FaceVisitorWrapper(const Functor &functor) : functor(functor) -{ -} - -void operator()(FaceInstance &faceInstance) const -{ - functor(faceInstance.getFace()); -} -}; - -template -inline const Functor &Scene_ForEachSelectedBrushFace(scene::Graph &graph, const Functor &functor) -{ - g_SelectedFaceInstances.foreach(FaceVisitorWrapper(functor)); - return functor; -} - - -#endif diff --git a/tools/vmap/brush_primit.c b/src/brush_primit.c similarity index 100% rename from tools/vmap/brush_primit.c rename to src/brush_primit.c diff --git a/src/brush_primit.cpp b/src/brush_primit.cpp deleted file mode 100644 index ca48f06..0000000 --- a/src/brush_primit.cpp +++ /dev/null @@ -1,1484 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brush_primit.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "itexdef.h" -#include "itextures.h" - -#include - -#include "stringio.h" -#include "texturelib.h" -#include "math/matrix.h" -#include "math/plane.h" -#include "math/aabb.h" - -#include "winding.h" -#include "preferences.h" - - -/*! - \brief Construct a transform from XYZ space to ST space (3d to 2d). - This will be one of three axis-aligned spaces, depending on the surface normal. - NOTE: could also be done by swapping values. - */ -void Normal_GetTransform(const Vector3 &normal, Matrix4 &transform) -{ - switch (projectionaxis_for_normal(normal)) { - case eProjectionAxisZ: - transform[0] = 1; - transform[1] = 0; - transform[2] = 0; - - transform[4] = 0; - transform[5] = 1; - transform[6] = 0; - - transform[8] = 0; - transform[9] = 0; - transform[10] = 1; - break; - case eProjectionAxisY: - transform[0] = 1; - transform[1] = 0; - transform[2] = 0; - - transform[4] = 0; - transform[5] = 0; - transform[6] = -1; - - transform[8] = 0; - transform[9] = 1; - transform[10] = 0; - break; - case eProjectionAxisX: - transform[0] = 0; - transform[1] = 0; - transform[2] = 1; - - transform[4] = 1; - transform[5] = 0; - transform[6] = 0; - - transform[8] = 0; - transform[9] = 1; - transform[10] = 0; - break; - } - transform[3] = transform[7] = transform[11] = transform[12] = transform[13] = transform[14] = 0; - transform[15] = 1; -} - -/*! - \brief Construct a transform in ST space from the texdef. - Transforms constructed from quake's texdef format are (-shift)*(1/scale)*(-rotate) with x translation sign flipped. - This would really make more sense if it was inverseof(shift*rotate*scale).. oh well. - */ -inline void Texdef_toTransform(const texdef_t &texdef, float width, float height, Matrix4 &transform) -{ - double inverse_scale[2]; - - // transform to texdef shift/scale/rotate - inverse_scale[0] = 1 / (texdef.scale[0] * width); - inverse_scale[1] = 1 / (texdef.scale[1] * -height); - transform[12] = texdef.shift[0] / width; - transform[13] = -texdef.shift[1] / -height; - double c = cos(degrees_to_radians(-texdef.rotate)); - double s = sin(degrees_to_radians(-texdef.rotate)); - transform[0] = static_cast( c * inverse_scale[0] ); - transform[1] = static_cast( s * inverse_scale[1] ); - transform[4] = static_cast( -s * inverse_scale[0] ); - transform[5] = static_cast( c * inverse_scale[1] ); - transform[2] = transform[3] = transform[6] = transform[7] = transform[8] = transform[9] = transform[11] = transform[14] = 0; - transform[10] = transform[15] = 1; -} - -inline void BPTexdef_toTransform(const brushprimit_texdef_t &bp_texdef, Matrix4 &transform) -{ - transform = g_matrix4_identity; - transform.xx() = bp_texdef.coords[0][0]; - transform.yx() = bp_texdef.coords[0][1]; - transform.tx() = bp_texdef.coords[0][2]; - transform.xy() = bp_texdef.coords[1][0]; - transform.yy() = bp_texdef.coords[1][1]; - transform.ty() = bp_texdef.coords[1][2]; -} - -inline void Texdef_toTransform(const TextureProjection &projection, float width, float height, Matrix4 &transform) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_toTransform(projection.m_brushprimit_texdef, transform); - } else { - Texdef_toTransform(projection.m_texdef, width, height, transform); - } -} - -// handles degenerate cases, just in case library atan2 doesn't -inline double arctangent_yx(double y, double x) -{ - if (fabs(x) > 1.0E-6) { - return atan2(y, x); - } else if (y > 0) { - return c_half_pi; - } else { - return -c_half_pi; - } -} - -inline void Texdef_fromTransform(texdef_t &texdef, float width, float height, const Matrix4 &transform) -{ - texdef.scale[0] = static_cast((1.0 / vector2_length(Vector2(transform[0], transform[4]))) / width ); - texdef.scale[1] = static_cast((1.0 / vector2_length(Vector2(transform[1], transform[5]))) / height ); - - texdef.rotate = static_cast( -radians_to_degrees(arctangent_yx(-transform[4], transform[0]))); - - if (texdef.rotate == -180.0f) { - texdef.rotate = 180.0f; - } - - texdef.shift[0] = transform[12] * width; - texdef.shift[1] = transform[13] * height; - - // If the 2d cross-product of the x and y axes is positive, one of the axes has a negative scale. - if (vector2_cross(Vector2(transform[0], transform[4]), Vector2(transform[1], transform[5])) > 0) { - if (texdef.rotate >= 180.0f) { - texdef.rotate -= 180.0f; - texdef.scale[0] = -texdef.scale[0]; - } else { - texdef.scale[1] = -texdef.scale[1]; - } - } - //globalOutputStream() << "fromTransform: " << texdef.shift[0] << " " << texdef.shift[1] << " " << texdef.scale[0] << " " << texdef.scale[1] << " " << texdef.rotate << "\n"; -} - -inline void BPTexdef_fromTransform(brushprimit_texdef_t &bp_texdef, const Matrix4 &transform) -{ - bp_texdef.coords[0][0] = transform.xx(); - bp_texdef.coords[0][1] = transform.yx(); - bp_texdef.coords[0][2] = transform.tx(); - bp_texdef.coords[1][0] = transform.xy(); - bp_texdef.coords[1][1] = transform.yy(); - bp_texdef.coords[1][2] = transform.ty(); -} - -inline void Texdef_fromTransform(TextureProjection &projection, float width, float height, const Matrix4 &transform) -{ - ASSERT_MESSAGE((transform[0] != 0 || transform[4] != 0) - && (transform[1] != 0 || transform[5] != 0), "invalid texture matrix"); - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_fromTransform(projection.m_brushprimit_texdef, transform); - } else { - Texdef_fromTransform(projection.m_texdef, width, height, transform); - } -} - -inline void Texdef_normalise(texdef_t &texdef, float width, float height) -{ - // it may be useful to also normalise the rotation here, if this function is used elsewhere. - texdef.shift[0] = float_mod(texdef.shift[0], width); - texdef.shift[1] = float_mod(texdef.shift[1], height); - //globalOutputStream() << "normalise: " << texdef.shift[0] << " " << texdef.shift[1] << " " << texdef.scale[0] << " " << texdef.scale[1] << " " << texdef.rotate << "\n"; -} - -inline void BPTexdef_normalise(brushprimit_texdef_t &bp_texdef, float width, float height) -{ - bp_texdef.coords[0][2] = float_mod(bp_texdef.coords[0][2], width); - bp_texdef.coords[1][2] = float_mod(bp_texdef.coords[1][2], height); -} - -/// \brief Normalise \p projection for a given texture \p width and \p height. -/// -/// All texture-projection translation (shift) values are congruent modulo the dimensions of the texture. -/// This function normalises shift values to the smallest positive congruent values. -void Texdef_normalise(TextureProjection &projection, float width, float height) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_normalise(projection.m_brushprimit_texdef, width, height); - } else { - Texdef_normalise(projection.m_texdef, width, height); - } -} - -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT); - -inline void DebugAxisBase(const Vector3 &normal) -{ - Vector3 x, y; - ComputeAxisBase(normal, x, y); - globalOutputStream() << "BP debug: " << x << y << normal << "\n"; -} - -void Texdef_basisForNormal(const TextureProjection &projection, const Vector3 &normal, Matrix4 &basis) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - basis = g_matrix4_identity; - ComputeAxisBase(normal, vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y())); - vector4_to_vector3(basis.z()) = normal; - matrix4_transpose(basis); - //DebugAxisBase(normal); - } else if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - basis = g_matrix4_identity; - vector4_to_vector3(basis.x()) = projection.m_basis_s; - vector4_to_vector3(basis.y()) = vector3_negated(projection.m_basis_t); - vector4_to_vector3(basis.z()) = vector3_normalised( - vector3_cross(vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y()))); - matrix4_multiply_by_matrix4(basis, matrix4_rotation_for_z_degrees(-projection.m_texdef.rotate)); - //globalOutputStream() << "debug: " << projection.m_basis_s << projection.m_basis_t << normal << "\n"; - matrix4_transpose(basis); - } else { - Normal_GetTransform(normal, basis); - } -} - -void -Texdef_EmitTextureCoordinates(const TextureProjection &projection, std::size_t width, std::size_t height, Winding &w, - const Vector3 &normal, const Matrix4 &localToWorld) -{ - if (w.numpoints < 3) { - return; - } - //globalOutputStream() << "normal: " << normal << "\n"; - - Matrix4 local2tex; - Texdef_toTransform(projection, (float) width, (float) height, local2tex); - //globalOutputStream() << "texdef: " << static_cast(local2tex.x()) << static_cast(local2tex.y()) << "\n"; - -#if 0 - { - TextureProjection tmp; - Texdef_fromTransform( tmp, (float)width, (float)height, local2tex ); - Matrix4 tmpTransform; - Texdef_toTransform( tmp, (float)width, (float)height, tmpTransform ); - ASSERT_MESSAGE( matrix4_equal_epsilon( local2tex, tmpTransform, 0.0001f ), "bleh" ); - } -#endif - - { - Matrix4 xyz2st; - // we don't care if it's not normalised... - Texdef_basisForNormal(projection, matrix4_transformed_direction(localToWorld, normal), xyz2st); - //globalOutputStream() << "basis: " << static_cast(xyz2st.x()) << static_cast(xyz2st.y()) << static_cast(xyz2st.z()) << "\n"; - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - Vector3 tangent(vector3_normalised(vector4_to_vector3(matrix4_transposed(local2tex).x()))); - Vector3 bitangent(vector3_normalised(vector4_to_vector3(matrix4_transposed(local2tex).y()))); - - matrix4_multiply_by_matrix4(local2tex, localToWorld); - - for (Winding::iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - (*i).texcoord[0] = texcoord[0]; - (*i).texcoord[1] = texcoord[1]; - - (*i).tangent = tangent; - (*i).bitangent = bitangent; - } -} - -/*! - \brief Provides the axis-base of the texture ST space for this normal, - as they had been transformed to world XYZ space. - */ -void TextureAxisFromNormal(const Vector3 &normal, Vector3 &s, Vector3 &t) -{ - switch (projectionaxis_for_normal(normal)) { - case eProjectionAxisZ: - s[0] = 1; - s[1] = 0; - s[2] = 0; - - t[0] = 0; - t[1] = -1; - t[2] = 0; - - break; - case eProjectionAxisY: - s[0] = 1; - s[1] = 0; - s[2] = 0; - - t[0] = 0; - t[1] = 0; - t[2] = -1; - - break; - case eProjectionAxisX: - s[0] = 0; - s[1] = 1; - s[2] = 0; - - t[0] = 0; - t[1] = 0; - t[2] = -1; - - break; - } -} - -void Texdef_Assign(texdef_t &td, const texdef_t &other) -{ - td = other; -} - -void Texdef_Shift(texdef_t &td, float s, float t) -{ - td.shift[0] += s; - td.shift[1] += t; -} - -void Texdef_Scale(texdef_t &td, float s, float t) -{ - td.scale[0] += s; - td.scale[1] += t; -} - -void Texdef_Rotate(texdef_t &td, float angle) -{ - td.rotate += angle; - td.rotate = static_cast( float_to_integer(td.rotate) % 360 ); -} - -// NOTE: added these from Ritual's Q3Radiant -void ClearBounds(Vector3 &mins, Vector3 &maxs) -{ - mins[0] = mins[1] = mins[2] = 99999; - maxs[0] = maxs[1] = maxs[2] = -99999; -} - -void AddPointToBounds(const Vector3 &v, Vector3 &mins, Vector3 &maxs) -{ - int i; - float val; - - for (i = 0; i < 3; i++) { - val = v[i]; - if (val < mins[i]) { - mins[i] = val; - } - if (val > maxs[i]) { - maxs[i] = val; - } - } -} - -template -inline BasicVector3 vector3_inverse(const BasicVector3 &self) -{ - return BasicVector3( - Element(1.0 / self.x()), - Element(1.0 / self.y()), - Element(1.0 / self.z()) - ); -} - -// low level functions .. put in mathlib? -#define BPMatCopy(a, b) {b[0][0] = a[0][0]; b[0][1] = a[0][1]; b[0][2] = a[0][2]; b[1][0] = a[1][0]; b[1][1] = a[1][1]; b[1][2] = a[1][2]; } -// apply a scale transformation to the BP matrix -#define BPMatScale(m, sS, sT) {m[0][0] *= sS; m[1][0] *= sS; m[0][1] *= sT; m[1][1] *= sT; } -// apply a translation transformation to a BP matrix -#define BPMatTranslate(m, s, t) {m[0][2] += m[0][0] * s + m[0][1] * t; m[1][2] += m[1][0] * s + m[1][1] * t; } - -// 2D homogeneous matrix product C = A*B -void BPMatMul(float A[2][3], float B[2][3], float C[2][3]); - -// apply a rotation (degrees) -void BPMatRotate(float A[2][3], float theta); - -#if GDEF_DEBUG - -void BPMatDump(float A[2][3]); - -#endif - -#if GDEF_DEBUG -//#define DBG_BP -#endif - - -bp_globals_t g_bp_globals; -float g_texdef_default_scale; - -// compute a determinant using Sarrus rule -//++timo "inline" this with a macro -// NOTE : the three vectors are understood as columns of the matrix -inline float SarrusDet(const Vector3 &a, const Vector3 &b, const Vector3 &c) -{ - return a[0] * b[1] * c[2] + b[0] * c[1] * a[2] + c[0] * a[1] * b[2] - - c[0] * b[1] * a[2] - a[1] * b[0] * c[2] - a[0] * b[2] * c[1]; -} - -// in many case we know three points A,B,C in two axis base B1 and B2 -// and we want the matrix M so that A(B1) = T * A(B2) -// NOTE: 2D homogeneous space stuff -// NOTE: we don't do any check to see if there's a solution or we have a particular case .. need to make sure before calling -// NOTE: the third coord of the A,B,C point is ignored -// NOTE: see the commented out section to fill M and D -//++timo TODO: update the other members to use this when possible -void MatrixForPoints(Vector3 M[3], Vector3 D[2], brushprimit_texdef_t *T) -{ -// Vector3 M[3]; // columns of the matrix .. easier that way (the indexing is not standard! it's column-line .. later computations are easier that way) - float det; -// Vector3 D[2]; - M[2][0] = 1.0f; - M[2][1] = 1.0f; - M[2][2] = 1.0f; -#if 0 - // fill the data vectors - M[0][0] = A2[0]; M[0][1] = B2[0]; M[0][2] = C2[0]; - M[1][0] = A2[1]; M[1][1] = B2[1]; M[1][2] = C2[1]; - M[2][0] = 1.0f; M[2][1] = 1.0f; M[2][2] = 1.0f; - D[0][0] = A1[0]; - D[0][1] = B1[0]; - D[0][2] = C1[0]; - D[1][0] = A1[1]; - D[1][1] = B1[1]; - D[1][2] = C1[1]; -#endif - // solve - det = SarrusDet(M[0], M[1], M[2]); - T->coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det; - T->coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det; - T->coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det; - T->coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det; - T->coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det; - T->coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det; -} - -//++timo replace everywhere texX by texS etc. ( ----> and in q3map !) -// NOTE : ComputeAxisBase here and in q3map code must always BE THE SAME ! -// WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0 -// rotation by (0,RotY,RotZ) assigns X to normal -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT) -{ -#if 1 - const Vector3 up(0, 0, 1); - const Vector3 down(0, 0, -1); - - if (vector3_equal_epsilon(normal, up, float(1e-6))) { - texS = Vector3(0, 1, 0); - texT = Vector3(1, 0, 0); - } else if (vector3_equal_epsilon(normal, down, float(1e-6))) { - texS = Vector3(0, 1, 0); - texT = Vector3(-1, 0, 0); - } else { - texS = vector3_normalised(vector3_cross(normal, up)); - texT = vector3_normalised(vector3_cross(normal, texS)); - vector3_negate(texS); - } - -#else - float RotY,RotZ; - // do some cleaning - /* - if (fabs(normal[0])<1e-6) - normal[0]=0.0f; - if (fabs(normal[1])<1e-6) - normal[1]=0.0f; - if (fabs(normal[2])<1e-6) - normal[2]=0.0f; - */ - RotY = -atan2( normal[2],sqrt( normal[1] * normal[1] + normal[0] * normal[0] ) ); - RotZ = atan2( normal[1],normal[0] ); - // rotate (0,1,0) and (0,0,1) to compute texS and texT - texS[0] = -sin( RotZ ); - texS[1] = cos( RotZ ); - texS[2] = 0; - // the texT vector is along -Z ( T texture coorinates axis ) - texT[0] = -sin( RotY ) * cos( RotZ ); - texT[1] = -sin( RotY ) * sin( RotZ ); - texT[2] = -cos( RotY ); -#endif -} - -#if 0 // texdef conversion -void FaceToBrushPrimitFace( face_t *f ){ - Vector3 texX,texY; - Vector3 proj; - // ST of (0,0) (1,0) (0,1) - float ST[3][5]; // [ point index ] [ xyz ST ] - //++timo not used as long as brushprimit_texdef and texdef are static -/* f->brushprimit_texdef.contents=f->texdef.contents; - f->brushprimit_texdef.flags=f->texdef.flags; - f->brushprimit_texdef.value=f->texdef.value; - strcpy(f->brushprimit_texdef.name,f->texdef.name); */ -#ifdef DBG_BP - if ( f->plane.normal[0] == 0.0f && f->plane.normal[1] == 0.0f && f->plane.normal[2] == 0.0f ) { - globalOutputStream() << "Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n"; - } - // check d_texture - if ( !f->d_texture ) { - globalOutputStream() << "Warning : f.d_texture is 0 in FaceToBrushPrimitFace\n"; - return; - } -#endif - // compute axis base - ComputeAxisBase( f->plane.normal,texX,texY ); - // compute projection vector - VectorCopy( f->plane.normal,proj ); - VectorScale( proj,f->plane.dist,proj ); - // (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the affine plane - // (1,0) in plane axis base is texX in world coordinates + projection on the affine plane - // (0,1) in plane axis base is texY in world coordinates + projection on the affine plane - // use old texture code to compute the ST coords of these points - VectorCopy( proj,ST[0] ); - EmitTextureCoordinates( ST[0], f->pShader->getTexture(), f ); - VectorCopy( texX,ST[1] ); - VectorAdd( ST[1],proj,ST[1] ); - EmitTextureCoordinates( ST[1], f->pShader->getTexture(), f ); - VectorCopy( texY,ST[2] ); - VectorAdd( ST[2],proj,ST[2] ); - EmitTextureCoordinates( ST[2], f->pShader->getTexture(), f ); - // compute texture matrix - f->brushprimit_texdef.coords[0][2] = ST[0][3]; - f->brushprimit_texdef.coords[1][2] = ST[0][4]; - f->brushprimit_texdef.coords[0][0] = ST[1][3] - f->brushprimit_texdef.coords[0][2]; - f->brushprimit_texdef.coords[1][0] = ST[1][4] - f->brushprimit_texdef.coords[1][2]; - f->brushprimit_texdef.coords[0][1] = ST[2][3] - f->brushprimit_texdef.coords[0][2]; - f->brushprimit_texdef.coords[1][1] = ST[2][4] - f->brushprimit_texdef.coords[1][2]; -} - -// compute texture coordinates for the winding points -void EmitBrushPrimitTextureCoordinates( face_t * f, Winding * w ){ - Vector3 texX,texY; - float x,y; - // compute axis base - ComputeAxisBase( f->plane.normal,texX,texY ); - // in case the texcoords matrix is empty, build a default one - // same behaviour as if scale[0]==0 && scale[1]==0 in old code - if ( f->brushprimit_texdef.coords[0][0] == 0 && f->brushprimit_texdef.coords[1][0] == 0 && f->brushprimit_texdef.coords[0][1] == 0 && f->brushprimit_texdef.coords[1][1] == 0 ) { - f->brushprimit_texdef.coords[0][0] = 1.0f; - f->brushprimit_texdef.coords[1][1] = 1.0f; - ConvertTexMatWithQTexture( &f->brushprimit_texdef, 0, &f->brushprimit_texdef, f->pShader->getTexture() ); - } - int i; - for ( i = 0; i < w.numpoints; i++ ) - { - x = vector3_dot( w.point_at( i ),texX ); - y = vector3_dot( w.point_at( i ),texY ); -#if 0 -#ifdef DBG_BP - if ( g_bp_globals.bNeedConvert ) { - // check we compute the same ST as the traditional texture computation used before - float S = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; - float T = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; - if ( fabs( S - w.point_at( i )[3] ) > 1e-2 || fabs( T - w.point_at( i )[4] ) > 1e-2 ) { - if ( fabs( S - w.point_at( i )[3] ) > 1e-4 || fabs( T - w.point_at( i )[4] ) > 1e-4 ) { - globalOutputStream() << "Warning : precision loss in brush -> brush primitive texture computation\n"; - } - else{ - globalOutputStream() << "Warning : brush -> brush primitive texture computation bug detected\n"; - } - } - } -#endif -#endif - w.point_at( i )[3] = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; - w.point_at( i )[4] = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; - } -} -#endif - -typedef float texmat_t[2][3]; - -void TexMat_Scale(texmat_t texmat, float s, float t) -{ - texmat[0][0] *= s; - texmat[0][1] *= s; - texmat[0][2] *= s; - texmat[1][0] *= t; - texmat[1][1] *= t; - texmat[1][2] *= t; -} - -void TexMat_Assign(texmat_t texmat, const texmat_t other) -{ - texmat[0][0] = other[0][0]; - texmat[0][1] = other[0][1]; - texmat[0][2] = other[0][2]; - texmat[1][0] = other[1][0]; - texmat[1][1] = other[1][1]; - texmat[1][2] = other[1][2]; -} - -void ConvertTexMatWithDimensions(const texmat_t texmat1, std::size_t w1, std::size_t h1, - texmat_t texmat2, std::size_t w2, std::size_t h2) -{ - TexMat_Assign(texmat2, texmat1); - TexMat_Scale(texmat2, static_cast( w1 ) / static_cast( w2 ), - static_cast( h1 ) / static_cast( h2 )); -} - -#if 0 -// convert a texture matrix between two qtexture_t -// if 0 for qtexture_t, basic 2x2 texture is assumed ( straight mapping between s/t coordinates and geometric coordinates ) -void ConvertTexMatWithQTexture( const float texMat1[2][3], const qtexture_t *qtex1, float texMat2[2][3], const qtexture_t *qtex2 ){ - ConvertTexMatWithDimensions( texMat1, ( qtex1 ) ? qtex1->width : 2, ( qtex1 ) ? qtex1->height : 2, - texMat2, ( qtex2 ) ? qtex2->width : 2, ( qtex2 ) ? qtex2->height : 2 ); -} - -void ConvertTexMatWithQTexture( const brushprimit_texdef_t *texMat1, const qtexture_t *qtex1, brushprimit_texdef_t *texMat2, const qtexture_t *qtex2 ){ - ConvertTexMatWithQTexture( texMat1->coords, qtex1, texMat2->coords, qtex2 ); -} -#endif - -// compute a fake shift scale rot representation from the texture matrix -// these shift scale rot values are to be understood in the local axis base -// Note: this code looks similar to Texdef_fromTransform, but the algorithm is slightly different. - -void TexMatToFakeTexCoords(const brushprimit_texdef_t &bp_texdef, texdef_t &texdef) -{ - texdef.scale[0] = static_cast( 1.0 / - vector2_length(Vector2(bp_texdef.coords[0][0], bp_texdef.coords[1][0]))); - texdef.scale[1] = static_cast( 1.0 / - vector2_length(Vector2(bp_texdef.coords[0][1], bp_texdef.coords[1][1]))); - - texdef.rotate = -static_cast( radians_to_degrees( - arctangent_yx(bp_texdef.coords[1][0], bp_texdef.coords[0][0]))); - - texdef.shift[0] = -bp_texdef.coords[0][2]; - texdef.shift[1] = bp_texdef.coords[1][2]; - - // determine whether or not an axis is flipped using a 2d cross-product - double cross = vector2_cross(Vector2(bp_texdef.coords[0][0], bp_texdef.coords[0][1]), - Vector2(bp_texdef.coords[1][0], bp_texdef.coords[1][1])); - if (cross < 0) { - // This is a bit of a compromise when using BPs--since we don't know *which* axis was flipped, - // we pick one (rather arbitrarily) using the following convention: If the X-axis is between - // 0 and 180, we assume it's the Y-axis that flipped, otherwise we assume it's the X-axis and - // subtract out 180 degrees to compensate. - if (texdef.rotate >= 180.0f) { - texdef.rotate -= 180.0f; - texdef.scale[0] = -texdef.scale[0]; - } else { - texdef.scale[1] = -texdef.scale[1]; - } - } -} - -// compute back the texture matrix from fake shift scale rot -void FakeTexCoordsToTexMat(const texdef_t &texdef, brushprimit_texdef_t &bp_texdef) -{ - double r = degrees_to_radians(-texdef.rotate); - double c = cos(r); - double s = sin(r); - double x = 1.0f / texdef.scale[0]; - double y = 1.0f / texdef.scale[1]; - bp_texdef.coords[0][0] = static_cast( x * c ); - bp_texdef.coords[1][0] = static_cast( x * s ); - bp_texdef.coords[0][1] = static_cast( y * -s ); - bp_texdef.coords[1][1] = static_cast( y * c ); - bp_texdef.coords[0][2] = -texdef.shift[0]; - bp_texdef.coords[1][2] = texdef.shift[1]; -} - -#if 0 // texture locking (brush primit) -// used for texture locking -// will move the texture according to a geometric vector -void ShiftTextureGeometric_BrushPrimit( face_t *f, Vector3& delta ){ - Vector3 texS,texT; - float tx,ty; - Vector3 M[3]; // columns of the matrix .. easier that way - float det; - Vector3 D[2]; - // compute plane axis base ( doesn't change with translation ) - ComputeAxisBase( f->plane.normal, texS, texT ); - // compute translation vector in plane axis base - tx = vector3_dot( delta, texS ); - ty = vector3_dot( delta, texT ); - // fill the data vectors - M[0][0] = tx; M[0][1] = 1.0f + tx; M[0][2] = tx; - M[1][0] = ty; M[1][1] = ty; M[1][2] = 1.0f + ty; - M[2][0] = 1.0f; M[2][1] = 1.0f; M[2][2] = 1.0f; - D[0][0] = f->brushprimit_texdef.coords[0][2]; - D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; - D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; - D[1][0] = f->brushprimit_texdef.coords[1][2]; - D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; - D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; - // solve - det = SarrusDet( M[0], M[1], M[2] ); - f->brushprimit_texdef.coords[0][0] = SarrusDet( D[0], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[0][1] = SarrusDet( M[0], D[0], M[2] ) / det; - f->brushprimit_texdef.coords[0][2] = SarrusDet( M[0], M[1], D[0] ) / det; - f->brushprimit_texdef.coords[1][0] = SarrusDet( D[1], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][1] = SarrusDet( M[0], D[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][2] = SarrusDet( M[0], M[1], D[1] ) / det; -} - -// shift a texture (texture adjustments) along it's current texture axes -// x and y are geometric values, which we must compute as ST increments -// this depends on the texture size and the pixel/texel ratio -void ShiftTextureRelative_BrushPrimit( face_t *f, float x, float y ){ - float s,t; - // as a ratio against texture size - // the scale of the texture is not relevant here (we work directly on a transformation from the base vectors) - s = ( x * 2.0 ) / (float)f->pShader->getTexture().width; - t = ( y * 2.0 ) / (float)f->pShader->getTexture().height; - f->brushprimit_texdef.coords[0][2] -= s; - f->brushprimit_texdef.coords[1][2] -= t; -} -#endif - -// TTimo: FIXME: I don't like that, it feels broken -// (and it's likely that it's not used anymore) -// best fitted 2D vector is x.X+y.Y -void ComputeBest2DVector(Vector3 &v, Vector3 &X, Vector3 &Y, int &x, int &y) -{ - double sx, sy; - sx = vector3_dot(v, X); - sy = vector3_dot(v, Y); - if (fabs(sy) > fabs(sx)) { - x = 0; - if (sy > 0.0) { - y = 1; - } else { - y = -1; - } - } else { - y = 0; - if (sx > 0.0) { - x = 1; - } else { - x = -1; - } - } -} - - -#if 0 // texdef conversion -void BrushPrimitFaceToFace( face_t *face ){ - // we have parsed brush primitives and need conversion back to standard format - // NOTE: converting back is a quick hack, there's some information lost and we can't do anything about it - // FIXME: if we normalize the texture matrix to a standard 2x2 size, we end up with wrong scaling - // I tried various tweaks, no luck .. seems shifting is lost - brushprimit_texdef_t aux; - ConvertTexMatWithQTexture( &face->brushprimit_texdef, face->pShader->getTexture(), &aux, 0 ); - TexMatToFakeTexCoords( aux.coords, face->texdef.shift, &face->texdef.rotate, face->texdef.scale ); - face->texdef.scale[0] /= 2.0; - face->texdef.scale[1] /= 2.0; -} -#endif - - -#if 0 // texture locking (brush primit) -// TEXTURE LOCKING ----------------------------------------------------------------------------------------------------- -// (Relevant to the editor only?) - -// internally used for texture locking on rotation and flipping -// the general algorithm is the same for both lockings, it's only the geometric transformation part that changes -// so I wanted to keep it in a single function -// if there are more linear transformations that need the locking, going to a C++ or code pointer solution would be best -// (but right now I want to keep brush_primit.cpp striclty C) - -bool txlock_bRotation; - -// rotation locking params -int txl_nAxis; -float txl_fDeg; -Vector3 txl_vOrigin; - -// flip locking params -Vector3 txl_matrix[3]; -Vector3 txl_origin; - -void TextureLockTransformation_BrushPrimit( face_t *f ){ - Vector3 Orig,texS,texT; // axis base of initial plane - // used by transformation algo - Vector3 temp; int j; - Vector3 vRotate; // rotation vector - - Vector3 rOrig,rvecS,rvecT; // geometric transformation of (0,0) (1,0) (0,1) { initial plane axis base } - Vector3 rNormal,rtexS,rtexT; // axis base for the transformed plane - Vector3 lOrig,lvecS,lvecT; // [2] are not used ( but usefull for debugging ) - Vector3 M[3]; - float det; - Vector3 D[2]; - - // compute plane axis base - ComputeAxisBase( f->plane.normal, texS, texT ); - VectorSet( Orig, 0.0f, 0.0f, 0.0f ); - - // compute coordinates of (0,0) (1,0) (0,1) ( expressed in initial plane axis base ) after transformation - // (0,0) (1,0) (0,1) ( expressed in initial plane axis base ) <-> (0,0,0) texS texT ( expressed world axis base ) - // input: Orig, texS, texT (and the global locking params) - // ouput: rOrig, rvecS, rvecT, rNormal - if ( txlock_bRotation ) { - // rotation vector - VectorSet( vRotate, 0.0f, 0.0f, 0.0f ); - vRotate[txl_nAxis] = txl_fDeg; - VectorRotateOrigin( Orig, vRotate, txl_vOrigin, rOrig ); - VectorRotateOrigin( texS, vRotate, txl_vOrigin, rvecS ); - VectorRotateOrigin( texT, vRotate, txl_vOrigin, rvecT ); - // compute normal of plane after rotation - VectorRotate( f->plane.normal, vRotate, rNormal ); - } - else - { - for ( j = 0; j < 3; j++ ) - rOrig[j] = vector3_dot( vector3_subtracted( Orig, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - for ( j = 0; j < 3; j++ ) - rvecS[j] = vector3_dot( vector3_subtracted( texS, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - for ( j = 0; j < 3; j++ ) - rvecT[j] = vector3_dot( vector3_subtracted( texT, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - // we also need the axis base of the target plane, apply the transformation matrix to the normal too.. - for ( j = 0; j < 3; j++ ) - rNormal[j] = vector3_dot( f->plane.normal, txl_matrix[j] ); - } - - // compute rotated plane axis base - ComputeAxisBase( rNormal, rtexS, rtexT ); - // compute S/T coordinates of the three points in rotated axis base ( in M matrix ) - lOrig[0] = vector3_dot( rOrig, rtexS ); - lOrig[1] = vector3_dot( rOrig, rtexT ); - lvecS[0] = vector3_dot( rvecS, rtexS ); - lvecS[1] = vector3_dot( rvecS, rtexT ); - lvecT[0] = vector3_dot( rvecT, rtexS ); - lvecT[1] = vector3_dot( rvecT, rtexT ); - M[0][0] = lOrig[0]; M[1][0] = lOrig[1]; M[2][0] = 1.0f; - M[0][1] = lvecS[0]; M[1][1] = lvecS[1]; M[2][1] = 1.0f; - M[0][2] = lvecT[0]; M[1][2] = lvecT[1]; M[2][2] = 1.0f; - // fill data vector - D[0][0] = f->brushprimit_texdef.coords[0][2]; - D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; - D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; - D[1][0] = f->brushprimit_texdef.coords[1][2]; - D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; - D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; - // solve - det = SarrusDet( M[0], M[1], M[2] ); - f->brushprimit_texdef.coords[0][0] = SarrusDet( D[0], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[0][1] = SarrusDet( M[0], D[0], M[2] ) / det; - f->brushprimit_texdef.coords[0][2] = SarrusDet( M[0], M[1], D[0] ) / det; - f->brushprimit_texdef.coords[1][0] = SarrusDet( D[1], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][1] = SarrusDet( M[0], D[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][2] = SarrusDet( M[0], M[1], D[1] ) / det; -} - -// texture locking -// called before the points on the face are actually rotated -void RotateFaceTexture_BrushPrimit( face_t *f, int nAxis, float fDeg, Vector3& vOrigin ){ - // this is a placeholder to call the general texture locking algorithm - txlock_bRotation = true; - txl_nAxis = nAxis; - txl_fDeg = fDeg; - VectorCopy( vOrigin, txl_vOrigin ); - TextureLockTransformation_BrushPrimit( f ); -} - -// compute the new brush primit texture matrix for a transformation matrix and a flip order flag (change plane orientation) -// this matches the select_matrix algo used in select.cpp -// this needs to be called on the face BEFORE any geometric transformation -// it will compute the texture matrix that will represent the same texture on the face after the geometric transformation is done -void ApplyMatrix_BrushPrimit( face_t *f, Vector3 matrix[3], Vector3& origin ){ - // this is a placeholder to call the general texture locking algorithm - txlock_bRotation = false; - VectorCopy( matrix[0], txl_matrix[0] ); - VectorCopy( matrix[1], txl_matrix[1] ); - VectorCopy( matrix[2], txl_matrix[2] ); - VectorCopy( origin, txl_origin ); - TextureLockTransformation_BrushPrimit( f ); -} -#endif - -// don't do C==A! -void BPMatMul(float A[2][3], float B[2][3], float C[2][3]) -{ - C[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0]; - C[1][0] = A[1][0] * B[0][0] + A[1][1] * B[1][0]; - C[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1]; - C[1][1] = A[1][0] * B[0][1] + A[1][1] * B[1][1]; - C[0][2] = A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2]; - C[1][2] = A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2]; -} - -void BPMatDump(float A[2][3]) -{ - globalOutputStream() << "" << A[0][0] - << " " << A[0][1] - << " " << A[0][2] - << "\n" << A[1][0] - << " " << A[1][2] - << " " << A[1][2] - << "\n0 0 1\n"; -} - -void BPMatRotate(float A[2][3], float theta) -{ - float m[2][3]; - float aux[2][3]; - memset(&m, 0, sizeof(float) * 6); - m[0][0] = static_cast( cos(degrees_to_radians(theta))); - m[0][1] = static_cast( -sin(degrees_to_radians(theta))); - m[1][0] = -m[0][1]; - m[1][1] = m[0][0]; - BPMatMul(A, m, aux); - BPMatCopy(aux, A); -} - -#if 0 // camera-relative texture shift -// get the relative axes of the current texturing -void BrushPrimit_GetRelativeAxes( face_t *f, Vector3& vecS, Vector3& vecT ){ - float vS[2],vT[2]; - // first we compute them as expressed in plane axis base - // BP matrix has coordinates of plane axis base expressed in geometric axis base - // so we use the line vectors - vS[0] = f->brushprimit_texdef.coords[0][0]; - vS[1] = f->brushprimit_texdef.coords[0][1]; - vT[0] = f->brushprimit_texdef.coords[1][0]; - vT[1] = f->brushprimit_texdef.coords[1][1]; - // now compute those vectors in geometric space - Vector3 texS, texT; // axis base of the plane (geometric) - ComputeAxisBase( f->plane.normal, texS, texT ); - // vecS[] = vS[0].texS[] + vS[1].texT[] - // vecT[] = vT[0].texS[] + vT[1].texT[] - vecS[0] = vS[0] * texS[0] + vS[1] * texT[0]; - vecS[1] = vS[0] * texS[1] + vS[1] * texT[1]; - vecS[2] = vS[0] * texS[2] + vS[1] * texT[2]; - vecT[0] = vT[0] * texS[0] + vT[1] * texT[0]; - vecT[1] = vT[0] * texS[1] + vT[1] * texT[1]; - vecT[2] = vT[0] * texS[2] + vT[1] * texT[2]; -} - -// brush primitive texture adjustments, use the camera view to map adjustments -// ShiftTextureRelative_BrushPrimit ( s , t ) will shift relative to the texture -void ShiftTextureRelative_Camera( face_t *f, int x, int y ){ - Vector3 vecS, vecT; - float XY[2]; // the values we are going to send for translation - float sgn[2]; // +1 or -1 - int axis[2]; - CamWnd* pCam; - - // get the two relative texture axes for the current texturing - BrushPrimit_GetRelativeAxes( f, vecS, vecT ); - - // center point of the face, project it on the camera space - Vector3 C; - VectorClear( C ); - int i; - for ( i = 0; i < f->face_winding->numpoints; i++ ) - { - VectorAdd( C,f->face_winding->point_at( i ),C ); - } - VectorScale( C,1.0 / f->face_winding->numpoints,C ); - - pCam = g_pParentWnd->GetCamWnd(); - pCam->MatchViewAxes( C, vecS, axis[0], sgn[0] ); - pCam->MatchViewAxes( C, vecT, axis[1], sgn[1] ); - - // this happens when the two directions can't be mapped on two different directions on the screen - // then the move will occur against a single axis - // (i.e. the user is not positioned well enough to send understandable shift commands) - // NOTE: in most cases this warning is not very relevant because the user would use one of the two axes - // for which the solution is easy (the other one being unknown) - // so this warning could be removed - if ( axis[0] == axis[1] ) { - globalOutputStream() << "Warning: degenerate in ShiftTextureRelative_Camera\n"; - } - - // compute the X Y geometric increments - // those geometric increments will be applied along the texture axes (the ones we computed above) - XY[0] = 0; - XY[1] = 0; - if ( x != 0 ) { - // moving right/left - XY[axis[0]] += sgn[0] * x; - } - if ( y != 0 ) { - XY[axis[1]] += sgn[1] * y; - } - // we worked out a move along vecS vecT, and we now it's geometric amplitude - // apply it - ShiftTextureRelative_BrushPrimit( f, XY[0], XY[1] ); -} -#endif - - -void BPTexdef_Assign(brushprimit_texdef_t &bp_td, const brushprimit_texdef_t &bp_other) -{ - bp_td = bp_other; -} - -void BPTexdef_Shift(brushprimit_texdef_t &bp_td, float s, float t) -{ - // shift a texture (texture adjustments) along it's current texture axes - // x and y are geometric values, which we must compute as ST increments - // this depends on the texture size and the pixel/texel ratio - // as a ratio against texture size - // the scale of the texture is not relevant here (we work directly on a transformation from the base vectors) - bp_td.coords[0][2] -= s; - bp_td.coords[1][2] += t; -} - -void BPTexdef_Scale(brushprimit_texdef_t &bp_td, float s, float t) -{ - // apply same scale as the spinner button of the surface inspector - texdef_t texdef; - // compute fake shift scale rot - TexMatToFakeTexCoords(bp_td, texdef); - // update - texdef.scale[0] += s; - texdef.scale[1] += t; - // compute new normalized texture matrix - FakeTexCoordsToTexMat(texdef, bp_td); -} - -void BPTexdef_Rotate(brushprimit_texdef_t &bp_td, float angle) -{ - // apply same scale as the spinner button of the surface inspector - texdef_t texdef; - // compute fake shift scale rot - TexMatToFakeTexCoords(bp_td, texdef); - // update - texdef.rotate += angle; - // compute new normalized texture matrix - FakeTexCoordsToTexMat(texdef, bp_td); -} - -void BPTexdef_Construct(brushprimit_texdef_t &bp_td, std::size_t width, std::size_t height) -{ - bp_td.coords[0][0] = 1.0f; - bp_td.coords[1][1] = 1.0f; - ConvertTexMatWithDimensions(bp_td.coords, 2, 2, bp_td.coords, width, height); -} - -void Texdef_Assign(TextureProjection &projection, const TextureProjection &other) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Assign(projection.m_brushprimit_texdef, other.m_brushprimit_texdef); - } else { - Texdef_Assign(projection.m_texdef, other.m_texdef); - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - projection.m_basis_s = other.m_basis_s; - projection.m_basis_t = other.m_basis_t; - } - } -} - -void Texdef_Shift(TextureProjection &projection, float s, float t) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Shift(projection.m_brushprimit_texdef, s, t); - } else { - Texdef_Shift(projection.m_texdef, s, t); - } -} - -void Texdef_Scale(TextureProjection &projection, float s, float t) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Scale(projection.m_brushprimit_texdef, s, t); - } else { - Texdef_Scale(projection.m_texdef, s, t); - } -} - -void Texdef_Rotate(TextureProjection &projection, float angle) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Rotate(projection.m_brushprimit_texdef, angle); - } else { - Texdef_Rotate(projection.m_texdef, angle); - } -} - -void Texdef_FitTexture(TextureProjection &projection, std::size_t width, std::size_t height, const Vector3 &normal, - const Winding &w, float s_repeat, float t_repeat) -{ - if (w.numpoints < 3) { - return; - } - - Matrix4 st2tex; - Texdef_toTransform(projection, (float) width, (float) height, st2tex); - - // the current texture transform - Matrix4 local2tex = st2tex; - { - Matrix4 xyz2st; - Texdef_basisForNormal(projection, normal, xyz2st); - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - // the bounds of the current texture transform - AABB bounds; - for (Winding::const_iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - aabb_extend_by_point_safe(bounds, texcoord); - } - bounds.origin.z() = 0; - bounds.extents.z() = 1; - - // the bounds of a perfectly fitted texture transform - AABB perfect(Vector3(s_repeat * 0.5, t_repeat * 0.5, 0), Vector3(s_repeat * 0.5, t_repeat * 0.5, 1)); - - // the difference between the current texture transform and the perfectly fitted transform - Matrix4 matrix(matrix4_translation_for_vec3(bounds.origin - perfect.origin)); - matrix4_pivoted_scale_by_vec3(matrix, bounds.extents / perfect.extents, perfect.origin); - matrix4_affine_invert(matrix); - - // apply the difference to the current texture transform - matrix4_premultiply_by_matrix4(st2tex, matrix); - - Texdef_fromTransform(projection, (float) width, (float) height, st2tex); - Texdef_normalise(projection, (float) width, (float) height); -} - - -void Texdef_AlignTexture(TextureProjection &projection, const Plane3 &plane, const Vector3 &normal, const Winding &w, std::size_t width, std::size_t height, int alignment) -{ - if (w.numpoints < 3) { - return; - } - - Matrix4 st2tex; - Texdef_toTransform(projection, (float) width, (float) height, st2tex); - - // the current texture transform - Matrix4 local2tex = st2tex; - { - Matrix4 xyz2st; - Texdef_basisForNormal(projection, normal, xyz2st); - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - // the bounds of the current texture transform - AABB bounds; - for (Winding::const_iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - aabb_extend_by_point_safe(bounds, texcoord); - } - bounds.extents.z() = 1; - - AABB perfect; - perfect.extents = bounds.extents; - printf("Bounds: %f %f %f\n", bounds.origin.x(), bounds.origin.y(), bounds.origin.z()); - - switch (alignment) { - case 0: - printf("Top Left\n"); - perfect.origin = Vector3(0, 0, 0); - break; - case 1: - printf("Top Center\n"); - perfect.origin = Vector3(width /2, 0, 0); - break; - case 2: - printf("Top Right\n"); - perfect.origin = Vector3(width, 0, 0); - break; - case 3: - printf("Middle Left\n"); - perfect.origin = Vector3(0.0, 0.5, 0); - break; - case 4: - printf("Middle Center\n"); - perfect.origin = Vector3(0.5, 0.5, 0); - break; - case 5: - printf("Middle Right\n"); - perfect.origin = Vector3(1.0, 0.5, 0); - break; - case 6: - printf("Bottom Left\n"); - perfect.origin = Vector3(0.0, 1.0, 0); - break; - case 7: - printf("Bottom Center\n"); - perfect.origin = Vector3(0.5, 1.0, 0); - break; - case 8: - printf("Bottom Right\n"); - perfect.origin = Vector3(1.0, 1.0, 0); - break; - } - - // the difference between the current texture transform and the perfectly fitted transform - Matrix4 matrix(matrix4_translation_for_vec3(bounds.origin - perfect.origin)); - - /* - matrix4_pivoted_scale_by_vec3(matrix, bounds.extents, perfect.origin); - matrix4_affine_invert(matrix); - */ - - // apply the difference to the current texture transform - matrix4_premultiply_by_matrix4(st2tex, matrix); - Texdef_fromTransform(projection, (float) width, (float) height, st2tex); - Texdef_normalise(projection, (float) width, (float) height); -} - -float Texdef_getDefaultTextureScale() -{ - return g_texdef_default_scale; -} - -void TexDef_Construct_Default(TextureProjection &projection) -{ - projection.m_texdef.scale[0] = Texdef_getDefaultTextureScale(); - projection.m_texdef.scale[1] = Texdef_getDefaultTextureScale(); - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - FakeTexCoordsToTexMat(projection.m_texdef, projection.m_brushprimit_texdef); - } -} - - -void ShiftScaleRotate_fromFace(texdef_t &shiftScaleRotate, const TextureProjection &projection) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - TexMatToFakeTexCoords(projection.m_brushprimit_texdef, shiftScaleRotate); - } else { - shiftScaleRotate = projection.m_texdef; - } -} - -void ShiftScaleRotate_toFace(const texdef_t &shiftScaleRotate, TextureProjection &projection) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - // compute texture matrix - // the matrix returned must be understood as a qtexture_t with width=2 height=2 - FakeTexCoordsToTexMat(shiftScaleRotate, projection.m_brushprimit_texdef); - } else { - projection.m_texdef = shiftScaleRotate; - } -} - - -inline void print_vector3(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n"; -} - -inline void print_3x3(const Matrix4 &m) -{ - globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) " - << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) " - << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n"; -} - - -inline Matrix4 matrix4_rotation_for_vector3(const Vector3 &x, const Vector3 &y, const Vector3 &z) -{ - return Matrix4( - x.x(), x.y(), x.z(), 0, - y.x(), y.y(), y.z(), 0, - z.x(), z.y(), z.z(), 0, - 0, 0, 0, 1 - ); -} - -inline Matrix4 matrix4_swap_axes(const Vector3 &from, const Vector3 &to) -{ - if (from.x() != 0 && to.y() != 0) { - return matrix4_rotation_for_vector3(to, from, g_vector3_axis_z); - } - - if (from.x() != 0 && to.z() != 0) { - return matrix4_rotation_for_vector3(to, g_vector3_axis_y, from); - } - - if (from.y() != 0 && to.z() != 0) { - return matrix4_rotation_for_vector3(g_vector3_axis_x, to, from); - } - - if (from.y() != 0 && to.x() != 0) { - return matrix4_rotation_for_vector3(from, to, g_vector3_axis_z); - } - - if (from.z() != 0 && to.x() != 0) { - return matrix4_rotation_for_vector3(from, g_vector3_axis_y, to); - } - - if (from.z() != 0 && to.y() != 0) { - return matrix4_rotation_for_vector3(g_vector3_axis_x, from, to); - } - - ERROR_MESSAGE("unhandled axis swap case"); - - return g_matrix4_identity; -} - -inline Matrix4 matrix4_reflection_for_plane(const Plane3 &plane) -{ - return Matrix4( - static_cast( 1 - (2 * plane.a * plane.a)), - static_cast( -2 * plane.a * plane.b ), - static_cast( -2 * plane.a * plane.c ), - 0, - static_cast( -2 * plane.b * plane.a ), - static_cast( 1 - (2 * plane.b * plane.b)), - static_cast( -2 * plane.b * plane.c ), - 0, - static_cast( -2 * plane.c * plane.a ), - static_cast( -2 * plane.c * plane.b ), - static_cast( 1 - (2 * plane.c * plane.c)), - 0, - static_cast( -2 * plane.d * plane.a ), - static_cast( -2 * plane.d * plane.b ), - static_cast( -2 * plane.d * plane.c ), - 1 - ); -} - -inline Matrix4 matrix4_reflection_for_plane45(const Plane3 &plane, const Vector3 &from, const Vector3 &to) -{ - Vector3 first = from; - Vector3 second = to; - - if ((vector3_dot(from, plane.normal()) > 0) == (vector3_dot(to, plane.normal()) > 0)) { - first = vector3_negated(first); - second = vector3_negated(second); - } - -#if 0 - globalOutputStream() << "normal: "; - print_vector3( plane.normal() ); - - globalOutputStream() << "from: "; - print_vector3( first ); - - globalOutputStream() << "to: "; - print_vector3( second ); -#endif - - Matrix4 swap = matrix4_swap_axes(first, second); - - swap.tx() = -static_cast( -2 * plane.a * plane.d ); - swap.ty() = -static_cast( -2 * plane.b * plane.d ); - swap.tz() = -static_cast( -2 * plane.c * plane.d ); - - return swap; -} - -void Texdef_transformLocked(TextureProjection &projection, std::size_t width, std::size_t height, const Plane3 &plane, - const Matrix4 &identity2transformed) -{ - //globalOutputStream() << "identity2transformed: " << identity2transformed << "\n"; - - //globalOutputStream() << "plane.normal(): " << plane.normal() << "\n"; - - Vector3 normalTransformed(matrix4_transformed_direction(identity2transformed, plane.normal())); - - //globalOutputStream() << "normalTransformed: " << normalTransformed << "\n"; - - // identity: identity space - // transformed: transformation - // stIdentity: base st projection space before transformation - // stTransformed: base st projection space after transformation - // stOriginal: original texdef space - - // stTransformed2stOriginal = stTransformed -> transformed -> identity -> stIdentity -> stOriginal - - Matrix4 identity2stIdentity; - Texdef_basisForNormal(projection, plane.normal(), identity2stIdentity); - //globalOutputStream() << "identity2stIdentity: " << identity2stIdentity << "\n"; - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - matrix4_transform_direction(identity2transformed, projection.m_basis_s); - matrix4_transform_direction(identity2transformed, projection.m_basis_t); - } - - Matrix4 transformed2stTransformed; - Texdef_basisForNormal(projection, normalTransformed, transformed2stTransformed); - - Matrix4 stTransformed2identity( - matrix4_affine_inverse(matrix4_multiplied_by_matrix4(transformed2stTransformed, identity2transformed))); - - Vector3 originalProjectionAxis(vector4_to_vector3(matrix4_affine_inverse(identity2stIdentity).z())); - - Vector3 transformedProjectionAxis(vector4_to_vector3(stTransformed2identity.z())); - - Matrix4 stIdentity2stOriginal; - Texdef_toTransform(projection, (float) width, (float) height, stIdentity2stOriginal); - Matrix4 identity2stOriginal(matrix4_multiplied_by_matrix4(stIdentity2stOriginal, identity2stIdentity)); - - //globalOutputStream() << "originalProj: " << originalProjectionAxis << "\n"; - //globalOutputStream() << "transformedProj: " << transformedProjectionAxis << "\n"; - double dot = vector3_dot(originalProjectionAxis, transformedProjectionAxis); - //globalOutputStream() << "dot: " << dot << "\n"; - if (dot == 0) { - // The projection axis chosen for the transformed normal is at 90 degrees - // to the transformed projection axis chosen for the original normal. - // This happens when the projection axis is ambiguous - e.g. for the plane - // 'X == Y' the projection axis could be either X or Y. - //globalOutputStream() << "flipped\n"; -#if 0 - globalOutputStream() << "projection off by 90\n"; - globalOutputStream() << "normal: "; - print_vector3( plane.normal() ); - globalOutputStream() << "original projection: "; - print_vector3( originalProjectionAxis ); - globalOutputStream() << "transformed projection: "; - print_vector3( transformedProjectionAxis ); -#endif - - Matrix4 identityCorrected = matrix4_reflection_for_plane45(plane, originalProjectionAxis, - transformedProjectionAxis); - - identity2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, identityCorrected); - } - - Matrix4 stTransformed2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, stTransformed2identity); - - Texdef_fromTransform(projection, (float) width, (float) height, stTransformed2stOriginal); - Texdef_normalise(projection, (float) width, (float) height); -} - -#if 1 - -void Q3_to_matrix(const texdef_t &texdef, float width, float height, const Vector3 &normal, Matrix4 &matrix) -{ - Normal_GetTransform(normal, matrix); - - Matrix4 transform; - - Texdef_toTransform(texdef, width, height, transform); - - matrix4_multiply_by_matrix4(matrix, transform); -} - -void BP_from_matrix(brushprimit_texdef_t &bp_texdef, const Vector3 &normal, const Matrix4 &transform) -{ - Matrix4 basis; - basis = g_matrix4_identity; - ComputeAxisBase(normal, vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y())); - vector4_to_vector3(basis.z()) = normal; - matrix4_transpose(basis); - matrix4_affine_invert(basis); - - Matrix4 basis2texture = matrix4_multiplied_by_matrix4(basis, transform); - - BPTexdef_fromTransform(bp_texdef, basis2texture); -} - -void Q3_to_BP(const texdef_t &texdef, float width, float height, const Vector3 &normal, brushprimit_texdef_t &bp_texdef) -{ - Matrix4 matrix; - Q3_to_matrix(texdef, width, height, normal, matrix); - BP_from_matrix(bp_texdef, normal, matrix); -} - -#endif diff --git a/src/brush_primit.h b/src/brush_primit.h deleted file mode 100644 index 0714996..0000000 --- a/src/brush_primit.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_PRIMIT_H ) -#define INCLUDED_BRUSH_PRIMIT_H - -#include "math/vector.h" -#include "itexdef.h" -#include "debugging/debugging.h" - -// Timo -// new brush primitive texdef -struct brushprimit_texdef_t { - brushprimit_texdef_t() - { - coords[0][0] = 2.0f; - coords[0][1] = 0.f; - coords[0][2] = 0.f; - coords[1][0] = 0.f; - coords[1][1] = 2.0f; - coords[1][2] = 0.f; - } - - void removeScale(std::size_t width, std::size_t height) - { -#if 1 - coords[0][0] *= width; - coords[0][1] *= width; - coords[0][2] *= width; - coords[1][0] *= height; - coords[1][1] *= height; - coords[1][2] *= height; -#endif - } - - void addScale(std::size_t width, std::size_t height) - { -#if 1 - ASSERT_MESSAGE(width > 0, "shader-width is 0"); - ASSERT_MESSAGE(height > 0, "shader-height is 0"); - coords[0][0] /= width; - coords[0][1] /= width; - coords[0][2] /= width; - coords[1][0] /= height; - coords[1][1] /= height; - coords[1][2] /= height; -#endif - } - - float coords[2][3]; -}; - -class TextureProjection { -public: -texdef_t m_texdef; -brushprimit_texdef_t m_brushprimit_texdef; -Vector3 m_basis_s; -Vector3 m_basis_t; - -TextureProjection() -{ -} - -TextureProjection( - const texdef_t &texdef, - const brushprimit_texdef_t &brushprimit_texdef, - const Vector3 &basis_s, - const Vector3 &basis_t - ) : - m_texdef(texdef), - m_brushprimit_texdef(brushprimit_texdef), - m_basis_s(basis_s), - m_basis_t(basis_t) -{ -} -}; - -float Texdef_getDefaultTextureScale(); - -class texdef_t; - -struct Winding; - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -template -class BasicVector4; - -typedef BasicVector4 Vector4; -typedef Vector4 Quaternion; - -class Matrix4; - -class Plane3; - -void Normal_GetTransform(const Vector3 &normal, Matrix4 &transform); - -void TexDef_Construct_Default(TextureProjection &projection); - -void Texdef_Assign(TextureProjection &projection, const TextureProjection &other); - -void Texdef_Shift(TextureProjection &projection, float s, float t); - -void Texdef_Scale(TextureProjection &projection, float s, float t); - -void Texdef_Rotate(TextureProjection &projection, float angle); - -void Texdef_FitTexture(TextureProjection &projection, std::size_t width, std::size_t height, const Vector3 &normal, - const Winding &w, float s_repeat, float t_repeat); -void Texdef_AlignTexture(TextureProjection &projection, const Plane3 &plane, const Vector3 &normal, const Winding &w, std::size_t width, std::size_t height, int alignment); - -void -Texdef_EmitTextureCoordinates(const TextureProjection &projection, std::size_t width, std::size_t height, Winding &w, - const Vector3 &normal, const Matrix4 &localToWorld); - -void ShiftScaleRotate_fromFace(texdef_t &shiftScaleRotate, const TextureProjection &projection); - -void ShiftScaleRotate_toFace(const texdef_t &shiftScaleRotate, TextureProjection &projection); - -void Texdef_transformLocked(TextureProjection &projection, std::size_t width, std::size_t height, const Plane3 &plane, - const Matrix4 &transform); - -void Texdef_normalise(TextureProjection &projection, float width, float height); - -enum TexdefTypeId { - TEXDEFTYPEID_QUAKE, - TEXDEFTYPEID_BRUSHPRIMITIVES, - TEXDEFTYPEID_HALFLIFE, -}; - -struct bp_globals_t { - // tells if we are internally using brush primitive (texture coordinates and map format) - // this is a shortcut for IntForKey( g_qeglobals.d_project_entity, "brush_primit" ) - // NOTE: must keep the two ones in sync - TexdefTypeId m_texdefTypeId; -}; - -extern bp_globals_t g_bp_globals; -extern float g_texdef_default_scale; - -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT); - -#endif diff --git a/src/brushmanip.cpp b/src/brushmanip.cpp deleted file mode 100644 index b94a909..0000000 --- a/src/brushmanip.cpp +++ /dev/null @@ -1,1388 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushmanip.h" - - -#include "gtkutil/widget.h" -#include "gtkutil/menu.h" -#include "gtkmisc.h" -#include "brushnode.h" -#include "map.h" -#include "texwindow.h" -#include "gtkdlgs.h" -#include "commands.h" -#include "mainframe.h" -#include "dialog.h" -#include "xywindow.h" -#include "preferences.h" - -#include -#include - -void Brush_ConstructCuboid(Brush &brush, const AABB &bounds, const char *shader, const TextureProjection &projection) -{ - const unsigned char box[3][2] = {{0, 1}, - {2, 0}, - {1, 2}}; - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - brush.clear(); - brush.reserve(6); - - { - for (int i = 0; i < 3; ++i) { - Vector3 planepts1(maxs); - Vector3 planepts2(maxs); - planepts2[box[i][0]] = mins[box[i][0]]; - planepts1[box[i][1]] = mins[box[i][1]]; - - brush.addPlane(maxs, planepts1, planepts2, shader, projection); - } - } - { - for (int i = 0; i < 3; ++i) { - Vector3 planepts1(mins); - Vector3 planepts2(mins); - planepts1[box[i][0]] = maxs[box[i][0]]; - planepts2[box[i][1]] = maxs[box[i][1]]; - - brush.addPlane(mins, planepts1, planepts2, shader, projection); - } - } -} - -inline float max_extent(const Vector3 &extents) -{ - return std::max(std::max(extents[0], extents[1]), extents[2]); -} - -inline float max_extent_2d(const Vector3 &extents, int axis) -{ - switch (axis) { - case 0: - return std::max(extents[1], extents[2]); - case 1: - return std::max(extents[0], extents[2]); - default: - return std::max(extents[0], extents[1]); - } -} - -const std::size_t c_brushPrism_minSides = 3; -const std::size_t c_brushPrism_maxSides = c_brush_maxFaces - 2; -const char *const c_brushPrism_name = "brushPrism"; - -void Brush_ConstructPrism(Brush &brush, const AABB &bounds, std::size_t sides, int axis, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushPrism_minSides) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushPrism_minSides) << "\n"; - return; - } - if (sides > c_brushPrism_maxSides) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushPrism_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides + 2); - - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - float radius = max_extent_2d(bounds.extents, axis); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - planepts[2][(axis + 1) % 3] = mins[(axis + 1) % 3]; - planepts[2][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[2][axis] = maxs[axis]; - planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[1][axis] = maxs[axis]; - planepts[0][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[0][(axis + 2) % 3] = maxs[(axis + 2) % 3]; - planepts[0][axis] = maxs[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - planepts[0][(axis + 1) % 3] = mins[(axis + 1) % 3]; - planepts[0][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[0][axis] = mins[axis]; - planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[1][axis] = mins[axis]; - planepts[2][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[2][(axis + 2) % 3] = maxs[(axis + 2) % 3]; - planepts[2][axis] = mins[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - for (std::size_t i = 0; i < sides; ++i) { - double sv = sin(i * 3.14159265 * 2 / sides); - double cv = cos(i * 3.14159265 * 2 / sides); - - planepts[0][(axis + 1) % 3] = static_cast( floor(mid[(axis + 1) % 3] + radius * cv + 0.5)); - planepts[0][(axis + 2) % 3] = static_cast( floor(mid[(axis + 2) % 3] + radius * sv + 0.5)); - planepts[0][axis] = mins[axis]; - - planepts[1][(axis + 1) % 3] = planepts[0][(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = planepts[0][(axis + 2) % 3]; - planepts[1][axis] = maxs[axis]; - - planepts[2][(axis + 1) % 3] = static_cast( floor(planepts[0][(axis + 1) % 3] - radius * sv + 0.5)); - planepts[2][(axis + 2) % 3] = static_cast( floor(planepts[0][(axis + 2) % 3] + radius * cv + 0.5)); - planepts[2][axis] = maxs[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -const std::size_t c_brushCone_minSides = 3; -const std::size_t c_brushCone_maxSides = 32; -const char *const c_brushCone_name = "brushCone"; - -void Brush_ConstructCone(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushCone_minSides) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushCone_minSides) << "\n"; - return; - } - if (sides > c_brushCone_maxSides) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushCone_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides + 1); - - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - planepts[0][0] = mins[0]; - planepts[0][1] = mins[1]; - planepts[0][2] = mins[2]; - planepts[1][0] = maxs[0]; - planepts[1][1] = mins[1]; - planepts[1][2] = mins[2]; - planepts[2][0] = maxs[0]; - planepts[2][1] = maxs[1]; - planepts[2][2] = mins[2]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - for (std::size_t i = 0; i < sides; ++i) { - double sv = sin(i * 3.14159265 * 2 / sides); - double cv = cos(i * 3.14159265 * 2 / sides); - - planepts[0][0] = static_cast( floor(mid[0] + radius * cv + 0.5)); - planepts[0][1] = static_cast( floor(mid[1] + radius * sv + 0.5)); - planepts[0][2] = mins[2]; - - planepts[1][0] = mid[0]; - planepts[1][1] = mid[1]; - planepts[1][2] = maxs[2]; - - planepts[2][0] = static_cast( floor(planepts[0][0] - radius * sv + 0.5)); - planepts[2][1] = static_cast( floor(planepts[0][1] + radius * cv + 0.5)); - planepts[2][2] = maxs[2]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -const std::size_t c_brushSphere_minSides = 3; -const std::size_t c_brushSphere_maxSides = 31; -const char *const c_brushSphere_name = "brushSphere"; - -void Brush_ConstructSphere(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushSphere_minSides) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushSphere_minSides) << "\n"; - return; - } - if (sides > c_brushSphere_maxSides) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushSphere_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides * sides); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - double dt = 2 * c_pi / sides; - double dp = c_pi / sides; - for (std::size_t i = 0; i < sides; i++) { - for (std::size_t j = 0; j < sides - 1; j++) { - double t = i * dt; - double p = float(j * dp - c_pi / 2); - - planepts[0] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p), radius)); - planepts[1] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p + dp), radius)); - planepts[2] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius)); - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } - } - - { - double p = (sides - 1) * dp - c_pi / 2; - for (std::size_t i = 0; i < sides; i++) { - double t = i * dt; - - planepts[0] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p), radius)); - planepts[1] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius)); - planepts[2] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p), radius)); - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } - } -} - -const std::size_t c_brushRock_minSides = 10; -const std::size_t c_brushRock_maxSides = 1000; -const char *const c_brushRock_name = "brushRock"; - -void Brush_ConstructRock(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushRock_minSides) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushRock_minSides) << "\n"; - return; - } - if (sides > c_brushRock_maxSides) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushRock_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides * sides); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - for (std::size_t j = 0; j < sides; j++) { - planepts[0][0] = rand() - (RAND_MAX / 2); - planepts[0][1] = rand() - (RAND_MAX / 2); - planepts[0][2] = rand() - (RAND_MAX / 2); - vector3_normalise(planepts[0]); - - // find two vectors that are perpendicular to planepts[0] - ComputeAxisBase(planepts[0], planepts[1], planepts[2]); - - planepts[0] = vector3_added(mid, vector3_scaled(planepts[0], radius)); - planepts[1] = vector3_added(planepts[0], vector3_scaled(planepts[1], radius)); - planepts[2] = vector3_added(planepts[0], vector3_scaled(planepts[2], radius)); - -#if 0 - // make sure the orientation is right - if ( vector3_dot( vector3_subtracted( planepts[0], mid ), vector3_cross( vector3_subtracted( planepts[1], mid ), vector3_subtracted( planepts[2], mid ) ) ) > 0 ) { - Vector3 h; - h = planepts[1]; - planepts[1] = planepts[2]; - planepts[2] = h; - globalOutputStream() << "flip\n"; - } - else{ - globalOutputStream() << "no flip\n"; - } -#endif - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -int GetViewAxis() -{ - switch (GlobalXYWnd_getCurrentViewType()) { - case XY: - return 2; - case XZ: - return 1; - case YZ: - return 0; - } - return 2; -} - -void Brush_ConstructPrefab(Brush &brush, EBrushPrefab type, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - switch (type) { - case eBrushCuboid: { - UndoableCommand undo("brushCuboid"); - - Brush_ConstructCuboid(brush, bounds, shader, projection); - } - break; - case eBrushPrism: { - int axis = GetViewAxis(); - StringOutputStream command; - command << c_brushPrism_name << " -sides " << Unsigned(sides) << " -axis " << axis; - UndoableCommand undo(command.c_str()); - - Brush_ConstructPrism(brush, bounds, sides, axis, shader, projection); - } - break; - case eBrushCone: { - StringOutputStream command; - command << c_brushCone_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructCone(brush, bounds, sides, shader, projection); - } - break; - case eBrushSphere: { - StringOutputStream command; - command << c_brushSphere_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructSphere(brush, bounds, sides, shader, projection); - } - break; - case eBrushRock: { - StringOutputStream command; - command << c_brushRock_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructRock(brush, bounds, sides, shader, projection); - } - break; - } -} - - -void ConstructRegionBrushes(scene::Node *brushes[6], const Vector3 ®ion_mins, const Vector3 ®ion_maxs) -{ - { - // set mins - Vector3 mins(region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32); - - // vary maxs - for (std::size_t i = 0; i < 3; i++) { - Vector3 maxs(region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32); - maxs[i] = region_mins[i]; - Brush_ConstructCuboid(*Node_getBrush(*brushes[i]), aabb_for_minmax(mins, maxs), texdef_name_default(), - TextureProjection()); - } - } - - { - // set maxs - Vector3 maxs(region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32); - - // vary mins - for (std::size_t i = 0; i < 3; i++) { - Vector3 mins(region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32); - mins[i] = region_maxs[i]; - Brush_ConstructCuboid(*Node_getBrush(*brushes[i + 3]), aabb_for_minmax(mins, maxs), texdef_name_default(), - TextureProjection()); - } - } -} - - -void Scene_BrushSetTexdef_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetTexdef(projection, ignorebasis); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetTexdef_Component_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetTexdef(projection, ignorebasis); - }); - SceneChangeNotify(); -} - - -void Scene_BrushSetFlags_Selected(scene::Graph &graph, const ContentsFlagsValue &flags) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetFlags(flags); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetFlags_Component_Selected(scene::Graph &graph, const ContentsFlagsValue &flags) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetFlags(flags); - }); - SceneChangeNotify(); -} - -void Scene_BrushShiftTexdef_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.ShiftTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushShiftTexdef_Component_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.ShiftTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushScaleTexdef_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.ScaleTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushScaleTexdef_Component_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.ScaleTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushRotateTexdef_Selected(scene::Graph &graph, float angle) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.RotateTexdef(angle); - }); - SceneChangeNotify(); -} - -void Scene_BrushRotateTexdef_Component_Selected(scene::Graph &graph, float angle) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.RotateTexdef(angle); - }); - SceneChangeNotify(); -} - - -void Scene_BrushSetShader_Selected(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetShader_Component_Selected(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetDetail_Selected(scene::Graph &graph, bool detail) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.setDetail(detail); - }); - SceneChangeNotify(); -} - -bool Face_FindReplaceShader(Face &face, const char *find, const char *replace) -{ - if (shader_equal(face.GetShader(), find)) { - face.SetShader(replace); - return true; - } - return false; -} - -bool DoingSearch(const char *repl) -{ - return (repl == NULL || (strcmp("textures/", repl) == 0)); -} - -void Scene_BrushFindReplaceShader(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - Scene_ForEachBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) { - if (shader_equal(faceinst.getFace().GetShader(), find)) { - faceinst.setSelected(SelectionSystem::eFace, true); - } - }); - } else { - Scene_ForEachBrush_ForEachFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - -void Scene_BrushFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) { - if (shader_equal(faceinst.getFace().GetShader(), find)) { - faceinst.setSelected(SelectionSystem::eFace, true); - } - }); - } else { - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - -// TODO: find for components -// d1223m: dont even know what they are... -void Scene_BrushFindReplaceShader_Component_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - - } else { - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - - -void Scene_BrushFitTexture_Selected(scene::Graph &graph, float s_repeat, float t_repeat) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.FitTexture(s_repeat, t_repeat); - }); - SceneChangeNotify(); -} -void Scene_BrushFitTexture_Component_Selected(scene::Graph &graph, float s_repeat, float t_repeat) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.FitTexture(s_repeat, t_repeat); - }); - SceneChangeNotify(); -} - -void Scene_BrushAlignTexture_Selected(scene::Graph &graph, int alignment) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.AlignTexture(alignment); - }); - SceneChangeNotify(); -} -void Scene_BrushAlignTexture_Component_Selected(scene::Graph &graph, int alignment) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.AlignTexture(alignment); - }); - SceneChangeNotify(); -} - -TextureProjection g_defaultTextureProjection; - -const TextureProjection &TextureTransform_getDefault() -{ - TexDef_Construct_Default(g_defaultTextureProjection); - return g_defaultTextureProjection; -} - -void Scene_BrushConstructPrefab(scene::Graph &graph, EBrushPrefab type, std::size_t sides, const char *shader) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Brush *brush = Node_getBrush(path.top()); - if (brush != 0) { - AABB bounds = brush->localAABB(); // copy bounds because the brush will be modified - Brush_ConstructPrefab(*brush, type, bounds, sides, shader, TextureTransform_getDefault()); - SceneChangeNotify(); - } - } -} - -void Scene_BrushResize_Selected(scene::Graph &graph, const AABB &bounds, const char *shader) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Brush *brush = Node_getBrush(path.top()); - if (brush != 0) { - Brush_ConstructCuboid(*brush, bounds, shader, TextureTransform_getDefault()); - SceneChangeNotify(); - } - } -} - -bool Brush_hasShader(const Brush &brush, const char *name) -{ - for (Brush::const_iterator i = brush.begin(); i != brush.end(); ++i) { - if (shader_equal((*i)->GetShader(), name)) { - return true; - } - } - return false; -} - -class BrushSelectByShaderWalker : public scene::Graph::Walker { -const char *m_name; -public: -BrushSelectByShaderWalker(const char *name) - : m_name(name) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 && Brush_hasShader(*brush, m_name)) { - Instance_getSelectable(instance)->setSelected(true); - } - } - return true; -} -}; - -void Scene_BrushSelectByShader(scene::Graph &graph, const char *name) -{ - graph.traverse(BrushSelectByShaderWalker(name)); -} - -void Scene_BrushSelectByShader_Component(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &face) { - printf("checking %s = %s\n", face.getFace().GetShader(), name); - if (shader_equal(face.getFace().GetShader(), name)) { - face.setSelected(SelectionSystem::eFace, true); - } - }); -} - -void Scene_BrushGetTexdef_Selected(scene::Graph &graph, TextureProjection &projection) -{ - bool done = false; - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - if (!done) { - done = true; - face.GetTexdef(projection); - } - }); -} - -void Scene_BrushGetTexdef_Component_Selected(scene::Graph &graph, TextureProjection &projection) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - faceInstance.getFace().GetTexdef(projection); - } -#else - FaceGetTexdef visitor( projection ); - Scene_ForEachSelectedBrushFace( graph, visitor ); -#endif -} - -void Scene_BrushGetShaderSize_Component_Selected(scene::Graph &graph, size_t &width, size_t &height) -{ - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - width = faceInstance.getFace().getShader().width(); - height = faceInstance.getFace().getShader().height(); - } -} - - -void Scene_BrushGetFlags_Selected(scene::Graph &graph, ContentsFlagsValue &flags) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - BrushInstance *brush = Instance_getBrush(GlobalSelectionSystem().ultimateSelected()); - if (brush != 0) { - bool done = false; - Brush_forEachFace(*brush, [&](Face &face) { - if (!done) { - done = true; - face.GetFlags(flags); - } - }); - } - } -#else - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetFlags( flags ) ); -#endif -} - -void Scene_BrushGetFlags_Component_Selected(scene::Graph &graph, ContentsFlagsValue &flags) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - faceInstance.getFace().GetFlags(flags); - } -#else - Scene_ForEachSelectedBrushFace( graph, FaceGetFlags( flags ) ); -#endif -} - - -void Scene_BrushGetShader_Selected(scene::Graph &graph, CopiedString &shader) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - BrushInstance *brush = Instance_getBrush(GlobalSelectionSystem().ultimateSelected()); - if (brush != 0) { - bool done = false; - Brush_forEachFace(*brush, [&](Face &face) { - if (!done) { - done = true; - shader = face.GetShader(); - } - }); - } - } -#else - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetShader( shader ) ); -#endif -} - -void Scene_BrushGetShader_Component_Selected(scene::Graph &graph, CopiedString &shader) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - shader = faceInstance.getFace().GetShader(); - } -#else - FaceGetShader visitor( shader ); - Scene_ForEachSelectedBrushFace( graph, visitor ); -#endif -} - - -class filter_face_shader : public FaceFilter { -const char *m_shader; -public: -filter_face_shader(const char *shader) : m_shader(shader) -{ -} - -bool filter(const Face &face) const -{ - return shader_equal(face.GetShader(), m_shader); -} -}; - -class filter_face_shader_prefix : public FaceFilter { -const char *m_prefix; -public: -filter_face_shader_prefix(const char *prefix) : m_prefix(prefix) -{ -} - -bool filter(const Face &face) const -{ - return shader_equal_n(face.GetShader(), m_prefix, strlen(m_prefix)); -} -}; - -class filter_face_flags : public FaceFilter { -int m_flags; -public: -filter_face_flags(int flags) : m_flags(flags) -{ -} - -bool filter(const Face &face) const -{ - return (face.getShader().shaderFlags() & m_flags) != 0; -} -}; - -class filter_face_contents : public FaceFilter { -int m_contents; -public: -filter_face_contents(int contents) : m_contents(contents) -{ -} - -bool filter(const Face &face) const -{ - return (face.getShader().m_flags.m_contentFlags & m_contents) != 0; -} -}; - - -class filter_brush_any_face : public BrushFilter { -FaceFilter *m_filter; -public: -filter_brush_any_face(FaceFilter *filter) : m_filter(filter) -{ -} - -bool filter(const Brush &brush) const -{ - bool filtered = false; - Brush_forEachFace(brush, [&](Face &face) { - if (m_filter->filter(face)) { - filtered = true; - } - }); - return filtered; -} -}; - -class filter_brush_all_faces : public BrushFilter { -FaceFilter *m_filter; -public: -filter_brush_all_faces(FaceFilter *filter) : m_filter(filter) -{ -} - -bool filter(const Brush &brush) const -{ - bool filtered = true; - Brush_forEachFace(brush, [&](Face &face) { - if (!m_filter->filter(face)) { - filtered = false; - } - }); - return filtered; -} -}; - - -filter_face_flags g_filter_face_clip(QER_CLIP); -filter_brush_all_faces g_filter_brush_clip(&g_filter_face_clip); - -filter_face_shader g_filter_face_clip_q2("textures/clip"); -filter_brush_all_faces g_filter_brush_clip_q2(&g_filter_face_clip_q2); - -filter_face_shader g_filter_face_weapclip("textures/common/weapclip"); -filter_brush_all_faces g_filter_brush_weapclip(&g_filter_face_weapclip); - -filter_face_shader g_filter_face_commonclip("textures/common/clip"); -filter_brush_all_faces g_filter_brush_commonclip(&g_filter_face_commonclip); - -filter_face_shader g_filter_face_fullclip("textures/common/fullclip"); -filter_brush_all_faces g_filter_brush_fullclip(&g_filter_face_fullclip); - -filter_face_shader g_filter_face_botclip("textures/common/botclip"); -filter_brush_all_faces g_filter_brush_botclip(&g_filter_face_botclip); - -filter_face_shader_prefix g_filter_face_caulk("textures/common/caulk"); -filter_brush_all_faces g_filter_brush_caulk(&g_filter_face_caulk); - -filter_face_shader_prefix g_filter_face_caulk_ja("textures/system/caulk"); -filter_brush_all_faces g_filter_brush_caulk_ja(&g_filter_face_caulk_ja); - -filter_face_shader_prefix g_filter_face_liquids("textures/liquids/"); -filter_brush_any_face g_filter_brush_liquids(&g_filter_face_liquids); - -filter_face_shader g_filter_face_hint("textures/common/hint"); -filter_brush_any_face g_filter_brush_hint(&g_filter_face_hint); - -filter_face_shader g_filter_face_hint_q2("textures/hint"); -filter_brush_any_face g_filter_brush_hint_q2(&g_filter_face_hint_q2); - -filter_face_shader g_filter_face_hint_ja("textures/system/hint"); -filter_brush_any_face g_filter_brush_hint_ja(&g_filter_face_hint_ja); - -filter_face_shader g_filter_face_areaportal("textures/common/areaportal"); -filter_brush_all_faces g_filter_brush_areaportal(&g_filter_face_areaportal); - -filter_face_shader g_filter_face_visportal("textures/editor/visportal"); -filter_brush_any_face g_filter_brush_visportal(&g_filter_face_visportal); - -filter_face_shader g_filter_face_clusterportal("textures/common/clusterportal"); -filter_brush_all_faces g_filter_brush_clusterportal(&g_filter_face_clusterportal); - -filter_face_shader g_filter_face_lightgrid("textures/common/lightgrid"); -filter_brush_all_faces g_filter_brush_lightgrid(&g_filter_face_lightgrid); - -filter_face_flags g_filter_face_translucent(QER_TRANS); -filter_brush_all_faces g_filter_brush_translucent(&g_filter_face_translucent); - -filter_face_contents g_filter_face_detail(BRUSH_DETAIL_MASK); -filter_brush_all_faces g_filter_brush_detail(&g_filter_face_detail); - -filter_face_shader_prefix g_filter_face_decals("textures/decals/"); -filter_brush_any_face g_filter_brush_decals(&g_filter_face_decals); - - -void BrushFilters_construct() -{ - add_brush_filter(g_filter_brush_clip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_clip_q2, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_weapclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_fullclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_commonclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_botclip, EXCLUDE_BOTCLIP); - add_brush_filter(g_filter_brush_caulk, EXCLUDE_CAULK); - add_brush_filter(g_filter_brush_caulk_ja, EXCLUDE_CAULK); - add_face_filter(g_filter_face_caulk, EXCLUDE_CAULK); - add_face_filter(g_filter_face_caulk_ja, EXCLUDE_CAULK); - add_brush_filter(g_filter_brush_liquids, EXCLUDE_LIQUIDS); - add_brush_filter(g_filter_brush_hint, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_hint_q2, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_hint_ja, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_clusterportal, EXCLUDE_CLUSTERPORTALS); - add_brush_filter(g_filter_brush_visportal, EXCLUDE_VISPORTALS); - add_brush_filter(g_filter_brush_areaportal, EXCLUDE_AREAPORTALS); - add_brush_filter(g_filter_brush_translucent, EXCLUDE_TRANSLUCENT); - add_brush_filter(g_filter_brush_detail, EXCLUDE_DETAILS); - add_brush_filter(g_filter_brush_detail, EXCLUDE_STRUCTURAL, true); - add_brush_filter(g_filter_brush_lightgrid, EXCLUDE_LIGHTGRID); - add_brush_filter(g_filter_brush_decals, EXCLUDE_DECALS); -} - -#if 0 - -void normalquantisation_draw(){ - glPointSize( 1 ); - glBegin( GL_POINTS ); - for ( std::size_t i = 0; i <= c_quantise_normal; ++i ) - { - for ( std::size_t j = 0; j <= c_quantise_normal; ++j ) - { - Normal3f vertex( normal3f_normalised( Normal3f( - static_cast( c_quantise_normal - j - i ), - static_cast( i ), - static_cast( j ) - ) ) ); - VectorScale( normal3f_to_array( vertex ), 64.f, normal3f_to_array( vertex ) ); - glVertex3fv( normal3f_to_array( vertex ) ); - vertex.x = -vertex.x; - glVertex3fv( normal3f_to_array( vertex ) ); - } - } - glEnd(); -} - -class RenderableNormalQuantisation : public OpenGLRenderable -{ -public: -void render( RenderStateFlags state ) const { - normalquantisation_draw(); -} -}; - -const float g_test_quantise_normal = 1.f / static_cast( 1 << 3 ); - -class TestNormalQuantisation -{ -void check_normal( const Normal3f& normal, const Normal3f& other ){ - spherical_t spherical = spherical_from_normal3f( normal ); - double longditude = RAD2DEG( spherical.longditude ); - double latitude = RAD2DEG( spherical.latitude ); - double x = cos( spherical.longditude ) * sin( spherical.latitude ); - double y = sin( spherical.longditude ) * sin( spherical.latitude ); - double z = cos( spherical.latitude ); - - ASSERT_MESSAGE( normal3f_dot( normal, other ) > 0.99, "bleh" ); -} - -void test_normal( const Normal3f& normal ){ - Normal3f test = normal3f_from_spherical( spherical_from_normal3f( normal ) ); - check_normal( normal, test ); - - EOctant octant = normal3f_classify_octant( normal ); - Normal3f folded = normal3f_fold_octant( normal, octant ); - ESextant sextant = normal3f_classify_sextant( folded ); - folded = normal3f_fold_sextant( folded, sextant ); - - double scale = static_cast( c_quantise_normal ) / ( folded.x + folded.y + folded.z ); - - double zbits = folded.z * scale; - double ybits = folded.y * scale; - - std::size_t zbits_q = static_cast( zbits ); - std::size_t ybits_q = static_cast( ybits ); - - ASSERT_MESSAGE( zbits_q <= ( c_quantise_normal / 8 ) * 3, "bleh" ); - ASSERT_MESSAGE( ybits_q <= ( c_quantise_normal / 2 ), "bleh" ); - ASSERT_MESSAGE( zbits_q + ( ( c_quantise_normal / 2 ) - ybits_q ) <= ( c_quantise_normal / 2 ), "bleh" ); - - std::size_t y_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? ybits_q : ( c_quantise_normal / 2 ) - ybits_q; - std::size_t z_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? zbits_q : ( c_quantise_normal / 2 ) - zbits_q; - std::size_t index = ( c_quantise_normal / 4 ) * y_t + z_t; - ASSERT_MESSAGE( index <= ( c_quantise_normal / 4 ) * ( c_quantise_normal / 2 ), "bleh" ); - - Normal3f tmp( c_quantise_normal - zbits_q - ybits_q, ybits_q, zbits_q ); - tmp = normal3f_normalised( tmp ); - - Normal3f unfolded = normal3f_unfold_octant( normal3f_unfold_sextant( tmp, sextant ), octant ); - - check_normal( normal, unfolded ); - - double dot = normal3f_dot( normal, unfolded ); - float length = VectorLength( normal3f_to_array( unfolded ) ); - float inv_length = 1 / length; - - Normal3f quantised = normal3f_quantised( normal ); - check_normal( normal, quantised ); -} -void test2( const Normal3f& normal, const Normal3f& other ){ - if ( normal3f_quantised( normal ) != normal3f_quantised( other ) ) { - int bleh = 0; - } -} - -static Normal3f normalise( float x, float y, float z ){ - return normal3f_normalised( Normal3f( x, y, z ) ); -} - -float vec_rand(){ - return static_cast( rand() - ( RAND_MAX / 2 ) ); -} - -Normal3f normal3f_rand(){ - return normalise( vec_rand(), vec_rand(), vec_rand() ); -} - -public: -TestNormalQuantisation(){ - for ( int i = 4096; i > 0; --i ) - test_normal( normal3f_rand() ); - - test_normal( normalise( 1, 0, 0 ) ); - test_normal( normalise( 0, 1, 0 ) ); - test_normal( normalise( 0, 0, 1 ) ); - test_normal( normalise( 1, 1, 0 ) ); - test_normal( normalise( 1, 0, 1 ) ); - test_normal( normalise( 0, 1, 1 ) ); - - test_normal( normalise( 10000, 10000, 10000 ) ); - test_normal( normalise( 10000, 10000, 10001 ) ); - test_normal( normalise( 10000, 10000, 10002 ) ); - test_normal( normalise( 10000, 10000, 10010 ) ); - test_normal( normalise( 10000, 10000, 10020 ) ); - test_normal( normalise( 10000, 10000, 10030 ) ); - test_normal( normalise( 10000, 10000, 10100 ) ); - test_normal( normalise( 10000, 10000, 10101 ) ); - test_normal( normalise( 10000, 10000, 10102 ) ); - test_normal( normalise( 10000, 10000, 10200 ) ); - test_normal( normalise( 10000, 10000, 10201 ) ); - test_normal( normalise( 10000, 10000, 10202 ) ); - test_normal( normalise( 10000, 10000, 10203 ) ); - test_normal( normalise( 10000, 10000, 10300 ) ); - - - test2( normalise( 10000, 10000, 10000 ), normalise( 10000, 10000, 10001 ) ); - test2( normalise( 10000, 10000, 10001 ), normalise( 10000, 10001, 10000 ) ); -} -}; - -TestNormalQuantisation g_testNormalQuantisation; - - -#endif - -#if 0 -class TestSelectableObserver : public observer_template -{ -public: -void notify( const Selectable& arguments ){ - bool bleh = arguments.isSelected(); -} -}; - -inline void test_bleh(){ - TestSelectableObserver test; - ObservableSelectableInstance< SingleObservable< SelectionChangeCallback > > bleh; - bleh.attach( test ); - bleh.setSelected( true ); - bleh.detach( test ); -} - -class TestBleh -{ -public: -TestBleh(){ - test_bleh(); -} -}; - -const TestBleh testbleh; -#endif - - -#if 0 -class TestRefcountedString -{ -public: -TestRefcountedString(){ - { - // copy construct - SmartString string1( "string1" ); - SmartString string2( string1 ); - SmartString string3( string2 ); - } - { - // refcounted assignment - SmartString string1( "string1" ); - SmartString string2( "string2" ); - string1 = string2; - } - { - // copy assignment - SmartString string1( "string1" ); - SmartString string2( "string2" ); - string1 = string2.c_str(); - } - { - // self-assignment - SmartString string1( "string1" ); - string1 = string1; - } - { - // self-assignment via another reference - SmartString string1( "string1" ); - SmartString string2( string1 ); - string1 = string2; - } -} -}; - -const TestRefcountedString g_testRefcountedString; - -#endif - -void Select_MakeDetail() -{ - UndoableCommand undo("brushSetDetail"); - Scene_BrushSetDetail_Selected(GlobalSceneGraph(), true); -} - -void Select_MakeStructural() -{ - UndoableCommand undo("brushClearDetail"); - Scene_BrushSetDetail_Selected(GlobalSceneGraph(), false); -} - -class BrushMakeSided { -std::size_t m_count; -public: -BrushMakeSided(std::size_t count) - : m_count(count) -{ -} - -void set() -{ - Scene_BrushConstructPrefab(GlobalSceneGraph(), eBrushPrism, m_count, - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -typedef MemberCaller SetCaller; -}; - - -BrushMakeSided g_brushmakesided3(3); -BrushMakeSided g_brushmakesided4(4); -BrushMakeSided g_brushmakesided5(5); -BrushMakeSided g_brushmakesided6(6); -BrushMakeSided g_brushmakesided7(7); -BrushMakeSided g_brushmakesided8(8); -BrushMakeSided g_brushmakesided9(9); - -inline int axis_for_viewtype(int viewtype) -{ - switch (viewtype) { - case XY: - return 2; - case XZ: - return 1; - case YZ: - return 0; - } - return 2; -} - -class BrushPrefab { -EBrushPrefab m_type; -public: -BrushPrefab(EBrushPrefab type) - : m_type(type) -{ -} - -void set() -{ - DoSides(m_type, axis_for_viewtype(GetViewAxis())); -} - -typedef MemberCaller SetCaller; -}; - -BrushPrefab g_brushprism(eBrushPrism); -BrushPrefab g_brushcone(eBrushCone); -BrushPrefab g_brushsphere(eBrushSphere); -BrushPrefab g_brushrock(eBrushRock); - - -void FlipClip(); - -void SplitClip(); - -void Clip(); - -void OnClipMode(bool enable); - -bool ClipMode(); - - -void ClipSelected() -{ - if (ClipMode()) { - UndoableCommand undo("clipperClip"); - Clip(); - } -} - -void SplitSelected() -{ - if (ClipMode()) { - UndoableCommand undo("clipperSplit"); - SplitClip(); - } -} - -void FlipClipper() -{ - FlipClip(); -} - - -Callback g_texture_lock_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_texdef_movelock_caller( - g_brush_texturelock_enabled); -ToggleItem g_texdef_movelock_item(g_texdef_movelock_caller); - -void Texdef_ToggleMoveLock() -{ - g_brush_texturelock_enabled = !g_brush_texturelock_enabled; - g_texdef_movelock_item.update(); - g_texture_lock_status_changed(); -} - - -void Brush_registerCommands() -{ - GlobalToggles_insert("TogTexLock", makeCallbackF(Texdef_ToggleMoveLock), - ToggleItem::AddCallbackCaller(g_texdef_movelock_item), - Accelerator('T', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("BrushPrism", BrushPrefab::SetCaller(g_brushprism)); - GlobalCommands_insert("BrushCone", BrushPrefab::SetCaller(g_brushcone)); - GlobalCommands_insert("BrushSphere", BrushPrefab::SetCaller(g_brushsphere)); - GlobalCommands_insert("BrushRock", BrushPrefab::SetCaller(g_brushrock)); - - GlobalCommands_insert("Brush3Sided", BrushMakeSided::SetCaller(g_brushmakesided3), - Accelerator('3', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush4Sided", BrushMakeSided::SetCaller(g_brushmakesided4), - Accelerator('4', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush5Sided", BrushMakeSided::SetCaller(g_brushmakesided5), - Accelerator('5', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush6Sided", BrushMakeSided::SetCaller(g_brushmakesided6), - Accelerator('6', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush7Sided", BrushMakeSided::SetCaller(g_brushmakesided7), - Accelerator('7', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush8Sided", BrushMakeSided::SetCaller(g_brushmakesided8), - Accelerator('8', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush9Sided", BrushMakeSided::SetCaller(g_brushmakesided9), - Accelerator('9', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("ClipSelected", makeCallbackF(ClipSelected), Accelerator(GDK_KEY_Return)); - GlobalCommands_insert("SplitSelected", makeCallbackF(SplitSelected), - Accelerator(GDK_KEY_Return, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("FlipClip", makeCallbackF(FlipClipper), - Accelerator(GDK_KEY_Return, (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("MakeDetail", makeCallbackF(Select_MakeDetail), - Accelerator('M', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("MakeStructural", makeCallbackF(Select_MakeStructural), - Accelerator('S', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); -} - -void Brush_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Prism...", "BrushPrism"); - create_menu_item_with_mnemonic(menu, "Cone...", "BrushCone"); - create_menu_item_with_mnemonic(menu, "Sphere...", "BrushSphere"); - create_menu_item_with_mnemonic(menu, "Rock...", "BrushRock"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "CSG"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGMakeHollow"); - create_menu_item_with_mnemonic(menu_in_menu, "Make _Room", "CSGMakeRoom"); - create_menu_item_with_mnemonic(menu_in_menu, "CSG _Subtract", "CSGSubtract"); - create_menu_item_with_mnemonic(menu_in_menu, "CSG _Merge", "CSGMerge"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Clipper"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - - create_menu_item_with_mnemonic(menu_in_menu, "Clip selection", "ClipSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Split selection", "SplitSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip Clip orientation", "FlipClip"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu, "Snap selection to _grid", "SnapToGrid"); - - create_check_menu_item_with_mnemonic(menu, "Texture Lock", "TogTexLock"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Copy Face Texture", "FaceCopyTexture"); - create_menu_item_with_mnemonic(menu, "Paste Face Texture", "FacePasteTexture"); - - command_connect_accelerator("Brush3Sided"); - command_connect_accelerator("Brush4Sided"); - command_connect_accelerator("Brush5Sided"); - command_connect_accelerator("Brush6Sided"); - command_connect_accelerator("Brush7Sided"); - command_connect_accelerator("Brush8Sided"); - command_connect_accelerator("Brush9Sided"); -} diff --git a/src/brushmanip.h b/src/brushmanip.h deleted file mode 100644 index 0ac2c65..0000000 --- a/src/brushmanip.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_BRUSHWRAPPER_H ) -#define INCLUDED_BRUSHWRAPPER_H - -#include -#include -#include "string/stringfwd.h" -#include "generic/callback.h" - -enum EBrushPrefab { - eBrushCuboid, - eBrushPrism, - eBrushCone, - eBrushSphere, - eBrushRock, -}; - -class TextureProjection; - -class ContentsFlagsValue; -namespace scene { -class Graph; -} - -void Scene_BrushConstructPrefab(scene::Graph &graph, EBrushPrefab type, std::size_t sides, const char *shader); - -class AABB; - -void Scene_BrushResize_Selected(scene::Graph &graph, const AABB &bounds, const char *shader); - -void Scene_BrushSetTexdef_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis); - -void Scene_BrushSetTexdef_Component_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis); - -void Scene_BrushGetTexdef_Selected(scene::Graph &graph, TextureProjection &projection); - -void Scene_BrushGetTexdef_Component_Selected(scene::Graph &graph, TextureProjection &projection); - -void Scene_BrushGetShaderSize_Component_Selected(scene::Graph &graph, size_t &width, size_t &height); - -void Scene_BrushSetFlags_Selected(scene::Graph &graph, const ContentsFlagsValue &flags); - -void Scene_BrushSetFlags_Component_Selected(scene::Graph &graph, const ContentsFlagsValue &flags); - -void Scene_BrushGetFlags_Selected(scene::Graph &graph, ContentsFlagsValue &flags); - -void Scene_BrushGetFlags_Component_Selected(scene::Graph &graph, ContentsFlagsValue &flags); - -void Scene_BrushShiftTexdef_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushShiftTexdef_Component_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushScaleTexdef_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushScaleTexdef_Component_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushRotateTexdef_Selected(scene::Graph &graph, float angle); - -void Scene_BrushRotateTexdef_Component_Selected(scene::Graph &graph, float angle); - -void Scene_BrushSetShader_Selected(scene::Graph &graph, const char *name); - -void Scene_BrushSetShader_Component_Selected(scene::Graph &graph, const char *name); - -void Scene_BrushGetShader_Selected(scene::Graph &graph, CopiedString &shader); - -void Scene_BrushGetShader_Component_Selected(scene::Graph &graph, CopiedString &shader); - -void Scene_BrushFindReplaceShader(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushFindReplaceShader_Component_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushSelectByShader(scene::Graph &graph, const char *name); - -void Scene_BrushSelectByShader_Component(scene::Graph &graph, const char *name); - -void Scene_BrushFitTexture_Selected(scene::Graph &graph, float s_repeat, float t_repeat); - -void Scene_BrushFitTexture_Component_Selected(scene::Graph &graph, float s_repeat, float t_repeat); - -void Scene_BrushAlignTexture_Selected(scene::Graph &graph, int alignment); -void Scene_BrushAlignTexture_Component_Selected(scene::Graph &graph, int alignment); - -void Brush_constructMenu(ui::Menu menu); - -extern Callback g_texture_lock_status_changed; - -void BrushFilters_construct(); - -void Brush_registerCommands(); - -#endif diff --git a/src/brushmodule.cpp b/src/brushmodule.cpp deleted file mode 100644 index c9acb28..0000000 --- a/src/brushmodule.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushmodule.h" - -#include "qerplugin.h" - -#include "brushnode.h" -#include "brushmanip.h" - -#include "preferencesystem.h" -#include "stringio.h" - -#include "map.h" -#include "qe3.h" -#include "mainframe.h" -#include "preferences.h" - -LatchedValue g_useAlternativeTextureProjection(false, "Use alternative texture-projection (\"brush primitives\")"); -static int g_numbrushtypes = 0; -static int g_selectedbrushtype; -static EBrushType g_brushTypes[8], g_brushType; -//bool g_showAlternativeTextureProjectionOption = false; -bool g_brush_always_caulk = true; - -bool getTextureLockEnabled() -{ - return g_brush_texturelock_enabled; -} - -struct Face_SnapPlanes { - static void Export(const QuantiseFunc &self, const Callback &returnz) - { - returnz(self == quantiseInteger); - } - - static void Import(QuantiseFunc &self, bool value) - { - self = value ? quantiseInteger : quantiseFloating; - } -}; - -const char* BrushType_getName( EBrushType type ){ - switch ( type ) - { - case eBrushTypeQuake: - case eBrushTypeQuake2: - case eBrushTypeQuake3: - return "Axial Projection"; - case eBrushTypeQuake3BP: - return "Brush Primitives"; - case eBrushTypeQuake3Valve: - case eBrushTypeHalfLife: - return "Valve 220"; - case eBrushTypeDoom3: - return "Doom3"; - case eBrushTypeQuake4: - return "Quake4"; - default: - return "unknown"; - } -} - -void Brush_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "", "Snap planes to integer grid", - make_property(Face::m_quantise) - ); - page.appendEntry( - "Default texture scale", - g_texdef_default_scale - ); - if (g_numbrushtypes > 1) { - const char *names[8]; - for(int i = 0; i < g_numbrushtypes; i++) - names[i] = BrushType_getName(g_brushTypes[i]); - page.appendCombo("Default Brush Type", g_selectedbrushtype, StringArrayRange(names, names+g_numbrushtypes)); - } - // d1223m - page.appendCheckBox("", - "Always use caulk for new brushes", - g_brush_always_caulk - ); -} - -void Brush_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Brush", "Brush Settings")); - Brush_constructPreferences(page); -} - -void Brush_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Brush_constructPage)); -} - -void Brush_unlatchPreferences() -{ - Brush_toggleFormat(0); -} - -void Brush_setFormat(EBrushType t) -{ - if (g_numbrushtypes) { -// g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i; - Brush::destroyStatic(); - g_brushType = t; - Brush::constructStatic(t); - } -} -void Brush_toggleFormat(int i) -{ - if (g_numbrushtypes) { -// g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i; - Brush::destroyStatic(); - g_brushType = g_brushTypes[i]; - Brush::constructStatic(g_brushType); - } -} - -int Brush_toggleFormatCount() -{ - if (g_numbrushtypes) { - return g_numbrushtypes; - } - return 1; -} - -static void Brush_Construct(void) -{ - EBrushType type = g_brushType = g_brushTypes[g_selectedbrushtype]; - - // d1223m - GlobalPreferenceSystem().registerPreference( - "BrushAlwaysCaulk", - make_property_string(g_brush_always_caulk) - ); - - Brush_registerCommands(); - Brush_registerPreferencesPage(); - - BrushFilters_construct(); - - BrushClipPlane::constructStatic(); - BrushInstance::constructStatic(); - Brush::constructStatic(type); - - Brush::m_maxWorldCoord = g_MaxWorldCoord; - BrushInstance::m_counter = &g_brushCount; - - g_texdef_default_scale = 0.5f; - const char *value = g_pGameDescription->getKeyValue("default_scale"); - if (!string_empty(value)) { - float scale = static_cast( atof(value)); - if (scale != 0) { - g_texdef_default_scale = scale; - } else { - globalErrorStream() << "error parsing \"default_scale\" attribute\n"; - } - } - - GlobalPreferenceSystem().registerPreference("TextureLock", make_property_string(g_brush_texturelock_enabled)); - GlobalPreferenceSystem().registerPreference("BrushSnapPlanes", - make_property_string(Face::m_quantise)); - GlobalPreferenceSystem().registerPreference("TexdefDefaultScale", make_property_string(g_texdef_default_scale)); - - GridStatus_getTextureLockEnabled = getTextureLockEnabled; - g_texture_lock_status_changed = makeCallbackF(GridStatus_onTextureLockEnabledChanged); -} -static void Brush_Construct(EBrushType type0, EBrushType type1, EBrushType type2) -{ - g_numbrushtypes = 0; - g_brushTypes[g_numbrushtypes++] = type0; - if (type1 != type0) - g_brushTypes[g_numbrushtypes++] = type1; - if (type2 != type0 && type2 != type1) - g_brushTypes[g_numbrushtypes++] = type2; - - if (g_numbrushtypes) { - const char *value = g_pGameDescription->getKeyValue("brush_primit"); - if (!string_empty(value)) { - g_selectedbrushtype = atoi(value); - if (g_selectedbrushtype < 0 || g_selectedbrushtype >= g_numbrushtypes) - g_selectedbrushtype = 0; - } - -// GlobalPreferenceSystem().registerPreference( -// "BrushType", -// make_property(g_selectedbrushtype) -// ); - } - - Brush_Construct(); -} -static void Brush_Construct(EBrushType type0, EBrushType type1) -{ - Brush_Construct(type0, type1, type0); -} -static void Brush_Construct(EBrushType type0) -{ - Brush_Construct(type0, type0, type0); -} - -void Brush_Destroy() -{ - Brush::m_maxWorldCoord = 0; - BrushInstance::m_counter = 0; - - Brush::destroyStatic(); - BrushInstance::destroyStatic(); - BrushClipPlane::destroyStatic(); -} - -void Brush_clipperColourChanged() -{ - BrushClipPlane::destroyStatic(); - BrushClipPlane::constructStatic(); -} - -void BrushFaceData_fromFace(const BrushFaceDataCallback &callback, Face &face) -{ - _QERFaceData faceData; - faceData.m_p0 = face.getPlane().planePoints()[0]; - faceData.m_p1 = face.getPlane().planePoints()[1]; - faceData.m_p2 = face.getPlane().planePoints()[2]; - faceData.m_shader = face.GetShader(); - faceData.m_texdef = face.getTexdef().m_projection.m_texdef; - faceData.contents = face.getShader().m_flags.m_contentFlags; - faceData.flags = face.getShader().m_flags.m_surfaceFlags; - faceData.value = face.getShader().m_flags.m_value; - callback(faceData); -} - -typedef ConstReferenceCaller BrushFaceDataFromFaceCaller; -typedef Callback FaceCallback; - -class Quake3BrushCreator : public BrushCreator { -public: -scene::Node &createBrush() -{ - return (new BrushNode)->node(); -} - -virtual EBrushType getBrushType() -{ - return g_brushType; -} -virtual void setBrushType(EBrushType t) -{ - if (g_brushType != t) - Brush_setFormat(t); -} - -void Brush_forEachFace(scene::Node &brush, const BrushFaceDataCallback &callback) -{ - ::Brush_forEachFace(*Node_getBrush(brush), FaceCallback(BrushFaceDataFromFaceCaller(callback))); -} - -bool Brush_addFace(scene::Node &brush, const _QERFaceData &faceData) -{ - Node_getBrush(brush)->undoSave(); - return Node_getBrush(brush)->addPlane(faceData.m_p0, faceData.m_p1, faceData.m_p2, faceData.m_shader, - TextureProjection(faceData.m_texdef, brushprimit_texdef_t(), - Vector3(0, 0, 0), Vector3(0, 0, 0))) != 0; -} -}; - -Quake3BrushCreator g_Quake3BrushCreator; - -BrushCreator &GetBrushCreator() -{ - return g_Quake3BrushCreator; -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - - -class BrushDependencies : - public GlobalRadiantModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalFilterModuleRef { -}; - -class BrushDoom3API : public TypeSystemRef { -BrushCreator *m_brushdoom3; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "doom3"); - -BrushDoom3API() -{ - Brush_Construct(eBrushTypeDoom3); - - m_brushdoom3 = &GetBrushCreator(); -} - -~BrushDoom3API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushdoom3; -} -}; - -typedef SingletonModule BrushDoom3Module; -typedef Static StaticBrushDoom3Module; -StaticRegisterModule staticRegisterBrushDoom3(StaticBrushDoom3Module::instance()); - - -class BrushQuake4API : public TypeSystemRef { -BrushCreator *m_brushquake4; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake4"); - -BrushQuake4API() -{ - Brush_Construct(eBrushTypeQuake4); - - m_brushquake4 = &GetBrushCreator(); -} - -~BrushQuake4API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake4; -} -}; - -typedef SingletonModule BrushQuake4Module; -typedef Static StaticBrushQuake4Module; -StaticRegisterModule staticRegisterBrushQuake4(StaticBrushQuake4Module::instance()); - - -class BrushQuake3API : public TypeSystemRef { -BrushCreator *m_brushquake3; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -BrushQuake3API() -{ - Brush_Construct(eBrushTypeQuake3, eBrushTypeQuake3BP, eBrushTypeQuake3Valve); - - m_brushquake3 = &GetBrushCreator(); -} - -~BrushQuake3API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake3; -} -}; - -typedef SingletonModule BrushQuake3Module; -typedef Static StaticBrushQuake3Module; -StaticRegisterModule staticRegisterBrushQuake3(StaticBrushQuake3Module::instance()); - - -class BrushQuake2API : public TypeSystemRef { -BrushCreator *m_brushquake2; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake2"); - -BrushQuake2API() -{ - Brush_Construct(eBrushTypeQuake2); - - m_brushquake2 = &GetBrushCreator(); -} - -~BrushQuake2API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake2; -} -}; - -typedef SingletonModule BrushQuake2Module; -typedef Static StaticBrushQuake2Module; -StaticRegisterModule staticRegisterBrushQuake2(StaticBrushQuake2Module::instance()); - - -class BrushQuake1API : public TypeSystemRef { -BrushCreator *m_brushquake1; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake"); - -BrushQuake1API() -{ - Brush_Construct(eBrushTypeQuake, eBrushTypeHalfLife); - - m_brushquake1 = &GetBrushCreator(); -} - -~BrushQuake1API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake1; -} -}; - -typedef SingletonModule BrushQuake1Module; -typedef Static StaticBrushQuake1Module; -StaticRegisterModule staticRegisterBrushQuake1(StaticBrushQuake1Module::instance()); - - -class BrushHalfLifeAPI : public TypeSystemRef { -BrushCreator *m_brushhalflife; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "halflife"); - -BrushHalfLifeAPI() -{ - Brush_Construct(eBrushTypeHalfLife); - - m_brushhalflife = &GetBrushCreator(); -} - -~BrushHalfLifeAPI() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushhalflife; -} -}; - -typedef SingletonModule BrushHalfLifeModule; -typedef Static StaticBrushHalfLifeModule; -StaticRegisterModule staticRegisterBrushHalfLife(StaticBrushHalfLifeModule::instance()); diff --git a/src/brushmodule.h b/src/brushmodule.h deleted file mode 100644 index 9501247..0000000 --- a/src/brushmodule.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHMODULE_H ) -#define INCLUDED_BRUSHMODULE_H - -#include "brush.h" - -void Brush_clipperColourChanged(); - -void Brush_unlatchPreferences(); - -int Brush_toggleFormatCount(); - -void Brush_toggleFormat(int i); -void Brush_setFormat(EBrushType t); - -#endif diff --git a/src/brushnode.cpp b/src/brushnode.cpp deleted file mode 100644 index aed252d..0000000 --- a/src/brushnode.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushnode.h" diff --git a/src/brushnode.h b/src/brushnode.h deleted file mode 100644 index 2f20505..0000000 --- a/src/brushnode.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHNODE_H ) -#define INCLUDED_BRUSHNODE_H - -#include "instancelib.h" -#include "brush.h" -#include "brushtokens.h" -#include "brushxml.h" - -class BrushNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Brush m_brush; -BrushTokenImporter m_mapImporter; -BrushTokenExporter m_mapExporter; -BrushXMLImporter m_xmlImporter; -BrushXMLExporter m_xmlExporter; - -public: - -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_brush; -} - -TransformNode &get(NullType) -{ - return m_brush; -} - -Brush &get(NullType) -{ - return m_brush; -} - -XMLImporter &get(NullType) -{ - return m_xmlImporter; -} - -XMLExporter &get(NullType) -{ - return m_xmlExporter; -} - -MapImporter &get(NullType) -{ - return m_mapImporter; -} - -MapExporter &get(NullType) -{ - return m_mapExporter; -} - -Nameable &get(NullType) -{ - return m_brush; -} - -BrushDoom3 &get(NullType) -{ - return m_brush; -} - -BrushNode() : - m_node(this, this, StaticTypeCasts::instance().get()), - m_brush(m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_mapImporter(m_brush), - m_mapExporter(m_brush), - m_xmlImporter(m_brush), - m_xmlExporter(m_brush) -{ -} - -BrushNode(const BrushNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_brush(other.m_brush, m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_mapImporter(m_brush), - m_mapExporter(m_brush), - m_xmlImporter(m_brush), - m_xmlExporter(m_brush) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new BrushNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new BrushInstance(path, parent, m_brush); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -inline Brush *Node_getBrush(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -#endif diff --git a/src/brushtokens.cpp b/src/brushtokens.cpp deleted file mode 100644 index 3a3d970..0000000 --- a/src/brushtokens.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushtokens.h" diff --git a/src/brushtokens.h b/src/brushtokens.h deleted file mode 100644 index 554544b..0000000 --- a/src/brushtokens.h +++ /dev/null @@ -1,755 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHTOKENS_H ) -#define INCLUDED_BRUSHTOKENS_H - -#include "stringio.h" -#include "stream/stringstream.h" -#include "brush.h" - -inline bool FaceShader_importContentsFlagsValue(FaceShader &faceShader, Tokeniser &tokeniser) -{ - //don't break if they're omitted. Yes, this might mean that it silently accepts quake-format maps where q3 maps were expected. - if (Tokeniser_nextTokenIsDigit(tokeniser)) - { - // parse the optional contents/flags/value - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_contentFlags)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_surfaceFlags)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_value)); - } - return true; -} - -inline bool FaceTexdef_HalfLife_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ - // parse texdef - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "[")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.x())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.y())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.z())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]")); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "[")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.x())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.y())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.z())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate)); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1])); - - texdef.m_projection.m_texdef.rotate = -texdef.m_projection.m_texdef.rotate; - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef"); - return true; -} - -inline bool FaceTexdef_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ -/* //pass it on to halflife parsing if we unexpectedly find it in one of the other formats (blame J.A.C.K.) - const char* token = tokeniser.getToken(); - if ( token && *token == '[' ) - { - tokeniser.ungetToken(); - texdef.m_scaleApplied = true; - return FaceTexdef_HalfLife_importTokens(texdef, tokeniser); - } - tokeniser.ungetToken(); - */ - // parse texdef - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate)); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1])); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef"); - return true; -} - -inline bool FaceTexdef_BP_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ - // parse alternate texdef - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][2])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][2])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool FacePlane_importTokens(FacePlane &facePlane, Tokeniser &tokeniser) -{ - // parse planepts - for (std::size_t i = 0; i < 3; i++) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - for (std::size_t j = 0; j < 3; ++j) { - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, facePlane.planePoints()[i][j])); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - facePlane.MakePlane(); - return true; -} - -inline bool FacePlane_Doom3_importTokens(FacePlane &facePlane, Tokeniser &tokeniser) -{ - Plane3 plane; - // parse plane equation - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.a)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.b)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.c)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.d)); - plane.d = -plane.d; - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - - facePlane.setDoom3Plane(plane); - return true; -} - -inline bool FaceShader_Doom3_importTokens(FaceShader &faceShader, Tokeniser &tokeniser) -{ - const char *shader = tokeniser.getToken(); - if (shader == 0) { - Tokeniser_unexpectedError(tokeniser, shader, "#shader-name"); - return false; - } - if (string_equal(shader, "_emptyname")) { - shader = texdef_name_default(); - } - faceShader.setShader(shader); - return true; -} - -inline bool FaceShader_importTokens(FaceShader &faceShader, Tokeniser &tokeniser) -{ - const char *texture = tokeniser.getToken(); - if (texture == 0) { - Tokeniser_unexpectedError(tokeniser, texture, "#texture-name"); - return false; - } - if (string_equal(texture, "NULL")) { - faceShader.setShader(texdef_name_default()); - } else { - StringOutputStream shader(string_length(GlobalTexturePrefix_get()) + string_length(texture)); - shader << GlobalTexturePrefix_get() << texture; - faceShader.setShader(shader.c_str()); - } - return true; -} - - -class Doom3FaceTokenImporter { -Face &m_face; -public: -Doom3FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake4FaceTokenImporter { -Face &m_face; -public: -Quake4FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake2FaceTokenImporter { -Face &m_face; -public: -Quake2FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - if (Tokeniser_nextTokenIsDigit(tokeniser)) { - m_face.getShader().m_flags.m_specified = true; - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - } - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class Quake3FaceTokenImporter { -Face &m_face; -public: -Quake3FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class Quake3BPFaceTokenImporter { -Face &m_face; -public: -Quake3BPFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake3ValveFaceTokenImporter { -Face &m_face; -public: -Quake3ValveFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_HalfLife_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class QuakeFaceTokenImporter { -Face &m_face; -public: -QuakeFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class HalfLifeFaceTokenImporter { -Face &m_face; -public: -HalfLifeFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_HalfLife_importTokens(m_face.getTexdef(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - - -inline void FacePlane_Doom3_exportTokens(const FacePlane &facePlane, TokenWriter &writer) -{ - // write plane equation - writer.writeToken("("); - writer.writeFloat(facePlane.getDoom3Plane().a); - writer.writeFloat(facePlane.getDoom3Plane().b); - writer.writeFloat(facePlane.getDoom3Plane().c); - writer.writeFloat(-facePlane.getDoom3Plane().d); - writer.writeToken(")"); -} - -inline void FacePlane_exportTokens(const FacePlane &facePlane, TokenWriter &writer) -{ - // write planepts - for (std::size_t i = 0; i < 3; i++) { - writer.writeToken("("); - for (std::size_t j = 0; j < 3; j++) { - writer.writeFloat(Face::m_quantise(facePlane.planePoints()[i][j])); - } - writer.writeToken(")"); - } -} - -inline void FaceTexdef_BP_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - // write alternate texdef - writer.writeToken("("); - { - writer.writeToken("("); - for (std::size_t i = 0; i < 3; i++) { - writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[0][i]); - } - writer.writeToken(")"); - } - { - writer.writeToken("("); - for (std::size_t i = 0; i < 3; i++) { - writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[1][i]); - } - writer.writeToken(")"); - } - writer.writeToken(")"); -} - -inline void FaceTexdef_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef"); - // write texdef - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.rotate); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]); -} - -inline void FaceTexdef_HalfLife_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef"); - // write texdef - writer.writeToken("["); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.x()); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.y()); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.z()); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]); - writer.writeToken("]"); - writer.writeToken("["); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.x()); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.y()); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.z()); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]); - writer.writeToken("]"); - writer.writeFloat(-faceTexdef.m_projection.m_texdef.rotate); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]); -} - -inline void FaceShader_ContentsFlagsValue_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write surface flags - writer.writeInteger(faceShader.m_flags.m_contentFlags); - writer.writeInteger(faceShader.m_flags.m_surfaceFlags); - writer.writeInteger(faceShader.m_flags.m_value); -} - -inline void FaceShader_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write shader name - if (string_empty(shader_get_textureName(faceShader.getShader()))) { - writer.writeToken("NULL"); - } else { - writer.writeToken(shader_get_textureName(faceShader.getShader())); - } -} - -inline void FaceShader_Doom3_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write shader name - if (string_empty(shader_get_textureName(faceShader.getShader()))) { - writer.writeString("_emptyname"); - } else { - writer.writeString(faceShader.getShader()); - } -} - -class Doom3FaceTokenExporter { -const Face &m_face; -public: -Doom3FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_Doom3_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_Doom3_exportTokens(m_face.getShader(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake4FaceTokenExporter { -const Face &m_face; -public: -Quake4FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_Doom3_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_Doom3_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake2FaceTokenExporter { -const Face &m_face; -public: -Quake2FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - if (m_face.getShader().m_flags.m_specified || m_face.isDetail()) { - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - } - writer.nextLine(); -} -}; - -class Quake3FaceTokenExporter { -const Face &m_face; -public: -Quake3FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake3BPFaceTokenExporter { -const Face &m_face; -public: -Quake3BPFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake3ValveFaceTokenExporter { -const Face &m_face; -public: -Quake3ValveFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_HalfLife_exportTokens(m_face.getTexdef(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class QuakeFaceTokenExporter { -const Face &m_face; -public: -QuakeFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - writer.nextLine(); -} -}; - -class HalfLifeFaceTokenExporter { -const Face &m_face; -public: -HalfLifeFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_HalfLife_exportTokens(m_face.getTexdef(), writer); - writer.nextLine(); -} -}; - - -class BrushTokenImporter : public MapImporter { -Brush &m_brush; - -public: -BrushTokenImporter(Brush &brush) : m_brush(brush) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - } - while (1) { - // check for end of brush - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - if (string_equal(token, "}")) { - break; - } - - tokeniser.ungetToken(); - - m_brush.push_back(FaceSmartPointer(new Face(&m_brush))); - - //!todo BP support - tokeniser.nextLine(); - - Face &face = *m_brush.back(); - - switch (Brush::m_type) { - case eBrushTypeDoom3: { - Doom3FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake4: { - Quake4FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake2: { - Quake2FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3: { - Quake3FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3BP: { - Quake3BPFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3Valve: { - Quake3ValveFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake: { - QuakeFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeHalfLife: { - HalfLifeFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - } - face.planeChanged(); - } - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - } - - m_brush.planeChanged(); - m_brush.shaderChanged(); - - return true; -} -}; - - -class BrushTokenExporter : public MapExporter { -const Brush &m_brush; - -public: -BrushTokenExporter(const Brush &brush) : m_brush(brush) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified. - - if (!m_brush.hasContributingFaces()) { - return; - } - - writer.writeToken("{"); - writer.nextLine(); - - if (Brush::m_type == eBrushTypeQuake3BP) { - writer.writeToken("brushDef"); - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); - } - - if (Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4) { - writer.writeToken("brushDef3"); - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); - } - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - const Face &face = *(*i); - - if (face.contributes()) { - switch (Brush::m_type) { - case eBrushTypeDoom3: { - Doom3FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake4: { - Quake4FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake2: { - Quake2FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake3: { - Quake3FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake3BP: { - Quake3BPFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - break; - case eBrushTypeQuake3Valve: { - Quake3ValveFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake: { - QuakeFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeHalfLife: { - HalfLifeFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - } - } - } - - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - writer.writeToken("}"); - writer.nextLine(); - } - - writer.writeToken("}"); - writer.nextLine(); -} -}; - - -#endif diff --git a/src/brushxml.cpp b/src/brushxml.cpp deleted file mode 100644 index bca6877..0000000 --- a/src/brushxml.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushxml.h" diff --git a/src/brushxml.h b/src/brushxml.h deleted file mode 100644 index 58a138b..0000000 --- a/src/brushxml.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHXML_H ) -#define INCLUDED_BRUSHXML_H - -#include "stream/stringstream.h" -#include "xml/xmlelement.h" - -#include "brush.h" - -inline void FaceTexdef_BP_importXML(FaceTexdef &texdef, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - texdef.m_projection.m_brushprimit_texdef.coords[0][0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[0][1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[0][2] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][2] = static_cast( atof(content.getToken())); -} - -inline void FaceTexdef_importXML(FaceTexdef &texdef, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - texdef.m_projection.m_texdef.shift[0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.shift[1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.rotate = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.scale[0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.scale[1] = static_cast( atof(content.getToken())); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importXML: bad texdef"); -} - -inline void FacePlane_importXML(FacePlane &facePlane, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - facePlane.planePoints()[i][j] = atof(content.getToken()); - } - } - facePlane.MakePlane(); -} - - -class FaceXMLImporter { -struct xml_state_t { - enum EState { - eDefault, - ePlanePts, - eTexdef, - eBPMatrix, - eFlags, - eShader, - }; - - EState m_state; - StringOutputStream m_content; - - xml_state_t(EState state) - : m_state(state) - { - } - - EState state() const - { - return m_state; - } - - const char *content() const - { - return m_content.c_str(); - } - - std::size_t write(const char *buffer, std::size_t length) - { - return m_content.write(buffer, length); - } -}; - -std::vector m_xml_state; -Face &m_face; -public: -FaceXMLImporter(Face &face) : m_face(face) -{ - m_xml_state.push_back(xml_state_t::eDefault); -} - -~FaceXMLImporter() -{ - m_face.planeChanged(); -} - -void pushElement(const XMLElement &element) -{ - ASSERT_MESSAGE(m_xml_state.back().state() == xml_state_t::eDefault, "parse error"); - - if (strcmp(element.name(), "planepts") == 0) { - m_xml_state.push_back(xml_state_t::ePlanePts); - } else if (strcmp(element.name(), "texdef") == 0) { - m_xml_state.push_back(xml_state_t::eTexdef); - } else if (strcmp(element.name(), "bpmatrix") == 0) { - m_xml_state.push_back(xml_state_t::eBPMatrix); - } else if (strcmp(element.name(), "flags") == 0) { - m_xml_state.push_back(xml_state_t::eFlags); - } else if (strcmp(element.name(), "shader") == 0) { - m_xml_state.push_back(xml_state_t::eShader); - } -} - -void popElement(const char *name) -{ - ASSERT_MESSAGE(m_xml_state.back().state() != xml_state_t::eDefault, "parse error"); - - switch (m_xml_state.back().state()) { - case xml_state_t::ePlanePts: { - FacePlane_importXML(m_face.getPlane(), m_xml_state.back().content()); - } - break; - case xml_state_t::eTexdef: { - FaceTexdef_importXML(m_face.getTexdef(), m_xml_state.back().content()); - } - break; - case xml_state_t::eBPMatrix: { - FaceTexdef_BP_importXML(m_face.getTexdef(), m_xml_state.back().content()); - } - break; - case xml_state_t::eFlags: { - StringTokeniser content(m_xml_state.back().content()); - - m_face.getShader().m_flags.m_contentFlags = atoi(content.getToken()); - m_face.getShader().m_flags.m_surfaceFlags = atoi(content.getToken()); - m_face.getShader().m_flags.m_value = atoi(content.getToken()); - } - break; - case xml_state_t::eShader: { - m_face.getShader().setShader(m_xml_state.back().content()); - } - break; - default: - break; - } - - m_xml_state.pop_back(); -} - -std::size_t write(const char *data, std::size_t length) -{ - ASSERT_MESSAGE(!m_xml_state.empty(), "parse error"); - return m_xml_state.back().write(data, length); -} -}; - - -inline void FaceTexdef_exportXML(const FaceTexdef &texdef, XMLImporter &importer) -{ - StaticElement element("texdef"); - importer.pushElement(element); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_exportXML: bad texdef"); - - importer << texdef.m_projection.m_texdef.shift[0] - << ' ' << texdef.m_projection.m_texdef.shift[1] - << ' ' << texdef.m_projection.m_texdef.rotate - << ' ' << texdef.m_projection.m_texdef.scale[0] - << ' ' << texdef.m_projection.m_texdef.scale[1]; - - importer.popElement(element.name()); -} - -inline void FaceTexdef_BP_exportXML(const FaceTexdef &texdef, XMLImporter &importer) -{ - StaticElement element("texdef"); - importer.pushElement(element); - - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 3; ++j) { - importer << texdef.m_projection.m_brushprimit_texdef.coords[i][j] << ' '; - } - } - - importer.popElement(element.name()); -} - -inline void FaceShader_ContentsFlagsValue_exportXML(const FaceShader &faceShader, XMLImporter &importer) -{ - StaticElement element("flags"); - importer.pushElement(element); - - { - importer << faceShader.m_flags.m_contentFlags - << ' ' << faceShader.m_flags.m_surfaceFlags - << ' ' << faceShader.m_flags.m_value; - } - - importer.popElement(element.name()); -} - -inline void FacePlane_exportXML(const FacePlane &facePlane, XMLImporter &importer) -{ - StaticElement element("planepts"); - importer.pushElement(element); - - { - // write planepts - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - importer << Face::m_quantise(facePlane.planePoints()[i][j]) << ' '; - } - } - } - - importer.popElement(element.name()); -} - -inline void FacePolygon_exportXML(const Winding &w, const BasicVector3 &normal, XMLImporter &importer) -{ - DynamicElement element("polygon"); - - char tmp[32]; - - sprintf(tmp, "%f", normal.x()); - element.insertAttribute("nx", tmp); - - sprintf(tmp, "%f", normal.y()); - element.insertAttribute("ny", tmp); - - sprintf(tmp, "%f", normal.z()); - element.insertAttribute("nz", tmp); - - importer.pushElement(element); - - for (unsigned int i = 0; i < w.numpoints; ++i) { - DynamicElement c("vertex"); - - sprintf(tmp, "%f", w.points[i].vertex.x()); - c.insertAttribute("x", tmp); - - sprintf(tmp, "%f", w.points[i].vertex.y()); - c.insertAttribute("y", tmp); - - sprintf(tmp, "%f", w.points[i].vertex.z()); - c.insertAttribute("z", tmp); - - sprintf(tmp, "%f", w.points[i].texcoord.x()); - c.insertAttribute("s", tmp); - - sprintf(tmp, "%f", w.points[i].texcoord.y()); - c.insertAttribute("t", tmp); - - importer.pushElement(c); - importer.popElement(c.name()); - } - - importer.popElement(element.name()); -} - -class FaceXMLExporter { -const Face &m_face; -public: -FaceXMLExporter(const Face &face) : m_face(face) -{ -} - -void exportXML(XMLImporter &importer) -{ - bool bAlternateTexdef = (Face::m_type == eBrushTypeQuake3BP || Face::m_type == eBrushTypeDoom3 || - Face::m_type == eBrushTypeQuake4); - - // write shader - { - StaticElement element("shader"); - importer.pushElement(element); - importer << m_face.getShader().getShader(); - importer.popElement(element.name()); - } - - FacePolygon_exportXML(m_face.getWinding(), m_face.getPlane().plane3().normal(), importer); - FacePlane_exportXML(m_face.getPlane(), importer); - - if (!bAlternateTexdef) { - FaceTexdef_exportXML(m_face.getTexdef(), importer); - } else { - FaceTexdef_BP_exportXML(m_face.getTexdef(), importer); - } - - FaceShader_ContentsFlagsValue_exportXML(m_face.getShader(), importer); -} -}; - - -class BrushXMLImporter : public XMLImporter { -class xml_state_t { -public: -enum EState { - eDefault, - eBrush, - eFace, -}; - -private: -EState m_state; - -public: -xml_state_t(EState state) - : m_state(state) -{ -} - -EState state() const -{ - return m_state; -} -}; - -std::vector m_xml_state; -char m_faceImporter[sizeof(FaceXMLImporter)]; -Brush &m_brush; - -FaceXMLImporter &faceImporter() -{ - return *reinterpret_cast( m_faceImporter ); -} - -public: -BrushXMLImporter(Brush &brush) : m_brush(brush) -{ - m_xml_state.push_back(xml_state_t::eDefault); -} - -void pushElement(const XMLElement &element) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ASSERT_MESSAGE(strcmp(element.name(), "brush") == 0, "parse error"); - m_xml_state.push_back(xml_state_t::eBrush); - break; - case xml_state_t::eBrush: - ASSERT_MESSAGE(strcmp(element.name(), "plane") == 0, "parse error"); - m_xml_state.push_back(xml_state_t::eFace); - m_brush.push_back(FaceSmartPointer(new Face(&m_brush))); - constructor(faceImporter(), makeReference(*m_brush.back())); - m_brush.planeChanged(); - m_brush.shaderChanged(); - break; - case xml_state_t::eFace: - m_xml_state.push_back(xml_state_t::eFace); - faceImporter().pushElement(element); - break; - } -} - -void popElement(const char *name) -{ - ASSERT_MESSAGE(!m_xml_state.empty(), "parse error"); - m_xml_state.pop_back(); - - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - break; - case xml_state_t::eBrush: - destructor(faceImporter()); - break; - case xml_state_t::eFace: - faceImporter().popElement(name); - break; - } -} - -std::size_t write(const char *data, std::size_t length) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eFace: - return faceImporter().write(data, length); - break; - default: - break; - } - return length; -} -}; - -class BrushXMLExporter : public XMLExporter { -const Brush &m_brush; - -public: -BrushXMLExporter(const Brush &brush) : m_brush(brush) -{ -} - -void exportXML(XMLImporter &importer) -{ - m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified. - ASSERT_MESSAGE(m_brush.hasContributingFaces(), "exporting an empty brush"); - - const StaticElement brushElement("brush"); - importer.pushElement(brushElement); - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - if ((*i)->contributes()) { - const StaticElement element("plane"); - importer.pushElement(element); - FaceXMLExporter(*(*i)).exportXML(importer); - importer.popElement(element.name()); - } - } - - importer.popElement(brushElement.name()); -} -}; - - -#endif diff --git a/tools/vmap/bsp.c b/src/bsp.c similarity index 100% rename from tools/vmap/bsp.c rename to src/bsp.c diff --git a/tools/vmap/bsp_analyze.c b/src/bsp_analyze.c similarity index 100% rename from tools/vmap/bsp_analyze.c rename to src/bsp_analyze.c diff --git a/tools/vmap/bsp_info.c b/src/bsp_info.c similarity index 100% rename from tools/vmap/bsp_info.c rename to src/bsp_info.c diff --git a/tools/vmap/bsp_scale.c b/src/bsp_scale.c similarity index 100% rename from tools/vmap/bsp_scale.c rename to src/bsp_scale.c diff --git a/tools/vmap/bspfile_abstract.c b/src/bspfile_abstract.c similarity index 100% rename from tools/vmap/bspfile_abstract.c rename to src/bspfile_abstract.c diff --git a/tools/vmap/bspfile_ibsp.c b/src/bspfile_ibsp.c similarity index 100% rename from tools/vmap/bspfile_ibsp.c rename to src/bspfile_ibsp.c diff --git a/tools/vmap/bspfile_rbsp.c b/src/bspfile_rbsp.c similarity index 100% rename from tools/vmap/bspfile_rbsp.c rename to src/bspfile_rbsp.c diff --git a/src/build.cpp b/src/build.cpp deleted file mode 100644 index 4be1a68..0000000 --- a/src/build.cpp +++ /dev/null @@ -1,1104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "build.h" -#include "debugging/debugging.h" - -#include -#include -#include -#include "stream/stringstream.h" -#include "versionlib.h" - -#include "mainframe.h" - -typedef std::map Variables; -Variables g_build_variables; - -void build_clear_variables() -{ - g_build_variables.clear(); -} - -void build_set_variable(const char *name, const char *value) -{ - g_build_variables[name] = value; -} - -const char *build_get_variable(const char *name) -{ - Variables::iterator i = g_build_variables.find(name); - if (i != g_build_variables.end()) { - return (*i).second.c_str(); - } - globalErrorStream() << "undefined build variable: " << makeQuoted(name) << "\n"; - return ""; -} - -#include "xml/ixml.h" -#include "xml/xmlelement.h" - -class Evaluatable { -public: -virtual ~Evaluatable() = default; - -virtual void evaluate(StringBuffer &output) = 0; - -virtual void exportXML(XMLImporter &importer) = 0; -}; - -class VariableString : public Evaluatable { -CopiedString m_string; -public: -VariableString() : m_string() -{ -} - -VariableString(const char *string) : m_string(string) -{ -} - -const char *c_str() const -{ - return m_string.c_str(); -} - -void setString(const char *string) -{ - m_string = string; -} - -void evaluate(StringBuffer &output) -{ - StringBuffer variable; - bool in_variable = false; - for (const char *i = m_string.c_str(); *i != '\0'; ++i) { - if (!in_variable) { - switch (*i) { - case '[': - in_variable = true; - break; - default: - output.push_back(*i); - break; - } - } else { - switch (*i) { - case ']': - in_variable = false; - output.push_string(build_get_variable(variable.c_str())); - variable.clear(); - break; - default: - variable.push_back(*i); - break; - } - } - } -} - -void exportXML(XMLImporter &importer) -{ - importer << c_str(); -} -}; - -class Conditional : public Evaluatable { -VariableString *m_test; -public: -Evaluatable *m_result; - -Conditional(VariableString *test) : m_test(test) -{ -} - -~Conditional() -{ - delete m_test; - delete m_result; -} - -void evaluate(StringBuffer &output) -{ - StringBuffer buffer; - m_test->evaluate(buffer); - if (!string_empty(buffer.c_str())) { - m_result->evaluate(output); - } -} - -void exportXML(XMLImporter &importer) -{ - StaticElement conditionElement("cond"); - conditionElement.insertAttribute("value", m_test->c_str()); - importer.pushElement(conditionElement); - m_result->exportXML(importer); - importer.popElement(conditionElement.name()); -} -}; - -typedef std::vector Evaluatables; - -class Tool : public Evaluatable { -Evaluatables m_evaluatables; -public: -~Tool() -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - delete (*i); - } -} - -void push_back(Evaluatable *evaluatable) -{ - m_evaluatables.push_back(evaluatable); -} - -void evaluate(StringBuffer &output) -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - (*i)->evaluate(output); - } -} - -void exportXML(XMLImporter &importer) -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - (*i)->exportXML(importer); - } -} -}; - -#include "xml/ixml.h" - -class XMLElementParser : public TextOutputStream { -public: -virtual ~XMLElementParser() = default; - -virtual XMLElementParser &pushElement(const XMLElement &element) = 0; - -virtual void popElement(const char *name) = 0; -}; - -class VariableStringXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -VariableString &m_variableString; -public: -VariableStringXMLConstructor(VariableString &variableString) : m_variableString(variableString) -{ -} - -~VariableStringXMLConstructor() -{ - m_variableString.setString(m_buffer.c_str()); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class ConditionalXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -Conditional &m_conditional; -public: -ConditionalXMLConstructor(Conditional &conditional) : m_conditional(conditional) -{ -} - -~ConditionalXMLConstructor() -{ - m_conditional.m_result = new VariableString(m_buffer.c_str()); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class ToolXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -Tool &m_tool; -ConditionalXMLConstructor *m_conditional; -public: -ToolXMLConstructor(Tool &tool) : m_tool(tool) -{ -} - -~ToolXMLConstructor() -{ - flush(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "cond")) { - flush(); - Conditional *conditional = new Conditional(new VariableString(element.attribute("value"))); - m_tool.push_back(conditional); - m_conditional = new ConditionalXMLConstructor(*conditional); - return *m_conditional; - } else { - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; - } -} - -void popElement(const char *name) -{ - if (string_equal(name, "cond")) { - delete m_conditional; - } -} - -void flush() -{ - if (!m_buffer.empty()) { - m_tool.push_back(new VariableString(m_buffer.c_str())); - m_buffer.clear(); - } -} -}; - -typedef VariableString BuildCommand; -typedef std::list Build; - -class BuildXMLConstructor : public XMLElementParser { -VariableStringXMLConstructor *m_variableString; -Build &m_build; -public: -BuildXMLConstructor(Build &build) : m_build(build) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "command")) { - m_build.push_back(BuildCommand()); - m_variableString = new VariableStringXMLConstructor(m_build.back()); - return *m_variableString; - } else { - ERROR_MESSAGE("parse error: invalid element"); - return *this; - } -} - -void popElement(const char *name) -{ - delete m_variableString; -} -}; - -typedef std::pair BuildPair; -const char *SEPARATOR_STRING = "-"; - -static bool is_separator(const BuildPair &p) -{ - if (!string_equal(p.first.c_str(), SEPARATOR_STRING)) { - return false; - } - for (Build::const_iterator j = p.second.begin(); j != p.second.end(); ++j) { - if (!string_equal((*j).c_str(), "")) { - return false; - } - } - return true; -} - - -typedef std::list Project; - -Project::iterator Project_find(Project &project, const char *name) -{ - return std::find_if(project.begin(), project.end(), [&](const BuildPair &self) { - return string_equal(self.first.c_str(), name); - }); -} - -Project::iterator Project_find(Project &project, std::size_t index) -{ - Project::iterator i = project.begin(); - while (index-- != 0 && i != project.end()) { - ++i; - } - return i; -} - -Build &project_find(Project &project, const char *build) -{ - Project::iterator i = Project_find(project, build); - ASSERT_MESSAGE(i != project.end(), "error finding build command"); - return (*i).second; -} - -Build::iterator Build_find(Build &build, std::size_t index) -{ - Build::iterator i = build.begin(); - while (index-- != 0 && i != build.end()) { - ++i; - } - return i; -} - -typedef std::map Tools; - -class ProjectXMLConstructor : public XMLElementParser { -ToolXMLConstructor *m_tool; -BuildXMLConstructor *m_build; -Project &m_project; -Tools &m_tools; -public: -ProjectXMLConstructor(Project &project, Tools &tools) : m_project(project), m_tools(tools) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "var")) { - Tools::iterator i = m_tools.insert(Tools::value_type(element.attribute("name"), Tool())).first; - m_tool = new ToolXMLConstructor((*i).second); - return *m_tool; - } else if (string_equal(element.name(), "build")) { - m_project.push_back(Project::value_type(element.attribute("name"), Build())); - m_build = new BuildXMLConstructor(m_project.back().second); - return *m_build; - } else if (string_equal(element.name(), "separator")) { - m_project.push_back(Project::value_type(SEPARATOR_STRING, Build())); - return *this; - } else { - ERROR_MESSAGE("parse error: invalid element"); - return *this; - } -} - -void popElement(const char *name) -{ - if (string_equal(name, "var")) { - delete m_tool; - } else if (string_equal(name, "build")) { - delete m_build; - } -} -}; - -class SkipAllParser : public XMLElementParser { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class RootXMLConstructor : public XMLElementParser { -CopiedString m_elementName; -XMLElementParser &m_parser; -SkipAllParser m_skip; -Version m_version; -bool m_compatible; -public: -RootXMLConstructor(const char *elementName, XMLElementParser &parser, const char *version) : - m_elementName(elementName), - m_parser(parser), - m_version(version_parse(version)), - m_compatible(false) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), m_elementName.c_str())) { - Version dataVersion(version_parse(element.attribute("version"))); - if (version_compatible(m_version, dataVersion)) { - m_compatible = true; - return m_parser; - } else { - return m_skip; - } - } else { - //ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; - } -} - -void popElement(const char *name) -{ -} - -bool versionCompatible() const -{ - return m_compatible; -} -}; - -namespace { -Project g_build_project; -Tools g_build_tools; -bool g_build_changed = false; -} - -void build_error_undefined_tool(const char *build, const char *tool) -{ - globalErrorStream() << "build " << makeQuoted(build) << " refers to undefined tool " << makeQuoted(tool) << '\n'; -} - -void project_verify(Project &project, Tools &tools) -{ -#if 0 - for ( Project::iterator i = project.begin(); i != project.end(); ++i ) - { - Build& build = ( *i ).second; - for ( Build::iterator j = build.begin(); j != build.end(); ++j ) - { - Tools::iterator k = tools.find( ( *j ).first ); - if ( k == g_build_tools.end() ) { - build_error_undefined_tool( ( *i ).first.c_str(), ( *j ).first.c_str() ); - } - } - } -#endif -} - -void build_run(const char *name, CommandListener &listener) -{ - for (Tools::iterator i = g_build_tools.begin(); i != g_build_tools.end(); ++i) { - StringBuffer output; - (*i).second.evaluate(output); - build_set_variable((*i).first.c_str(), output.c_str()); - } - - { - Project::iterator i = Project_find(g_build_project, name); - if (i != g_build_project.end()) { - Build &build = (*i).second; - for (Build::iterator j = build.begin(); j != build.end(); ++j) { - StringBuffer output; - (*j).evaluate(output); - listener.execute(output.c_str()); - } - } else { - globalErrorStream() << "build " << makeQuoted(name) << " not defined"; - } - } -} - - -typedef std::vector XMLElementStack; - -class XMLParser : public XMLImporter { -XMLElementStack m_stack; -public: -XMLParser(XMLElementParser &parser) -{ - m_stack.push_back(&parser); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_stack.back()->write(buffer, length); -} - -void pushElement(const XMLElement &element) -{ - m_stack.push_back(&m_stack.back()->pushElement(element)); -} - -void popElement(const char *name) -{ - m_stack.pop_back(); - m_stack.back()->popElement(name); -} -}; - -#include "stream/textfilestream.h" -#include "xml/xmlparser.h" - -const char *const BUILDMENU_VERSION = "2.0"; - -bool build_commands_parse(const char *filename) -{ - TextFileInputStream projectFile(filename); - if (!projectFile.failed()) { - ProjectXMLConstructor projectConstructor(g_build_project, g_build_tools); - RootXMLConstructor rootConstructor("project", projectConstructor, BUILDMENU_VERSION); - XMLParser importer(rootConstructor); - XMLStreamParser parser(projectFile); - parser.exportXML(importer); - - if (rootConstructor.versionCompatible()) { - project_verify(g_build_project, g_build_tools); - - return true; - } - globalErrorStream() << "failed to parse build menu: " << makeQuoted(filename) << "\n"; - } - return false; -} - -void build_commands_clear() -{ - g_build_project.clear(); - g_build_tools.clear(); -} - -class BuildXMLExporter { -Build &m_build; -public: -BuildXMLExporter(Build &build) : m_build(build) -{ -} - -void exportXML(XMLImporter &importer) -{ - importer << "\n"; - for (Build::iterator i = m_build.begin(); i != m_build.end(); ++i) { - StaticElement commandElement("command"); - importer.pushElement(commandElement); - (*i).exportXML(importer); - importer.popElement(commandElement.name()); - importer << "\n"; - } -} -}; - -class ProjectXMLExporter { -Project &m_project; -Tools &m_tools; -public: -ProjectXMLExporter(Project &project, Tools &tools) : m_project(project), m_tools(tools) -{ -} - -void exportXML(XMLImporter &importer) -{ - StaticElement projectElement("project"); - projectElement.insertAttribute("version", BUILDMENU_VERSION); - importer.pushElement(projectElement); - importer << "\n"; - - for (Tools::iterator i = m_tools.begin(); i != m_tools.end(); ++i) { - StaticElement toolElement("var"); - toolElement.insertAttribute("name", (*i).first.c_str()); - importer.pushElement(toolElement); - (*i).second.exportXML(importer); - importer.popElement(toolElement.name()); - importer << "\n"; - } - for (Project::iterator i = m_project.begin(); i != m_project.end(); ++i) { - if (is_separator(*i)) { - StaticElement buildElement("separator"); - importer.pushElement(buildElement); - importer.popElement(buildElement.name()); - importer << "\n"; - } else { - StaticElement buildElement("build"); - buildElement.insertAttribute("name", (*i).first.c_str()); - importer.pushElement(buildElement); - BuildXMLExporter buildExporter((*i).second); - buildExporter.exportXML(importer); - importer.popElement(buildElement.name()); - importer << "\n"; - } - } - importer.popElement(projectElement.name()); -} -}; - -#include "xml/xmlwriter.h" - -void build_commands_write(const char *filename) -{ - TextFileOutputStream projectFile(filename); - if (!projectFile.failed()) { - XMLStreamWriter writer(projectFile); - ProjectXMLExporter projectExporter(g_build_project, g_build_tools); - writer << "\n"; - projectExporter.exportXML(writer); - writer << "\n"; - } -} - - -#include - -#include "gtkutil/dialog.h" -#include "gtkutil/closure.h" -#include "gtkutil/window.h" -#include "gtkdlgs.h" - -void Build_refreshMenu(ui::Menu menu); - - -void BSPCommandList_Construct(ui::ListStore store, Project &project) -{ - store.clear(); - - for (Project::iterator i = project.begin(); i != project.end(); ++i) { - store.append(0, (*i).first.c_str()); - } - - store.append(); -} - -class ProjectList { -public: -Project &m_project; -ui::ListStore m_store{ui::null}; -bool m_changed; - -ProjectList(Project &project) : m_project(project), m_changed(false) -{ -} -}; - -gboolean project_cell_edited(ui::CellRendererText cell, gchar *path_string, gchar *new_text, ProjectList *projectList) -{ - Project &project = projectList->m_project; - - auto path = ui::TreePath(path_string); - - ASSERT_MESSAGE(gtk_tree_path_get_depth(path) == 1, "invalid path length"); - - GtkTreeIter iter; - gtk_tree_model_get_iter(projectList->m_store, &iter, path); - - Project::iterator i = Project_find(project, gtk_tree_path_get_indices(path)[0]); - if (i != project.end()) { - projectList->m_changed = true; - if (string_empty(new_text)) { - project.erase(i); - gtk_list_store_remove(projectList->m_store, &iter); - } else { - (*i).first = new_text; - gtk_list_store_set(projectList->m_store, &iter, 0, new_text, -1); - } - } else if (!string_empty(new_text)) { - projectList->m_changed = true; - project.push_back(Project::value_type(new_text, Build())); - - gtk_list_store_set(projectList->m_store, &iter, 0, new_text, -1); - projectList->m_store.append(); - } - - gtk_tree_path_free(path); - - Build_refreshMenu(g_bsp_menu); - - return FALSE; -} - -gboolean project_key_press(ui::TreeView widget, GdkEventKey *event, ProjectList *projectList) -{ - Project &project = projectList->m_project; - - if (event->keyval == GDK_KEY_Delete) { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(widget)); - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Project::iterator x = Project_find(project, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (x != project.end()) { - projectList->m_changed = true; - project.erase(x); - Build_refreshMenu(g_bsp_menu); - - gtk_list_store_remove(projectList->m_store, &iter); - } - } - } - return FALSE; -} - - -Build *g_current_build = 0; - -gboolean project_selection_changed(ui::TreeSelection selection, ui::ListStore store) -{ - Project &project = g_build_project; - - store.clear(); - - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Project::iterator x = Project_find(project, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (x != project.end()) { - Build &build = (*x).second; - g_current_build = &build; - - for (Build::iterator i = build.begin(); i != build.end(); ++i) { - store.append(0, (*i).c_str()); - } - store.append(); - } else { - g_current_build = 0; - } - } else { - g_current_build = 0; - } - - return FALSE; -} - -gboolean commands_cell_edited(ui::CellRendererText cell, gchar *path_string, gchar *new_text, ui::ListStore store) -{ - if (g_current_build == 0) { - return FALSE; - } - Build &build = *g_current_build; - - auto path = ui::TreePath(path_string); - - ASSERT_MESSAGE(gtk_tree_path_get_depth(path) == 1, "invalid path length"); - - GtkTreeIter iter; - gtk_tree_model_get_iter(store, &iter, path); - - Build::iterator i = Build_find(build, gtk_tree_path_get_indices(path)[0]); - if (i != build.end()) { - g_build_changed = true; - (*i).setString(new_text); - - gtk_list_store_set(store, &iter, 0, new_text, -1); - } else if (!string_empty(new_text)) { - g_build_changed = true; - build.push_back(Build::value_type(VariableString(new_text))); - - gtk_list_store_set(store, &iter, 0, new_text, -1); - - store.append(); - } - - gtk_tree_path_free(path); - - Build_refreshMenu(g_bsp_menu); - - return FALSE; -} - -gboolean commands_key_press(ui::TreeView widget, GdkEventKey *event, ui::ListStore store) -{ - if (g_current_build == 0) { - return FALSE; - } - Build &build = *g_current_build; - - if (event->keyval == GDK_KEY_Delete) { - auto selection = gtk_tree_view_get_selection(widget); - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Build::iterator i = Build_find(build, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (i != build.end()) { - g_build_changed = true; - build.erase(i); - - gtk_list_store_remove(store, &iter); - } - } - } - return FALSE; -} - - -ui::Window BuildMenuDialog_construct(ModalDialog &modal, ProjectList &projectList) -{ - ui::Window window = MainFrame_getWindow().create_dialog_window("Build Menu", G_CALLBACK(dialog_delete_callback), - &modal, -1, 400); - - { - auto table1 = create_dialog_table(2, 2, 4, 4, 4); - window.add(table1); - { - auto vbox = create_dialog_vbox(4); - table1.attach(vbox, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL}); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - auto buildViewStore = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - auto buildView = ui::TreeView(ui::TreeModel::from(buildViewStore._handle)); - { - auto frame = create_dialog_frame("Build menu"); - table1.attach(frame, {0, 1, 0, 1}); - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - frame.add(scr); - - { - auto view = buildView; - auto store = buildViewStore; - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - object_set_boolean_property(G_OBJECT(renderer), "editable", TRUE); - renderer.connect("edited", G_CALLBACK(project_cell_edited), &projectList); - - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - - auto selection = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - - view.show(); - - projectList.m_store = store; - scr.add(view); - - view.connect("key_press_event", G_CALLBACK(project_key_press), &projectList); - - store.unref(); - } - } - } - { - auto frame = create_dialog_frame("Commandline"); - table1.attach(frame, {0, 1, 1, 2}); - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - frame.add(scr); - - { - auto store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - object_set_boolean_property(G_OBJECT(renderer), "editable", TRUE); - renderer.connect("edited", G_CALLBACK(commands_cell_edited), store); - - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - - auto selection = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - - view.show(); - - scr.add(view); - - store.unref(); - - view.connect("key_press_event", G_CALLBACK(commands_key_press), store); - - auto sel = ui::TreeSelection::from(gtk_tree_view_get_selection(buildView)); - sel.connect("changed", G_CALLBACK(project_selection_changed), store); - } - } - } - } - - BSPCommandList_Construct(projectList.m_store, g_build_project); - - return window; -} - -namespace { -CopiedString g_buildMenu; -} - -void LoadBuildMenu(); - -void DoBuildMenu() -{ - ModalDialog modal; - - ProjectList projectList(g_build_project); - - ui::Window window = BuildMenuDialog_construct(modal, projectList); - - if (modal_dialog_show(window, modal) == eIDCANCEL) { - build_commands_clear(); - LoadBuildMenu(); - - Build_refreshMenu(g_bsp_menu); - } else if (projectList.m_changed) { - g_build_changed = true; - } - - window.destroy(); -} - - -#include "gtkutil/menu.h" -#include "mainframe.h" -#include "preferences.h" -#include "qe3.h" - -class BuildMenuItem { -const char *m_name; -public: -ui::MenuItem m_item; - -BuildMenuItem(const char *name, ui::MenuItem item) - : m_name(name), m_item(item) -{ -} - -void run() -{ - RunBSP(m_name); -} - -typedef MemberCaller RunCaller; -}; - -typedef std::list BuildMenuItems; -BuildMenuItems g_BuildMenuItems; - - -ui::Menu g_bsp_menu{ui::null}; - -void Build_constructMenu(ui::Menu menu) -{ - for (Project::iterator i = g_build_project.begin(); i != g_build_project.end(); ++i) { - g_BuildMenuItems.push_back(BuildMenuItem((*i).first.c_str(), ui::MenuItem(ui::null))); - if (is_separator(*i)) { - g_BuildMenuItems.back().m_item = menu_separator(menu); - } else { - g_BuildMenuItems.back().m_item = create_menu_item_with_mnemonic(menu, (*i).first.c_str(), - BuildMenuItem::RunCaller( - g_BuildMenuItems.back())); - } - } -} - - -void Build_refreshMenu(ui::Menu menu) -{ - for (auto i = g_BuildMenuItems.begin(); i != g_BuildMenuItems.end(); ++i) { - menu.remove(ui::MenuItem(i->m_item)); - } - - g_BuildMenuItems.clear(); - - Build_constructMenu(menu); -} - - -void LoadBuildMenu() -{ - if (string_empty(g_buildMenu.c_str()) || !build_commands_parse(g_buildMenu.c_str())) { - { - StringOutputStream buffer(256); - buffer << GameToolsPath_get() << "default_build_menu.xml"; - - bool success = build_commands_parse(buffer.c_str()); - ASSERT_MESSAGE(success, "failed to parse default build commands: " << buffer.c_str()); - } - { - StringOutputStream buffer(256); - buffer << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/build_menu.xml"; - - g_buildMenu = buffer.c_str(); - } - } -} - -void SaveBuildMenu() -{ - if (g_build_changed) { - g_build_changed = false; - build_commands_write(g_buildMenu.c_str()); - } -} - -#include "preferencesystem.h" -#include "stringio.h" - -void BuildMenu_Construct() -{ - GlobalPreferenceSystem().registerPreference("BuildMenu", make_property_string(g_buildMenu)); - LoadBuildMenu(); -} - -void BuildMenu_Destroy() -{ - SaveBuildMenu(); -} diff --git a/src/build.h b/src/build.h deleted file mode 100644 index 7597328..0000000 --- a/src/build.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#if !defined( INCLUDED_BUILD_H ) -#define INCLUDED_BUILD_H - -void build_set_variable(const char *name, const char *value); - -void build_clear_variables(); - -class CommandListener { -public: -virtual void execute(const char *command) = 0; -}; - -void build_run(const char *name, CommandListener &listener); - -void DoBuildMenu(); - -void BuildMenu_Construct(); - -void BuildMenu_Destroy(); - -void Build_constructMenu(ui::Menu menu); - -extern ui::Menu g_bsp_menu; - - -#endif diff --git a/src/camwindow.cpp b/src/camwindow.cpp deleted file mode 100644 index d20b074..0000000 --- a/src/camwindow.cpp +++ /dev/null @@ -1,2248 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Camera Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "camwindow.h" - -#include -#include - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "igl.h" -#include "icamera.h" -#include "cullable.h" -#include "renderable.h" -#include "preferencesystem.h" - -#include "signal/signal.h" -#include "container/array.h" -#include "scenelib.h" -#include "render.h" -#include "cmdlib.h" -#include "math/frustum.h" - -#include "gtkutil/widget.h" -#include "gtkutil/button.h" -#include "gtkutil/toolbar.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/xorrectangle.h" -#include "gtkmisc.h" -#include "selection.h" -#include "mainframe.h" -#include "preferences.h" -#include "commands.h" -#include "xywindow.h" -#include "windowobservers.h" -#include "renderstate.h" - -#include "timer.h" - -Signal0 g_cameraMoved_callbacks; - -void AddCameraMovedCallback(const SignalHandler &handler) -{ - g_cameraMoved_callbacks.connectLast(handler); -} - -void CameraMovedNotify() -{ - g_cameraMoved_callbacks(); -} - - -struct camwindow_globals_private_t { - int m_nMoveSpeed; - bool m_bCamLinkSpeed; - int m_nAngleSpeed; - bool m_bCamInverseMouse; - bool m_bCamDiscrete; - bool m_bCubicClipping; - bool m_showStats; - bool m_showLighting; - bool m_showAlpha; - bool m_showPatchBalls; - int m_nStrafeMode; - - camwindow_globals_private_t() : - m_nMoveSpeed(50), - m_bCamLinkSpeed(true), - m_nAngleSpeed(3), - m_bCamInverseMouse(false), - m_bCamDiscrete(true), - m_bCubicClipping(true), - m_showStats(false), - m_showLighting(false), - m_showAlpha(true), - m_showPatchBalls(true), - m_nStrafeMode(0) - { - } - -}; - -camwindow_globals_private_t g_camwindow_globals_private; - - -const Matrix4 g_opengl2radiant( - 0, 0, -1, 0, - -1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 1 - ); - -const Matrix4 g_radiant2opengl( - 0, -1, 0, 0, - 0, 0, 1, 0, - -1, 0, 0, 0, - 0, 0, 0, 1 - ); - -struct camera_t; - -void Camera_mouseMove(camera_t &camera, int x, int y); - -enum camera_draw_mode { - cd_wire, - cd_solid, - cd_texture, - cd_lighting -}; - -struct camera_t { - int width, height; - - bool timing; - - Vector3 origin; - Vector3 angles; - - Vector3 color; // background - - Vector3 forward, right; // move matrix (TTimo: used to have up but it was not updated) - Vector3 vup, vpn, vright; // view matrix (taken from the modelview matrix) - - Matrix4 projection; - Matrix4 modelview; - - bool m_strafe; // true when in strafemode toggled by the ctrl-key - bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing - - unsigned int movementflags; // movement flags - Timer m_keycontrol_timer; - guint m_keymove_handler; - - - float fieldOfView; - - DeferredMotionDelta m_mouseMove; - - static void motionDelta(int x, int y, void *data) - { - Camera_mouseMove(*reinterpret_cast( data ), x, y); - } - - View *m_view; - Callback m_update; - - static camera_draw_mode draw_mode; - - camera_t(View *view, const Callback &update) - : width(0), - height(0), - timing(false), - origin(0, 0, 0), - angles(0, 0, 0), - color(0, 0, 0), - movementflags(0), - m_keymove_handler(0), - fieldOfView(75.0f), - m_mouseMove(motionDelta, this), - m_view(view), - m_update(update) - { - } -}; - -camera_draw_mode camera_t::draw_mode = cd_texture; - -inline Matrix4 projection_for_camera(float near_z, float far_z, float fieldOfView, int width, int height) -{ - const float half_width = static_cast( near_z * tan(degrees_to_radians(fieldOfView * 0.5))); - const float half_height = half_width * (static_cast( width ) / static_cast( height )); - - return matrix4_frustum( - -half_height, - half_height, - -half_width, - half_width, - near_z, - far_z - ); -} - -float Camera_getFarClipPlane(camera_t &camera) -{ - return (g_camwindow_globals_private.m_bCubicClipping) ? pow(2.0, (g_camwindow_globals.m_nCubicScale + 7) / 2.0) - : 32768.0f; -} - -void Camera_updateProjection(camera_t &camera) -{ - float farClip = Camera_getFarClipPlane(camera); - camera.projection = projection_for_camera(farClip / 4096.0f, farClip, camera.fieldOfView, camera.width, - camera.height); - - camera.m_view->Construct(camera.projection, camera.modelview, camera.width, camera.height); -} - -void Camera_updateVectors(camera_t &camera) -{ - for (int i = 0; i < 3; i++) { - camera.vright[i] = camera.modelview[(i << 2) + 0]; - camera.vup[i] = camera.modelview[(i << 2) + 1]; - camera.vpn[i] = camera.modelview[(i << 2) + 2]; - } -} - -void Camera_updateModelview(camera_t &camera) -{ - camera.modelview = g_matrix4_identity; - - // roll, pitch, yaw - Vector3 radiant_eulerXYZ(0, -camera.angles[CAMERA_PITCH], camera.angles[CAMERA_YAW]); - - matrix4_translate_by_vec3(camera.modelview, camera.origin); - matrix4_rotate_by_euler_xyz_degrees(camera.modelview, radiant_eulerXYZ); - matrix4_multiply_by_matrix4(camera.modelview, g_radiant2opengl); - matrix4_affine_invert(camera.modelview); - - Camera_updateVectors(camera); - - camera.m_view->Construct(camera.projection, camera.modelview, camera.width, camera.height); -} - - -void Camera_Move_updateAxes(camera_t &camera) -{ - double ya = degrees_to_radians(camera.angles[CAMERA_YAW]); - - // the movement matrix is kept 2d - camera.forward[0] = static_cast( cos(ya)); - camera.forward[1] = static_cast( sin(ya)); - camera.forward[2] = 0; - camera.right[0] = camera.forward[1]; - camera.right[1] = -camera.forward[0]; -} - -void Camera_Freemove_updateAxes(camera_t &camera) -{ - camera.right = camera.vright; - camera.forward = vector3_negated(camera.vpn); -} - -const Vector3 &Camera_getOrigin(camera_t &camera) -{ - return camera.origin; -} - -void Camera_setOrigin(camera_t &camera, const Vector3 &origin) -{ - camera.origin = origin; - Camera_updateModelview(camera); - camera.m_update(); - CameraMovedNotify(); -} - -const Vector3 &Camera_getAngles(camera_t &camera) -{ - return camera.angles; -} - -void Camera_setAngles(camera_t &camera, const Vector3 &angles) -{ - camera.angles = angles; - Camera_updateModelview(camera); - camera.m_update(); - CameraMovedNotify(); -} - - -void Camera_FreeMove(camera_t &camera, int dx, int dy) -{ - // free strafe mode, toggled by the ctrl key with optional shift for forward movement - if (camera.m_strafe) { - float strafespeed = 0.65f; - - if (g_camwindow_globals_private.m_bCamLinkSpeed) { - strafespeed = (float) g_camwindow_globals_private.m_nMoveSpeed / 100; - } - - camera.origin -= camera.vright * strafespeed * dx; - if (camera.m_strafe_forward) { - camera.origin += camera.vpn * strafespeed * dy; - } else { - camera.origin += camera.vup * strafespeed * dy; - } - } else // free rotation - { -#if 1 - const float dtime = 0.05f; -#else - float dtime = camera.m_keycontrol_timer.elapsed_msec() / static_cast( msec_per_sec ); - dtime *= 0.01f; -#endif - - if (g_camwindow_globals_private.m_bCamInverseMouse) { - camera.angles[CAMERA_PITCH] -= (dy * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } else { - camera.angles[CAMERA_PITCH] += (dy * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - - camera.angles[CAMERA_YAW] += (dx * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - - if (camera.angles[CAMERA_PITCH] > 90) { - camera.angles[CAMERA_PITCH] = 90; - } else if (camera.angles[CAMERA_PITCH] < -90) { - camera.angles[CAMERA_PITCH] = -90; - } - - if (camera.angles[CAMERA_YAW] >= 360) { - camera.angles[CAMERA_YAW] -= 360; - } else if (camera.angles[CAMERA_YAW] <= 0) { - camera.angles[CAMERA_YAW] += 360; - } - } - - Camera_updateModelview(camera); - Camera_Freemove_updateAxes(camera); -} - -void Cam_MouseControl(camera_t &camera, int x, int y) -{ - float xf = (float) (x - camera.width / 2) / (camera.width / 2); - float yf = (float) (y - camera.height / 2) / (camera.height / 2); - - xf *= 1.0f - fabsf(yf); - if (xf < 0) { - xf += 0.1f; - if (xf > 0) { - xf = 0; - } - } else { - xf -= 0.1f; - if (xf < 0) { - xf = 0; - } - } - - vector3_add(camera.origin, vector3_scaled(camera.forward, yf * 0.1f * g_camwindow_globals_private.m_nMoveSpeed)); - camera.angles[CAMERA_YAW] += xf * -0.1f * g_camwindow_globals_private.m_nAngleSpeed; - - Camera_updateModelview(camera); -} - -void Camera_mouseMove(camera_t &camera, int x, int y) -{ - //globalOutputStream() << "mousemove... "; - Camera_FreeMove(camera, -x, -y); - camera.m_update(); - CameraMovedNotify(); -} - -const unsigned int MOVE_NONE = 0; -const unsigned int MOVE_FORWARD = 1 << 0; -const unsigned int MOVE_BACK = 1 << 1; -const unsigned int MOVE_ROTRIGHT = 1 << 2; -const unsigned int MOVE_ROTLEFT = 1 << 3; -const unsigned int MOVE_STRAFERIGHT = 1 << 4; -const unsigned int MOVE_STRAFELEFT = 1 << 5; -const unsigned int MOVE_UP = 1 << 6; -const unsigned int MOVE_DOWN = 1 << 7; -const unsigned int MOVE_PITCHUP = 1 << 8; -const unsigned int MOVE_PITCHDOWN = 1 << 9; -const unsigned int MOVE_ALL = - MOVE_FORWARD | MOVE_BACK | MOVE_ROTRIGHT | MOVE_ROTLEFT | MOVE_STRAFERIGHT | MOVE_STRAFELEFT | MOVE_UP | - MOVE_DOWN | MOVE_PITCHUP | MOVE_PITCHDOWN; - -void Cam_KeyControl(camera_t &camera, float dtime) -{ - // Update angles - if (camera.movementflags & MOVE_ROTLEFT) { - camera.angles[CAMERA_YAW] += (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - if (camera.movementflags & MOVE_ROTRIGHT) { - camera.angles[CAMERA_YAW] -= (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - if (camera.movementflags & MOVE_PITCHUP) { - camera.angles[CAMERA_PITCH] += (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - if (camera.angles[CAMERA_PITCH] > 90) { - camera.angles[CAMERA_PITCH] = 90; - } - } - if (camera.movementflags & MOVE_PITCHDOWN) { - camera.angles[CAMERA_PITCH] -= (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - if (camera.angles[CAMERA_PITCH] < -90) { - camera.angles[CAMERA_PITCH] = -90; - } - } - - Camera_updateModelview(camera); - Camera_Freemove_updateAxes(camera); - - // Update position - if (camera.movementflags & MOVE_FORWARD) { - vector3_add(camera.origin, vector3_scaled(camera.forward, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_BACK) { - vector3_add(camera.origin, vector3_scaled(camera.forward, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_STRAFELEFT) { - vector3_add(camera.origin, vector3_scaled(camera.right, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_STRAFERIGHT) { - vector3_add(camera.origin, vector3_scaled(camera.right, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_UP) { - vector3_add(camera.origin, vector3_scaled(g_vector3_axis_z, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_DOWN) { - vector3_add(camera.origin, vector3_scaled(g_vector3_axis_z, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - - Camera_updateModelview(camera); -} - -void Camera_keyMove(camera_t &camera) -{ - camera.m_mouseMove.flush(); - - //globalOutputStream() << "keymove... "; - float time_seconds = camera.m_keycontrol_timer.elapsed_msec() / static_cast( msec_per_sec ) * 0.01; - camera.m_keycontrol_timer.start(); - Cam_KeyControl(camera, 0.016f); - - camera.m_update(); - CameraMovedNotify(); -} - -gboolean camera_keymove(gpointer data) -{ - Camera_keyMove(*reinterpret_cast( data )); - return TRUE; -} - -void Camera_setMovementFlags(camera_t &camera, unsigned int mask) -{ - if ((~camera.movementflags & mask) != 0 && camera.movementflags == 0) { - camera.m_keymove_handler = g_idle_add(camera_keymove, &camera); - } - camera.movementflags |= mask; -} - -void Camera_clearMovementFlags(camera_t &camera, unsigned int mask) -{ - if ((camera.movementflags & ~mask) == 0 && camera.movementflags != 0) { - g_source_remove(camera.m_keymove_handler); - camera.m_keymove_handler = 0; - } - camera.movementflags &= ~mask; -} - -void Camera_MoveForward_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_FORWARD); -} - -void Camera_MoveForward_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_FORWARD); -} - -void Camera_MoveBack_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_BACK); -} - -void Camera_MoveBack_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_BACK); -} - -void Camera_MoveLeft_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_STRAFELEFT); -} - -void Camera_MoveLeft_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_STRAFELEFT); -} - -void Camera_MoveRight_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_STRAFERIGHT); -} - -void Camera_MoveRight_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_STRAFERIGHT); -} - -void Camera_MoveUp_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_UP); -} - -void Camera_MoveUp_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_UP); -} - -void Camera_MoveDown_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_DOWN); -} - -void Camera_MoveDown_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_DOWN); -} - -void Camera_RotateLeft_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_ROTLEFT); -} - -void Camera_RotateLeft_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_ROTLEFT); -} - -void Camera_RotateRight_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_ROTRIGHT); -} - -void Camera_RotateRight_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_ROTRIGHT); -} - -void Camera_PitchUp_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_PITCHUP); -} - -void Camera_PitchUp_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_PITCHUP); -} - -void Camera_PitchDown_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_PITCHDOWN); -} - -void Camera_PitchDown_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_PITCHDOWN); -} - - -typedef ReferenceCaller FreeMoveCameraMoveForwardKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveForwardKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveBackKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveBackKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveLeftKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveLeftKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveRightKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveRightKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveUpKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveUpKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveDownKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveDownKeyUpCaller; - - -const float SPEED_MOVE = 32; -const float SPEED_TURN = 22.5; -const float MIN_CAM_SPEED = 10; -const float MAX_CAM_SPEED = 610; -const float CAM_SPEED_STEP = 50; - -void Camera_MoveForward_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.forward, SPEED_MOVE))); -} - -void Camera_MoveBack_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.forward, -SPEED_MOVE))); -} - -void Camera_MoveUp_Discrete(camera_t &camera) -{ - Vector3 origin(Camera_getOrigin(camera)); - origin[2] += SPEED_MOVE; - Camera_setOrigin(camera, origin); -} - -void Camera_MoveDown_Discrete(camera_t &camera) -{ - Vector3 origin(Camera_getOrigin(camera)); - origin[2] -= SPEED_MOVE; - Camera_setOrigin(camera, origin); -} - -void Camera_MoveLeft_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.right, -SPEED_MOVE))); -} - -void Camera_MoveRight_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.right, SPEED_MOVE))); -} - -void Camera_RotateLeft_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_YAW] += SPEED_TURN; - Camera_setAngles(camera, angles); -} - -void Camera_RotateRight_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_YAW] -= SPEED_TURN; - Camera_setAngles(camera, angles); -} - -void Camera_PitchUp_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_PITCH] += SPEED_TURN; - if (angles[CAMERA_PITCH] > 90) { - angles[CAMERA_PITCH] = 90; - } - Camera_setAngles(camera, angles); -} - -void Camera_PitchDown_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_PITCH] -= SPEED_TURN; - if (angles[CAMERA_PITCH] < -90) { - angles[CAMERA_PITCH] = -90; - } - Camera_setAngles(camera, angles); -} - - -class RadiantCameraView : public CameraView { -camera_t &m_camera; -View *m_view; -Callback m_update; -public: -RadiantCameraView(camera_t &camera, View *view, const Callback &update) : m_camera(camera), m_view(view), - m_update(update) -{ -} - -void update() -{ - m_view->Construct(m_camera.projection, m_camera.modelview, m_camera.width, m_camera.height); - m_update(); -} - -void setModelview(const Matrix4 &modelview) -{ - m_camera.modelview = modelview; - matrix4_multiply_by_matrix4(m_camera.modelview, g_radiant2opengl); - matrix4_affine_invert(m_camera.modelview); - Camera_updateVectors(m_camera); - update(); -} - -void setFieldOfView(float fieldOfView) -{ - float farClip = Camera_getFarClipPlane(m_camera); - m_camera.projection = projection_for_camera(farClip / 4096.0f, farClip, fieldOfView, m_camera.width, - m_camera.height); - update(); -} -}; - - -void Camera_motionDelta(int x, int y, unsigned int state, void *data) -{ - camera_t *cam = reinterpret_cast( data ); - - cam->m_mouseMove.motion_delta(x, y, state); - - switch (g_camwindow_globals_private.m_nStrafeMode) { - case 0: - cam->m_strafe = (state & GDK_SHIFT_MASK) != 0; - if (cam->m_strafe) { - cam->m_strafe_forward = (state & GDK_CONTROL_MASK) != 0; - } else { - cam->m_strafe_forward = false; - } - break; - case 1: - cam->m_strafe = (state & GDK_CONTROL_MASK) != 0 && (state & GDK_SHIFT_MASK) == 0; - cam->m_strafe_forward = false; - break; - case 2: - cam->m_strafe = (state & GDK_CONTROL_MASK) != 0 && (state & GDK_SHIFT_MASK) == 0; - cam->m_strafe_forward = cam->m_strafe; - break; - } -} - -class CamWnd { -View m_view; -camera_t m_Camera; -RadiantCameraView m_cameraview; -#if 0 -int m_PositionDragCursorX; -int m_PositionDragCursorY; -#endif - -guint m_freemove_handle_focusout; - -static Shader *m_state_select1; -static Shader *m_state_select2; - -FreezePointer m_freezePointer; - -public: -ui::GLArea m_gl_widget; -ui::Window m_parent{ui::null}; - -SelectionSystemWindowObserver *m_window_observer; -XORRectangle m_XORRectangle; - -DeferredDraw m_deferredDraw; -DeferredMotion m_deferred_motion; - -guint m_selection_button_press_handler; -guint m_selection_button_release_handler; -guint m_selection_motion_handler; - -guint m_freelook_button_press_handler; -guint m_freelook_key_press_handler; - -guint m_sizeHandler; -guint m_exposeHandler; - -CamWnd(); - -~CamWnd(); - -bool m_drawing; - -void queue_draw() -{ - //ASSERT_MESSAGE(!m_drawing, "CamWnd::queue_draw(): called while draw is already in progress"); - if (m_drawing) { - return; - } - //globalOutputStream() << "queue... "; - m_deferredDraw.draw(); -} - -void draw(); - -static void captureStates() -{ - m_state_select1 = GlobalShaderCache().capture("$CAM_HIGHLIGHT"); - m_state_select2 = GlobalShaderCache().capture("$CAM_OVERLAY"); -} - -static void releaseStates() -{ - GlobalShaderCache().release("$CAM_HIGHLIGHT"); - GlobalShaderCache().release("$CAM_OVERLAY"); -} - -camera_t &getCamera() -{ - return m_Camera; -}; - -void BenchMark(); - -void Cam_ChangeFloor(bool up); - -void DisableFreeMove(); - -void EnableFreeMove(); - -bool m_bFreeMove; - -CameraView &getCameraView() -{ - return m_cameraview; -} - -private: -void Cam_Draw(); -}; - -typedef MemberCaller CamWndQueueDraw; - -Shader *CamWnd::m_state_select1 = 0; -Shader *CamWnd::m_state_select2 = 0; - -CamWnd *NewCamWnd() -{ - return new CamWnd; -} - -void DeleteCamWnd(CamWnd *camwnd) -{ - delete camwnd; -} - -void CamWnd_constructStatic() -{ - CamWnd::captureStates(); -} - -void CamWnd_destroyStatic() -{ - CamWnd::releaseStates(); -} - -static CamWnd *g_camwnd = 0; - -void GlobalCamera_setCamWnd(CamWnd &camwnd) -{ - g_camwnd = &camwnd; -} - - -ui::GLArea CamWnd_getWidget(CamWnd &camwnd) -{ - return camwnd.m_gl_widget; -} - -ui::Window CamWnd_getParent(CamWnd &camwnd) -{ - return camwnd.m_parent; -} - -ToggleShown g_camera_shown(true); - -void CamWnd_setParent(CamWnd &camwnd, ui::Window parent) -{ - camwnd.m_parent = parent; - g_camera_shown.connect(camwnd.m_parent); -} - -void CamWnd_Update(CamWnd &camwnd) -{ - camwnd.queue_draw(); -} - - -camwindow_globals_t g_camwindow_globals; - -const Vector3 &Camera_getOrigin(CamWnd &camwnd) -{ - return Camera_getOrigin(camwnd.getCamera()); -} - -void Camera_setOrigin(CamWnd &camwnd, const Vector3 &origin) -{ - Camera_setOrigin(camwnd.getCamera(), origin); -} - -const Vector3 &Camera_getAngles(CamWnd &camwnd) -{ - return Camera_getAngles(camwnd.getCamera()); -} - -void Camera_setAngles(CamWnd &camwnd, const Vector3 &angles) -{ - Camera_setAngles(camwnd.getCamera(), angles); -} - - -// ============================================================================= -// CamWnd class - -gboolean enable_freelook_button_press(ui::Widget widget, GdkEventButton *event, CamWnd *camwnd) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - camwnd->EnableFreeMove(); - return TRUE; - } - return FALSE; -} - -gboolean disable_freelook_button_press(ui::Widget widget, GdkEventButton *event, CamWnd *camwnd) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - camwnd->DisableFreeMove(); - return TRUE; - } - return FALSE; -} - -static gint disable_freelook_key_press(ui::Entry widget, GdkEventKey *event, CamWnd *camwnd) -{ - if (event->keyval == GDK_KEY_Escape) { - camwnd->DisableFreeMove(); - return TRUE; - } - return FALSE; -} - -#if 0 -gboolean mousecontrol_button_press( ui::Widget widget, GdkEventButton* event, CamWnd* camwnd ){ - if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) { - Cam_MouseControl( camwnd->getCamera(), event->x, widget->allocation.height - 1 - event->y ); - } - return FALSE; -} -#endif - -void camwnd_update_xor_rectangle(CamWnd &self, rect_t area) -{ - if (self.m_gl_widget.visible()) { - self.m_XORRectangle.set( - rectangle_from_area(area.min, area.max, self.getCamera().width, self.getCamera().height)); - } -} - - -gboolean selection_button_press(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_PRESS) { - observer->onMouseDown(WindowVector_forDouble(event->x, event->y), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_button_release(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_RELEASE) { - observer->onMouseUp(WindowVector_forDouble(event->x, event->y), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -void selection_motion(gdouble x, gdouble y, guint state, void *data) -{ - //globalOutputStream() << "motion... "; - reinterpret_cast( data )->onMouseMotion(WindowVector_forDouble(x, y), modifiers_for_state(state)); -} - -inline WindowVector windowvector_for_widget_centre(ui::Widget widget) -{ - auto allocation = widget.dimensions(); - return WindowVector(static_cast( allocation.width / 2 ), static_cast(allocation.height / 2 )); -} - -gboolean selection_button_press_freemove(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_PRESS) { - observer->onMouseDown(windowvector_for_widget_centre(widget), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_button_release_freemove(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_RELEASE) { - observer->onMouseUp(windowvector_for_widget_centre(widget), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_motion_freemove(ui::Widget widget, GdkEventMotion *event, WindowObserver *observer) -{ - observer->onMouseMotion(windowvector_for_widget_centre(widget), modifiers_for_state(event->state)); - return FALSE; -} - -gboolean wheelmove_scroll(ui::Widget widget, GdkEventScroll *event, CamWnd *camwnd) -{ - if (event->direction == GDK_SCROLL_UP) { - Camera_Freemove_updateAxes(camwnd->getCamera()); - Camera_setOrigin(*camwnd, vector3_added(Camera_getOrigin(*camwnd), vector3_scaled(camwnd->getCamera().forward, - static_cast( g_camwindow_globals_private.m_nMoveSpeed )))); - } else if (event->direction == GDK_SCROLL_DOWN) { - Camera_Freemove_updateAxes(camwnd->getCamera()); - Camera_setOrigin(*camwnd, vector3_added(Camera_getOrigin(*camwnd), vector3_scaled(camwnd->getCamera().forward, - -static_cast( g_camwindow_globals_private.m_nMoveSpeed )))); - } - - return FALSE; -} - -gboolean camera_size_allocate(ui::Widget widget, GtkAllocation *allocation, CamWnd *camwnd) -{ - camwnd->getCamera().width = allocation->width; - camwnd->getCamera().height = allocation->height; - Camera_updateProjection(camwnd->getCamera()); - camwnd->m_window_observer->onSizeChanged(camwnd->getCamera().width, camwnd->getCamera().height); - camwnd->queue_draw(); - return FALSE; -} - -gboolean camera_expose(ui::Widget widget, GdkEventExpose *event, gpointer data) -{ - reinterpret_cast( data )->draw(); - return FALSE; -} - -void KeyEvent_connect(const char *name) -{ - const KeyEvent &keyEvent = GlobalKeyEvents_find(name); - keydown_accelerators_add(keyEvent.m_accelerator, keyEvent.m_keyDown); - keyup_accelerators_add(keyEvent.m_accelerator, keyEvent.m_keyUp); -} - -void KeyEvent_disconnect(const char *name) -{ - const KeyEvent &keyEvent = GlobalKeyEvents_find(name); - keydown_accelerators_remove(keyEvent.m_accelerator); - keyup_accelerators_remove(keyEvent.m_accelerator); -} - -void CamWnd_registerCommands(CamWnd &camwnd) -{ - GlobalKeyEvents_insert("CameraForward", Accelerator(GDK_KEY_Up), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraBack", Accelerator(GDK_KEY_Down), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraLeft", Accelerator(GDK_KEY_Left), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraRight", Accelerator(GDK_KEY_Right), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraStrafeRight", Accelerator(GDK_KEY_period), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraStrafeLeft", Accelerator(GDK_KEY_comma), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraUp", Accelerator('D'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraDown", Accelerator('C'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraAngleDown", Accelerator('A'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraAngleUp", Accelerator('Z'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - - GlobalKeyEvents_insert("CameraFreeMoveForward", Accelerator(GDK_KEY_Up), - FreeMoveCameraMoveForwardKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveForwardKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveBack", Accelerator(GDK_KEY_Down), - FreeMoveCameraMoveBackKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveBackKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveLeft", Accelerator(GDK_KEY_Left), - FreeMoveCameraMoveLeftKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveLeftKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveRight", Accelerator(GDK_KEY_Right), - FreeMoveCameraMoveRightKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveRightKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveUp", Accelerator('D'), - FreeMoveCameraMoveUpKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveUpKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveDown", Accelerator('C'), - FreeMoveCameraMoveDownKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveDownKeyUpCaller(camwnd.getCamera()) - ); - - GlobalCommands_insert("CameraForward", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Up)); - GlobalCommands_insert("CameraBack", ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Down)); - GlobalCommands_insert("CameraLeft", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Left)); - GlobalCommands_insert("CameraRight", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Right)); - GlobalCommands_insert("CameraStrafeRight", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_period)); - GlobalCommands_insert("CameraStrafeLeft", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_comma)); - - GlobalCommands_insert("CameraUp", ReferenceCaller(camwnd.getCamera()), - Accelerator('D')); - GlobalCommands_insert("CameraDown", ReferenceCaller(camwnd.getCamera()), - Accelerator('C')); - GlobalCommands_insert("CameraAngleUp", - ReferenceCaller(camwnd.getCamera()), - Accelerator('A')); - GlobalCommands_insert("CameraAngleDown", - ReferenceCaller(camwnd.getCamera()), - Accelerator('Z')); -} - -void CamWnd_Move_Enable(CamWnd &camwnd) -{ - KeyEvent_connect("CameraForward"); - KeyEvent_connect("CameraBack"); - KeyEvent_connect("CameraLeft"); - KeyEvent_connect("CameraRight"); - KeyEvent_connect("CameraStrafeRight"); - KeyEvent_connect("CameraStrafeLeft"); - KeyEvent_connect("CameraUp"); - KeyEvent_connect("CameraDown"); - KeyEvent_connect("CameraAngleUp"); - KeyEvent_connect("CameraAngleDown"); -} - -void CamWnd_Move_Disable(CamWnd &camwnd) -{ - KeyEvent_disconnect("CameraForward"); - KeyEvent_disconnect("CameraBack"); - KeyEvent_disconnect("CameraLeft"); - KeyEvent_disconnect("CameraRight"); - KeyEvent_disconnect("CameraStrafeRight"); - KeyEvent_disconnect("CameraStrafeLeft"); - KeyEvent_disconnect("CameraUp"); - KeyEvent_disconnect("CameraDown"); - KeyEvent_disconnect("CameraAngleUp"); - KeyEvent_disconnect("CameraAngleDown"); -} - -void CamWnd_Move_Discrete_Enable(CamWnd &camwnd) -{ - command_connect_accelerator("CameraForward"); - command_connect_accelerator("CameraBack"); - command_connect_accelerator("CameraLeft"); - command_connect_accelerator("CameraRight"); - command_connect_accelerator("CameraStrafeRight"); - command_connect_accelerator("CameraStrafeLeft"); - command_connect_accelerator("CameraUp"); - command_connect_accelerator("CameraDown"); - command_connect_accelerator("CameraAngleUp"); - command_connect_accelerator("CameraAngleDown"); -} - -void CamWnd_Move_Discrete_Disable(CamWnd &camwnd) -{ - command_disconnect_accelerator("CameraForward"); - command_disconnect_accelerator("CameraBack"); - command_disconnect_accelerator("CameraLeft"); - command_disconnect_accelerator("CameraRight"); - command_disconnect_accelerator("CameraStrafeRight"); - command_disconnect_accelerator("CameraStrafeLeft"); - command_disconnect_accelerator("CameraUp"); - command_disconnect_accelerator("CameraDown"); - command_disconnect_accelerator("CameraAngleUp"); - command_disconnect_accelerator("CameraAngleDown"); -} - -struct CamWnd_Move_Discrete { - static void Export(const Callback &returnz) - { - returnz(g_camwindow_globals_private.m_bCamDiscrete); - } - - static void Import(bool value) - { - if (g_camwnd) { - Import_(*g_camwnd, value); - } else { - g_camwindow_globals_private.m_bCamDiscrete = value; - } - } - - static void Import_(CamWnd &camwnd, bool value) - { - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Disable(camwnd); - } else { - CamWnd_Move_Disable(camwnd); - } - - g_camwindow_globals_private.m_bCamDiscrete = value; - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Enable(camwnd); - } else { - CamWnd_Move_Enable(camwnd); - } - } -}; - - -void CamWnd_Add_Handlers_Move(CamWnd &camwnd) -{ - camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect("button_press_event", - G_CALLBACK(selection_button_press), - camwnd.m_window_observer); - camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect("button_release_event", - G_CALLBACK(selection_button_release), - camwnd.m_window_observer); - camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect("motion_notify_event", - G_CALLBACK(DeferredMotion::gtk_motion), - &camwnd.m_deferred_motion); - - camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect("button_press_event", - G_CALLBACK(enable_freelook_button_press), - &camwnd); - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Enable(camwnd); - } else { - CamWnd_Move_Enable(camwnd); - } -} - -void CamWnd_Remove_Handlers_Move(CamWnd &camwnd) -{ - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_release_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_motion_handler); - - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_key_press_handler); - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Disable(camwnd); - } else { - CamWnd_Move_Disable(camwnd); - } -} - -void CamWnd_Add_Handlers_FreeMove(CamWnd &camwnd) -{ - camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect( - "button_press_event", - G_CALLBACK(selection_button_press_freemove), - camwnd.m_window_observer); - camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect( - "button_release_event", - G_CALLBACK(selection_button_release_freemove), - camwnd.m_window_observer); - camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect( - "motion_notify_event", - G_CALLBACK(selection_motion_freemove), - camwnd.m_window_observer); - camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect( - "button_press_event", - G_CALLBACK(disable_freelook_button_press), - &camwnd); - camwnd.m_freelook_key_press_handler = camwnd.m_gl_widget.connect( - "key_press_event", - G_CALLBACK(disable_freelook_key_press), - &camwnd); - - KeyEvent_connect("CameraFreeMoveForward"); - KeyEvent_connect("CameraFreeMoveBack"); - KeyEvent_connect("CameraFreeMoveLeft"); - KeyEvent_connect("CameraFreeMoveRight"); - KeyEvent_connect("CameraFreeMoveUp"); - KeyEvent_connect("CameraFreeMoveDown"); -} - -void CamWnd_Remove_Handlers_FreeMove(CamWnd &camwnd) -{ - KeyEvent_disconnect("CameraFreeMoveForward"); - KeyEvent_disconnect("CameraFreeMoveBack"); - KeyEvent_disconnect("CameraFreeMoveLeft"); - KeyEvent_disconnect("CameraFreeMoveRight"); - KeyEvent_disconnect("CameraFreeMoveUp"); - KeyEvent_disconnect("CameraFreeMoveDown"); - - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_release_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_motion_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_key_press_handler); -} - -CamWnd::CamWnd() : - m_view(true), - m_Camera(&m_view, CamWndQueueDraw(*this)), - m_cameraview(m_Camera, &m_view, ReferenceCaller(*this)), - m_gl_widget(glwidget_new(TRUE)), - m_window_observer(NewWindowObserver()), - m_XORRectangle(m_gl_widget), - m_deferredDraw(WidgetQueueDrawCaller(m_gl_widget)), - m_deferred_motion(selection_motion, m_window_observer), - m_selection_button_press_handler(0), - m_selection_button_release_handler(0), - m_selection_motion_handler(0), - m_freelook_button_press_handler(0), - m_freelook_key_press_handler(0), - m_drawing(false) -{ - m_bFreeMove = false; - - GlobalWindowObservers_add(m_window_observer); - GlobalWindowObservers_connectWidget(m_gl_widget); - - m_window_observer->setRectangleDrawCallback( - ReferenceCaller(*this)); - m_window_observer->setView(m_view); - - g_object_ref(m_gl_widget._handle); - - gtk_widget_set_events(m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(m_gl_widget, true); - - m_sizeHandler = m_gl_widget.connect("size_allocate", G_CALLBACK(camera_size_allocate), this); - m_exposeHandler = m_gl_widget.on_render(G_CALLBACK(camera_expose), this); - - Map_addValidCallback(g_map, DeferredDrawOnMapValidChangedCaller(m_deferredDraw)); - - CamWnd_registerCommands(*this); - - CamWnd_Add_Handlers_Move(*this); - - m_gl_widget.connect("scroll_event", G_CALLBACK(wheelmove_scroll), this); - - AddSceneChangeCallback(ReferenceCaller(*this)); - - PressedButtons_connect(g_pressedButtons, m_gl_widget); -} - -CamWnd::~CamWnd() -{ - if (m_bFreeMove) { - DisableFreeMove(); - } - - CamWnd_Remove_Handlers_Move(*this); - - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_exposeHandler); - - m_gl_widget.unref(); - - m_window_observer->release(); -} - -class FloorHeightWalker : public scene::Graph::Walker { -float m_current; -float &m_bestUp; -float &m_bestDown; -public: -FloorHeightWalker(float current, float &bestUp, float &bestDown) : - m_current(current), m_bestUp(bestUp), m_bestDown(bestDown) -{ - bestUp = g_MaxWorldCoord; - bestDown = -g_MaxWorldCoord; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible() - && Node_isBrush(path.top())) { // this node is a floor - const AABB &aabb = instance.worldAABB(); - float floorHeight = aabb.origin.z() + aabb.extents.z(); - if (floorHeight > m_current && floorHeight < m_bestUp) { - m_bestUp = floorHeight; - } - if (floorHeight < m_current && floorHeight > m_bestDown) { - m_bestDown = floorHeight; - } - } - return true; -} -}; - -void CamWnd::Cam_ChangeFloor(bool up) -{ - float current = m_Camera.origin[2] - 48; - float bestUp; - float bestDown; - GlobalSceneGraph().traverse(FloorHeightWalker(current, bestUp, bestDown)); - - if (up && bestUp != g_MaxWorldCoord) { - current = bestUp; - } - if (!up && bestDown != -g_MaxWorldCoord) { - current = bestDown; - } - - m_Camera.origin[2] = current + 48; - Camera_updateModelview(getCamera()); - CamWnd_Update(*this); - CameraMovedNotify(); -} - - -#if 0 - -// button_press -Sys_GetCursorPos( &m_PositionDragCursorX, &m_PositionDragCursorY ); - -// motion -if ( ( m_bFreeMove && ( buttons == ( RAD_CONTROL | RAD_SHIFT ) ) ) - || ( !m_bFreeMove && ( buttons == ( RAD_RBUTTON | RAD_CONTROL ) ) ) ) { - Cam_PositionDrag(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - return; -} - -void CamWnd::Cam_PositionDrag(){ - int x, y; - - Sys_GetCursorPos( m_gl_widget, &x, &y ); - if ( x != m_PositionDragCursorX || y != m_PositionDragCursorY ) { - x -= m_PositionDragCursorX; - vector3_add( m_Camera.origin, vector3_scaled( m_Camera.vright, x ) ); - y -= m_PositionDragCursorY; - m_Camera.origin[2] -= y; - Camera_updateModelview(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - - Sys_SetCursorPos( m_parent, m_PositionDragCursorX, m_PositionDragCursorY ); - } -} -#endif - - -// NOTE TTimo if there's an OS-level focus out of the application -// then we can release the camera cursor grab -static gboolean camwindow_freemove_focusout(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - reinterpret_cast( data )->DisableFreeMove(); - return FALSE; -} - -void CamWnd::EnableFreeMove() -{ - //globalOutputStream() << "EnableFreeMove\n"; - - ASSERT_MESSAGE(!m_bFreeMove, "EnableFreeMove: free-move was already enabled"); - m_bFreeMove = true; - Camera_clearMovementFlags(getCamera(), MOVE_ALL); - - CamWnd_Remove_Handlers_Move(*this); - CamWnd_Add_Handlers_FreeMove(*this); - - gtk_window_set_focus(m_parent, m_gl_widget); - m_freemove_handle_focusout = m_gl_widget.connect("focus_out_event", G_CALLBACK(camwindow_freemove_focusout), this); - m_freezePointer.freeze_pointer(m_parent, Camera_motionDelta, &m_Camera); - - CamWnd_Update(*this); -} - -void CamWnd::DisableFreeMove() -{ - //globalOutputStream() << "DisableFreeMove\n"; - - //ASSERT_MESSAGE(m_bFreeMove, "DisableFreeMove: free-move was not enabled"); - if (m_bFreeMove == false) { - return; - } - m_bFreeMove = false; - Camera_clearMovementFlags(getCamera(), MOVE_ALL); - - CamWnd_Remove_Handlers_FreeMove(*this); - CamWnd_Add_Handlers_Move(*this); - - m_freezePointer.unfreeze_pointer(m_parent); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_freemove_handle_focusout); - - CamWnd_Update(*this); -} - - -#include "renderer.h" - -class CamRenderer : public Renderer { -struct state_type { - state_type() : m_highlight(0), m_state(0), m_lights(0) - { - } - - unsigned int m_highlight; - Shader *m_state; - const LightList *m_lights; -}; - -std::vector m_state_stack; -RenderStateFlags m_globalstate; -Shader *m_state_select0; -Shader *m_state_select1; -const Vector3 &m_viewer; - -public: -CamRenderer(RenderStateFlags globalstate, Shader *select0, Shader *select1, const Vector3 &viewer) : - m_globalstate(globalstate), - m_state_select0(select0), - m_state_select1(select1), - m_viewer(viewer) -{ - ASSERT_NOTNULL(select0); - ASSERT_NOTNULL(select1); - m_state_stack.push_back(state_type()); -} - -void SetState(Shader *state, EStyle style) -{ - ASSERT_NOTNULL(state); - if (style == eFullMaterials) { - m_state_stack.back().m_state = state; - } -} - -EStyle getStyle() const -{ - return eFullMaterials; -} - -void PushState() -{ - m_state_stack.push_back(m_state_stack.back()); -} - -void PopState() -{ - ASSERT_MESSAGE(!m_state_stack.empty(), "popping empty stack"); - m_state_stack.pop_back(); -} - -void Highlight(EHighlightMode mode, bool bEnable = true) -{ - (bEnable) - ? m_state_stack.back().m_highlight |= mode - : m_state_stack.back().m_highlight &= ~mode; -} - -void setLights(const LightList &lights) -{ - m_state_stack.back().m_lights = &lights; -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &world) -{ - if (m_state_stack.back().m_highlight & ePrimitive) { - m_state_select0->addRenderable(renderable, world, m_state_stack.back().m_lights); - } - if (m_state_stack.back().m_highlight & eFace) { - m_state_select1->addRenderable(renderable, world, m_state_stack.back().m_lights); - } - - m_state_stack.back().m_state->addRenderable(renderable, world, m_state_stack.back().m_lights); -} - -void render(const Matrix4 &modelview, const Matrix4 &projection) -{ - GlobalShaderCache().render(m_globalstate, modelview, projection, m_viewer); -} -}; - -/* - ============== - Cam_Draw - ============== - */ - -void ShowStatsToggle() -{ - g_camwindow_globals_private.m_showStats ^= 1; -} -void ShowStatsExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showStats); -} -FreeCaller &), ShowStatsExport> g_show_stats_caller; -Callback &)> g_show_stats_callback(g_show_stats_caller); -ToggleItem g_show_stats(g_show_stats_callback); - -void ShowLightToggle() -{ - g_camwindow_globals_private.m_showLighting ^= 1; -} -void ShowLightExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showLighting); -} -FreeCaller &), ShowLightExport> g_show_light_caller; -Callback &)> g_show_light_callback(g_show_light_caller); -ToggleItem g_show_light(g_show_light_callback); - -void ShowAlphaToggle() -{ - g_camwindow_globals_private.m_showAlpha ^= 1; -} -void ShowAlphaExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showAlpha); -} -FreeCaller &), ShowAlphaExport> g_show_alpha_caller; -Callback &)> g_show_alpha_callback(g_show_alpha_caller); -ToggleItem g_show_alpha(g_show_alpha_callback); - -/* Show Patch Balls */ -void ShowPatchBallsToggle() -{ - g_camwindow_globals_private.m_showPatchBalls ^= 1; -} -void ShowPatchBallsExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showPatchBalls); -} -FreeCaller &), ShowPatchBallsExport> g_show_patchballs_caller; -Callback &)> g_show_patchballs_callback(g_show_patchballs_caller); -ToggleItem g_show_patchballs(g_show_patchballs_callback); - -bool -PatchBalls_Visible(void) -{ - return g_camwindow_globals_private.m_showPatchBalls; -} - -void CamWnd::Cam_Draw() -{ - glViewport(0, 0, m_Camera.width, m_Camera.height); - glScissor(0, 0, m_Camera.width, m_Camera.height); - glEnable(GL_SCISSOR_TEST); - #if 0 - GLint viewprt[4]; - glGetIntegerv( GL_VIEWPORT, viewprt ); - #endif - - // enable depth buffer writes - glDepthMask(GL_TRUE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - Vector3 clearColour(0, 0, 0); - if (m_Camera.draw_mode != cd_lighting) { - clearColour = g_camwindow_globals.color_cameraback; - } - - glClearColor(clearColour[0], clearColour[1], clearColour[2], 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - extern void Renderer_ResetStats(); - Renderer_ResetStats(); - extern void Cull_ResetStats(); - Cull_ResetStats(); - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &m_Camera.projection )); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(reinterpret_cast( &m_Camera.modelview )); - - - /* | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH */ - unsigned int globalstate = - /*RENDER_DEPTHTEST | RENDER_COLOURWRITE | | - RENDER_COLOURARRAY | RENDER_OFFSETLINE | RENDER_FOG | RENDER_COLOURCHANGE |*/ - RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_POLYOFS | RENDER_DEPTHWRITE; - - if (g_camwindow_globals_private.m_showAlpha) { - globalstate |= RENDER_ALPHATEST | RENDER_BLEND; - } - - if (g_camwindow_globals_private.m_showLighting) { - GLfloat inverse_cam_dir[4], ambient[4], diffuse[4]; - ambient[0] = ambient[1] = ambient[2] = 0.25f; - ambient[3] = 1.0f; - diffuse[0] = diffuse[1] = diffuse[2] = 1.0f; - diffuse[3] = 1.0f; - inverse_cam_dir[0] = m_Camera.vpn[0]; - inverse_cam_dir[1] = m_Camera.vpn[1]; - inverse_cam_dir[2] = m_Camera.vpn[2]; - inverse_cam_dir[3] = 0; - glLightfv(GL_LIGHT0, GL_POSITION, inverse_cam_dir); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glEnable(GL_LIGHT0); - globalstate |= RENDER_LIGHTING; - } - - switch (m_Camera.draw_mode) { - case cd_wire: - break; - case cd_solid: - globalstate |= RENDER_FILL - | RENDER_SCALED; - break; - case cd_texture: - globalstate |= RENDER_FILL - | RENDER_TEXTURE - | RENDER_SMOOTH - | RENDER_SCALED; - break; - case cd_lighting: - globalstate |= RENDER_FILL - | RENDER_TEXTURE - | RENDER_SMOOTH - | RENDER_SCALED - | RENDER_BUMP - | RENDER_PROGRAM - | RENDER_SCREEN; - break; - default: - globalstate = 0; - break; - } - - if (!g_xywindow_globals.m_bNoStipple) { - globalstate |= RENDER_LINESTIPPLE | RENDER_POLYGONSTIPPLE; - } - - /* render */ - { - CamRenderer renderer(globalstate, m_state_select2, m_state_select1, m_view.getViewer()); - Scene_Render(renderer, m_view); - renderer.render(m_Camera.modelview, m_Camera.projection); - } - - // prepare for 2d stuff - glColor4f(1, 1, 1, 1); - glDisable(GL_BLEND); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, (float) m_Camera.width, 0, (float) m_Camera.height, -100, 100); - glScalef(1, -1, 1); - glTranslatef(0, -(float) m_Camera.height, 0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (GlobalOpenGL().GL_1_3()) { - glClientActiveTexture(GL_TEXTURE0); - glActiveTexture(GL_TEXTURE0); - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_DEPTH_TEST); - glColor3f(1.f, 1.f, 1.f); - glLineWidth(1); - - // draw the crosshair - if (m_bFreeMove) { - glBegin(GL_LINES); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 6); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 2); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 6); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 2); - glVertex2f((float) m_Camera.width / 2.f + 6, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f + 2, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f - 6, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f - 2, (float) m_Camera.height / 2.f); - glEnd(); - } - - if (g_camwindow_globals_private.m_showStats) { - glRasterPos3f(1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent(), 0.0f); - extern const char *Renderer_GetStats(); - GlobalOpenGL().drawString(Renderer_GetStats()); - - glRasterPos3f(1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent() - - GlobalOpenGL().m_font->getPixelHeight(), 0.0f); - extern const char *Cull_GetStats(); - GlobalOpenGL().drawString(Cull_GetStats()); - } - - // bind back to the default texture so that we don't have problems - // elsewhere using/modifying texture maps between contexts - glBindTexture(GL_TEXTURE_2D, 0); -} - -void CamWnd::draw() -{ - m_drawing = true; - - if (glwidget_make_current(m_gl_widget) != FALSE) { - if (Map_Valid(g_map) && ScreenUpdates_Enabled()) { - GlobalOpenGL_debugAssertNoErrors(); - Cam_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - m_XORRectangle.set(rectangle_t()); - } - - glwidget_swap_buffers(m_gl_widget); - } - - m_drawing = false; -} - -void CamWnd::BenchMark() -{ - double dStart = Sys_DoubleTime(); - for (int i = 0; i < 100; i++) { - Vector3 angles; - angles[CAMERA_ROLL] = 0; - angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = static_cast( i * (360.0 / 100.0)); - Camera_setAngles(*this, angles); - } - double dEnd = Sys_DoubleTime(); - globalOutputStream() << FloatFormat(dEnd - dStart, 5, 2) << " seconds\n"; -} - - -void fill_view_camera_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "Camera View", "ToggleCamera"); -} - -void GlobalCamera_ResetAngles() -{ - CamWnd &camwnd = *g_camwnd; - Vector3 angles; - angles[CAMERA_ROLL] = angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = static_cast( 22.5 * floor((Camera_getAngles(camwnd)[CAMERA_YAW] + 11) / 22.5)); - Camera_setAngles(camwnd, angles); -} - -void Camera_ChangeFloorUp() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.Cam_ChangeFloor(true); -} - -void Camera_ChangeFloorDown() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.Cam_ChangeFloor(false); -} - -void Camera_CubeIn() -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals.m_nCubicScale--; - if (g_camwindow_globals.m_nCubicScale < 1) { - g_camwindow_globals.m_nCubicScale = 1; - } - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - g_pParentWnd->SetGridStatus(); -} - -void Camera_CubeOut() -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals.m_nCubicScale++; - if (g_camwindow_globals.m_nCubicScale > 23) { - g_camwindow_globals.m_nCubicScale = 23; - } - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - g_pParentWnd->SetGridStatus(); -} - -bool Camera_GetFarClip() -{ - return g_camwindow_globals_private.m_bCubicClipping; -} - -ConstReferenceCaller &), PropertyImpl::Export> g_getfarclip_caller( - g_camwindow_globals_private.m_bCubicClipping); -ToggleItem g_getfarclip_item(g_getfarclip_caller); - -void Camera_SetFarClip(bool value) -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals_private.m_bCubicClipping = value; - g_getfarclip_item.update(); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); -} - -struct Camera_FarClip { - static void Export(const Callback &returnz) - { - returnz(g_camwindow_globals_private.m_bCubicClipping); - } - - static void Import(bool value) - { - Camera_SetFarClip(value); - } -}; - -void Camera_ToggleFarClip() -{ - Camera_SetFarClip(!Camera_GetFarClip()); -} - - -void CamWnd_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_toggle_button(toolbar, "Cubic clip the camera view", "view_cubicclipping.xpm", - "ToggleCubicClip"); -} - -void CamWnd_registerShortcuts() -{ - toggle_add_accelerator("ToggleCubicClip"); - command_connect_accelerator("CameraSpeedInc"); - command_connect_accelerator("CameraSpeedDec"); -} - - -void GlobalCamera_Benchmark() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.BenchMark(); -} - -void GlobalCamera_Update() -{ - CamWnd &camwnd = *g_camwnd; - CamWnd_Update(camwnd); -} - -camera_draw_mode CamWnd_GetMode() -{ - return camera_t::draw_mode; -} - -void CamWnd_SetMode(camera_draw_mode mode) -{ - ShaderCache_setBumpEnabled(mode == cd_lighting); - camera_t::draw_mode = mode; - if (g_camwnd != 0) { - CamWnd_Update(*g_camwnd); - } -} - -void CamWnd_TogglePreview(void) -{ - // switch between textured and lighting mode - CamWnd_SetMode((CamWnd_GetMode() == cd_lighting) ? cd_texture : cd_lighting); -} - - -CameraModel *g_camera_model = 0; - -void CamWnd_LookThroughCamera(CamWnd &camwnd) -{ - if (g_camera_model != 0) { - CamWnd_Add_Handlers_Move(camwnd); - g_camera_model->setCameraView(0, Callback()); - g_camera_model = 0; - Camera_updateModelview(camwnd.getCamera()); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - } -} - -inline CameraModel *Instance_getCameraModel(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -void CamWnd_LookThroughSelected(CamWnd &camwnd) -{ - if (g_camera_model != 0) { - CamWnd_LookThroughCamera(camwnd); - } - - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - CameraModel *cameraModel = Instance_getCameraModel(instance); - if (cameraModel != 0) { - CamWnd_Remove_Handlers_Move(camwnd); - g_camera_model = cameraModel; - g_camera_model->setCameraView(&camwnd.getCameraView(), - ReferenceCaller(camwnd)); - } - } -} - -void GlobalCamera_LookThroughSelected() -{ - CamWnd_LookThroughSelected(*g_camwnd); -} - -void GlobalCamera_LookThroughCamera() -{ - CamWnd_LookThroughCamera(*g_camwnd); -} - -/* sets origin and angle to 0,0,0 coords */ -void XYZ_SetOrigin(const Vector3 &origin); -void GlobalCamera_GoToZero(void) -{ - CamWnd &camwnd = *g_camwnd; - Vector3 zero; - zero[0] = 0; - zero[1] = 0; - zero[2] = 0; - Camera_setAngles(camwnd, zero); - Camera_setOrigin(camwnd, zero); - Camera_updateModelview(camwnd.getCamera()); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - XYZ_SetOrigin(zero); -} - -struct RenderMode { - static void Export(const Callback &returnz) - { - switch (CamWnd_GetMode()) { - case cd_wire: - returnz(0); - break; - case cd_solid: - returnz(1); - break; - case cd_texture: - returnz(2); - break; - case cd_lighting: - returnz(3); - break; - } - } - - static void Import(int value) - { - switch (value) { - case 0: - CamWnd_SetMode(cd_wire); - break; - case 1: - CamWnd_SetMode(cd_solid); - break; - case 2: - CamWnd_SetMode(cd_texture); - break; - case 3: - CamWnd_SetMode(cd_lighting); - break; - default: - CamWnd_SetMode(cd_texture); - } - } -}; - -void Camera_constructPreferences(PreferencesPage &page) -{ - page.appendSlider("Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 100, MIN_CAM_SPEED, - MAX_CAM_SPEED, 1, 10); - page.appendCheckBox("", "Link strafe speed to movement speed", g_camwindow_globals_private.m_bCamLinkSpeed); - page.appendSlider("Rotation Speed", g_camwindow_globals_private.m_nAngleSpeed, TRUE, 0, 0, 3, 1, 180, 1, 10); - page.appendCheckBox("", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse); - page.appendCheckBox( - "", "Discrete movement", - make_property() - ); - page.appendCheckBox( - "", "Enable far-clip plane", - make_property() - ); - - - const char *render_mode[] = {"Wireframe", "Flatshade", "Textured"}; - - page.appendCombo( - "Render Mode", - STRING_ARRAY_RANGE(render_mode), - make_property() - ); - - - const char *strafe_mode[] = {"Both", "Forward", "Up"}; - - page.appendCombo( - "Strafe Mode", - g_camwindow_globals_private.m_nStrafeMode, - STRING_ARRAY_RANGE(strafe_mode) - ); -} - -void Camera_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Camera", "Camera View Preferences")); - Camera_constructPreferences(page); -} - -void Camera_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Camera_constructPage)); -} - -#include "preferencesystem.h" -#include "stringio.h" -#include "dialog.h" - -void CameraSpeed_increase() -{ - if (g_camwindow_globals_private.m_nMoveSpeed <= (MAX_CAM_SPEED - CAM_SPEED_STEP - 10)) { - g_camwindow_globals_private.m_nMoveSpeed += CAM_SPEED_STEP; - } else { - g_camwindow_globals_private.m_nMoveSpeed = MAX_CAM_SPEED - 10; - } -} - -void CameraSpeed_decrease() -{ - if (g_camwindow_globals_private.m_nMoveSpeed >= (MIN_CAM_SPEED + CAM_SPEED_STEP)) { - g_camwindow_globals_private.m_nMoveSpeed -= CAM_SPEED_STEP; - } else { - g_camwindow_globals_private.m_nMoveSpeed = MIN_CAM_SPEED; - } -} - -/// \brief Initialisation for things that have the same lifespan as this module. -void CamWnd_Construct() -{ - GlobalCommands_insert("CenterView", makeCallbackF(GlobalCamera_ResetAngles), Accelerator(GDK_KEY_End)); - GlobalCommands_insert("GoToZero", makeCallbackF(GlobalCamera_GoToZero)); - - GlobalToggles_insert("ToggleCubicClip", makeCallbackF(Camera_ToggleFarClip), - ToggleItem::AddCallbackCaller(g_getfarclip_item), - Accelerator('\\', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CubicClipZoomIn", makeCallbackF(Camera_CubeIn), - Accelerator('[', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CubicClipZoomOut", makeCallbackF(Camera_CubeOut), - Accelerator(']', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("UpFloor", makeCallbackF(Camera_ChangeFloorUp), Accelerator(GDK_KEY_Prior)); - GlobalCommands_insert("DownFloor", makeCallbackF(Camera_ChangeFloorDown), Accelerator(GDK_KEY_Next)); - - GlobalToggles_insert("ToggleCamera", ToggleShown::ToggleCaller(g_camera_shown), - ToggleItem::AddCallbackCaller(g_camera_shown.m_item), - Accelerator('C', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("LookThroughSelected", makeCallbackF(GlobalCamera_LookThroughSelected)); - GlobalCommands_insert("LookThroughCamera", makeCallbackF(GlobalCamera_LookThroughCamera)); - - GlobalCommands_insert("CameraSpeedInc", makeCallbackF(CameraSpeed_increase), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CameraSpeedDec", makeCallbackF(CameraSpeed_decrease), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalShortcuts_insert("CameraForward", Accelerator(GDK_KEY_Up)); - GlobalShortcuts_insert("CameraBack", Accelerator(GDK_KEY_Down)); - GlobalShortcuts_insert("CameraLeft", Accelerator(GDK_KEY_Left)); - GlobalShortcuts_insert("CameraRight", Accelerator(GDK_KEY_Right)); - GlobalShortcuts_insert("CameraStrafeRight", Accelerator(GDK_KEY_period)); - GlobalShortcuts_insert("CameraStrafeLeft", Accelerator(GDK_KEY_comma)); - - GlobalShortcuts_insert("CameraUp", Accelerator('D')); - GlobalShortcuts_insert("CameraDown", Accelerator('C')); - GlobalShortcuts_insert("CameraAngleUp", Accelerator('A')); - GlobalShortcuts_insert("CameraAngleDown", Accelerator('Z')); - - GlobalShortcuts_insert("CameraFreeMoveForward", Accelerator(GDK_KEY_Up)); - GlobalShortcuts_insert("CameraFreeMoveBack", Accelerator(GDK_KEY_Down)); - GlobalShortcuts_insert("CameraFreeMoveLeft", Accelerator(GDK_KEY_Left)); - GlobalShortcuts_insert("CameraFreeMoveRight", Accelerator(GDK_KEY_Right)); - - GlobalToggles_insert("ShowStats", makeCallbackF(ShowStatsToggle), ToggleItem::AddCallbackCaller(g_show_stats)); - GlobalToggles_insert("ShowLighting", makeCallbackF(ShowLightToggle), ToggleItem::AddCallbackCaller(g_show_light)); - GlobalToggles_insert("ShowAlpha", makeCallbackF(ShowAlphaToggle), ToggleItem::AddCallbackCaller(g_show_alpha)); - GlobalToggles_insert("ShowPatchBalls", makeCallbackF(ShowPatchBallsToggle), ToggleItem::AddCallbackCaller(g_show_patchballs)); - - GlobalPreferenceSystem().registerPreference("ShowStats", - make_property_string(g_camwindow_globals_private.m_showStats)); - GlobalPreferenceSystem().registerPreference("ShowLighting", - make_property_string(g_camwindow_globals_private.m_showLighting)); - GlobalPreferenceSystem().registerPreference("ShowAlpha", - make_property_string(g_camwindow_globals_private.m_showAlpha)); - GlobalPreferenceSystem().registerPreference("ShowPatchBalls", - make_property_string(g_camwindow_globals_private.m_showPatchBalls)); - GlobalPreferenceSystem().registerPreference("MoveSpeed", - make_property_string(g_camwindow_globals_private.m_nMoveSpeed)); - GlobalPreferenceSystem().registerPreference("CamLinkSpeed", - make_property_string(g_camwindow_globals_private.m_bCamLinkSpeed)); - GlobalPreferenceSystem().registerPreference("AngleSpeed", - make_property_string(g_camwindow_globals_private.m_nAngleSpeed)); - GlobalPreferenceSystem().registerPreference("CamInverseMouse", - make_property_string(g_camwindow_globals_private.m_bCamInverseMouse)); - GlobalPreferenceSystem().registerPreference("CamDiscrete", make_property_string()); - GlobalPreferenceSystem().registerPreference("CubicClipping", - make_property_string(g_camwindow_globals_private.m_bCubicClipping)); - GlobalPreferenceSystem().registerPreference("CubicScale", make_property_string(g_camwindow_globals.m_nCubicScale)); - GlobalPreferenceSystem().registerPreference("SI_Colors4", - make_property_string(g_camwindow_globals.color_cameraback)); - GlobalPreferenceSystem().registerPreference("SI_Colors12", - make_property_string(g_camwindow_globals.color_selbrushes3d)); - GlobalPreferenceSystem().registerPreference("CameraRenderMode", make_property_string()); - GlobalPreferenceSystem().registerPreference("StrafeMode", - make_property_string(g_camwindow_globals_private.m_nStrafeMode)); - - CamWnd_constructStatic(); - - Camera_registerPreferencesPage(); -} - -void CamWnd_Destroy() -{ - CamWnd_destroyStatic(); -} - -void CamWnd_DisableMovement() -{ - g_camwnd->DisableFreeMove(); -} diff --git a/src/camwindow.h b/src/camwindow.h deleted file mode 100644 index 4c832e4..0000000 --- a/src/camwindow.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CAMWINDOW_H ) -#define INCLUDED_CAMWINDOW_H - -#include -#include "math/vector.h" -#include "signal/signalfwd.h" - -class CamWnd; - -CamWnd *NewCamWnd(); - -void DeleteCamWnd(CamWnd *camwnd); - -void AddCameraMovedCallback(const SignalHandler &handler); - -void CamWnd_Update(CamWnd &camwnd); - -ui::GLArea CamWnd_getWidget(CamWnd &camwnd); - -void CamWnd_setParent(CamWnd &camwnd, ui::Window parent); - -void GlobalCamera_setCamWnd(CamWnd &camwnd); - -void fill_view_camera_menu(ui::Menu menu); - -void CamWnd_constructToolbar(ui::Toolbar toolbar); - -void CamWnd_registerShortcuts(); - -void GlobalCamera_Benchmark(); - -const Vector3 &Camera_getOrigin(CamWnd &camwnd); - -void Camera_setOrigin(CamWnd &camwnd, const Vector3 &origin); - -enum { - CAMERA_PITCH = 0, // up / down - CAMERA_YAW = 1, // left / right - CAMERA_ROLL = 2, // fall over -}; - -const Vector3 &Camera_getAngles(CamWnd &camwnd); - -void Camera_setAngles(CamWnd &camwnd, const Vector3 &angles); - - -struct camwindow_globals_t { - Vector3 color_cameraback; - Vector3 color_selbrushes3d; - - int m_nCubicScale; - - camwindow_globals_t() : - color_cameraback(0.15f, 0.15f, 0.15f), - color_selbrushes3d(1.0f, 0.0f, 0.0f), - m_nCubicScale(13) - { - } - -}; - -extern camwindow_globals_t g_camwindow_globals; - -void CamWnd_Construct(); - -void CamWnd_Destroy(); - -#endif diff --git a/src/commands.cpp b/src/commands.cpp deleted file mode 100644 index 8add75b..0000000 --- a/src/commands.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "commands.h" - -#include "gtk/gtk.h" -#include "debugging/debugging.h" -#include "warnings.h" - -#include -#include "string/string.h" -#include "versionlib.h" -#include "gtkutil/messagebox.h" -#include "gtkmisc.h" - -typedef std::pair ShortcutValue; // accelerator, isRegistered -typedef std::map Shortcuts; - -void Shortcuts_foreach(Shortcuts &shortcuts, CommandVisitor &visitor) -{ - for (Shortcuts::iterator i = shortcuts.begin(); i != shortcuts.end(); ++i) { - visitor.visit((*i).first.c_str(), (*i).second.first); - } -} - -Shortcuts g_shortcuts; - -const Accelerator &GlobalShortcuts_insert(const char *name, const Accelerator &accelerator) -{ - return (*g_shortcuts.insert(Shortcuts::value_type(name, ShortcutValue(accelerator, false))).first).second.first; -} - -void GlobalShortcuts_foreach(CommandVisitor &visitor) -{ - Shortcuts_foreach(g_shortcuts, visitor); -} - -void GlobalShortcuts_register(const char *name, int type) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - (*i).second.second = type; - } -} - -void GlobalShortcuts_reportUnregistered() -{ - for (Shortcuts::iterator i = g_shortcuts.begin(); i != g_shortcuts.end(); ++i) { - if ((*i).second.first.key != 0 && !(*i).second.second) { - globalOutputStream() << "shortcut not registered: " << (*i).first.c_str() << "\n"; - } - } -} - -typedef std::map Commands; - -Commands g_commands; - -void GlobalCommands_insert(const char *name, const Callback &callback, const Accelerator &accelerator) -{ - bool added = g_commands.insert( - Commands::value_type(name, Command(callback, GlobalShortcuts_insert(name, accelerator)))).second; - ASSERT_MESSAGE(added, "command already registered: " << makeQuoted(name)); -} - -const Command &GlobalCommands_find(const char *command) -{ - Commands::iterator i = g_commands.find(command); - ASSERT_MESSAGE(i != g_commands.end(), "failed to lookup command " << makeQuoted(command)); - return (*i).second; -} - -typedef std::map Toggles; - - -Toggles g_toggles; - -void GlobalToggles_insert(const char *name, const Callback &callback, - const Callback &)> &exportCallback, - const Accelerator &accelerator) -{ - bool added = g_toggles.insert(Toggles::value_type(name, Toggle(callback, GlobalShortcuts_insert(name, accelerator), - exportCallback))).second; - ASSERT_MESSAGE(added, "toggle already registered: " << makeQuoted(name)); -} - -const Toggle &GlobalToggles_find(const char *name) -{ - Toggles::iterator i = g_toggles.find(name); - ASSERT_MESSAGE(i != g_toggles.end(), "failed to lookup toggle " << makeQuoted(name)); - return (*i).second; -} - -typedef std::map KeyEvents; - - -KeyEvents g_keyEvents; - -void GlobalKeyEvents_insert(const char *name, const Accelerator &accelerator, const Callback &keyDown, - const Callback &keyUp) -{ - bool added = g_keyEvents.insert( - KeyEvents::value_type(name, KeyEvent(GlobalShortcuts_insert(name, accelerator), keyDown, keyUp))).second; - ASSERT_MESSAGE(added, "command already registered: " << makeQuoted(name)); -} - -const KeyEvent &GlobalKeyEvents_find(const char *name) -{ - KeyEvents::iterator i = g_keyEvents.find(name); - ASSERT_MESSAGE(i != g_keyEvents.end(), "failed to lookup keyEvent " << makeQuoted(name)); - return (*i).second; -} - - -void disconnect_accelerator(const char *name) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - switch ((*i).second.second) { - case 1: - // command - command_disconnect_accelerator(name); - break; - case 2: - // toggle - toggle_remove_accelerator(name); - break; - } - } -} - -void connect_accelerator(const char *name) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - switch ((*i).second.second) { - case 1: - // command - command_connect_accelerator(name); - break; - case 2: - // toggle - toggle_add_accelerator(name); - break; - } - } -} - - -#include -#include - -#include "gtkutil/dialog.h" -#include "mainframe.h" - -#include "stream/textfilestream.h" -#include "stream/stringstream.h" - - -struct command_list_dialog_t : public ModalDialog { - command_list_dialog_t() - : m_close_button(*this, eIDCANCEL), m_list(ui::null), m_command_iter(), m_model(ui::null), - m_waiting_for_key(false) - { - } - - ModalDialogButton m_close_button; - - ui::TreeView m_list; - GtkTreeIter m_command_iter; - ui::TreeModel m_model; - bool m_waiting_for_key; -}; - -void accelerator_clear_button_clicked(ui::Button btn, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if (dialog.m_waiting_for_key) { - // just unhighlight, user wanted to cancel - dialog.m_waiting_for_key = false; - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - dialog.m_model = ui::TreeModel(ui::null); - return; - } - - auto sel = gtk_tree_view_get_selection(dialog.m_list); - GtkTreeModel *model; - GtkTreeIter iter; - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { - return; - } - - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(model, &iter, 0, &val); - const char *commandName = g_value_get_string(&val);; - - // clear the ACTUAL accelerator too! - disconnect_accelerator(commandName); - - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find(commandName); - if (thisShortcutIterator == g_shortcuts.end()) { - return; - } - thisShortcutIterator->second.first = accelerator_null(); - - gtk_list_store_set(ui::ListStore::from(model), &iter, 1, "", -1); - - g_value_unset(&val); -} - -void accelerator_edit_button_clicked(ui::Button btn, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - // 1. find selected row - auto sel = gtk_tree_view_get_selection(dialog.m_list); - GtkTreeModel *model; - GtkTreeIter iter; - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { - return; - } - dialog.m_command_iter = iter; - dialog.m_model = ui::TreeModel::from(model); - - // 2. disallow changing the row - //gtk_widget_set_sensitive(dialog.m_list, false); - - // 3. highlight the row - gtk_list_store_set(ui::ListStore::from(model), &iter, 2, true, -1); - - // 4. grab keyboard focus - dialog.m_waiting_for_key = true; -} - -bool accelerator_window_key_press(ui::Window widget, GdkEventKey *event, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if (!dialog.m_waiting_for_key) { - return false; - } - -#if 0 - if ( event->is_modifier ) { - return false; - } -#else - switch (event->keyval) { - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - case GDK_KEY_Caps_Lock: - case GDK_KEY_Shift_Lock: - case GDK_KEY_Meta_L: - case GDK_KEY_Meta_R: - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - case GDK_KEY_Super_L: - case GDK_KEY_Super_R: - case GDK_KEY_Hyper_L: - case GDK_KEY_Hyper_R: - return false; - } -#endif - - dialog.m_waiting_for_key = false; - - // 7. find the name of the accelerator - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(dialog.m_model, &dialog.m_command_iter, 0, &val); - const char *commandName = g_value_get_string(&val);; - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find(commandName); - if (thisShortcutIterator == g_shortcuts.end()) { - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - return true; - } - - // 8. build an Accelerator - Accelerator newAccel(event->keyval, (GdkModifierType) event->state); - - // 8. verify the key is still free, show a dialog to ask what to do if not - class VerifyAcceleratorNotTaken : public CommandVisitor { - const char *commandName; - const Accelerator &newAccel; - ui::Widget widget; - ui::TreeModel model; -public: - bool allow; - - VerifyAcceleratorNotTaken(const char *name, const Accelerator &accelerator, ui::Widget w, ui::TreeModel m) - : commandName(name), newAccel(accelerator), widget(w), model(m), allow(true) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - if (!strcmp(name, commandName)) { - return; - } - if (!allow) { - return; - } - if (accelerator.key == 0) { - return; - } - if (accelerator == newAccel) { - StringOutputStream msg; - msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n" - << "Do you want to unassign " << name << " first?"; - auto r = ui::alert(widget.window(), msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL); - if (r == ui::alert_response::YES) { - // clear the ACTUAL accelerator too! - disconnect_accelerator(name); - // delete the modifier - accelerator = accelerator_null(); - // empty the cell of the key binds dialog - GtkTreeIter i; - if (gtk_tree_model_get_iter_first(model, &i)) { - for (;;) { - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(model, &i, 0, &val); - const char *thisName = g_value_get_string(&val);; - if (!strcmp(thisName, name)) { - gtk_list_store_set(ui::ListStore::from(model), &i, 1, "", -1); - } - g_value_unset(&val); - if (!gtk_tree_model_iter_next(model, &i)) { - break; - } - } - } - } else if (r == ui::alert_response::CANCEL) { - // aborted - allow = false; - } - } - } - } verify_visitor(commandName, newAccel, widget, dialog.m_model); - GlobalShortcuts_foreach(verify_visitor); - - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - - if (verify_visitor.allow) { - // clear the ACTUAL accelerator first - disconnect_accelerator(commandName); - - thisShortcutIterator->second.first = newAccel; - - // write into the cell - StringOutputStream modifiers; - modifiers << newAccel; - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 1, modifiers.c_str(), -1); - - // set the ACTUAL accelerator too! - connect_accelerator(commandName); - } - - g_value_unset(&val); - - dialog.m_model = ui::TreeModel(ui::null); - - return true; -} - -/* - GtkTreeIter row; - GValue val; - if(!model) {g_error("Unable to get model from cell renderer");} - gtk_tree_model_get_iter_from_string(model, &row, path_string); - - gtk_tree_model_get_value(model, &row, 0, &val); - const char *name = g_value_get_string(&val); - Shortcuts::iterator i = g_shortcuts.find(name); - if(i != g_shortcuts.end()) - { - accelerator_parse(i->second.first, new_text); - StringOutputStream modifiers; - modifiers << i->second.first; - gtk_list_store_set(ui::ListStore::from(model), &row, 1, modifiers.c_str(), -1); - } - }; - */ - -void DoCommandListDlg() -{ - command_list_dialog_t dialog; - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Mapped Commands", dialog, -1, 400); - window.on_key_press([](ui::Widget widget, GdkEventKey *event, gpointer dialogptr) { - return accelerator_window_key_press(ui::Window::from(widget), event, dialogptr); - }, &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC); - hbox.pack_start(scr, TRUE, TRUE, 0); - - { - auto store = ui::ListStore::from( - gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - dialog.m_list = view; - - gtk_tree_view_set_enable_search(view, false); // annoying - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Command", renderer, {{"text", 0}, - {"weight-set", 2}, - {"weight", 3}}); - gtk_tree_view_append_column(view, column); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Key", renderer, {{"text", 1}, - {"weight-set", 2}, - {"weight", 3}}); - gtk_tree_view_append_column(view, column); - } - - view.show(); - scr.add(view); - - { - // Initialize dialog - StringOutputStream path(256); - path << SettingsPath_get() << "commandlist.txt"; - globalOutputStream() << "Writing the command list to " << path.c_str() << "\n"; - class BuildCommandList : public CommandVisitor { - TextFileOutputStream m_commandList; - ui::ListStore m_store; -public: - BuildCommandList(const char *filename, ui::ListStore store) : m_commandList(filename), - m_store(store) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - StringOutputStream modifiers; - modifiers << accelerator; - - m_store.append(0, name, 1, modifiers.c_str(), 2, false, 3, 800); - - if (!m_commandList.failed()) { - int l = strlen(name); - m_commandList << name; - while (l++ < 25) { - m_commandList << ' '; - } - m_commandList << modifiers.c_str() << '\n'; - } - } - } visitor(path.c_str(), store); - - GlobalShortcuts_foreach(visitor); - } - - store.unref(); - } - } - - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto editbutton = create_dialog_button("Edit", (GCallback) accelerator_edit_button_clicked, &dialog); - vbox.pack_start(editbutton, FALSE, FALSE, 0); - - auto clearbutton = create_dialog_button("Clear", (GCallback) accelerator_clear_button_clicked, &dialog); - vbox.pack_start(clearbutton, FALSE, FALSE, 0); - - ui::Widget spacer = ui::Image(ui::New); - spacer.show(); - vbox.pack_start(spacer, TRUE, TRUE, 0); - - auto button = create_modal_dialog_button("Close", dialog.m_close_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_grab_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, (GtkAccelFlags) 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, (GtkAccelFlags) 0); - } - - modal_dialog_show(window, dialog); - window.destroy(); -} - -#include "profile/profile.h" - -const char *const COMMANDS_VERSION = "1.0-gtk-accelnames"; - -void SaveCommandMap(const char *path) -{ - StringOutputStream strINI(256); - strINI << path << "shortcuts.ini"; - - TextFileOutputStream file(strINI.c_str()); - if (!file.failed()) { - file << "[Version]\n"; - file << "number=" << COMMANDS_VERSION << "\n"; - file << "\n"; - file << "[Commands]\n"; - class WriteCommandMap : public CommandVisitor { - TextFileOutputStream &m_file; -public: - WriteCommandMap(TextFileOutputStream &file) : m_file(file) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - m_file << name << "="; - - const char *key = gtk_accelerator_name(accelerator.key, accelerator.modifiers); - m_file << key; - m_file << "\n"; - } - } visitor(file); - GlobalShortcuts_foreach(visitor); - } -} - -const char *stringrange_find(const char *first, const char *last, char c) -{ - const char *p = strchr(first, '+'); - if (p == 0) { - return last; - } - return p; -} - -class ReadCommandMap : public CommandVisitor { -const char *m_filename; -std::size_t m_count; -public: -ReadCommandMap(const char *filename) : m_filename(filename), m_count(0) -{ -} - -void visit(const char *name, Accelerator &accelerator) -{ - char value[1024]; - if (read_var(m_filename, "Commands", name, value)) { - if (string_empty(value)) { - accelerator.key = 0; - accelerator.modifiers = (GdkModifierType) 0; - return; - } - - gtk_accelerator_parse(value, &accelerator.key, &accelerator.modifiers); - accelerator = accelerator; // fix modifiers - - if (accelerator.key != 0) { - ++m_count; - } else { - globalOutputStream() << "WARNING: failed to parse user command " << makeQuoted(name) << ": unknown key " - << makeQuoted(value) << "\n"; - } - } -} - -std::size_t count() const -{ - return m_count; -} -}; - -void LoadCommandMap_ReadFile(const char *path) -{ - globalOutputStream() << "loading custom shortcuts list from " << makeQuoted(path) << "\n"; - - Version version = version_parse(COMMANDS_VERSION); - Version dataVersion = {0, 0}; - - { - char value[1024]; - if (read_var(path, "Version", "number", value)) { - dataVersion = version_parse(value); - } - } - - if (version_compatible(version, dataVersion)) { - globalOutputStream() << "commands import: data version " << dataVersion - << " is compatible with code version " << version << "\n"; - ReadCommandMap visitor(path); - GlobalShortcuts_foreach(visitor); - globalOutputStream() << "parsed " << Unsigned(visitor.count()) << " custom shortcuts\n"; - } else { - globalOutputStream() << "commands import: data version " << dataVersion - << " is not compatible with code version " << version << "\n"; - } -} - -void LoadCommandMap(const char *path, const char *defaultpath) -{ - StringOutputStream strINI(256); - StringOutputStream strDefault(256); - strDefault << defaultpath << "defaultkeys.ini"; - strINI << path << "shortcuts.ini"; - - FILE *f = fopen(strINI.c_str(), "r"); - if (f != 0) { - fclose(f); - LoadCommandMap_ReadFile(strINI.c_str()); - } else { - /* load the default */ - FILE *f = fopen(strDefault.c_str(), "r"); - if (f != 0) { - fclose(f); - LoadCommandMap_ReadFile(strDefault.c_str()); - } else { - globalOutputStream() << "failed to load custom shortcuts from " << makeQuoted(strDefault.c_str()) << "\n"; - } - } -} diff --git a/src/commands.h b/src/commands.h deleted file mode 100644 index 6050851..0000000 --- a/src/commands.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_COMMANDS_H ) -#define INCLUDED_COMMANDS_H - -#include "gtkutil/accelerator.h" - - -const Accelerator &GlobalShortcuts_insert(const char *name, const Accelerator &accelerator); - -void GlobalShortcuts_register(const char *name, int type); // 1 = command, 2 = toggle -void GlobalShortcuts_reportUnregistered(); - -class CommandVisitor { -public: -virtual void visit(const char *name, Accelerator &accelerator) = 0; -}; - -void GlobalCommands_insert(const char *name, const Callback &callback, - const Accelerator &accelerator = accelerator_null()); - -const Command &GlobalCommands_find(const char *name); - -void GlobalToggles_insert(const char *name, const Callback &callback, - const Callback &)> &exportCallback, - const Accelerator &accelerator = accelerator_null()); - -const Toggle &GlobalToggles_find(const char *name); - -void GlobalKeyEvents_insert(const char *name, const Accelerator &accelerator, const Callback &keyDown, - const Callback &keyUp); - -const KeyEvent &GlobalKeyEvents_find(const char *name); - - -void DoCommandListDlg(); - -void LoadCommandMap(const char *path, const char* defaultpath); - -void SaveCommandMap(const char *path); - - -#endif diff --git a/src/console.cpp b/src/console.cpp deleted file mode 100644 index bb9050e..0000000 --- a/src/console.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "console.h" - -#include -#include - -#include "stream/stringstream.h" -#include "convert.h" - -#include "mainframe.h" - -std::size_t Sys_Print(int level, const char *buf, std::size_t length) -{ - StringOutputStream name(256); - name << StringRange(buf, buf + length); - printf(name.c_str()); - return length; -} - - -class SysPrintOutputStream : public TextOutputStream { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return Sys_Print(SYS_STD, buffer, length); -} -}; - -class SysPrintErrorStream : public TextOutputStream { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return Sys_Print(SYS_ERR, buffer, length); -} -}; - -SysPrintOutputStream g_outputStream; - -TextOutputStream &getSysPrintOutputStream() -{ - return g_outputStream; -} - -SysPrintErrorStream g_errorStream; - -TextOutputStream &getSysPrintErrorStream() -{ - return g_errorStream; -} diff --git a/src/console.h b/src/console.h deleted file mode 100644 index d9fb2ed..0000000 --- a/src/console.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONSOLE_H ) -#define INCLUDED_CONSOLE_H - -#include -#include - -#define SYS_VRB 0 ///< verbose support (on/off) -#define SYS_STD 1 ///< standard print level - this is the default -#define SYS_WRN 2 ///< warnings -#define SYS_ERR 3 ///< error -#define SYS_NOCON 4 ///< no console, only print to the file (useful whenever Sys_Printf and output IS the problem) - -std::size_t Sys_Print(int level, const char *buf, std::size_t length); - -class TextOutputStream; - -TextOutputStream &getSysPrintOutputStream(); - -TextOutputStream &getSysPrintErrorStream(); - -#endif diff --git a/tools/vmap/convert_ase.c b/src/convert_ase.c similarity index 100% rename from tools/vmap/convert_ase.c rename to src/convert_ase.c diff --git a/tools/vmap/convert_bsp.c b/src/convert_bsp.c similarity index 100% rename from tools/vmap/convert_bsp.c rename to src/convert_bsp.c diff --git a/tools/vmap/convert_map.c b/src/convert_map.c similarity index 100% rename from tools/vmap/convert_map.c rename to src/convert_map.c diff --git a/tools/vmap/convert_obj.c b/src/convert_obj.c similarity index 100% rename from tools/vmap/convert_obj.c rename to src/convert_obj.c diff --git a/src/csg.cpp b/src/csg.cpp deleted file mode 100644 index b68c17e..0000000 --- a/src/csg.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "csg.h" - -#include "debugging/debugging.h" - -#include - -#include "map.h" -#include "brushmanip.h" -#include "brushnode.h" -#include "grid.h" - -void Face_makeBrush(Face &face, const Brush &brush, brush_vector_t &out, float offset) -{ - if (face.contributes()) { - out.push_back(new Brush(brush)); - Face *newFace = out.back()->addFace(face); - if (newFace != 0) { - newFace->flipWinding(); - newFace->getPlane().offset(offset); - newFace->planeChanged(); - } - } -} - -void Face_makeRoom(Face &face, const Brush &brush, brush_vector_t &out, float offset) -{ - if (face.contributes()) { - face.getPlane().offset(offset); - out.push_back(new Brush(brush)); - face.getPlane().offset(-offset); - Face *newFace = out.back()->addFace(face); - if (newFace != 0) { - newFace->flipWinding(); - newFace->planeChanged(); - } - } -} - -void Brush_makeHollow(const Brush &brush, brush_vector_t &out, float offset) -{ - Brush_forEachFace(brush, [&](Face &face) { - Face_makeBrush(face, brush, out, offset); - }); -} - -void Brush_makeRoom(const Brush &brush, brush_vector_t &out, float offset) -{ - Brush_forEachFace(brush, [&](Face &face) { - Face_makeRoom(face, brush, out, offset); - }); -} - -class BrushHollowSelectedWalker : public scene::Graph::Walker { -float m_offset; -bool m_makeRoom; -public: -BrushHollowSelectedWalker(float offset, bool makeRoom) - : m_offset(offset), m_makeRoom(makeRoom) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected() - && path.size() > 1) { - brush_vector_t out; - - if (m_makeRoom) { - Brush_makeRoom(*brush, out, m_offset); - } - else { - Brush_makeHollow(*brush, out, m_offset); - } - - for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) { - (*i)->removeEmptyFaces(); - NodeSmartReference node((new BrushNode())->node()); - Node_getBrush(node)->copy(*(*i)); - delete (*i); - Node_getTraversable(path.parent())->insert(node); - } - } - } - return true; -} -}; - -typedef std::list brushlist_t; - -class BrushGatherSelected : public scene::Graph::Walker { -brush_vector_t &m_brushlist; -public: -BrushGatherSelected(brush_vector_t &brushlist) - : m_brushlist(brushlist) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected()) { - m_brushlist.push_back(brush); - } - } - return true; -} -}; - -class BrushDeleteSelected : public scene::Graph::Walker { -public: -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected() - && path.size() > 1) { - Path_deleteTop(path); - } - } -} -}; - -void Scene_BrushMakeHollow_Selected(scene::Graph &graph, bool makeRoom) -{ - GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize(), makeRoom)); - GlobalSceneGraph().traverse(BrushDeleteSelected()); -} - -/* - ============= - CSG_MakeHollow - ============= - */ - -void CSG_MakeHollow(void) -{ - UndoableCommand undo("brushHollow"); - - Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), false); - - SceneChangeNotify(); -} - -void CSG_MakeRoom(void) -{ - UndoableCommand undo("brushRoom"); - - Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), true); - - SceneChangeNotify(); -} - -template -class RemoveReference { -public: -typedef Type type; -}; - -template -class RemoveReference { -public: -typedef Type type; -}; - -template -class Dereference { -const Functor &functor; -public: -Dereference(const Functor &functor) : functor(functor) -{ -} - -get_result_type operator()(typename RemoveReference >::type *firstArgument) const -{ - return functor(*firstArgument); -} -}; - -template -inline Dereference makeDereference(const Functor &functor) -{ - return Dereference(functor); -} - -typedef Face *FacePointer; -const FacePointer c_nullFacePointer = 0; - -template -Face *Brush_findIf(const Brush &brush, const Predicate &predicate) -{ - Brush::const_iterator i = std::find_if(brush.begin(), brush.end(), makeDereference(predicate)); - return i == brush.end() ? c_nullFacePointer - : *i; // uses c_nullFacePointer instead of 0 because otherwise gcc 4.1 attempts conversion to int -} - -template -class BindArguments1 { -typedef get_argument FirstBound; -FirstBound firstBound; -public: -BindArguments1(FirstBound firstBound) - : firstBound(firstBound) -{ -} - -get_result_type operator()(get_argument firstArgument) const -{ - return Caller::call(firstArgument, firstBound); -} -}; - -template -class BindArguments2 { -typedef get_argument FirstBound; -typedef get_argument SecondBound; -FirstBound firstBound; -SecondBound secondBound; -public: -BindArguments2(FirstBound firstBound, SecondBound secondBound) - : firstBound(firstBound), secondBound(secondBound) -{ -} - -get_result_type operator()(get_argument firstArgument) const -{ - return Caller::call(firstArgument, firstBound, secondBound); -} -}; - -template -BindArguments2 bindArguments(const Caller &caller, FirstBound firstBound, SecondBound secondBound) -{ - return BindArguments2(firstBound, secondBound); -} - -inline bool Face_testPlane(const Face &face, const Plane3 &plane, bool flipped) -{ - return face.contributes() && !Winding_TestPlane(face.getWinding(), plane, flipped); -} - -typedef Function FaceTestPlane; - - -/// \brief Returns true if -/// \li !flipped && brush is BACK or ON -/// \li flipped && brush is FRONT or ON -bool Brush_testPlane(const Brush &brush, const Plane3 &plane, bool flipped) -{ - brush.evaluateBRep(); -#if 1 - for (Brush::const_iterator i(brush.begin()); i != brush.end(); ++i) { - if (Face_testPlane(*(*i), plane, flipped)) { - return false; - } - } - return true; -#else - return Brush_findIf( brush, bindArguments( FaceTestPlane(), makeReference( plane ), flipped ) ) == 0; -#endif -} - -brushsplit_t Brush_classifyPlane(const Brush &brush, const Plane3 &plane) -{ - brush.evaluateBRep(); - brushsplit_t split; - for (Brush::const_iterator i(brush.begin()); i != brush.end(); ++i) { - if ((*i)->contributes()) { - split += Winding_ClassifyPlane((*i)->getWinding(), plane); - } - } - return split; -} - -bool Brush_subtract(const Brush &brush, const Brush &other, brush_vector_t &ret_fragments) -{ - if (aabb_intersects_aabb(brush.localAABB(), other.localAABB())) { - brush_vector_t fragments; - fragments.reserve(other.size()); - Brush back(brush); - - for (Brush::const_iterator i(other.begin()); i != other.end(); ++i) { - if ((*i)->contributes()) { - brushsplit_t split = Brush_classifyPlane(back, (*i)->plane3()); - if (split.counts[ePlaneFront] != 0 - && split.counts[ePlaneBack] != 0) { - fragments.push_back(new Brush(back)); - Face *newFace = fragments.back()->addFace(*(*i)); - if (newFace != 0) { - newFace->flipWinding(); - } - back.addFace(*(*i)); - } else if (split.counts[ePlaneBack] == 0) { - for (brush_vector_t::iterator i = fragments.begin(); i != fragments.end(); ++i) { - delete (*i); - } - return false; - } - } - } - ret_fragments.insert(ret_fragments.end(), fragments.begin(), fragments.end()); - return true; - } - return false; -} - -class SubtractBrushesFromUnselected : public scene::Graph::Walker { -const brush_vector_t &m_brushlist; -std::size_t &m_before; -std::size_t &m_after; -public: -SubtractBrushesFromUnselected(const brush_vector_t &brushlist, std::size_t &before, std::size_t &after) - : m_brushlist(brushlist), m_before(before), m_after(after) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && !Instance_getSelectable(instance)->isSelected()) { - brush_vector_t buffer[2]; - bool swap = false; - Brush *original = new Brush(*brush); - buffer[static_cast( swap )].push_back(original); - - { - for (brush_vector_t::const_iterator i(m_brushlist.begin()); i != m_brushlist.end(); ++i) { - for (brush_vector_t::iterator j(buffer[static_cast( swap )].begin()); - j != buffer[static_cast( swap )].end(); ++j) { - if (Brush_subtract(*(*j), *(*i), buffer[static_cast( !swap )])) { - delete (*j); - } else { - buffer[static_cast( !swap )].push_back((*j)); - } - } - buffer[static_cast( swap )].clear(); - swap = !swap; - } - } - - brush_vector_t &out = buffer[static_cast( swap )]; - - if (out.size() == 1 && out.back() == original) { - delete original; - } else { - ++m_before; - for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) { - ++m_after; - (*i)->removeEmptyFaces(); - if (!(*i)->empty()) { - NodeSmartReference node((new BrushNode())->node()); - Node_getBrush(node)->copy(*(*i)); - delete (*i); - Node_getTraversable(path.parent())->insert(node); - } else { - delete (*i); - } - } - Path_deleteTop(path); - } - } - } -} -}; - -void CSG_Subtract() -{ - brush_vector_t selected_brushes; - GlobalSceneGraph().traverse(BrushGatherSelected(selected_brushes)); - - if (selected_brushes.empty()) { - globalOutputStream() << "CSG Subtract: No brushes selected.\n"; - } else { - globalOutputStream() << "CSG Subtract: Subtracting " << Unsigned(selected_brushes.size()) << " brushes.\n"; - - UndoableCommand undo("brushSubtract"); - - // subtract selected from unselected - std::size_t before = 0; - std::size_t after = 0; - GlobalSceneGraph().traverse(SubtractBrushesFromUnselected(selected_brushes, before, after)); - globalOutputStream() << "CSG Subtract: Result: " - << Unsigned(after) << " fragment" << (after == 1 ? "" : "s") - << " from " << Unsigned(before) << " brush" << (before == 1 ? "" : "es") << ".\n"; - - SceneChangeNotify(); - } -} - -class BrushSplitByPlaneSelected : public scene::Graph::Walker { -const Vector3 &m_p0; -const Vector3 &m_p1; -const Vector3 &m_p2; -const char *m_shader; -const TextureProjection &m_projection; -EBrushSplit m_split; -public: -BrushSplitByPlaneSelected(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, const char *shader, - const TextureProjection &projection, EBrushSplit split) - : m_p0(p0), m_p1(p1), m_p2(p2), m_shader(shader), m_projection(projection), m_split(split) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected()) { - Plane3 plane(plane3_for_points(m_p0, m_p1, m_p2)); - if (plane3_valid(plane)) { - brushsplit_t split = Brush_classifyPlane(*brush, m_split == eFront ? plane3_flipped(plane) : plane); - if (split.counts[ePlaneBack] && split.counts[ePlaneFront]) { - // the plane intersects this brush - if (m_split == eFrontAndBack) { - NodeSmartReference node((new BrushNode())->node()); - Brush *fragment = Node_getBrush(node); - fragment->copy(*brush); - Face *newFace = fragment->addPlane(m_p0, m_p1, m_p2, m_shader, m_projection); - if (newFace != 0 && m_split != eFront) { - newFace->flipWinding(); - } - fragment->removeEmptyFaces(); - ASSERT_MESSAGE(!fragment->empty(), "brush left with no faces after split"); - - Node_getTraversable(path.parent())->insert(node); - { - scene::Path fragmentPath = path; - fragmentPath.top() = makeReference(node.get()); - selectPath(fragmentPath, true); - } - } - - Face *newFace = brush->addPlane(m_p0, m_p1, m_p2, m_shader, m_projection); - if (newFace != 0 && m_split == eFront) { - newFace->flipWinding(); - } - brush->removeEmptyFaces(); - ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after split"); - } else - // the plane does not intersect this brush - if (m_split != eFrontAndBack && split.counts[ePlaneBack] != 0) { - // the brush is "behind" the plane - Path_deleteTop(path); - } - } - } - } -} -}; - -void Scene_BrushSplitByPlane(scene::Graph &graph, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, - const char *shader, EBrushSplit split) -{ - TextureProjection projection; - TexDef_Construct_Default(projection); - graph.traverse(BrushSplitByPlaneSelected(p0, p1, p2, shader, projection, split)); - SceneChangeNotify(); -} - - -class BrushInstanceSetClipPlane : public scene::Graph::Walker { -Plane3 m_plane; -public: -BrushInstanceSetClipPlane(const Plane3 &plane) - : m_plane(plane) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0 - && path.top().get().visible() - && brush->isSelected()) { - BrushInstance &brushInstance = *brush; - brushInstance.setClipPlane(m_plane); - } - return true; -} -}; - -void Scene_BrushSetClipPlane(scene::Graph &graph, const Plane3 &plane) -{ - graph.traverse(BrushInstanceSetClipPlane(plane)); -} - -/* - ============= - CSG_Merge - ============= - */ -bool Brush_merge(Brush &brush, const brush_vector_t &in, bool onlyshape) -{ - // gather potential outer faces - - { - typedef std::vector Faces; - Faces faces; - for (brush_vector_t::const_iterator i(in.begin()); i != in.end(); ++i) { - (*i)->evaluateBRep(); - for (Brush::const_iterator j((*i)->begin()); j != (*i)->end(); ++j) { - if (!(*j)->contributes()) { - continue; - } - - const Face &face1 = *(*j); - - bool skip = false; - // test faces of all input brushes - //!\todo SPEEDUP: Flag already-skip faces and only test brushes from i+1 upwards. - for (brush_vector_t::const_iterator k(in.begin()); !skip && k != in.end(); ++k) { - if (k != i) { // don't test a brush against itself - for (Brush::const_iterator l((*k)->begin()); !skip && l != (*k)->end(); ++l) { - const Face &face2 = *(*l); - - // face opposes another face - if (plane3_opposing(face1.plane3(), face2.plane3())) { - // skip opposing planes - skip = true; - break; - } - } - } - } - - // check faces already stored - for (Faces::const_iterator m = faces.begin(); !skip && m != faces.end(); ++m) { - const Face &face2 = *(*m); - - // face equals another face - if (plane3_equal(face1.plane3(), face2.plane3())) { - //if the texture/shader references should be the same but are not - if (!onlyshape && !shader_equal(face1.getShader().getShader(), face2.getShader().getShader())) { - return false; - } - // skip duplicate planes - skip = true; - break; - } - - // face1 plane intersects face2 winding or vice versa - if (Winding_PlanesConcave(face1.getWinding(), face2.getWinding(), face1.plane3(), face2.plane3())) { - // result would not be convex - return false; - } - } - - if (!skip) { - faces.push_back(&face1); - } - } - } - for (Faces::const_iterator i = faces.begin(); i != faces.end(); ++i) { - if (!brush.addFace(*(*i))) { - // result would have too many sides - return false; - } - } - } - - brush.removeEmptyFaces(); - - return true; -} - -void CSG_Merge(void) -{ - brush_vector_t selected_brushes; - - // remove selected - GlobalSceneGraph().traverse(BrushGatherSelected(selected_brushes)); - - if (selected_brushes.empty()) { - globalOutputStream() << "CSG Merge: No brushes selected.\n"; - return; - } - - if (selected_brushes.size() < 2) { - globalOutputStream() << "CSG Merge: At least two brushes have to be selected.\n"; - return; - } - - globalOutputStream() << "CSG Merge: Merging " << Unsigned(selected_brushes.size()) << " brushes.\n"; - - UndoableCommand undo("brushMerge"); - - scene::Path merged_path = GlobalSelectionSystem().ultimateSelected().path(); - - NodeSmartReference node((new BrushNode())->node()); - Brush *brush = Node_getBrush(node); - // if the new brush would not be convex - if (!Brush_merge(*brush, selected_brushes, true)) { - globalOutputStream() << "CSG Merge: Failed - result would not be convex.\n"; - } else { - ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after merge"); - - // free the original brushes - GlobalSceneGraph().traverse(BrushDeleteSelected()); - - merged_path.pop(); - Node_getTraversable(merged_path.top())->insert(node); - merged_path.push(makeReference(node.get())); - - selectPath(merged_path, true); - - globalOutputStream() << "CSG Merge: Succeeded.\n"; - SceneChangeNotify(); - } -} diff --git a/src/csg.h b/src/csg.h deleted file mode 100644 index 051df21..0000000 --- a/src/csg.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CSG_H ) -#define INCLUDED_CSG_H - -void CSG_MakeHollow(void); - -void CSG_MakeRoom(void); - -void CSG_Subtract(void); - -void CSG_Merge(void); - -namespace scene { -class Graph; -} -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -class Plane3; - -void Scene_BrushSetClipPlane(scene::Graph &graph, const Plane3 &plane); - -enum EBrushSplit { - eFront, - eBack, - eFrontAndBack, -}; - -void Scene_BrushSplitByPlane(scene::Graph &graph, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, - const char *shader, EBrushSplit split); - -#endif diff --git a/tools/vmap/decals.c b/src/decals.c similarity index 100% rename from tools/vmap/decals.c rename to src/decals.c diff --git a/src/dialog.cpp b/src/dialog.cpp deleted file mode 100644 index e45cbb8..0000000 --- a/src/dialog.cpp +++ /dev/null @@ -1,717 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Base dialog class, provides a way to run modal dialogs and -// set/get the widget values in member variables. -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "dialog.h" - -#include - -#include "debugging/debugging.h" - - -#include "mainframe.h" - -#include - -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/dialog.h" -#include "gtkutil/button.h" -#include "gtkutil/entry.h" -#include "gtkutil/image.h" - -#include "gtkmisc.h" - - -ui::Entry DialogEntry_new() -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(64, -1); - return entry; -} - -class DialogEntryRow { -public: -DialogEntryRow(ui::Widget row, ui::Entry entry) : m_row(row), m_entry(entry) -{ -} - -ui::Widget m_row; -ui::Entry m_entry; -}; - -DialogEntryRow DialogEntryRow_new(const char *name) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - - auto entry = DialogEntry_new(); - alignment.add(entry); - - return DialogEntryRow(ui::Widget(DialogRow_new(name, alignment)), entry); -} - - -ui::SpinButton DialogSpinner_new(double value, double lower, double upper, int fraction) -{ - double step = 1.0 / double(fraction); - unsigned int digits = 0; - for (; fraction > 1; fraction /= 10) { - ++digits; - } - auto spin = ui::SpinButton(ui::Adjustment(value, lower, upper, step, 10, 0), step, digits); - spin.show(); - spin.dimensions(64, -1); - return spin; -} - -class DialogSpinnerRow { -public: -DialogSpinnerRow(ui::Widget row, ui::SpinButton spin) : m_row(row), m_spin(spin) -{ -} - -ui::Widget m_row; -ui::SpinButton m_spin; -}; - -DialogSpinnerRow DialogSpinnerRow_new(const char *name, double value, double lower, double upper, int fraction) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - - auto spin = DialogSpinner_new(value, lower, upper, fraction); - alignment.add(spin); - - return DialogSpinnerRow(ui::Widget(DialogRow_new(name, alignment)), spin); -} - - -struct BoolToggle { - static void Export(const ui::ToggleButton &self, const Callback &returnz) - { - returnz(self.active()); - } - - static void Import(ui::ToggleButton &self, bool value) - { - self.active(value); - } -}; - -using BoolToggleImportExport = PropertyAdaptor; - -struct IntEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(atoi(gtk_entry_get_text(self))); - } - - static void Import(ui::Entry &self, int value) - { - entry_set_int(self, value); - } -}; - -using IntEntryImportExport = PropertyAdaptor; - -struct IntRadio { - static void Export(const ui::RadioButton &self, const Callback &returnz) - { - returnz(radio_button_get_active(self)); - } - - static void Import(ui::RadioButton &self, int value) - { - radio_button_set_active(self, value); - } -}; - -using IntRadioImportExport = PropertyAdaptor; - -struct IntCombo { - static void Export(const ui::ComboBox &self, const Callback &returnz) - { - returnz(gtk_combo_box_get_active(self)); - } - - static void Import(ui::ComboBox &self, int value) - { - gtk_combo_box_set_active(self, value); - } -}; - -using IntComboImportExport = PropertyAdaptor; - -struct IntAdjustment { - static void Export(const ui::Adjustment &self, const Callback &returnz) - { - returnz(int(gtk_adjustment_get_value(self))); - } - - static void Import(ui::Adjustment &self, int value) - { - gtk_adjustment_set_value(self, value); - } -}; - -using IntAdjustmentImportExport = PropertyAdaptor; - -struct IntSpinner { - static void Export(const ui::SpinButton &self, const Callback &returnz) - { - returnz(gtk_spin_button_get_value_as_int(self)); - } - - static void Import(ui::SpinButton &self, int value) - { - gtk_spin_button_set_value(self, value); - } -}; - -using IntSpinnerImportExport = PropertyAdaptor; - -struct TextEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(gtk_entry_get_text(self)); - } - - static void Import(ui::Entry &self, const char *value) - { - self.text(value); - } -}; - -using TextEntryImportExport = PropertyAdaptor; - -struct SizeEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - int value = atoi(gtk_entry_get_text(self)); - if (value < 0) { - value = 0; - } - returnz(value); - } - - static void Import(ui::Entry &self, std::size_t value) - { - entry_set_int(self, int(value)); - } -}; - -using SizeEntryImportExport = PropertyAdaptor; - -struct FloatEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(float(atof(gtk_entry_get_text(self)))); - } - - static void Import(ui::Entry &self, float value) - { - entry_set_float(self, value); - } -}; - -using FloatEntryImportExport = PropertyAdaptor; - -struct FloatSpinner { - static void Export(const ui::SpinButton &self, const Callback &returnz) - { - returnz(float(gtk_spin_button_get_value(self))); - } - - static void Import(ui::SpinButton &self, float value) - { - gtk_spin_button_set_value(self, value); - } -}; - -using FloatSpinnerImportExport = PropertyAdaptor; - - -template -class CallbackDialogData : public DLG_DATA { -Property m_pWidget; -Property m_pData; - -public: -CallbackDialogData(const Property &pWidget, const Property &pData) - : m_pWidget(pWidget), m_pData(pData) -{ -} - -void release() -{ - delete this; -} - -void importData() const -{ - m_pData.get(m_pWidget.set); -} - -void exportData() const -{ - m_pWidget.get(m_pData.set); -} -}; - -template -struct AddDataCustom_Wrapper { - static void Export(const native &self, const Callback &returnz) { - native *p = &const_cast(self); - auto widget = Self::from(p); - Widget::Get::thunk_(widget, returnz); - } - - static void Import(native &self, T value) { - native *p = &self; - auto widget = Self::from(p); - Widget::Set::thunk_(widget, value); - } -}; - -template -void AddDataCustom(DialogDataList &self, typename Widget::Type widget, Property const &property) -{ - using Self = typename Widget::Type; - using T = typename Widget::Other; - using native = typename std::remove_pointer::type; - using Wrapper = AddDataCustom_Wrapper; - self.push_back(new CallbackDialogData( - make_property >(*static_cast(widget)), - property - )); -} - -template -void AddData(DialogDataList &self, typename Widget::Type widget, D &data) -{ - AddDataCustom(self, widget, make_property >(data)); -} - -// ============================================================================= -// Dialog class - -Dialog::Dialog() : m_window(ui::null), m_parent(ui::null) -{ -} - -Dialog::~Dialog() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->release(); - } - - ASSERT_MESSAGE(!m_window, "dialog window not destroyed"); -} - -void Dialog::ShowDlg() -{ - ASSERT_MESSAGE(m_window, "dialog was not constructed"); - importData(); - m_window.show(); -} - -void Dialog::HideDlg() -{ - ASSERT_MESSAGE(m_window, "dialog was not constructed"); - exportData(); - m_window.hide(); -} - -static gint delete_event_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - reinterpret_cast

( data )->HideDlg(); - reinterpret_cast( data )->EndModal(eIDCANCEL); - return TRUE; -} - -void Dialog::Create() -{ - ASSERT_MESSAGE(!m_window, "dialog cannot be constructed"); - - m_window = BuildDialog(); - m_window.connect("delete_event", G_CALLBACK(delete_event_callback), this); -} - -void Dialog::Destroy() -{ - ASSERT_MESSAGE(m_window, "dialog cannot be destroyed"); - - m_window.destroy(); - m_window = ui::Window{ui::null}; -} - - -void Dialog::AddBoolToggleData(ui::ToggleButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntRadioData(ui::RadioButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddTextEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddSizeEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddFloatEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddFloatSpinnerData(ui::SpinButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntSpinnerData(ui::SpinButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntAdjustmentData(ui::Adjustment widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntComboData(ui::ComboBox widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - - -void Dialog::AddDialogData(ui::ToggleButton widget, bool &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::RadioButton widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, CopiedString &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, std::size_t &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, float &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::SpinButton widget, float &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::SpinButton widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Adjustment widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::ComboBox widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::exportData() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->exportData(); - } -} - -void Dialog::importData() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->importData(); - } -} - -void Dialog::EndModal(EMessageBoxReturn code) -{ - m_modal.loop = 0; - m_modal.ret = code; -} - -EMessageBoxReturn Dialog::DoModal() -{ - importData(); - - PreModal(); - - EMessageBoxReturn ret = modal_dialog_show(m_window, m_modal); - ASSERT_TRUE((bool) m_window); - if (ret == eIDOK) { - exportData(); - } - - m_window.hide(); - - PostModal(m_modal.ret); - - return m_modal.ret; -} - - -ui::CheckButton Dialog::addCheckBox(ui::VBox vbox, const char *name, const char *flag, Property const &cb) -{ - auto check = ui::CheckButton(flag); - check.show(); - AddBoolToggleData(check, cb); - - DialogVBox_packRow(vbox, ui::Widget(DialogRow_new(name, check))); - return check; -} - -ui::CheckButton Dialog::addCheckBox(ui::VBox vbox, const char *name, const char *flag, bool &data) -{ - return addCheckBox(vbox, name, flag, make_property(data)); -} - -void Dialog::addCombo(ui::VBox vbox, const char *name, StringArrayRange values, Property const &cb) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - { - auto combo = ui::ComboBoxText(ui::New); - - for (StringArrayRange::Iterator i = values.first; i != values.last; ++i) { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), *i); - } - - AddIntComboData(combo, cb); - - combo.show(); - alignment.add(combo); - } - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addCombo(ui::VBox vbox, const char *name, int &data, StringArrayRange values) -{ - addCombo(vbox, name, values, make_property(data)); -} - -void -Dialog::addSlider(ui::VBox vbox, const char *name, int &data, gboolean draw_value, const char *low, const char *high, - double value, double lower, double upper, double step_increment, double page_increment) -{ -#if 0 - if ( draw_value == FALSE ) { - auto hbox2 = ui::HBox( FALSE, 0 ); - hbox2.show(); - vbox.pack_start( hbox2, FALSE, FALSE, 0 ); - { - ui::Widget label = ui::Label( low ); - label.show(); - hbox2.pack_start( label, FALSE, FALSE, 0 ); - } - { - ui::Widget label = ui::Label( high ); - label.show(); - hbox2.pack_end(label, FALSE, FALSE, 0); - } - } -#endif - - // adjustment - auto adj = ui::Adjustment(value, lower, upper, step_increment, page_increment, 0); - AddIntAdjustmentData(adj, make_property(data)); - - // scale - auto alignment = ui::Alignment(0.0, 0.5, 1.0, 0.0); - alignment.show(); - - ui::Widget scale = ui::HScale(adj); - gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT); - scale.show(); - alignment.add(scale); - - gtk_scale_set_draw_value(GTK_SCALE(scale), draw_value); - gtk_scale_set_digits(GTK_SCALE(scale), 0); - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addRadio(ui::VBox vbox, const char *name, StringArrayRange names, Property const &cb) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show();; - { - RadioHBox radioBox = RadioHBox_new(names); - alignment.add(radioBox.m_hbox); - AddIntRadioData(radioBox.m_radio, cb); - } - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addRadio(ui::VBox vbox, const char *name, int &data, StringArrayRange names) -{ - addRadio(vbox, name, names, make_property(data)); -} - -void Dialog::addRadioIcons(ui::VBox vbox, const char *name, StringArrayRange icons, Property const &cb) -{ - auto table = ui::Table(2, icons.last - icons.first, FALSE); - table.show(); - - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - GSList *group = 0; - ui::RadioButton radio{ui::null}; - for (StringArrayRange::Iterator icon = icons.first; icon != icons.last; ++icon) { - guint pos = static_cast( icon - icons.first ); - auto image = new_local_image(*icon); - image.show(); - table.attach(image, {pos, pos + 1, 0, 1}, {0, 0}); - - radio = ui::RadioButton::from(gtk_radio_button_new(group)); - radio.show(); - table.attach(radio, {pos, pos + 1, 1, 2}, {0, 0}); - - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); - } - - AddIntRadioData(radio, cb); - - DialogVBox_packRow(vbox, DialogRow_new(name, table)); -} - -void Dialog::addRadioIcons(ui::VBox vbox, const char *name, int &data, StringArrayRange icons) -{ - addRadioIcons(vbox, name, icons, make_property(data)); -} - -ui::Widget Dialog::addIntEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddIntEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget Dialog::addSizeEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddSizeEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget Dialog::addFloatEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddFloatEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget -Dialog::addPathEntry(ui::VBox vbox, const char *name, bool browse_directory, Property const &cb) -{ - PathEntry pathEntry = PathEntry_new(); - pathEntry.m_button.connect("clicked", G_CALLBACK( - browse_directory ? button_clicked_entry_browse_directory : button_clicked_entry_browse_file), - pathEntry.m_entry); - - AddTextEntryData(pathEntry.m_entry, cb); - - auto row = DialogRow_new(name, ui::Widget(pathEntry.m_frame)); - DialogVBox_packRow(vbox, row); - - return row; -} - -ui::Widget Dialog::addPathEntry(ui::VBox vbox, const char *name, CopiedString &data, bool browse_directory) -{ - return addPathEntry(vbox, name, browse_directory, make_property(data)); -} - -ui::SpinButton -Dialog::addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb) -{ - DialogSpinnerRow row(DialogSpinnerRow_new(name, value, lower, upper, 1)); - AddIntSpinnerData(row.m_spin, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_spin; -} - -ui::SpinButton Dialog::addSpinner(ui::VBox vbox, const char *name, int &data, double value, double lower, double upper) -{ - return addSpinner(vbox, name, value, lower, upper, make_property(data)); -} - -ui::SpinButton -Dialog::addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb) -{ - DialogSpinnerRow row(DialogSpinnerRow_new(name, value, lower, upper, 10)); - AddFloatSpinnerData(row.m_spin, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_spin; -} diff --git a/src/dialog.h b/src/dialog.h deleted file mode 100644 index 102bb51..0000000 --- a/src/dialog.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DIALOG_H ) -#define INCLUDED_DIALOG_H - -#include -#include -#include "property.h" - -#include "generic/callback.h" -#include "gtkutil/dialog.h" -#include "generic/callback.h" -#include "string/string.h" - -struct DLG_DATA { - virtual ~DLG_DATA() = default; - - virtual void release() = 0; - - virtual void importData() const = 0; - - virtual void exportData() const = 0; -}; - - -template -class CallbackDialogData; - -typedef std::list DialogDataList; - -class Dialog { -ui::Window m_window; -DialogDataList m_data; -public: -ModalDialog m_modal; -ui::Window m_parent; - -Dialog(); - -virtual ~Dialog(); - -/*! - start modal dialog box - you need to use AddModalButton to select eIDOK eIDCANCEL buttons - */ -EMessageBoxReturn DoModal(); - -void EndModal(EMessageBoxReturn code); - -virtual ui::Window BuildDialog() = 0; - -virtual void exportData(); - -virtual void importData(); - -virtual void PreModal() -{ -}; - -virtual void PostModal(EMessageBoxReturn code) -{ -}; - -virtual void ShowDlg(); - -virtual void HideDlg(); - -void Create(); - -void Destroy(); - -ui::Window GetWidget() -{ - return m_window; -} - -const ui::Window GetWidget() const -{ - return m_window; -} - -ui::CheckButton addCheckBox(ui::VBox vbox, const char *name, const char *flag, Property const &cb); - -ui::CheckButton addCheckBox(ui::VBox vbox, const char *name, const char *flag, bool &data); - -void addCombo(ui::VBox vbox, const char *name, StringArrayRange values, Property const &cb); - -void addCombo(ui::VBox vbox, const char *name, int &data, StringArrayRange values); - -void addSlider(ui::VBox vbox, const char *name, int &data, gboolean draw_value, const char *low, const char *high, - double value, double lower, double upper, double step_increment, double page_increment); - -void addRadio(ui::VBox vbox, const char *name, StringArrayRange names, Property const &cb); - -void addRadio(ui::VBox vbox, const char *name, int &data, StringArrayRange names); - -void addRadioIcons(ui::VBox vbox, const char *name, StringArrayRange icons, Property const &cb); - -void addRadioIcons(ui::VBox vbox, const char *name, int &data, StringArrayRange icons); - -ui::Widget addIntEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, int &data) -{ - return addIntEntry(vbox, name, make_property(data)); -} - -ui::Widget addSizeEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, std::size_t &data) -{ - return addSizeEntry(vbox, name, make_property(data)); -} - -ui::Widget addFloatEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, float &data) -{ - return addFloatEntry(vbox, name, make_property(data)); -} - -ui::Widget addPathEntry(ui::VBox vbox, const char *name, bool browse_directory, Property const &cb); - -ui::Widget addPathEntry(ui::VBox vbox, const char *name, CopiedString &data, bool directory); - -ui::SpinButton addSpinner(ui::VBox vbox, const char *name, int &data, double value, double lower, double upper); - -ui::SpinButton -addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb); - -ui::SpinButton -addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb); - -protected: - -void AddBoolToggleData(ui::ToggleButton object, Property const &cb); - -void AddIntRadioData(ui::RadioButton object, Property const &cb); - -void AddTextEntryData(ui::Entry object, Property const &cb); - -void AddIntEntryData(ui::Entry object, Property const &cb); - -void AddSizeEntryData(ui::Entry object, Property const &cb); - -void AddFloatEntryData(ui::Entry object, Property const &cb); - -void AddFloatSpinnerData(ui::SpinButton object, Property const &cb); - -void AddIntSpinnerData(ui::SpinButton object, Property const &cb); - -void AddIntAdjustmentData(ui::Adjustment object, Property const &cb); - -void AddIntComboData(ui::ComboBox object, Property const &cb); - -void AddDialogData(ui::ToggleButton object, bool &data); - -void AddDialogData(ui::RadioButton object, int &data); - -void AddDialogData(ui::Entry object, CopiedString &data); - -void AddDialogData(ui::Entry object, int &data); - -void AddDialogData(ui::Entry object, std::size_t &data); - -void AddDialogData(ui::Entry object, float &data); - -void AddDialogData(ui::SpinButton object, float &data); - -void AddDialogData(ui::SpinButton object, int &data); - -void AddDialogData(ui::Adjustment object, int &data); - -void AddDialogData(ui::ComboBox object, int &data); -}; - -#endif diff --git a/src/eclass.cpp b/src/eclass.cpp deleted file mode 100644 index c344c18..0000000 --- a/src/eclass.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" - -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" - -#include "cmdlib.h" - -#include "preferences.h" -#include "mainframe.h" - - -namespace { -typedef std::map EntityClasses; -EntityClasses g_entityClasses; -EntityClass *eclass_bad = 0; -char eclass_directory[1024]; -typedef std::map ListAttributeTypes; -ListAttributeTypes g_listTypes; -} - -EClassModules &EntityClassManager_getEClassModules(); - -/*! - implementation of the EClass manager API - */ - -void CleanEntityList(EntityClasses &entityClasses) -{ - for (EntityClasses::iterator i = entityClasses.begin(); i != entityClasses.end(); ++i) { - (*i).second->free((*i).second); - } - entityClasses.clear(); -} - -void Eclass_Clear() -{ - CleanEntityList(g_entityClasses); - g_listTypes.clear(); -} - -EntityClass *EClass_InsertSortedList(EntityClasses &entityClasses, EntityClass *entityClass) -{ - std::pair result = entityClasses.insert( - EntityClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - entityClass->free(entityClass); - } - return (*result.first).second; -} - -EntityClass *Eclass_InsertAlphabetized(EntityClass *e) -{ - return EClass_InsertSortedList(g_entityClasses, e); -} - -void Eclass_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_entityClasses.begin(); i != g_entityClasses.end(); ++i) { - visitor.visit((*i).second); - } -} - -void Eclass_forEachPoint(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_entityClasses.begin(); i != g_entityClasses.end(); ++i) { - if ((*i).second->fixedsize == true) { - visitor.visit((*i).second); - } - } -} - - -class RadiantEclassCollector : public EntityClassCollector { -public: -void insert(EntityClass *eclass) -{ - Eclass_InsertAlphabetized(eclass); -} - -void insert(const char *name, const ListAttributeType &list) -{ - g_listTypes.insert(ListAttributeTypes::value_type(name, list)); -} -}; - -RadiantEclassCollector g_collector; - -const ListAttributeType *EntityClass_findListType(const char *name) -{ - ListAttributeTypes::iterator i = g_listTypes.find(name); - if (i != g_listTypes.end()) { - return &(*i).second; - } - return 0; -} - - -class EntityClassFilterMode { -public: -bool filter_mp_sp; -const char *mp_ignore_prefix; -const char *sp_ignore_prefix; - -EntityClassFilterMode() : - filter_mp_sp(!string_empty(g_pGameDescription->getKeyValue("eclass_filter_gamemode"))), - mp_ignore_prefix(g_pGameDescription->getKeyValue("eclass_sp_prefix")), - sp_ignore_prefix(g_pGameDescription->getKeyValue("eclass_mp_prefix")) -{ - if (string_empty(mp_ignore_prefix)) { - mp_ignore_prefix = "sp_"; - } - if (string_empty(sp_ignore_prefix)) { - sp_ignore_prefix = "mp_"; - } -} -}; - -class EntityClassesLoadFile { -const EntityClassScanner &scanner; -const char *m_directory; -public: -EntityClassesLoadFile(const EntityClassScanner &scanner, const char *directory) : scanner(scanner), - m_directory(directory) -{ -} - -void operator()(const char *name) const -{ - EntityClassFilterMode filterMode; - - if (filterMode.filter_mp_sp) { - if (string_empty(GlobalRadiant().getGameMode()) || string_equal(GlobalRadiant().getGameMode(), "sp")) { - if (string_equal_n(name, filterMode.sp_ignore_prefix, strlen(filterMode.sp_ignore_prefix))) { - globalOutputStream() << "Ignoring '" << name << "'\n"; - return; - } - } else { - if (string_equal_n(name, filterMode.mp_ignore_prefix, strlen(filterMode.mp_ignore_prefix))) { - globalOutputStream() << "Ignoring '" << name << "'\n"; - return; - } - } - } - - // for a given name, we grab the first .def in the vfs - // this allows to override baseq3/scripts/entities.def for instance - StringOutputStream relPath(256); - relPath << m_directory << name; - - scanner.scanFile(g_collector, relPath.c_str()); -} -}; - -struct PathLess { - bool operator()(const CopiedString &path, const CopiedString &other) const - { - return path_less(path.c_str(), other.c_str()); - } -}; - -typedef std::map Paths; - -void EntityClassQuake3_constructDirectory(const char *directory, const char *extension, Paths &paths) -{ - globalOutputStream() << "EntityClass: searching " << makeQuoted(directory) << " for *." << extension << '\n'; - Directory_forEach(directory, matchFileExtension(extension, [&](const char *name) { - paths.insert(Paths::value_type(name, directory)); - })); -} - - -void EntityClassQuake3_Construct() -{ - StringOutputStream baseDirectory(256); - StringOutputStream gameDirectory(256); - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - const char *gamename = GlobalRadiant().getGameName(); - baseDirectory << GlobalRadiant().getEnginePath() << basegame << '/'; - gameDirectory << GlobalRadiant().getEnginePath() << gamename << '/'; - - class LoadEntityDefinitionsVisitor : public EClassModules::Visitor { - const char *baseDirectory; - const char *gameDirectory; -public: - LoadEntityDefinitionsVisitor(const char *baseDirectory, const char *gameDirectory) - : baseDirectory(baseDirectory), gameDirectory(gameDirectory) - { - } - - void visit(const char *name, const EntityClassScanner &table) const - { - Paths paths; - if (!string_equal(baseDirectory, gameDirectory)) - EntityClassQuake3_constructDirectory(gameDirectory, table.getExtension(), paths); - else - EntityClassQuake3_constructDirectory(baseDirectory, table.getExtension(), paths); - - for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) { - EntityClassesLoadFile(table, (*i).second)((*i).first.c_str()); - } - } - }; - - EntityClassManager_getEClassModules().foreachModule( - LoadEntityDefinitionsVisitor(baseDirectory.c_str(), gameDirectory.c_str())); -} - -EntityClass *Eclass_ForName(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return eclass_bad; - } - - EntityClasses::iterator i = g_entityClasses.find(name); - if (i != g_entityClasses.end() && string_equal((*i).first, name)) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - return Eclass_InsertAlphabetized(e); -} - -class EntityClassQuake3 : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassQuake3() : m_unrealised(4) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - //globalOutputStream() << "Entity Classes: realise\n"; - EntityClassQuake3_Construct(); - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - //globalOutputStream() << "Entity Classes: unrealise\n"; - Eclass_Clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassQuake3 g_EntityClassQuake3; - -void EntityClass_attach(ModuleObserver &observer) -{ - g_EntityClassQuake3.attach(observer); -} - -void EntityClass_detach(ModuleObserver &observer) -{ - g_EntityClassQuake3.detach(observer); -} - -void EntityClass_realise() -{ - g_EntityClassQuake3.realise(); -} - -void EntityClass_unrealise() -{ - g_EntityClassQuake3.unrealise(); -} - -void EntityClassQuake3_construct() -{ - // start by creating the default unknown eclass - eclass_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClass_realise(); -} - -void EntityClassQuake3_destroy() -{ - EntityClass_unrealise(); - - eclass_bad->free(eclass_bad); -} - -#include "modulesystem/modulesmap.h" - -class EntityClassQuake3Dependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalShaderCacheModuleRef { -EClassModulesRef m_eclass_modules; -public: -EntityClassQuake3Dependencies() : - m_eclass_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclasstype")) -{ -} - -EClassModules &getEClassModules() -{ - return m_eclass_modules.get(); -} -}; - -class EclassManagerAPI { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "quake3"); - -EclassManagerAPI() -{ - EntityClassQuake3_construct(); - - m_eclassmanager.findOrInsert = &Eclass_ForName; - m_eclassmanager.findListType = &EntityClass_findListType; - m_eclassmanager.forEach = &Eclass_forEach; - m_eclassmanager.forEachPoint = &Eclass_forEachPoint; - m_eclassmanager.attach = &EntityClass_attach; - m_eclassmanager.detach = &EntityClass_detach; - m_eclassmanager.realise = &EntityClass_realise; - m_eclassmanager.unrealise = &EntityClass_unrealise; - - Radiant_attachGameToolsPathObserver(g_EntityClassQuake3); - Radiant_attachGameModeObserver(g_EntityClassQuake3); - Radiant_attachGameNameObserver(g_EntityClassQuake3); -} - -~EclassManagerAPI() -{ - Radiant_detachGameNameObserver(g_EntityClassQuake3); - Radiant_detachGameModeObserver(g_EntityClassQuake3); - Radiant_detachGameToolsPathObserver(g_EntityClassQuake3); - - EntityClassQuake3_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EclassManagerModule; -typedef Static StaticEclassManagerModule; -StaticRegisterModule staticRegisterEclassManager(StaticEclassManagerModule::instance()); - -EClassModules &EntityClassManager_getEClassModules() -{ - return StaticEclassManagerModule::instance().getDependencies().getEClassModules(); -} diff --git a/src/eclass.h b/src/eclass.h deleted file mode 100644 index d4bfd1f..0000000 --- a/src/eclass.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_H ) -#define INCLUDED_ECLASS_H - -#endif diff --git a/src/eclass_def.cpp b/src/eclass_def.cpp deleted file mode 100644 index 7baf042..0000000 --- a/src/eclass_def.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_def.h" - -#include "iscriplib.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "eclasslib.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "modulesystem/moduleregistry.h" -#include "os/path.h" - -const char *EClass_GetExtension() -{ - return "def"; -} - -void Eclass_ScanFile(EntityClassCollector &collector, const char *filename); - - -#include "modulesystem/singletonmodule.h" - -class EntityClassDefDependencies : public GlobalShaderCacheModuleRef, public GlobalScripLibModuleRef { -}; - -class EclassDefAPI { -EntityClassScanner m_eclassdef; -public: -typedef EntityClassScanner Type; - -STRING_CONSTANT(Name, "def"); - -EclassDefAPI() -{ - m_eclassdef.scanFile = &Eclass_ScanFile; - m_eclassdef.getExtension = &EClass_GetExtension; -} - -EntityClassScanner *getTable() -{ - return &m_eclassdef; -} -}; - -typedef SingletonModule EclassDefModule; -typedef Static StaticEclassDefModule; -StaticRegisterModule staticRegisterEclassDef(StaticEclassDefModule::instance()); - - -#include "string/string.h" - -#include - - -char com_token[1024]; -bool com_eof; - -/* - ============== - COM_Parse - - Parse a token out of a string - ============== - */ -const char *COM_Parse(const char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) { - return 0; - } - -// skip whitespace -skipwhite: - while ((c = *data) <= ' ') { - if (c == 0) { - com_eof = true; - return 0; // end of file; - } - data++; - } - -// skip // comments - if (c == '/' && data[1] == '/') { - while (*data && *data != '\n') { - data++; - } - goto skipwhite; - } - - -// handle quoted strings specially - if (c == '\"') { - data++; - do { - c = *data++; - if (c == '\"') { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } while (1); - } - -// parse single characters - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') { - com_token[len] = c; - len++; - com_token[len] = 0; - return data + 1; - } - -// parse a regular word - do { - com_token[len] = c; - data++; - len++; - c = *data; - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') { - break; - } - } while (c > 32); - - com_token[len] = 0; - return data; -} - -const char *Get_COM_Token() -{ - return com_token; -} - - -const char *debugname; - -void setSpecialLoad(EntityClass *e, const char *pWhat, CopiedString &p) -{ - // Hydra: removed some amazingly bad cstring usage, whoever wrote that - // needs to be taken out and shot. - - const char *pText = 0; - const char *where = 0; - - where = strstr(e->comments(), pWhat); - if (!where) { - return; - } - - pText = where + strlen(pWhat); - if (*pText == '\"') { - pText++; - } - - where = strchr(pText, '\"'); - if (where) { - p = StringRange(pText, where); - } else { - p = pText; - } -} - -#include "eclasslib.h" - -/* - - the classname, color triple, and bounding box are parsed out of comments - A ? size means take the exact brush size. - - / *QUAKED (0 0 0) ? - / *QUAKED (0 0 0) (-8 -8 -8) (8 8 8) - - Flag names can follow the size description: - - / *QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY - - */ - -EntityClass *Eclass_InitFromText(const char *text) -{ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - // grab the name - text = COM_Parse(text); - e->m_name = Get_COM_Token(); - debugname = e->name(); - - { - // grab the color, reformat as texture name - int r = sscanf(text, " (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]); - if (r != 3) { - return e; - } - eclass_capture_state(e); - } - - while (*text != ')') { - if (!*text) { - return 0; - } - text++; - } - text++; - - // get the size - text = COM_Parse(text); - if (Get_COM_Token()[0] == '(') { // parse the size as two vectors - e->fixedsize = true; - int r = sscanf(text, "%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2], - &e->maxs[0], &e->maxs[1], &e->maxs[2]); - if (r != 6) { - return 0; - } - - for (int i = 0; i < 2; i++) { - while (*text != ')') { - if (!*text) { - return 0; - } - text++; - } - text++; - } - } - - char parms[256]; - // get the flags - { - // copy to the first /n - char *p = parms; - while (*text && *text != '\n') { - *p++ = *text++; - } - *p = 0; - text++; - } - - { - // any remaining words are parm flags - const char *p = parms; - for (std::size_t i = 0; i < MAX_FLAGS; i++) { - p = COM_Parse(p); - if (!p) { - break; - } - strcpy(e->flagnames[i], Get_COM_Token()); - } - } - - e->m_comments = text; - - setSpecialLoad(e, "model=", e->m_modelpath); - StringOutputStream buffer(string_length(e->m_modelpath.c_str())); - buffer << PathCleaned(e->m_modelpath.c_str()); - e->m_modelpath = buffer.c_str(); - - if (!e->fixedsize) { - EntityClass_insertAttribute(*e, "angle", EntityClassAttribute("direction", "Direction", "0")); - } else { - EntityClass_insertAttribute(*e, "angle", EntityClassAttribute("angle", "Yaw Angle", "0")); - } - EntityClass_insertAttribute(*e, "model", EntityClassAttribute("model", "Model")); - EntityClass_insertAttribute(*e, "noise", EntityClassAttribute("sound", "Sound")); - - return e; -} - -void Eclass_ScanFile(EntityClassCollector &collector, const char *filename) -{ - EntityClass *e; - - TextFileInputStream inputFile(filename); - if (inputFile.failed()) { - globalErrorStream() << "ScanFile: " << filename << " not found\n"; - return; - } - globalOutputStream() << "ScanFile: " << filename << "\n"; - - enum EParserState { - eParseDefault, - eParseSolidus, - eParseComment, - eParseQuakeED, - eParseEntityClass, - eParseEntityClassEnd, - } state = eParseDefault; - const char *quakeEd = "QUAKED"; - const char *p = 0; - StringBuffer buffer; - SingleCharacterInputStream bufferedInput(inputFile); - for (;;) { - char c; - if (!bufferedInput.readChar(c)) { - break; - } - - switch (state) { - case eParseDefault: - if (c == '/') { - state = eParseSolidus; - } - break; - case eParseSolidus: - if (c == '/') { - state = eParseComment; - } else if (c == '*') { - p = quakeEd; - state = eParseQuakeED; - } - break; - case eParseComment: - if (c == '\n') { - state = eParseDefault; - } - break; - case eParseQuakeED: - if (c == *p) { - if (*(++p) == '\0') { - state = eParseEntityClass; - } - } else { - state = eParseDefault; - } - break; - case eParseEntityClass: - if (c == '*') { - state = eParseEntityClassEnd; - } else { - buffer.push_back(c); - } - break; - case eParseEntityClassEnd: - if (c == '/') { - e = Eclass_InitFromText(buffer.c_str()); - state = eParseDefault; - if (e) { - collector.insert(e); - } else { - globalErrorStream() << "Error parsing: " << debugname << " in " << filename << "\n"; - } - - buffer.clear(); - state = eParseDefault; - } else { - buffer.push_back('*'); - buffer.push_back(c); - state = eParseEntityClass; - } - break; - } - } -} diff --git a/src/eclass_def.h b/src/eclass_def.h deleted file mode 100644 index 102fe4f..0000000 --- a/src/eclass_def.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_DEF_H ) -#define INCLUDED_ECLASS_DEF_H - -#endif diff --git a/src/eclass_doom3.cpp b/src/eclass_doom3.cpp deleted file mode 100644 index ffbcfef..0000000 --- a/src/eclass_doom3.cpp +++ /dev/null @@ -1,827 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_doom3.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "iarchive.h" -#include "qerplugin.h" - -#include "generic/callback.h" -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" -#include "stringio.h" - -class RawString { -const char *m_value; -public: -RawString(const char *value) : m_value(value) -{ -} - -const char *c_str() const -{ - return m_value; -} -}; - -inline bool operator<(const RawString &self, const RawString &other) -{ - return string_less_nocase(self.c_str(), other.c_str()); -} - -typedef std::map EntityClasses; -EntityClasses g_EntityClassDoom3_classes; -EntityClass *g_EntityClassDoom3_bad = 0; - - -void EntityClassDoom3_clear() -{ - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); i != g_EntityClassDoom3_classes.end(); ++i) { - (*i).second->free((*i).second); - } - g_EntityClassDoom3_classes.clear(); -} - -// entityClass will be inserted only if another of the same name does not already exist. -// if entityClass was inserted, the same object is returned, otherwise the already-existing object is returned. -EntityClass *EntityClassDoom3_insertUnique(EntityClass *entityClass) -{ - return (*g_EntityClassDoom3_classes.insert( - EntityClasses::value_type(entityClass->name(), entityClass)).first).second; -} - -void EntityClassDoom3_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); i != g_EntityClassDoom3_classes.end(); ++i) { - visitor.visit((*i).second); - } -} - -inline void printParseError(const char *message) -{ - globalErrorStream() << message; -} - -#define PARSE_RETURN_FALSE_IF_FAIL(expression) do { if (!( expression)) { printParseError(FILE_LINE "\nparse failed: " #expression "\n"); return false; } } while (0) - -bool EntityClassDoom3_parseToken(Tokeniser &tokeniser) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - return true; -} - -bool EntityClassDoom3_parseToken(Tokeniser &tokeniser, const char *string) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - return string_equal(token, string); -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, const char *&s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s = token; - return true; -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, CopiedString &s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s = token; - return true; -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, StringOutputStream &s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s << token; - return true; -} - -bool EntityClassDoom3_parseUnknown(Tokeniser &tokeniser) -{ - //const char* name = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - - //globalOutputStream() << "parsing unknown block " << makeQuoted(name) << "\n"; - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - std::size_t depth = 1; - for (;;) { - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - if (string_equal(token, "}")) { - if (--depth == 0) { - tokeniser.nextLine(); - break; - } - } else if (string_equal(token, "{")) { - ++depth; - } - tokeniser.nextLine(); - } - return true; -} - - -class Model { -public: -bool m_resolved; -CopiedString m_mesh; -CopiedString m_skin; -CopiedString m_parent; -typedef std::map Anims; -Anims m_anims; - -Model() : m_resolved(false) -{ -} -}; - -typedef std::map Models; - -Models g_models; - -void Model_resolveInheritance(const char *name, Model &model) -{ - if (model.m_resolved == false) { - model.m_resolved = true; - - if (!string_empty(model.m_parent.c_str())) { - Models::iterator i = g_models.find(model.m_parent); - if (i == g_models.end()) { - globalErrorStream() << "model " << name << " inherits unknown model " << model.m_parent.c_str() << "\n"; - } else { - Model_resolveInheritance((*i).first.c_str(), (*i).second); - model.m_mesh = (*i).second.m_mesh; - model.m_skin = (*i).second.m_skin; - } - } - } -} - -bool EntityClassDoom3_parseModel(Tokeniser &tokeniser) -{ - const char *name; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, name)); - - Model &model = g_models[name]; - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - for (;;) { - const char *parameter; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, parameter)); - if (string_equal(parameter, "}")) { - tokeniser.nextLine(); - break; - } else if (string_equal(parameter, "inherit")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_parent)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "remove")) { - //const char* remove = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "mesh")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_mesh)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "skin")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_skin)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "offset")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "(")); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, ")")); - tokeniser.nextLine(); - } else if (string_equal(parameter, "channel")) { - //const char* channelName = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "(")); - for (;;) { - const char *end; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, end)); - if (string_equal(end, ")")) { - tokeniser.nextLine(); - break; - } - } - } else if (string_equal(parameter, "anim")) { - CopiedString animName; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animName)); - const char *animFile; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animFile)); - model.m_anims.insert(Model::Anims::value_type(animName, animFile)); - - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - - while (string_equal(token, ",")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animFile)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - } - - if (string_equal(token, "{")) { - for (;;) { - const char *end; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, end)); - if (string_equal(end, "}")) { - tokeniser.nextLine(); - break; - } - tokeniser.nextLine(); - } - } else { - tokeniser.ungetToken(); - } - } else { - globalErrorStream() << "unknown model parameter: " << makeQuoted(parameter) << "\n"; - return false; - } - tokeniser.nextLine(); - } - return true; -} - -inline bool char_isSpaceOrTab(char c) -{ - return c == ' ' || c == '\t'; -} - -inline bool char_isNotSpaceOrTab(char c) -{ - return !char_isSpaceOrTab(c); -} - -template -inline const char *string_find_if(const char *string, Predicate predicate) -{ - for (; *string != 0; ++string) { - if (predicate(*string)) { - return string; - } - } - return string; -} - -inline const char *string_findFirstSpaceOrTab(const char *string) -{ - return string_find_if(string, char_isSpaceOrTab); -} - -inline const char *string_findFirstNonSpaceOrTab(const char *string) -{ - return string_find_if(string, char_isNotSpaceOrTab); -} - - -static bool EntityClass_parse(EntityClass &entityClass, Tokeniser &tokeniser) -{ - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, entityClass.m_name)); - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - StringOutputStream usage(256); - StringOutputStream description(256); - CopiedString *currentDescription = 0; - StringOutputStream *currentString = 0; - - for (;;) { - const char *key; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, key)); - - const char *last = string_findFirstSpaceOrTab(key); - CopiedString first(StringRange(key, last)); - - if (!string_empty(last)) { - last = string_findFirstNonSpaceOrTab(last); - } - - if (currentString != 0 && string_equal(key, "\\")) { - tokeniser.nextLine(); - *currentString << " "; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, *currentString)); - continue; - } - - if (currentDescription != 0) { - *currentDescription = description.c_str(); - description.clear(); - currentDescription = 0; - } - currentString = 0; - - if (string_equal(key, "}")) { - tokeniser.nextLine(); - break; - } else if (string_equal(key, "model")) { - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - entityClass.fixedsize = true; - StringOutputStream buffer(256); - buffer << PathCleaned(token); - entityClass.m_modelpath = buffer.c_str(); - } else if (string_equal(key, "editor_color")) { - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value)) { - entityClass.colorSpecified = true; - bool success = string_parse_vector3(value, entityClass.color); - ASSERT_MESSAGE(success, "editor_color: parse error"); - } - } else if (string_equal(key, "editor_ragdoll")) { - //bool ragdoll = atoi(tokeniser.getToken()) != 0; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_mins")) { - entityClass.sizeSpecified = true; - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value) && !string_equal(value, "?")) { - entityClass.fixedsize = true; - bool success = string_parse_vector3(value, entityClass.mins); - ASSERT_MESSAGE(success, "editor_mins: parse error"); - } - } else if (string_equal(key, "editor_maxs")) { - entityClass.sizeSpecified = true; - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value) && !string_equal(value, "?")) { - entityClass.fixedsize = true; - bool success = string_parse_vector3(value, entityClass.maxs); - ASSERT_MESSAGE(success, "editor_maxs: parse error"); - } - } else if (string_equal(key, "editor_usage")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, usage)); - currentString = &usage; - } else if (string_equal_n(key, "editor_usage", 12)) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, usage)); - currentString = &usage; - } else if (string_equal(key, "editor_rotatable") - || string_equal(key, "editor_showangle") - || string_equal(key, "editor_showangles") // typo? in prey movables.def - || string_equal(key, "editor_mover") - || string_equal(key, "editor_model") - || string_equal(key, "editor_material") - || string_equal(key, "editor_combatnode") - || (!string_empty(last) && string_equal(first.c_str(), "editor_gui")) - || string_equal_n(key, "editor_copy", 11)) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (!string_empty(last) && - (string_equal(first.c_str(), "editor_var") || string_equal(first.c_str(), "editor_string"))) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "string"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_float")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "string"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_snd")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "sound"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_bool")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "boolean"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_int")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "integer"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_model")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "model"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_color")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "color"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && - (string_equal(first.c_str(), "editor_material") || string_equal(first.c_str(), "editor_mat"))) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "shader"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (string_equal(key, "inherit")) { - entityClass.inheritanceResolved = false; - ASSERT_MESSAGE(entityClass.m_parent.empty(), "only one 'inherit' supported per entityDef"); - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - entityClass.m_parent.push_back(token); - } - // begin quake4-specific keys - else if (string_equal(key, "editor_targetonsel")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_menu")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_ignore")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } - // end quake4-specific keys - // begin ignore prey (unknown/unused?) entity keys - else if (string_equal(key, "editor_light") - || string_equal(key, "editor_def def_debrisspawner") - || string_equal(key, "editor_def def_drop") - || string_equal(key, "editor_def def_guihand") - || string_equal(key, "editor_def def_mine")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } - // end ignore prey entity keys - else { - CopiedString tmp(key); - if (string_equal_n(key, "editor_", 7)) { - globalErrorStream() << "unsupported editor key " << makeQuoted(key); - } - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, key).second; - attribute.m_type = "string"; - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (string_equal(value, "}")) { // hack for quake4 powerups.def bug - globalErrorStream() << "entityDef " << makeQuoted(entityClass.m_name.c_str()) << " key " - << makeQuoted(tmp.c_str()) << " has no value\n"; - break; - } else { - attribute.m_value = value; - } - } - tokeniser.nextLine(); - } - - entityClass.m_comments = usage.c_str(); - - if (string_equal(entityClass.m_name.c_str(), "light")) { - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "light_radius").second; - attribute.m_type = "vector3"; - attribute.m_value = "300 300 300"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "light_center").second; - attribute.m_type = "vector3"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "noshadows").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "nospecular").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "nodiffuse").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "falloff").second; - attribute.m_type = "real"; - } - } - - return true; -} - -bool EntityClassDoom3_parseEntityDef(Tokeniser &tokeniser) -{ - EntityClass *entityClass = Eclass_Alloc(); - entityClass->free = &Eclass_Free; - - if (!EntityClass_parse(*entityClass, tokeniser)) { - eclass_capture_state(entityClass); // finish constructing the entity so that it can be destroyed cleanly. - entityClass->free(entityClass); - return false; - } - - EntityClass *inserted = EntityClassDoom3_insertUnique(entityClass); - if (inserted != entityClass) { - globalErrorStream() << "entityDef " << entityClass->name() - << " is already defined, second definition ignored\n"; - eclass_capture_state(entityClass); // finish constructing the entity so that it can be destroyed cleanly. - entityClass->free(entityClass); - } - return true; -} - -bool EntityClassDoom3_parseBlock(Tokeniser &tokeniser, const char *blockType) -{ - if (string_equal(blockType, "entityDef")) { - return EntityClassDoom3_parseEntityDef(tokeniser); - } else if (string_equal(blockType, "model")) { - return EntityClassDoom3_parseModel(tokeniser); - } else { - return EntityClassDoom3_parseUnknown(tokeniser); - } -} - -bool EntityClassDoom3_parse(TextInputStream &inputStream, const char *filename) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(inputStream); - - tokeniser.nextLine(); - - for (;;) { - const char *blockType = tokeniser.getToken(); - if (blockType == 0) { - return true; - } - CopiedString tmp(blockType); - if (!EntityClassDoom3_parseBlock(tokeniser, tmp.c_str())) { - globalErrorStream() << GlobalFileSystem().findFile(filename) << filename << ":" - << (unsigned int) tokeniser.getLine() << ": " << tmp.c_str() - << " parse failed, skipping rest of file\n"; - return false; - } - } - - tokeniser.release(); -} - - -void EntityClassDoom3_loadFile(const char *filename) -{ - globalOutputStream() << "parsing entity classes from " << makeQuoted(filename) << "\n"; - - StringOutputStream fullname(256); - fullname << "def/" << filename; - - ArchiveTextFile *file = GlobalFileSystem().openTextFile(fullname.c_str()); - if (file != 0) { - EntityClassDoom3_parse(file->getInputStream(), fullname.c_str()); - file->release(); - } -} - -EntityClass *EntityClassDoom3_findOrInsert(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return g_EntityClassDoom3_bad; - } - - EntityClasses::iterator i = g_EntityClassDoom3_classes.find(name); - if (i != g_EntityClassDoom3_classes.end() - //&& string_equal((*i).first, name) - ) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - EntityClass *inserted = EntityClassDoom3_insertUnique(e); - ASSERT_MESSAGE(inserted == e, ""); - return inserted; -} - -const ListAttributeType *EntityClassDoom3_findListType(const char *name) -{ - return 0; -} - - -void EntityClass_resolveInheritance(EntityClass *derivedClass) -{ - if (derivedClass->inheritanceResolved == false) { - derivedClass->inheritanceResolved = true; - EntityClasses::iterator i = g_EntityClassDoom3_classes.find(derivedClass->m_parent.front().c_str()); - if (i == g_EntityClassDoom3_classes.end()) { - globalErrorStream() << "failed to find entityDef " << makeQuoted(derivedClass->m_parent.front().c_str()) - << " inherited by " << makeQuoted(derivedClass->m_name.c_str()) << "\n"; - } else { - EntityClass *parentClass = (*i).second; - EntityClass_resolveInheritance(parentClass); - if (!derivedClass->colorSpecified) { - derivedClass->colorSpecified = parentClass->colorSpecified; - derivedClass->color = parentClass->color; - } - if (!derivedClass->sizeSpecified) { - derivedClass->sizeSpecified = parentClass->sizeSpecified; - derivedClass->mins = parentClass->mins; - derivedClass->maxs = parentClass->maxs; - derivedClass->fixedsize = parentClass->fixedsize; - } - - for (EntityClassAttributes::iterator j = parentClass->m_attributes.begin(); - j != parentClass->m_attributes.end(); ++j) { - EntityClass_insertAttribute(*derivedClass, (*j).first.c_str(), (*j).second); - } - } - } -} - -class EntityClassDoom3 : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassDoom3() : m_unrealised(2) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - globalOutputStream() << "searching vfs directory " << makeQuoted("def") << " for *.def\n"; - GlobalFileSystem().forEachFile("def/", "def", makeCallbackF(EntityClassDoom3_loadFile)); - - { - for (Models::iterator i = g_models.begin(); i != g_models.end(); ++i) { - Model_resolveInheritance((*i).first.c_str(), (*i).second); - } - } - { - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); - i != g_EntityClassDoom3_classes.end(); ++i) { - EntityClass_resolveInheritance((*i).second); - if (!string_empty((*i).second->m_modelpath.c_str())) { - Models::iterator j = g_models.find((*i).second->m_modelpath); - if (j != g_models.end()) { - (*i).second->m_modelpath = (*j).second.m_mesh; - (*i).second->m_skin = (*j).second.m_skin; - } - } - eclass_capture_state((*i).second); - - StringOutputStream usage(256); - - usage << "-------- NOTES --------\n"; - - if (!string_empty((*i).second->m_comments.c_str())) { - usage << (*i).second->m_comments.c_str() << "\n"; - } - - usage << "\n-------- KEYS --------\n"; - - for (EntityClassAttributes::iterator j = (*i).second->m_attributes.begin(); - j != (*i).second->m_attributes.end(); ++j) { - const char *name = EntityClassAttributePair_getName(*j); - const char *description = EntityClassAttributePair_getDescription(*j); - if (!string_equal(name, description)) { - usage << EntityClassAttributePair_getName(*j) << " : " - << EntityClassAttributePair_getDescription(*j) << "\n"; - } - } - - (*i).second->m_comments = usage.c_str(); - } - } - - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - EntityClassDoom3_clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassDoom3 g_EntityClassDoom3; - -void EntityClassDoom3_attach(ModuleObserver &observer) -{ - g_EntityClassDoom3.attach(observer); -} - -void EntityClassDoom3_detach(ModuleObserver &observer) -{ - g_EntityClassDoom3.detach(observer); -} - -void EntityClassDoom3_realise() -{ - g_EntityClassDoom3.realise(); -} - -void EntityClassDoom3_unrealise() -{ - g_EntityClassDoom3.unrealise(); -} - -void EntityClassDoom3_construct() -{ - GlobalFileSystem().attach(g_EntityClassDoom3); - - // start by creating the default unknown eclass - g_EntityClassDoom3_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClassDoom3_realise(); -} - -void EntityClassDoom3_destroy() -{ - EntityClassDoom3_unrealise(); - - g_EntityClassDoom3_bad->free(g_EntityClassDoom3_bad); - - GlobalFileSystem().detach(g_EntityClassDoom3); -} - -class EntityClassDoom3Dependencies : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef { -}; - -class EntityClassDoom3API { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "doom3"); - -EntityClassDoom3API() -{ - EntityClassDoom3_construct(); - - m_eclassmanager.findOrInsert = &EntityClassDoom3_findOrInsert; - m_eclassmanager.findListType = &EntityClassDoom3_findListType; - m_eclassmanager.forEach = &EntityClassDoom3_forEach; - m_eclassmanager.attach = &EntityClassDoom3_attach; - m_eclassmanager.detach = &EntityClassDoom3_detach; - m_eclassmanager.realise = &EntityClassDoom3_realise; - m_eclassmanager.unrealise = &EntityClassDoom3_unrealise; -} - -~EntityClassDoom3API() -{ - EntityClassDoom3_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EntityClassDoom3Module; -typedef Static StaticEntityClassDoom3Module; -StaticRegisterModule staticRegisterEntityClassDoom3(StaticEntityClassDoom3Module::instance()); diff --git a/src/eclass_doom3.h b/src/eclass_doom3.h deleted file mode 100644 index 9dcd8bb..0000000 --- a/src/eclass_doom3.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_DOOM3_H ) -#define INCLUDED_ECLASS_DOOM3_H - -#endif diff --git a/src/eclass_fgd.cpp b/src/eclass_fgd.cpp deleted file mode 100644 index e420106..0000000 --- a/src/eclass_fgd.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_fgd.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "qerplugin.h" -#include "mainframe.h" - -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" -#include "stringio.h" -#include "stream/textfilestream.h" - -namespace { -typedef std::map EntityClasses; -EntityClasses g_EntityClassFGD_classes; -typedef std::map BaseClasses; -BaseClasses g_EntityClassFGD_bases; -EntityClass *g_EntityClassFGD_bad = 0; -typedef std::map ListAttributeTypes; -ListAttributeTypes g_listTypesFGD; -} - - -void EntityClassFGD_clear() -{ - for (BaseClasses::iterator i = g_EntityClassFGD_bases.begin(); i != g_EntityClassFGD_bases.end(); ++i) { - (*i).second->free((*i).second); - } - g_EntityClassFGD_bases.clear(); - g_listTypesFGD.clear(); -} - -EntityClass *EntityClassFGD_insertUniqueBase(EntityClass *entityClass) -{ - std::pair result = g_EntityClassFGD_bases.insert( - BaseClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - globalErrorStream() << "duplicate base class: " << makeQuoted(entityClass->name()) << "\n"; - //eclass_capture_state(entityClass); - //entityClass->free(entityClass); - } - return (*result.first).second; -} - -EntityClass *EntityClassFGD_insertUnique(EntityClass *entityClass) -{ - EntityClassFGD_insertUniqueBase(entityClass); - std::pair result = g_EntityClassFGD_classes.insert( - EntityClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - globalErrorStream() << "duplicate entity class: " << makeQuoted(entityClass->name()) << "\n"; - eclass_capture_state(entityClass); - entityClass->free(entityClass); - } - return (*result.first).second; -} - -void EntityClassFGD_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_EntityClassFGD_classes.begin(); i != g_EntityClassFGD_classes.end(); ++i) { - visitor.visit((*i).second); - } -} - -inline bool EntityClassFGD_parseToken(Tokeniser &tokeniser, const char *token) -{ - return string_equal(tokeniser.getToken(), token); -} - -const char *PARSE_ERROR = "error parsing entity class definition"; - -void EntityClassFGD_parseSplitString(Tokeniser &tokeniser, CopiedString &string) -{ - StringOutputStream buffer(256); - for (;;) { - buffer << tokeniser.getToken(); - if (!string_equal(tokeniser.getToken(), "+")) { - tokeniser.ungetToken(); - string = buffer.c_str(); - return; - } - } -} - -void EntityClassFGD_parseClass(Tokeniser &tokeniser, bool fixedsize, bool isBase) -{ - EntityClass *entityClass = Eclass_Alloc(); - entityClass->free = &Eclass_Free; - entityClass->fixedsize = fixedsize; - entityClass->inheritanceResolved = false; - entityClass->mins = Vector3(-8, -8, -8); - entityClass->maxs = Vector3(8, 8, 8); - - for (;;) { - const char *property = tokeniser.getToken(); - if (string_equal(property, "=")) { - break; - } else if (string_equal(property, "base")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - for (;;) { - const char *base = tokeniser.getToken(); - if (string_equal(base, ")")) { - break; - } else if (!string_equal(base, ",")) { - entityClass->m_parent.push_back(base); - } - } - } else if (string_equal(property, "size")) { - entityClass->sizeSpecified = true; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - Tokeniser_getFloat(tokeniser, entityClass->mins.x()); - Tokeniser_getFloat(tokeniser, entityClass->mins.y()); - Tokeniser_getFloat(tokeniser, entityClass->mins.z()); - const char *token = tokeniser.getToken(); - if (string_equal(token, ",")) { - Tokeniser_getFloat(tokeniser, entityClass->maxs.x()); - Tokeniser_getFloat(tokeniser, entityClass->maxs.y()); - Tokeniser_getFloat(tokeniser, entityClass->maxs.z()); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else { - entityClass->maxs = entityClass->mins; - vector3_negate(entityClass->mins); - ASSERT_MESSAGE(string_equal(token, ")"), ""); - } - } else if (string_equal(property, "color")) { - entityClass->colorSpecified = true; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - Tokeniser_getFloat(tokeniser, entityClass->color.x()); - entityClass->color.x() /= 256.0; - Tokeniser_getFloat(tokeniser, entityClass->color.y()); - entityClass->color.y() /= 256.0; - Tokeniser_getFloat(tokeniser, entityClass->color.z()); - entityClass->color.z() /= 256.0; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "iconsprite")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - StringOutputStream buffer(256); - buffer << PathCleaned(tokeniser.getToken()); - entityClass->m_modelpath = buffer.c_str(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "sprite") - || string_equal(property, "decal") - // hl2 below - || string_equal(property, "overlay") - || string_equal(property, "light") - || string_equal(property, "keyframe") - || string_equal(property, "animator") - || string_equal(property, "quadbounds")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } - // hl2 below - else if (string_equal(property, "sphere") - || string_equal(property, "sweptplayerhull") - || string_equal(property, "studio") - || string_equal(property, "studioprop") - || string_equal(property, "lightprop") - || string_equal(property, "lightcone") - || string_equal(property, "sidelist")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - if (string_equal(tokeniser.getToken(), ")")) { - tokeniser.ungetToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "line") - || string_equal(property, "cylinder")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* r = - tokeniser.getToken(); - //const char* g = - tokeniser.getToken(); - //const char* b = - tokeniser.getToken(); - for (;;) { - if (string_equal(tokeniser.getToken(), ")")) { - tokeniser.ungetToken(); - break; - } - //const char* name = - tokeniser.getToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "wirebox")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* mins = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ","), PARSE_ERROR); - //const char* maxs = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "halfgridsnap")) { - } else { - ERROR_MESSAGE(PARSE_ERROR); - } - } - - entityClass->m_name = tokeniser.getToken(); - - if (!isBase) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - - EntityClassFGD_parseSplitString(tokeniser, entityClass->m_comments); - } - - tokeniser.nextLine(); - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - - tokeniser.nextLine(); - - for (;;) { - CopiedString key = tokeniser.getToken(); - if (string_equal(key.c_str(), "]")) { - tokeniser.nextLine(); - break; - } - - if (string_equal_nocase(key.c_str(), "input") - || string_equal_nocase(key.c_str(), "output")) { - const char *name = tokeniser.getToken(); - if (!string_equal(name, "(")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* type = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - CopiedString description; - EntityClassFGD_parseSplitString(tokeniser, description); - } else { - tokeniser.ungetToken(); - } - tokeniser.nextLine(); - continue; - } - } - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - CopiedString type = tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - - if (string_equal_nocase(type.c_str(), "flags")) { - EntityClassAttribute attribute; - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "="), PARSE_ERROR); - tokeniser.nextLine(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - tokeniser.nextLine(); - for (;;) { - const char *flag = tokeniser.getToken(); - if (string_equal(flag, "]")) { - tokeniser.nextLine(); - break; - } else { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - //const char* name = - tokeniser.getToken(); - { - const char *defaultSeparator = tokeniser.getToken(); - if (string_equal(defaultSeparator, ":")) { - tokeniser.getToken(); - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - } - } - tokeniser.nextLine(); - } - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else if (string_equal_nocase(type.c_str(), "choices")) { - EntityClassAttribute attribute; - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - attribute.m_name = tokeniser.getToken(); - const char *valueSeparator = tokeniser.getToken(); - if (string_equal(valueSeparator, ":")) { - const char *value = tokeniser.getToken(); - if (!string_equal(value, ":")) { - attribute.m_value = value; - } else { - tokeniser.ungetToken(); - } - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "="), PARSE_ERROR); - tokeniser.nextLine(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - tokeniser.nextLine(); - - StringOutputStream listTypeName(64); - listTypeName << entityClass->m_name.c_str() << "_" << attribute.m_name.c_str(); - attribute.m_type = listTypeName.c_str(); - - ListAttributeType &listType = g_listTypesFGD[listTypeName.c_str()]; - - for (;;) { - const char *value = tokeniser.getToken(); - if (string_equal(value, "]")) { - tokeniser.nextLine(); - break; - } else { - CopiedString tmp(value); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - const char *name = tokeniser.getToken(); - listType.push_back(name, tmp.c_str()); - } - tokeniser.nextLine(); - } - - for (ListAttributeType::const_iterator i = listType.begin(); i != listType.end(); ++i) { - if (string_equal(attribute.m_value.c_str(), (*i).first.c_str())) { - attribute.m_value = (*i).second.c_str(); - } - } - - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else if (string_equal_nocase(type.c_str(), "decal")) { - } else if (string_equal_nocase(type.c_str(), "string") - || string_equal_nocase(type.c_str(), "integer") - || string_equal_nocase(type.c_str(), "studio") - || string_equal_nocase(type.c_str(), "sprite") - || string_equal_nocase(type.c_str(), "color255") - || string_equal_nocase(type.c_str(), "target_source") - || string_equal_nocase(type.c_str(), "target_destination") - || string_equal_nocase(type.c_str(), "sound") - // hl2 below - || string_equal_nocase(type.c_str(), "angle") - || string_equal_nocase(type.c_str(), "origin") - || string_equal_nocase(type.c_str(), "float") - || string_equal_nocase(type.c_str(), "node_dest") - || string_equal_nocase(type.c_str(), "filterclass") - || string_equal_nocase(type.c_str(), "vector") - || string_equal_nocase(type.c_str(), "sidelist") - || string_equal_nocase(type.c_str(), "material") - || string_equal_nocase(type.c_str(), "vecline") - || string_equal_nocase(type.c_str(), "axis") - || string_equal_nocase(type.c_str(), "npcclass") - || string_equal_nocase(type.c_str(), "target_name_or_class") - || string_equal_nocase(type.c_str(), "pointentityclass") - || string_equal_nocase(type.c_str(), "scene")) { - if (!string_equal(tokeniser.getToken(), "readonly")) { - tokeniser.ungetToken(); - } - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - const char *attributeType = "string"; - if (string_equal_nocase(type.c_str(), "studio")) { - attributeType = "model"; - } - - EntityClassAttribute attribute; - attribute.m_type = attributeType; - attribute.m_name = tokeniser.getToken(); - - const char *defaultSeparator = tokeniser.getToken(); - if (string_equal(defaultSeparator, ":")) { - const char *value = tokeniser.getToken(); - if (!string_equal(value, ":")) { - attribute.m_value = value; - } else { - tokeniser.ungetToken(); - } - - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else { - ERROR_MESSAGE("unknown key type: " << makeQuoted(type.c_str())); - } - tokeniser.nextLine(); - } - - if (isBase) { - EntityClassFGD_insertUniqueBase(entityClass); - } else { - EntityClassFGD_insertUnique(entityClass); - } -} - -void EntityClassFGD_loadFile(const char *filename); - -void EntityClassFGD_parse(TextInputStream &inputStream, const char *path) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(inputStream); - - tokeniser.nextLine(); - - for (;;) { - const char *blockType = tokeniser.getToken(); - if (blockType == 0) { - break; - } - if (string_equal(blockType, "@SolidClass")) { - EntityClassFGD_parseClass(tokeniser, false, false); - } else if (string_equal(blockType, "@BaseClass")) { - EntityClassFGD_parseClass(tokeniser, false, true); - } else if (string_equal(blockType, "@PointClass") - // hl2 below - || string_equal(blockType, "@KeyFrameClass") - || string_equal(blockType, "@MoveClass") - || string_equal(blockType, "@FilterClass") - || string_equal(blockType, "@NPCClass")) { - EntityClassFGD_parseClass(tokeniser, true, false); - } - // hl2 below - else if (string_equal(blockType, "@include")) { - StringOutputStream includePath(256); - includePath << StringRange(path, path_get_filename_start(path)); - includePath << tokeniser.getToken(); - EntityClassFGD_loadFile(includePath.c_str()); - } else if (string_equal(blockType, "@mapsize")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* min = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ","), PARSE_ERROR); - //const char* max = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else { - ERROR_MESSAGE("unknown block type: " << makeQuoted(blockType)); - } - } - - tokeniser.release(); -} - - -void EntityClassFGD_loadFile(const char *filename) -{ - TextFileInputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "parsing entity classes from " << makeQuoted(filename) << "\n"; - - EntityClassFGD_parse(file, filename); - } -} - -EntityClass *EntityClassFGD_findOrInsert(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return g_EntityClassFGD_bad; - } - - EntityClasses::iterator i = g_EntityClassFGD_classes.find(name); - if (i != g_EntityClassFGD_classes.end() - //&& string_equal((*i).first, name) - ) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - return EntityClassFGD_insertUnique(e); -} - -const ListAttributeType *EntityClassFGD_findListType(const char *name) -{ - ListAttributeTypes::iterator i = g_listTypesFGD.find(name); - if (i != g_listTypesFGD.end()) { - return &(*i).second; - } - return 0; - -} - - -void EntityClassFGD_resolveInheritance(EntityClass *derivedClass) -{ - if (derivedClass->inheritanceResolved == false) { - derivedClass->inheritanceResolved = true; - for (StringList::iterator j = derivedClass->m_parent.begin(); j != derivedClass->m_parent.end(); ++j) { - BaseClasses::iterator i = g_EntityClassFGD_bases.find((*j).c_str()); - if (i == g_EntityClassFGD_bases.end()) { - globalErrorStream() << "failed to find entityDef " << makeQuoted((*j).c_str()) << " inherited by " - << makeQuoted(derivedClass->m_name.c_str()) << "\n"; - } else { - EntityClass *parentClass = (*i).second; - EntityClassFGD_resolveInheritance(parentClass); - if (!derivedClass->colorSpecified) { - derivedClass->colorSpecified = parentClass->colorSpecified; - derivedClass->color = parentClass->color; - } - if (!derivedClass->sizeSpecified) { - derivedClass->sizeSpecified = parentClass->sizeSpecified; - derivedClass->mins = parentClass->mins; - derivedClass->maxs = parentClass->maxs; - } - - for (EntityClassAttributes::iterator k = parentClass->m_attributes.begin(); - k != parentClass->m_attributes.end(); ++k) { - EntityClass_insertAttribute(*derivedClass, (*k).first.c_str(), (*k).second); - } - } - } - } -} - -class EntityClassFGD : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassFGD() : m_unrealised(3) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - StringOutputStream filename(256); - filename << GlobalRadiant().getGameToolsPath() << GlobalRadiant().getGameName() << "/entities.fgd"; - EntityClassFGD_loadFile(filename.c_str()); - - { - for (EntityClasses::iterator i = g_EntityClassFGD_classes.begin(); - i != g_EntityClassFGD_classes.end(); ++i) { - EntityClassFGD_resolveInheritance((*i).second); - if ((*i).second->fixedsize && string_empty((*i).second->m_modelpath.c_str())) { - if (!(*i).second->sizeSpecified) { - globalErrorStream() << "size not specified for entity class: " - << makeQuoted((*i).second->m_name.c_str()) << '\n'; - } - if (!(*i).second->colorSpecified) { - globalErrorStream() << "color not specified for entity class: " - << makeQuoted((*i).second->m_name.c_str()) << '\n'; - } - } - } - } - { - for (BaseClasses::iterator i = g_EntityClassFGD_bases.begin(); i != g_EntityClassFGD_bases.end(); ++i) { - eclass_capture_state((*i).second); - } - } - - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - EntityClassFGD_clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassFGD g_EntityClassFGD; - -void EntityClassFGD_attach(ModuleObserver &observer) -{ - g_EntityClassFGD.attach(observer); -} - -void EntityClassFGD_detach(ModuleObserver &observer) -{ - g_EntityClassFGD.detach(observer); -} - -void EntityClassFGD_realise() -{ - g_EntityClassFGD.realise(); -} - -void EntityClassFGD_unrealise() -{ - g_EntityClassFGD.unrealise(); -} - -void EntityClassFGD_construct() -{ - // start by creating the default unknown eclass - g_EntityClassFGD_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClassFGD_realise(); -} - -void EntityClassFGD_destroy() -{ - EntityClassFGD_unrealise(); - - g_EntityClassFGD_bad->free(g_EntityClassFGD_bad); -} - -class EntityClassFGDDependencies - : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef, public GlobalRadiantModuleRef { -}; - -class EntityClassFGDAPI { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "halflife"); - -EntityClassFGDAPI() -{ - EntityClassFGD_construct(); - - m_eclassmanager.findOrInsert = &EntityClassFGD_findOrInsert; - m_eclassmanager.findListType = &EntityClassFGD_findListType; - m_eclassmanager.forEach = &EntityClassFGD_forEach; - m_eclassmanager.attach = &EntityClassFGD_attach; - m_eclassmanager.detach = &EntityClassFGD_detach; - m_eclassmanager.realise = &EntityClassFGD_realise; - m_eclassmanager.unrealise = &EntityClassFGD_unrealise; - - Radiant_attachGameToolsPathObserver(g_EntityClassFGD); - Radiant_attachGameNameObserver(g_EntityClassFGD); -} - -~EntityClassFGDAPI() -{ - Radiant_detachGameNameObserver(g_EntityClassFGD); - Radiant_detachGameToolsPathObserver(g_EntityClassFGD); - - EntityClassFGD_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EntityClassFGDModule; -typedef Static StaticEntityClassFGDModule; -StaticRegisterModule staticRegisterEntityClassFGD(StaticEntityClassFGDModule::instance()); diff --git a/src/eclass_fgd.h b/src/eclass_fgd.h deleted file mode 100644 index 9eafc54..0000000 --- a/src/eclass_fgd.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_FGD_H ) -#define INCLUDED_ECLASS_FGD_H - -#endif diff --git a/src/eclass_xml.cpp b/src/eclass_xml.cpp deleted file mode 100644 index 54bcd3e..0000000 --- a/src/eclass_xml.cpp +++ /dev/null @@ -1,598 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief EntityClass plugin that supports the .ent xml entity-definition format. -/// -/// the .ent xml format expresses entity-definitions. -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// the attributes of an entity type are defined like this: -/// -/// <[name of attribute type] -/// key="[entity key name]" -/// name="[name shown in gui]" -/// value="[default entity key value]" -/// >[comment text shown in gui] -/// -/// each attribute type has a specialised attribute-editor GUI -/// -/// currently-supported attribute types: -/// -/// string a string -/// array an array of strings - value is a semi-colon-delimited string -/// integer an integer value -/// boolean an integer - shows as a checkbox - true = non-zero -/// integer2 two integer values -/// integer3 three integer values -/// real3 three floating-point values -/// angle specialisation of real - Yaw angle -/// direction specialisation of real - Yaw angle, -1 = down, -2 = up -/// angles specialisation of real3 - Pitch Yaw Roll -/// color specialisation of real3 - RGB floating-point colour -/// target a string that uniquely identifies an entity or group of entities -/// targetname a string that uniquely identifies an entity or group of entities -/// sound the VFS path to a sound file -/// texture the VFS path to a texture file or a shader name -/// model the VFS path to a model file -/// skin the VFS path to a skin file -/// -/// -/// flag attributes define a flag in the "spawnflags" key: -/// -/// [comment text shown in gui] -/// -/// the default value for a flag bit is always 0. -/// -/// -/// List attributes have a set of valid values. -/// Create new list attribute types like this: -/// -/// -/// -/// -/// -/// -/// these can then be used as attribute types. -/// -/// -/// An attribute definition should specify a default value that corresponds -/// with the default value given by the game. If the default value is not -/// specified in the attribute definition, it is assumed to be an empty string. -/// -/// If the currently-selected entity in Radiant does not specify a value for -/// the key of an attribute, the default value from the attribute-definition -/// will be displayed in the attribute-editor and used when visualising the -/// entity in the preview windows. E.g. the Doom3 "light" entity has a -/// "light_radius" key. Light entities without a "light_radius" key are -/// displayed in Doom3 with a radius of 300. The default value for the -/// "light_radius" attribute definition should be specified as "300 300 300". -/// - - - - -#include "eclass_xml.h" - -#include "ieclass.h" -#include "irender.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "xml/xmlparser.h" -#include "generic/object.h" -#include "generic/reference.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "eclasslib.h" -#include "modulesystem/moduleregistry.h" -#include "stringio.h" - -#define PARSE_ERROR(elementName, name) makeQuoted( elementName ) << " is not a valid child of " << makeQuoted( name ) - -class IgnoreBreaks { -public: -const char *m_first; -const char *m_last; - -IgnoreBreaks(const char *first, const char *last) : m_first(first), m_last(last) -{ -} -}; - -template -TextOutputStreamType &ostream_write(TextOutputStreamType &ostream, const IgnoreBreaks &ignoreBreaks) -{ - for (const char *i = ignoreBreaks.m_first; i != ignoreBreaks.m_last; ++i) { - if (*i != '\n') { - ostream << *i; - } - } - return ostream; -} - -namespace { - -class TreeXMLImporter : public TextOutputStream { -public: -virtual TreeXMLImporter &pushElement(const XMLElement &element) = 0; - -virtual void popElement(const char *name) = 0; -}; - -template -class Storage { -char m_storage[sizeof(Type)]; -public: -Type &get() -{ - return *reinterpret_cast( m_storage ); -} - -const Type &get() const -{ - return *reinterpret_cast( m_storage ); -} -}; - -class BreakImporter : public TreeXMLImporter { -public: -BreakImporter(StringOutputStream &comment) -{ - comment << '\n'; -} - -static const char *name() -{ - return "n"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class AttributeImporter : public TreeXMLImporter { -StringOutputStream &m_comment; - -public: -AttributeImporter(StringOutputStream &comment, EntityClass *entityClass, const XMLElement &element) : m_comment( - comment) -{ - const char *type = element.name(); - const char *key = element.attribute("key"); - const char *name = element.attribute("name"); - const char *value = element.attribute("value"); - - ASSERT_MESSAGE(!string_empty(key), "key attribute not specified"); - ASSERT_MESSAGE(!string_empty(name), "name attribute not specified"); - - if (string_equal(type, "flag")) { - std::size_t bit = atoi(element.attribute("bit")); - ASSERT_MESSAGE(bit < MAX_FLAGS, "invalid flag bit"); - ASSERT_MESSAGE(string_empty(entityClass->flagnames[bit]), "non-unique flag bit"); - strcpy(entityClass->flagnames[bit], key); - } - - m_comment << key; - m_comment << " : "; - - EntityClass_insertAttribute(*entityClass, key, EntityClassAttribute(type, name, value)); -} - -~AttributeImporter() -{ -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), "attribute")); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, "attribute")); -} - -std::size_t write(const char *data, std::size_t length) -{ - return m_comment.write(data, length); -} -}; - -bool attributeSupported(const char *name) -{ - return string_equal(name, "real") - || string_equal(name, "integer") - || string_equal(name, "boolean") - || string_equal(name, "string") - || string_equal(name, "array") - || string_equal(name, "flag") - || string_equal(name, "real3") - || string_equal(name, "integer3") - || string_equal(name, "direction") - || string_equal(name, "angle") - || string_equal(name, "angles") - || string_equal(name, "color") - || string_equal(name, "target") - || string_equal(name, "targetname") - || string_equal(name, "sound") - || string_equal(name, "texture") - || string_equal(name, "model") - || string_equal(name, "skin") - || string_equal(name, "integer2"); -} - -typedef std::map ListAttributeTypes; - -bool listAttributeSupported(ListAttributeTypes &listTypes, const char *name) -{ - return listTypes.find(name) != listTypes.end(); -} - - -class ClassImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -EntityClass *m_eclass; -StringOutputStream m_comment; -Storage m_attribute; -ListAttributeTypes &m_listTypes; - -public: -ClassImporter(EntityClassCollector &collector, ListAttributeTypes &listTypes, const XMLElement &element) - : m_collector(collector), m_listTypes(listTypes) -{ - m_eclass = Eclass_Alloc(); - m_eclass->free = &Eclass_Free; - - const char *name = element.attribute("name"); - ASSERT_MESSAGE(!string_empty(name), "name attribute not specified for class"); - m_eclass->m_name = name; - - const char *color = element.attribute("color"); - ASSERT_MESSAGE(!string_empty(name), "color attribute not specified for class " << name); - string_parse_vector3(color, m_eclass->color); - eclass_capture_state(m_eclass); - - const char *model = element.attribute("model"); - if (!string_empty(model)) { - StringOutputStream buffer(256); - buffer << PathCleaned(model); - m_eclass->m_modelpath = buffer.c_str(); - } - - const char *type = element.name(); - if (string_equal(type, "point")) { - const char *box = element.attribute("box"); - ASSERT_MESSAGE(!string_empty(box), "box attribute not found for class " << name); - m_eclass->fixedsize = true; - string_parse_vector(box, &m_eclass->mins.x(), &m_eclass->mins.x() + 6); - } -} - -~ClassImporter() -{ - m_eclass->m_comments = m_comment.c_str(); - m_collector.insert(m_eclass); - - for (ListAttributeTypes::iterator i = m_listTypes.begin(); i != m_listTypes.end(); ++i) { - m_collector.insert((*i).first.c_str(), (*i).second); - } -} - -static const char *name() -{ - return "class"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (attributeSupported(element.name()) || listAttributeSupported(m_listTypes, element.name())) { - constructor(m_attribute.get(), makeReference(m_comment), m_eclass, element); - return m_attribute.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (attributeSupported(elementName) || listAttributeSupported(m_listTypes, elementName)) { - destructor(m_attribute.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return m_comment.write(data, length); -} -}; - -class ItemImporter : public TreeXMLImporter { -public: -ItemImporter(ListAttributeType &list, const XMLElement &element) -{ - const char *name = element.attribute("name"); - const char *value = element.attribute("value"); - list.push_back(name, value); -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), "item")); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, "item")); -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -bool isItem(const char *name) -{ - return string_equal(name, "item"); -} - -class ListAttributeImporter : public TreeXMLImporter { -ListAttributeType *m_listType; -Storage m_item; -public: -ListAttributeImporter(ListAttributeTypes &listTypes, const XMLElement &element) -{ - const char *name = element.attribute("name"); - m_listType = &listTypes[name]; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (isItem(element.name())) { - constructor(m_item.get(), makeReference(*m_listType), element); - return m_item.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), "list")); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (isItem(elementName)) { - destructor(m_item.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, "list")); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -bool classSupported(const char *name) -{ - return string_equal(name, "group") - || string_equal(name, "point"); -} - -bool listSupported(const char *name) -{ - return string_equal(name, "list"); -} - -class ClassesImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -Storage m_class; -Storage m_list; -ListAttributeTypes m_listTypes; - -public: -ClassesImporter(EntityClassCollector &collector) : m_collector(collector) -{ -} - -static const char *name() -{ - return "classes"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (classSupported(element.name())) { - constructor(m_class.get(), makeReference(m_collector), makeReference(m_listTypes), element); - return m_class.get(); - } else if (listSupported(element.name())) { - constructor(m_list.get(), makeReference(m_listTypes), element); - return m_list.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (classSupported(elementName)) { - destructor(m_class.get()); - } else if (listSupported(elementName)) { - destructor(m_list.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class EclassXMLImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -Storage m_classes; - -public: -EclassXMLImporter(EntityClassCollector &collector) : m_collector(collector) -{ -} - -static const char *name() -{ - return "classes"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), ClassesImporter::name())) { - constructor(m_classes.get(), makeReference(m_collector)); - return m_classes.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (string_equal(elementName, ClassesImporter::name())) { - destructor(m_classes.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class TreeXMLImporterStack : public XMLImporter { -std::vector > m_importers; -public: -TreeXMLImporterStack(TreeXMLImporter &importer) -{ - m_importers.push_back(makeReference(importer)); -} - -void pushElement(const XMLElement &element) -{ - m_importers.push_back(makeReference(m_importers.back().get().pushElement(element))); -} - -void popElement(const char *name) -{ - m_importers.pop_back(); - m_importers.back().get().popElement(name); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_importers.back().get().write(buffer, length); -} -}; - - -const char *GetExtension() -{ - return "ent"; -} - -void ScanFile(EntityClassCollector &collector, const char *filename) -{ - TextFileInputStream inputFile(filename); - if (!inputFile.failed()) { - XMLStreamParser parser(inputFile); - - EclassXMLImporter importer(collector); - TreeXMLImporterStack stack(importer); - parser.exportXML(stack); - } -} - - -} - -#include "modulesystem/singletonmodule.h" - -class EntityClassXMLDependencies : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef { -}; - -class EclassXMLAPI { -EntityClassScanner m_eclassxml; -public: -typedef EntityClassScanner Type; - -STRING_CONSTANT(Name, "xml"); - -EclassXMLAPI() -{ - m_eclassxml.scanFile = &ScanFile; - m_eclassxml.getExtension = &GetExtension; -} - -EntityClassScanner *getTable() -{ - return &m_eclassxml; -} -}; - -typedef SingletonModule EclassXMLModule; -typedef Static StaticEclassXMLModule; -StaticRegisterModule staticRegisterEclassXML(StaticEclassXMLModule::instance()); diff --git a/src/eclass_xml.h b/src/eclass_xml.h deleted file mode 100644 index 9b6f9dd..0000000 --- a/src/eclass_xml.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_XML_H ) -#define INCLUDED_ECLASS_XML_H - -#endif diff --git a/src/entity.cpp b/src/entity.cpp deleted file mode 100644 index 5c8342b..0000000 --- a/src/entity.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entity.h" - -#include "ientity.h" -#include "iselection.h" -#include "imodel.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "editable.h" - -#include "eclasslib.h" -#include "scenelib.h" -#include "os/path.h" -#include "os/file.h" -#include "stream/stringstream.h" -#include "stringio.h" - -#include "gtkutil/filechooser.h" -#include "gtkmisc.h" -#include "select.h" -#include "map.h" -#include "preferences.h" -#include "gtkdlgs.h" -#include "mainframe.h" -#include "qe3.h" -#include "commands.h" - -#include "uilib/uilib.h" - -struct entity_globals_t { - Vector3 color_entity; - - entity_globals_t() : - color_entity(0.0f, 0.0f, 0.0f) - { - } -}; - -entity_globals_t g_entity_globals; - -class EntitySetKeyValueSelected : public scene::Graph::Walker { -const char *m_key; -const char *m_value; -public: -EntitySetKeyValueSelected(const char *key, const char *value) - : m_key(key), m_value(value) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) { - entity->setKeyValue(m_key, m_value); - } -} -}; - -class EntitySetClassnameSelected : public scene::Graph::Walker { -const char *m_classname; -public: -EntitySetClassnameSelected(const char *classname) - : m_classname(classname) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) { - NodeSmartReference node(GlobalEntityCreator().createEntity( - GlobalEntityClassManager().findOrInsert(m_classname, node_is_group(path.top())))); - - EntityCopyingVisitor visitor(*Node_getEntity(node)); - - entity->forEachKeyValue(visitor); - - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - Node_getTraversable(parent)->erase(child); - if (Node_getTraversable(child) != 0 - && Node_getTraversable(node) != 0 - && node_is_group(node)) { - parentBrushes(child, node); - } - Node_getTraversable(parent)->insert(node); - } -} -}; - -void Scene_EntitySetKeyValue_Selected(const char *key, const char *value) -{ - GlobalSceneGraph().traverse(EntitySetKeyValueSelected(key, value)); -} - -void Scene_EntitySetClassname_Selected(const char *classname) -{ - GlobalSceneGraph().traverse(EntitySetClassnameSelected(classname)); -} - -/* to worldspawn */ -void Entity_ungroupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("ungroupSelectedEntities"); - - /* to auto-select */ - /*scene::Path entitypath(makeReference(GlobalSceneGraph().root())); - scene::Instance& einstance = findInstance(entitypath);*/ - - while (GlobalSelectionSystem().countSelected()) { - scene::Path world_path(makeReference(GlobalSceneGraph().root())); - world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map))); - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - scene::Path path = instance.path(); - - /* remove it from the path if its not an ent? */ - if (!Node_isEntity(path.top())) { - path.pop(); - } - - /* we'll cause a crash otherwise */ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 && entity->getEntityClass().fixedsize) { - /* Unselect us */ - Instance_setSelected(instance, false); - continue; - } - - /* this will sadly unselect anything it touches (merge to world) */ - if (entity != 0 && node_is_group(path.top())) { - if (world_path.top().get_pointer() != path.top().get_pointer()) { - parentBrushes(path.top(), world_path.top()); - Path_deleteTop(path); - } - } - } - - /*Scene_forEachChildSelectable(SelectableSetSelected(true), einstance.path());*/ -} - - -class EntityFindSelected : public scene::Graph::Walker { -public: -mutable const scene::Path *groupPath; -mutable scene::Instance *groupInstance; - -EntityFindSelected() : groupPath(0), groupInstance(0) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && Instance_getSelectable(instance)->isSelected() - && node_is_group(path.top()) - && !groupPath) { - groupPath = &path; - groupInstance = &instance; - } -} -}; - -class EntityGroupSelected : public scene::Graph::Walker { -NodeSmartReference group, worldspawn; -//typedef std::pair DeletionPair; -//Stack deleteme; -public: -EntityGroupSelected(const scene::Path &p) : group(p.top().get()), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - - if (selectable && selectable->isSelected()) { - Entity *entity = Node_getEntity(path.top()); - if (entity == 0 && Node_isPrimitive(path.top())) { - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - - if (path.size() >= 3 && parent != worldspawn) { - NodeSmartReference parentparent(path[path.size() - 3].get()); - - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); - - if (Node_getTraversable(parent)->empty()) { - //deleteme.push(DeletionPair(parentparent, parent)); - Node_getTraversable(parentparent)->erase(parent); - } - } else { - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); - } - } - } -} -}; - -void Scene_DeleteEmpty(); -void Entity_groupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("groupSelectedEntities"); - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strClassname = entity->getKeyValue("classname"); - if (!string_empty(strClassname)) { - Entity_createFromSelection(strClassname, g_vector3_identity); - } - } -} - -void Entity_groupMake() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("entityCreate -class func_group" ); - Entity_createFromSelection("func_group", g_vector3_identity); - /*Scene_DeleteEmpty();*/ -} - - -void Entity_connectSelected() -{ - if (GlobalSelectionSystem().countSelected() == 2) { - GlobalEntityCreator().connectEntities( - GlobalSelectionSystem().penultimateSelected().path(), - GlobalSelectionSystem().ultimateSelected().path(), - 0 - ); - } else { - globalErrorStream() << "entityConnectSelected: exactly two instances must be selected\n"; - } -} - -void Entity_killconnectSelected() -{ - if (GlobalSelectionSystem().countSelected() == 2) { - GlobalEntityCreator().connectEntities( - GlobalSelectionSystem().penultimateSelected().path(), - GlobalSelectionSystem().ultimateSelected().path(), - 1 - ); - } else { - globalErrorStream() << "entityKillConnectSelected: exactly two instances must be selected\n"; - } -} - -AABB Doom3Light_getBounds(const AABB &workzone) -{ - AABB aabb(workzone); - - Vector3 defaultRadius(300, 300, 300); - if (!string_parse_vector3( - EntityClass_valueForKey(*GlobalEntityClassManager().findOrInsert("light", false), "light_radius"), - defaultRadius)) { - globalErrorStream() << "Doom3Light_getBounds: failed to parse default light radius\n"; - } - - if (aabb.extents[0] == 0) { - aabb.extents[0] = defaultRadius[0]; - } - if (aabb.extents[1] == 0) { - aabb.extents[1] = defaultRadius[1]; - } - if (aabb.extents[2] == 0) { - aabb.extents[2] = defaultRadius[2]; - } - - if (aabb_valid(aabb)) { - return aabb; - } - return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64)); -} - -int g_iLastLightIntensity; - -bool -Entity_isModelEntity(const char *name) -{ - if (string_equal_nocase(name, "prop_static")) - return true; - else if (string_equal_nocase(name, "prop_dynamic")) - return true; - - return false; -} - -void Entity_createFromSelection(const char *name, const Vector3 &origin) -{ - EntityClass *entityClass = GlobalEntityClassManager().findOrInsert(name, true); - - bool isModel = Entity_isModelEntity(name); - bool brushesSelected = Scene_countSelectedBrushes(GlobalSceneGraph()) != 0; - - if (!(entityClass->fixedsize || isModel) && !brushesSelected) { - globalErrorStream() << "failed to create a group entity - no brushes are selected\n"; - return; - } - - AABB workzone(aabb_for_minmax(Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max)); - - /* this is where ghost entities happen */ - NodeSmartReference node(GlobalEntityCreator().createEntity(entityClass)); - Node_getTraversable(GlobalSceneGraph().root())->insert(node); - scene::Path entitypath(makeReference(GlobalSceneGraph().root())); - entitypath.push(makeReference(node.get())); - scene::Instance& instance = findInstance(entitypath); - - if (entityClass->fixedsize) - { - Select_Delete(); - Transformable* transform = Instance_getTransformable(instance); - if(transform != 0) - { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setTranslation(origin); - transform->freezeTransform(); - } - - GlobalSelectionSystem().setSelectedAll(false); - Instance_setSelected(instance, true); - } else { - Scene_parentSelectedBrushesToEntity(GlobalSceneGraph(), node); - Scene_forEachChildSelectable(SelectableSetSelected(true), instance.path()); - Scene_DeleteEmpty(); - } - - // tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box - // see SF bug 105383 - - if (g_pGameDescription->mGameType == "hl") { - // FIXME - Hydra: really we need a combined light AND color dialog for halflife. - if (string_equal_nocase(name, "light") - || string_equal_nocase(name, "light_environment") - || string_equal_nocase(name, "light_spot")) { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg(&intensity) == eIDOK) { - g_iLastLightIntensity = intensity; - char buf[30]; - sprintf(buf, "255 255 255 %d", intensity); - Node_getEntity(node)->setKeyValue("_light", buf); - } - } - } else if (string_equal_nocase(name, "light")) { - if (g_pGameDescription->mGameType != "doom3") { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg(&intensity) == eIDOK) { - g_iLastLightIntensity = intensity; - char buf[10]; - sprintf(buf, "%d", intensity); - Node_getEntity(node)->setKeyValue("light", buf); - } - } else if (brushesSelected) { // use workzone to set light position/size for doom3 lights, if there are brushes selected - AABB bounds(Doom3Light_getBounds(workzone)); - StringOutputStream key(64); - key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2]; - Node_getEntity(node)->setKeyValue("origin", key.c_str()); - key.clear(); - key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2]; - Node_getEntity(node)->setKeyValue("light_radius", key.c_str()); - } - } - - if (isModel) { - const char *model = misc_model_dialog(MainFrame_getWindow()); - if (model != 0) { - Node_getEntity(node)->setKeyValue("model", model); - } - } -} - -#if 0 -bool DoNormalisedColor( Vector3& color ){ - if ( !color_dialog( MainFrame_getWindow( ), color ) ) { - return false; - } - /* - ** scale colors so that at least one component is at 1.0F - */ - - float largest = 0.0F; - - if ( color[0] > largest ) { - largest = color[0]; - } - if ( color[1] > largest ) { - largest = color[1]; - } - if ( color[2] > largest ) { - largest = color[2]; - } - - if ( largest == 0.0F ) { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } - else - { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } - - return true; -} -#endif - -void NormalizeColor(Vector3 &color) -{ - // scale colors so that at least one component is at 1.0F - - float largest = 0.0F; - - if (color[0] > largest) { - largest = color[0]; - } - if (color[1] > largest) { - largest = color[1]; - } - if (color[2] > largest) { - largest = color[2]; - } - - if (largest == 0.0F) { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } else { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } -} - -void Entity_normalizeColor() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strColor = entity->getKeyValue("_color"); - if (!string_empty(strColor)) { - Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) { - g_entity_globals.color_entity = rgb; - NormalizeColor(g_entity_globals.color_entity); - - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); - - Scene_EntitySetKeyValue_Selected("_color", buffer); - } - } - } - } -} - -void Entity_setColour() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - bool normalize = false; - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strColor = entity->getKeyValue("_color"); - if (!string_empty(strColor)) { - Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) { - g_entity_globals.color_entity = rgb; - } - } - - if (color_dialog(MainFrame_getWindow(), g_entity_globals.color_entity)) { - if (normalize) { - NormalizeColor(g_entity_globals.color_entity); - } - - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); - - Scene_EntitySetKeyValue_Selected("_color", buffer); - } - } - } -} - -const char *misc_model_dialog(ui::Widget parent) -{ - StringOutputStream buffer(1024); - - buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; - - if (!file_readable(buffer.c_str())) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str() << "/"; - } - - const char *filename = parent.file_dialog(TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name()); - if (filename != 0) { - // use VFS to get the correct relative path - const char *relative = path_make_relative(filename, GlobalFileSystem().findRoot(filename)); - if (relative == filename) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - return relative; - } - return 0; -} - -struct LightRadii { - static void Export(const EntityCreator &self, const Callback &returnz) - { - returnz(self.getLightRadii()); - } - - static void Import(EntityCreator &self, bool value) - { - self.setLightRadii(value); - } -}; - -void Entity_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "Show", "Light Radii", - make_property(GlobalEntityCreator()) - ); -} - -void Entity_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Entities", "Entity Display Preferences")); - Entity_constructPreferences(page); -} - -void Entity_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Entity_constructPage)); -} - - -void Entity_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "_To Worldspawn", "UngroupSelection"); - create_menu_item_with_mnemonic(menu, "_Regroup", "GroupSelection"); - create_menu_item_with_mnemonic(menu, "_Connect", "ConnectSelection"); - create_menu_item_with_mnemonic(menu, "_KillConnect", "KillConnectSelection"); - create_menu_item_with_mnemonic(menu, "_Select Color...", "EntityColor"); - create_menu_item_with_mnemonic(menu, "_Normalize Color...", "NormalizeColor"); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void Entity_Construct() -{ - GlobalCommands_insert("EntityColor", makeCallbackF(Entity_setColour), Accelerator('K')); - GlobalCommands_insert("NormalizeColor", makeCallbackF(Entity_normalizeColor)); - GlobalCommands_insert("ConnectSelection", makeCallbackF(Entity_connectSelected), - Accelerator('K', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("KillConnectSelection", makeCallbackF(Entity_killconnectSelected), - Accelerator('K', (GdkModifierType) (GDK_SHIFT_MASK))); - GlobalCommands_insert("GroupSelection", makeCallbackF(Entity_groupSelected)); - GlobalCommands_insert("UngroupSelection", makeCallbackF(Entity_ungroupSelected)); - GlobalCommands_insert("CreateFuncGroup", makeCallbackF(Entity_groupMake)); - - GlobalPreferenceSystem().registerPreference("SI_Colors5", make_property_string(g_entity_globals.color_entity)); - GlobalPreferenceSystem().registerPreference("LastLightIntensity", make_property_string(g_iLastLightIntensity)); - - Entity_registerPreferencesPage(); -} - -void Entity_Destroy() -{ -} diff --git a/src/entity.h b/src/entity.h deleted file mode 100644 index a2a9f75..0000000 --- a/src/entity.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITY_H ) -#define INCLUDED_ENTITY_H - -#include - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -void Entity_createFromSelection(const char *name, const Vector3 &origin); - -void Scene_EntitySetKeyValue_Selected(const char *key, const char *value); - -void Scene_EntitySetClassname_Selected(const char *classname); - - -const char *misc_model_dialog(ui::Widget parent); - -void Entity_constructMenu(ui::Menu menu); - -void Entity_Construct(); - -void Entity_Destroy(); - -#endif diff --git a/src/entityinspector.cpp b/src/entityinspector.cpp deleted file mode 100644 index d398d73..0000000 --- a/src/entityinspector.cpp +++ /dev/null @@ -1,1756 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entityinspector.h" - -#include "debugging/debugging.h" -#include - -#include "ientity.h" -#include "ifilesystem.h" -#include "imodel.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "iundo.h" - -#include -#include -#include -#include - - -#include "os/path.h" -#include "eclasslib.h" -#include "scenelib.h" -#include "generic/callback.h" -#include "os/file.h" -#include "stream/stringstream.h" -#include "moduleobserver.h" -#include "convert.h" -#include "stringio.h" - -#include "gtkutil/accelerator.h" -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/button.h" -#include "gtkutil/entry.h" -#include "gtkutil/container.h" - -#include "qe3.h" -#include "gtkmisc.h" -#include "gtkdlgs.h" -#include "entity.h" -#include "mainframe.h" -#include "textureentry.h" -#include "groupdialog.h" - -ui::Entry numeric_entry_new() -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(64, -1); - return entry; -} - -namespace { -typedef std::map KeyValues; -KeyValues g_selectedKeyValues; -KeyValues g_selectedDefaultKeyValues; -} - -const char *SelectedEntity_getValueForKey(const char *key) -{ - { - KeyValues::const_iterator i = g_selectedKeyValues.find(key); - if (i != g_selectedKeyValues.end()) { - return (*i).second.c_str(); - } - } - { - KeyValues::const_iterator i = g_selectedDefaultKeyValues.find(key); - if (i != g_selectedDefaultKeyValues.end()) { - return (*i).second.c_str(); - } - } - return ""; -} - -void Scene_EntitySetKeyValue_Selected_Undoable(const char *key, const char *value) -{ - StringOutputStream command(256); - command << "entitySetKeyValue -key " << makeQuoted(key) << " -value " << makeQuoted(value); - UndoableCommand undo(command.c_str()); - Scene_EntitySetKeyValue_Selected(key, value); -} - -class EntityAttribute { -public: -virtual ~EntityAttribute() = default; - -virtual ui::Widget getWidget() const = 0; - -virtual void update() = 0; - -virtual void release() = 0; -}; - -class BooleanAttribute : public EntityAttribute { -CopiedString m_key; -ui::CheckButton m_check; - -static gboolean toggled(ui::Widget widget, BooleanAttribute *self) -{ - self->apply(); - return FALSE; -} - -public: -BooleanAttribute(const char *key) : - m_key(key), - m_check(ui::null) -{ - auto check = ui::CheckButton(ui::New); - check.show(); - - m_check = check; - - guint handler = check.connect("toggled", G_CALLBACK(toggled), this); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler)); - - update(); -} - -ui::Widget getWidget() const -{ - return m_check; -} - -void release() -{ - delete this; -} - -void apply() -{ - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), m_check.active() ? "1" : "0"); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - toggle_button_set_active_no_signal(m_check, atoi(value) != 0); - } else { - toggle_button_set_active_no_signal(m_check, false); - } -} - -typedef MemberCaller UpdateCaller; -}; - - -class StringAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -public: -StringAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(50, -1); - - m_entry = entry; - m_nonModal.connect(m_entry); -} - -ui::Widget getWidget() const -{ - return m_entry; -} - -ui::Entry getEntry() const -{ - return m_entry; -} - -void release() -{ - delete this; -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; -}; - -class ShaderAttribute : public StringAttribute { -public: -ShaderAttribute(const char *key) : StringAttribute(key) -{ - GlobalShaderEntryCompletion::instance().connect(StringAttribute::getEntry()); -} -}; - - -class ModelAttribute : public EntityAttribute { -CopiedString m_key; -BrowsedPathEntry m_entry; -NonModalEntry m_nonModal; -public: -ModelAttribute(const char *key) : - m_key(key), - m_entry(BrowseCaller(*this)), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_nonModal.connect(m_entry.m_entry.m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return m_entry.m_entry.m_frame; -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.m_entry.m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.m_entry.m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; - -void browse(const BrowsedPathEntry::SetPathCallback &setPath) -{ - const char *filename = misc_model_dialog(m_entry.m_entry.m_frame.window()); - - if (filename != 0) { - setPath(filename); - apply(); - } -} - -typedef MemberCaller BrowseCaller; -}; - -const char *browse_sound(ui::Widget parent) -{ - StringOutputStream buffer(1024); - - buffer << g_qeglobals.m_userGamePath.c_str() << "sound/"; - - if (!file_readable(buffer.c_str())) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str() << "/"; - } - - const char *filename = parent.file_dialog(TRUE, "Open Wav File", buffer.c_str(), "sound"); - if (filename != 0) { - const char *relative = path_make_relative(filename, GlobalFileSystem().findRoot(filename)); - if (relative == filename) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - return relative; - } - return filename; -} - -class SoundAttribute : public EntityAttribute { -CopiedString m_key; -BrowsedPathEntry m_entry; -NonModalEntry m_nonModal; -public: -SoundAttribute(const char *key) : - m_key(key), - m_entry(BrowseCaller(*this)), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_nonModal.connect(m_entry.m_entry.m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_entry.m_entry.m_frame); -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.m_entry.m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.m_entry.m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; - -void browse(const BrowsedPathEntry::SetPathCallback &setPath) -{ - const char *filename = browse_sound(m_entry.m_entry.m_frame.window()); - - if (filename != 0) { - setPath(filename); - apply(); - } -} - -typedef MemberCaller BrowseCaller; -}; - -inline double angle_normalised(double angle) -{ - return float_mod(angle, 360.0); -} - -class AngleAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -public: -AngleAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - auto entry = numeric_entry_new(); - m_entry = entry; - m_nonModal.connect(m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_entry); -} - -void apply() -{ - StringOutputStream angle(32); - angle << angle_normalised(entry_get_float(m_entry)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angle.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - StringOutputStream angle(32); - angle << angle_normalised(atof(value)); - m_entry.text(angle.c_str()); - } else { - m_entry.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -namespace { -typedef const char *String; -const String buttons[] = {"up", "down", "z-axis"}; -} - -class DirectionAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -RadioHBox m_radio; -NonModalRadio m_nonModalRadio; -ui::HBox m_hbox{ui::null}; -public: -DirectionAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)), - m_radio(RadioHBox_new(STRING_ARRAY_RANGE(buttons))), - m_nonModalRadio(ApplyRadioCaller(*this)) -{ - auto entry = numeric_entry_new(); - m_entry = entry; - m_nonModal.connect(m_entry); - - m_nonModalRadio.connect(m_radio.m_radio); - - m_hbox = ui::HBox(FALSE, 4); - m_hbox.show(); - - m_hbox.pack_start(m_radio.m_hbox, TRUE, TRUE, 0); - m_hbox.pack_start(m_entry, TRUE, TRUE, 0); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream angle(32); - angle << angle_normalised(entry_get_float(m_entry)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angle.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - float f = float(atof(value)); - if (f == -1) { - gtk_widget_set_sensitive(m_entry, FALSE); - radio_button_set_active_no_signal(m_radio.m_radio, 0); - m_entry.text(""); - } else if (f == -2) { - gtk_widget_set_sensitive(m_entry, FALSE); - radio_button_set_active_no_signal(m_radio.m_radio, 1); - m_entry.text(""); - } else { - gtk_widget_set_sensitive(m_entry, TRUE); - radio_button_set_active_no_signal(m_radio.m_radio, 2); - StringOutputStream angle(32); - angle << angle_normalised(f); - m_entry.text(angle.c_str()); - } - } else { - m_entry.text("0"); - } -} - -typedef MemberCaller UpdateCaller; - -void applyRadio() -{ - int index = radio_button_get_active(m_radio.m_radio); - if (index == 0) { - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), "-1"); - } else if (index == 1) { - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), "-2"); - } else if (index == 2) { - apply(); - } -} - -typedef MemberCaller ApplyRadioCaller; -}; - - -class AnglesEntry { -public: -ui::Entry m_roll; -ui::Entry m_pitch; -ui::Entry m_yaw; - -AnglesEntry() : m_roll(ui::null), m_pitch(ui::null), m_yaw(ui::null) -{ -} -}; - -typedef BasicVector3 DoubleVector3; - -class AnglesAttribute : public EntityAttribute { -CopiedString m_key; -AnglesEntry m_angles; -NonModalEntry m_nonModal; -ui::HBox m_hbox; -public: -AnglesAttribute(const char *key) : - m_key(key), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)), - m_hbox(ui::HBox(TRUE, 4)) -{ - m_hbox.show(); - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_pitch = entry; - m_nonModal.connect(m_angles.m_pitch); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_yaw = entry; - m_nonModal.connect(m_angles.m_yaw); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_roll = entry; - m_nonModal.connect(m_angles.m_roll); - } -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream angles(64); - angles << angle_normalised(entry_get_float(m_angles.m_pitch)) - << " " << angle_normalised(entry_get_float(m_angles.m_yaw)) - << " " << angle_normalised(entry_get_float(m_angles.m_roll)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angles.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream angle(32); - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - DoubleVector3 pitch_yaw_roll; - if (!string_parse_vector3(value, pitch_yaw_roll)) { - pitch_yaw_roll = DoubleVector3(0, 0, 0); - } - - angle << angle_normalised(pitch_yaw_roll.x()); - m_angles.m_pitch.text(angle.c_str()); - angle.clear(); - - angle << angle_normalised(pitch_yaw_roll.y()); - m_angles.m_yaw.text(angle.c_str()); - angle.clear(); - - angle << angle_normalised(pitch_yaw_roll.z()); - m_angles.m_roll.text(angle.c_str()); - angle.clear(); - } else { - m_angles.m_pitch.text("0"); - m_angles.m_yaw.text("0"); - m_angles.m_roll.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -class Vector3Entry { -public: -ui::Entry m_x; -ui::Entry m_y; -ui::Entry m_z; - -Vector3Entry() : m_x(ui::null), m_y(ui::null), m_z(ui::null) -{ -} -}; - -class Vector3Attribute : public EntityAttribute { -CopiedString m_key; -Vector3Entry m_vector3; -NonModalEntry m_nonModal; -ui::Box m_hbox{ui::null}; -public: -Vector3Attribute(const char *key) : - m_key(key), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_hbox = ui::HBox(TRUE, 4); - m_hbox.show(); - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_x = entry; - m_nonModal.connect(m_vector3.m_x); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_y = entry; - m_nonModal.connect(m_vector3.m_y); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_z = entry; - m_nonModal.connect(m_vector3.m_z); - } -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream vector3(64); - vector3 << entry_get_float(m_vector3.m_x) - << " " << entry_get_float(m_vector3.m_y) - << " " << entry_get_float(m_vector3.m_z); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), vector3.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream buffer(32); - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - DoubleVector3 x_y_z; - if (!string_parse_vector3(value, x_y_z)) { - x_y_z = DoubleVector3(0, 0, 0); - } - - buffer << x_y_z.x(); - m_vector3.m_x.text(buffer.c_str()); - buffer.clear(); - - buffer << x_y_z.y(); - m_vector3.m_y.text(buffer.c_str()); - buffer.clear(); - - buffer << x_y_z.z(); - m_vector3.m_z.text(buffer.c_str()); - buffer.clear(); - } else { - m_vector3.m_x.text("0"); - m_vector3.m_y.text("0"); - m_vector3.m_z.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -class NonModalComboBox { -Callback m_changed; -guint m_changedHandler; - -static gboolean changed(ui::ComboBox widget, NonModalComboBox *self) -{ - self->m_changed(); - return FALSE; -} - -public: -NonModalComboBox(const Callback &changed) : m_changed(changed), m_changedHandler(0) -{ -} - -void connect(ui::ComboBox combo) -{ - m_changedHandler = combo.connect("changed", G_CALLBACK(changed), this); -} - -void setActive(ui::ComboBox combo, int value) -{ - g_signal_handler_disconnect(G_OBJECT(combo), m_changedHandler); - gtk_combo_box_set_active(combo, value); - connect(combo); -} -}; - -class ListAttribute : public EntityAttribute { -CopiedString m_key; -ui::ComboBox m_combo; -NonModalComboBox m_nonModal; -const ListAttributeType &m_type; -public: -ListAttribute(const char *key, const ListAttributeType &type) : - m_key(key), - m_combo(ui::null), - m_nonModal(ApplyCaller(*this)), - m_type(type) -{ - auto combo = ui::ComboBoxText(ui::New); - - for (ListAttributeType::const_iterator i = type.begin(); i != type.end(); ++i) { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), (*i).first.c_str()); - } - - combo.show(); - m_nonModal.connect(combo); - - m_combo = combo; -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_combo); -} - -void apply() -{ - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), - m_type[gtk_combo_box_get_active(m_combo)].second.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - ListAttributeType::const_iterator i = m_type.findValue(value); - if (i != m_type.end()) { - m_nonModal.setActive(m_combo, static_cast( std::distance(m_type.begin(), i))); - } else { - m_nonModal.setActive(m_combo, 0); - } -} - -typedef MemberCaller UpdateCaller; -}; - - -namespace { -ui::Widget g_entity_split1{ui::null}; -ui::Widget g_entity_split2{ui::null}; -int g_entitysplit1_position; -int g_entitysplit2_position; - -bool g_entityInspector_windowConstructed = false; - -ui::TreeView g_entityClassList{ui::null}; -ui::TextView g_entityClassComment{ui::null}; - -GtkCheckButton *g_entitySpawnflagsCheck[MAX_FLAGS]; - -ui::Entry g_entityKeyEntry{ui::null}; -ui::Entry g_entityValueEntry{ui::null}; - -ui::ListStore g_entlist_store{ui::null}; -ui::ListStore g_entprops_store{ui::null}; -const EntityClass *g_current_flags = 0; -const EntityClass *g_current_comment = 0; -const EntityClass *g_current_attributes = 0; - -// the number of active spawnflags -int g_spawnflag_count; -// table: index, match spawnflag item to the spawnflag index (i.e. which bit) -int spawn_table[MAX_FLAGS]; -// we change the layout depending on how many spawn flags we need to display -// the table is a 4x4 in which we need to put the comment box g_entityClassComment and the spawn flags.. -ui::Table g_spawnflagsTable{ui::null}; - -ui::VBox g_attributeBox{ui::null}; -typedef std::vector EntityAttributes; -EntityAttributes g_entityAttributes; -} - -void GlobalEntityAttributes_clear() -{ - for (EntityAttributes::iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i) { - (*i)->release(); - } - g_entityAttributes.clear(); -} - -class GetKeyValueVisitor : public Entity::Visitor { -KeyValues &m_keyvalues; -public: -GetKeyValueVisitor(KeyValues &keyvalues) - : m_keyvalues(keyvalues) -{ -} - -void visit(const char *key, const char *value) -{ - m_keyvalues.insert(KeyValues::value_type(CopiedString(key), CopiedString(value))); -} - -}; - -void Entity_GetKeyValues(const Entity &entity, KeyValues &keyvalues, KeyValues &defaultValues) -{ - GetKeyValueVisitor visitor(keyvalues); - - entity.forEachKeyValue(visitor); - - const EntityClassAttributes &attributes = entity.getEntityClass().m_attributes; - - for (EntityClassAttributes::const_iterator i = attributes.begin(); i != attributes.end(); ++i) { - defaultValues.insert(KeyValues::value_type((*i).first, (*i).second.m_value)); - } -} - -void Entity_GetKeyValues_Selected(KeyValues &keyvalues, KeyValues &defaultValues) -{ - class EntityGetKeyValues : public SelectionSystem::Visitor { - KeyValues &m_keyvalues; - KeyValues &m_defaultValues; - mutable std::set m_visited; -public: - EntityGetKeyValues(KeyValues &keyvalues, KeyValues &defaultValues) - : m_keyvalues(keyvalues), m_defaultValues(defaultValues) - { - } - - void visit(scene::Instance &instance) const - { - Entity *entity = Node_getEntity(instance.path().top()); - if (entity == 0 && instance.path().size() != 1) { - entity = Node_getEntity(instance.path().parent()); - } - if (entity != 0 && m_visited.insert(entity).second) { - Entity_GetKeyValues(*entity, m_keyvalues, m_defaultValues); - } - } - } visitor(keyvalues, defaultValues); - GlobalSelectionSystem().foreachSelected(visitor); -} - -const char *keyvalues_valueforkey(KeyValues &keyvalues, const char *key) -{ - KeyValues::iterator i = keyvalues.find(CopiedString(key)); - if (i != keyvalues.end()) { - return (*i).second.c_str(); - } - return ""; -} - -class EntityClassListStoreAppend : public EntityClassVisitor { -ui::ListStore store; -public: -EntityClassListStoreAppend(ui::ListStore store_) : store(store_) -{ -} - -void visit(EntityClass *e) -{ - store.append(0, e->name(), 1, e); -} -}; - -void EntityClassList_fill() -{ - EntityClassListStoreAppend append(g_entlist_store); - GlobalEntityClassManager().forEach(append); -} - -void EntityClassList_clear() -{ - g_entlist_store.clear(); -} - -void SetComment(EntityClass *eclass) -{ - if (eclass == g_current_comment) { - return; - } - - g_current_comment = eclass; - - g_entityClassComment.text(eclass->comments()); -} - -void SurfaceFlags_setEntityClass(EntityClass *eclass) -{ - if (eclass == g_current_flags) { - return; - } - - g_current_flags = eclass; - - unsigned int spawnflag_count = 0; - - { - // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are - for (int i = 0; i < MAX_FLAGS; i++) { - if (eclass->flagnames[i] && eclass->flagnames[i][0] != 0 && strcmp(eclass->flagnames[i], "-")) { - spawn_table[spawnflag_count] = i; - spawnflag_count++; - } - } - } - - // disable all remaining boxes - // NOTE: these boxes might not even be on display - { - for (int i = 0; i < g_spawnflag_count; ++i) { - auto widget = ui::CheckButton::from(g_entitySpawnflagsCheck[i]); - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(widget))); - label.text(" "); - widget.hide(); - widget.ref(); - g_spawnflagsTable.remove(widget); - } - } - - g_spawnflag_count = spawnflag_count; - - { - for (unsigned int i = 0; (int) i < g_spawnflag_count; ++i) { - auto widget = ui::CheckButton::from(g_entitySpawnflagsCheck[i]); - widget.show(); - - StringOutputStream str(16); - str << LowerCase(eclass->flagnames[spawn_table[i]]); - - g_spawnflagsTable.attach(widget, {i % 4, i % 4 + 1, i / 4, i / 4 + 1}, {GTK_FILL, GTK_FILL}); - widget.unref(); - - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(widget))); - label.text(str.c_str()); - } - } -} - -void EntityClassList_selectEntityClass(EntityClass *eclass) -{ - auto model = g_entlist_store; - GtkTreeIter iter; - for (gboolean good = gtk_tree_model_get_iter_first(model, &iter); - good != FALSE; good = gtk_tree_model_iter_next(model, &iter)) { - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - if (strcmp(text, eclass->name()) == 0) { - auto view = ui::TreeView(g_entityClassList); - auto path = gtk_tree_model_get_path(model, &iter); - gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path); - if (gtk_widget_get_realized(view)) { - gtk_tree_view_scroll_to_cell(view, path, 0, FALSE, 0, 0); - } - gtk_tree_path_free(path); - good = FALSE; - } - g_free(text); - } -} - -void EntityInspector_appendAttribute(const char *name, EntityAttribute &attribute) -{ - auto row = DialogRow_new(name, attribute.getWidget()); - DialogVBox_packRow(ui::VBox(g_attributeBox), row); -} - - -template -class StatelessAttributeCreator { -public: -static EntityAttribute *create(const char *name) -{ - return new Attribute(name); -} -}; - -class EntityAttributeFactory { -typedef EntityAttribute *( *CreateFunc )(const char *name); - -typedef std::map Creators; -Creators m_creators; -public: -EntityAttributeFactory() -{ - m_creators.insert(Creators::value_type("string", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("color", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("integer", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("real", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("shader", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("boolean", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("angle", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("direction", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("angles", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("model", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("sound", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("vector3", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("real3", &StatelessAttributeCreator::create)); -} - -EntityAttribute *create(const char *type, const char *name) -{ - Creators::iterator i = m_creators.find(type); - if (i != m_creators.end()) { - return (*i).second(name); - } - const ListAttributeType *listType = GlobalEntityClassManager().findListType(type); - if (listType != 0) { - return new ListAttribute(name, *listType); - } - return 0; -} -}; - -typedef Static GlobalEntityAttributeFactory; - -void EntityInspector_setEntityClass(EntityClass *eclass) -{ - EntityClassList_selectEntityClass(eclass); - SurfaceFlags_setEntityClass(eclass); - - if (eclass != g_current_attributes) { - g_current_attributes = eclass; - - container_remove_all(g_attributeBox); - GlobalEntityAttributes_clear(); - - for (EntityClassAttributes::const_iterator i = eclass->m_attributes.begin(); - i != eclass->m_attributes.end(); ++i) { - EntityAttribute *attribute = GlobalEntityAttributeFactory::instance().create((*i).second.m_type.c_str(), - (*i).first.c_str()); - if (attribute != 0) { - g_entityAttributes.push_back(attribute); - EntityInspector_appendAttribute(EntityClassAttributePair_getName(*i), *g_entityAttributes.back()); - } - } - } -} - -void EntityInspector_updateSpawnflags() -{ - { - int f = atoi(SelectedEntity_getValueForKey("spawnflags")); - for (int i = 0; i < g_spawnflag_count; ++i) { - int v = !!(f & (1 << spawn_table[i])); - - toggle_button_set_active_no_signal(ui::ToggleButton::from(g_entitySpawnflagsCheck[i]), v); - } - } - { - // take care of the remaining ones - for (int i = g_spawnflag_count; i < MAX_FLAGS; ++i) { - toggle_button_set_active_no_signal(ui::ToggleButton::from(g_entitySpawnflagsCheck[i]), FALSE); - } - } -} - -void EntityInspector_applySpawnflags() -{ - int f, i, v; - char sz[32]; - - f = 0; - for (i = 0; i < g_spawnflag_count; ++i) { - v = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_entitySpawnflagsCheck[i])); - f |= v << spawn_table[i]; - } - - sprintf(sz, "%i", f); - const char *value = (f == 0) ? "" : sz; - - { - StringOutputStream command; - command << "entitySetFlags -flags " << f; - UndoableCommand undo("entitySetSpawnflags"); - - Scene_EntitySetKeyValue_Selected("spawnflags", value); - } -} - - -void EntityInspector_updateKeyValues() -{ - g_selectedKeyValues.clear(); - g_selectedDefaultKeyValues.clear(); - Entity_GetKeyValues_Selected(g_selectedKeyValues, g_selectedDefaultKeyValues); - - EntityInspector_setEntityClass( - GlobalEntityClassManager().findOrInsert(keyvalues_valueforkey(g_selectedKeyValues, "classname"), false)); - - EntityInspector_updateSpawnflags(); - - ui::ListStore store = g_entprops_store; - - // save current key/val pair around filling epair box - // row_select wipes it and sets to first in list - CopiedString strKey(g_entityKeyEntry.text()); - CopiedString strVal(g_entityValueEntry.text()); - - store.clear(); - // Walk through list and add pairs - for (KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i) { - StringOutputStream key(64); - key << (*i).first.c_str(); - StringOutputStream value(64); - value << (*i).second.c_str(); - store.append(0, key.c_str(), 1, value.c_str()); - } - - g_entityKeyEntry.text(strKey.c_str()); - g_entityValueEntry.text(strVal.c_str()); - - for (EntityAttributes::const_iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i) { - (*i)->update(); - } -} - -class EntityInspectorDraw { -IdleDraw m_idleDraw; -public: -EntityInspectorDraw() : m_idleDraw(makeCallbackF(EntityInspector_updateKeyValues)) -{ -} - -void queueDraw() -{ - m_idleDraw.queueDraw(); -} -}; - -EntityInspectorDraw g_EntityInspectorDraw; - - -void EntityInspector_keyValueChanged() -{ - g_EntityInspectorDraw.queueDraw(); -} - -void EntityInspector_selectionChanged(const Selectable &) -{ - EntityInspector_keyValueChanged(); -} - -// Creates a new entity based on the currently selected brush and entity type. -// -void EntityClassList_createEntity() -{ - auto view = g_entityClassList; - - // find out what type of entity we are trying to create - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(g_entityClassList), &model, &iter) == FALSE) { - ui::alert(view.window(), "You must have a selected class to create an entity", "info"); - return; - } - - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - { - StringOutputStream command; - command << "entityCreate -class " << text; - printf(command.c_str()); - printf("\n"); - UndoableCommand undo(command.c_str()); - - Entity_createFromSelection(text, g_vector3_identity); - } - g_free(text); -} - -void EntityInspector_applyKeyValue() -{ - // Get current selection text - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - StringOutputStream value(64); - value << gtk_entry_get_text(g_entityValueEntry); - - - // TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity - if (!strcmp(key.c_str(), "classname") && !strcmp(value.c_str(), "worldspawn")) { - ui::alert(g_entityKeyEntry.window(), "Cannot change \"classname\" key back to worldspawn.", 0, - ui::alert_type::OK); - return; - } - - - // RR2DO2: we don't want spaces in entity keys - if (strstr(key.c_str(), " ")) { - ui::alert(g_entityKeyEntry.window(), "No spaces are allowed in entity keys.", 0, ui::alert_type::OK); - return; - } - - if (strcmp(key.c_str(), "classname") == 0) { - StringOutputStream command; - command << "entitySetClass -class " << value.c_str(); - UndoableCommand undo(command.c_str()); - Scene_EntitySetClassname_Selected(value.c_str()); - } else { - Scene_EntitySetKeyValue_Selected_Undoable(key.c_str(), value.c_str()); - } -} - -void EntityInspector_clearKeyValue() -{ - // Get current selection text - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - - if (strcmp(key.c_str(), "classname") != 0) { - StringOutputStream command; - command << "entityDeleteKey -key " << key.c_str(); - UndoableCommand undo(command.c_str()); - Scene_EntitySetKeyValue_Selected(key.c_str(), ""); - } -} - -void EntityInspector_clearAllKeyValues() -{ - UndoableCommand undo("entityClear"); - - // remove all keys except classname - for (KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i) { - if (strcmp((*i).first.c_str(), "classname") != 0) { - Scene_EntitySetKeyValue_Selected((*i).first.c_str(), ""); - } - } -} - -// ============================================================================= -// callbacks - -static void EntityClassList_selection_changed(ui::TreeSelection selection, gpointer data) -{ - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - EntityClass *eclass; - gtk_tree_model_get(model, &selected, 1, &eclass, -1); - if (eclass != 0) { - SetComment(eclass); - } - } -} - -static gint EntityClassList_button_press(ui::Widget widget, GdkEventButton *event, gpointer data) -{ - if (event->type == GDK_2BUTTON_PRESS) { - /* If we're worldspawn - DO NOT ALLOW RENAMING! */ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey("classname"); - - if (!strcmp(value.c_str(), "worldspawn")) { - EntityClassList_createEntity(); - return TRUE; - } - - auto view = g_entityClassList; - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(g_entityClassList), &model, &iter) == FALSE) { - ui::alert(view.window(), "You must have a selected class to change an entity", "info"); - return FALSE; - } - - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - StringOutputStream command; - command << "entitySetClass -class " << text; - UndoableCommand undo(command.c_str()); - Scene_EntitySetClassname_Selected(text); - g_free(text); - return TRUE; - } - return FALSE; -} - -static gint EntityClassList_keypress(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - unsigned int code = gdk_keyval_to_upper(event->keyval); - - /* -eukara */ - /*if (event->keyval == GDK_KEY_Return) { - EntityClassList_createEntity(); - return TRUE; - }*/ - - // select the entity that starts with the key pressed - if (code <= 'Z' && code >= 'A') { - auto view = ui::TreeView(g_entityClassList); - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE - || gtk_tree_model_iter_next(model, &iter) == FALSE) { - gtk_tree_model_get_iter_first(model, &iter); - } - - for (std::size_t count = gtk_tree_model_iter_n_children(model, 0); count > 0; --count) { - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - if (toupper(text[0]) == (int) code) { - auto path = gtk_tree_model_get_path(model, &iter); - gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path); - if (gtk_widget_get_realized(view)) { - gtk_tree_view_scroll_to_cell(view, path, 0, FALSE, 0, 0); - } - gtk_tree_path_free(path); - count = 1; - } - - g_free(text); - - if (gtk_tree_model_iter_next(model, &iter) == FALSE) { - gtk_tree_model_get_iter_first(model, &iter); - } - } - - return TRUE; - } - return FALSE; -} - -static void EntityProperties_selection_changed(ui::TreeSelection selection, gpointer data) -{ - // find out what type of entity we are trying to create - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) { - return; - } - - char *key; - char *val; - gtk_tree_model_get(model, &iter, 0, &key, 1, &val, -1); - - g_entityKeyEntry.text(key); - g_entityValueEntry.text(val); - - g_free(key); - g_free(val); -} - -static void SpawnflagCheck_toggled(ui::Widget widget, gpointer data) -{ - EntityInspector_applySpawnflags(); -} - -static gint EntityEntry_keypress(ui::Entry widget, GdkEventKey *event, gpointer data) -{ - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - StringOutputStream value(64); - value << gtk_entry_get_text(g_entityValueEntry); - - if (event->keyval == GDK_KEY_Return) { - if (widget._handle == g_entityKeyEntry._handle) { - g_entityValueEntry.text(""); - gtk_window_set_focus(widget.window(), g_entityValueEntry); - } else { - if (!strcmp(key.c_str(), "classname")) { - ui::alert(widget.window(), "Do not rename classnames. Pick a new entity from the list instead.", "info"); - return FALSE; - } else { - EntityInspector_applyKeyValue(); - } - } - return TRUE; - } - if (event->keyval == GDK_KEY_Escape) { - gtk_window_set_focus(widget.window(), NULL); - return TRUE; - } - - return FALSE; -} - -void EntityInspector_destroyWindow(ui::Widget widget, gpointer data) -{ - g_entitysplit1_position = gtk_paned_get_position(GTK_PANED(g_entity_split1)); - g_entitysplit2_position = gtk_paned_get_position(GTK_PANED(g_entity_split2)); - - g_entityInspector_windowConstructed = false; - GlobalEntityAttributes_clear(); -} - -ui::Widget EntityInspector_constructWindow(ui::Window toplevel) -{ - auto hbox = ui::HBox(FALSE, 2); - hbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); - hbox.connect("destroy", G_CALLBACK(EntityInspector_destroyWindow), 0); - - auto vbox = ui::VBox(FALSE, 2); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto split1 = ui::VPaned(ui::New); - vbox.pack_start(split1, TRUE, TRUE, 0); - split1.show(); - - g_entity_split1 = split1; - - { - ui::Widget split2 = ui::VPaned(ui::New); - gtk_paned_add1(GTK_PANED(split1), split2); - split2.show(); - - g_entity_split2 = split2; - - { - // class list - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_paned_add1(GTK_PANED(split2), scr); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_enable_search(view, FALSE); - gtk_tree_view_set_headers_visible(view, FALSE); - view.connect("button_press_event", G_CALLBACK(EntityClassList_button_press), 0); - view.connect("key_press_event", G_CALLBACK(EntityClassList_keypress), 0); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Key", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(EntityClassList_selection_changed), 0); - } - - view.show(); - - scr.add(view); - - store.unref(); - g_entityClassList = view; - g_entlist_store = store; - } - } - - /* this is the QUAKEED text */ - { - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - hbox.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - { - auto text = ui::TextView(ui::New); - text.dimensions(0, -1); // allow shrinking - gtk_text_view_set_wrap_mode(text, GTK_WRAP_WORD); - gtk_text_view_set_editable(text, FALSE); - text.show(); - scr.add(text); - g_entityClassComment = text; - } - } - } - - { - ui::Widget split2 = ui::VPaned(ui::New); - gtk_paned_add2(GTK_PANED(split1), split2); - split2.show(); - - { - auto vbox2 = ui::VBox(FALSE, 2); - vbox2.show(); - gtk_paned_pack1(GTK_PANED(split2), vbox2, FALSE, FALSE); - - { - // Spawnflags (4 colums wide max, or window gets too wide.) - auto table = ui::Table(4, 4, FALSE); - vbox2.pack_start(table, FALSE, TRUE, 0); - table.show(); - - g_spawnflagsTable = table; - - for (int i = 0; i < MAX_FLAGS; i++) { - auto check = ui::CheckButton(""); - check.ref(); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer( - check.connect("toggled", G_CALLBACK(SpawnflagCheck_toggled), 0))); - g_entitySpawnflagsCheck[i] = check; - } - } - - { - // key/value list - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - vbox2.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_enable_search(view, FALSE); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 1}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(EntityProperties_selection_changed), 0); - } - - view.show(); - - scr.add(view); - - store.unref(); - - g_entprops_store = store; - } - } - - { - // key/value entry - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox2.pack_start(table, FALSE, TRUE, 0); - gtk_table_set_row_spacings(table, 3); - gtk_table_set_col_spacings(table, 5); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_set_events(entry, GDK_KEY_PRESS_MASK); - entry.connect("key_press_event", G_CALLBACK(EntityEntry_keypress), 0); - g_entityKeyEntry = entry; - } - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_set_events(entry, GDK_KEY_PRESS_MASK); - entry.connect("key_press_event", G_CALLBACK(EntityEntry_keypress), 0); - g_entityValueEntry = entry; - } - - { - auto label = ui::Label("Value"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - - { - auto label = ui::Label("Key"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - - { - auto hbox = ui::HBox(TRUE, 4); - hbox.show(); - vbox2.pack_start(hbox, FALSE, TRUE, 0); - - { - auto button = ui::Button("Clear All"); - button.show(); - button.connect("clicked", G_CALLBACK(EntityInspector_clearAllKeyValues), 0); - hbox.pack_start(button, TRUE, TRUE, 0); - } - { - auto button = ui::Button("Delete Key"); - button.show(); - button.connect("clicked", G_CALLBACK(EntityInspector_clearKeyValue), 0); - hbox.pack_start(button, TRUE, TRUE, 0); - } - } - } - - // Let's keep it simple, okay? - /*{ - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - auto viewport = ui::Container::from(gtk_viewport_new(0, 0)); - viewport.show(); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE); - - g_attributeBox = ui::VBox(FALSE, 2); - g_attributeBox.show(); - - viewport.add(g_attributeBox); - scr.add(viewport); - gtk_paned_pack2(GTK_PANED(split2), scr, FALSE, FALSE); - }*/ - } - } - - - { - // show the sliders in any case - if (g_entitysplit2_position > 22) { - gtk_paned_set_position(GTK_PANED(g_entity_split2), g_entitysplit2_position); - } else { - g_entitysplit2_position = 22; - gtk_paned_set_position(GTK_PANED(g_entity_split2), 22); - } - if ((g_entitysplit1_position - g_entitysplit2_position) > 27) { - gtk_paned_set_position(GTK_PANED(g_entity_split1), g_entitysplit1_position); - } else { - gtk_paned_set_position(GTK_PANED(g_entity_split1), g_entitysplit2_position + 27); - } - } - - g_entityInspector_windowConstructed = true; - EntityClassList_fill(); - - typedef FreeCaller EntityInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(EntityInspectorSelectionChangedCaller()); - GlobalEntityCreator().setKeyValueChangedFunc(EntityInspector_keyValueChanged); - - // hack - gtk_container_set_focus_chain(GTK_CONTAINER(vbox), NULL); - - return hbox; -} - -class EntityInspector : public ModuleObserver { -std::size_t m_unrealised; -public: -EntityInspector() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - if (g_entityInspector_windowConstructed) { - //globalOutputStream() << "Entity Inspector: realise\n"; - EntityClassList_fill(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (g_entityInspector_windowConstructed) { - //globalOutputStream() << "Entity Inspector: unrealise\n"; - EntityClassList_clear(); - } - } -} -}; - -EntityInspector g_EntityInspector; - -#include "preferencesystem.h" -#include "stringio.h" - -void EntityInspector_construct() -{ - GlobalEntityClassManager().attach(g_EntityInspector); - - GlobalPreferenceSystem().registerPreference("EntitySplit1", make_property_string(g_entitysplit1_position)); - GlobalPreferenceSystem().registerPreference("EntitySplit2", make_property_string(g_entitysplit2_position)); - -} - -void EntityInspector_destroy() -{ - GlobalEntityClassManager().detach(g_EntityInspector); -} - -const char *EntityInspector_getCurrentKey() -{ - if (!GroupDialog_isShown()) { - return 0; - } - if (GroupDialog_getPage() != g_page_entity) { - return 0; - } - return gtk_entry_get_text(g_entityKeyEntry); -} diff --git a/src/entityinspector.h b/src/entityinspector.h deleted file mode 100644 index 4b200a8..0000000 --- a/src/entityinspector.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_ENTITYINSPECTOR_H ) -#define INCLUDED_ENTITYINSPECTOR_H - -ui::Widget EntityInspector_constructWindow(ui::Window parent); - -void EntityInspector_construct(); - -void EntityInspector_destroy(); - -const char *EntityInspector_getCurrentKey(); - -#endif diff --git a/src/entitylist.cpp b/src/entitylist.cpp deleted file mode 100644 index 50ca626..0000000 --- a/src/entitylist.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entitylist.h" - -#include "iselection.h" - -#include -#include - -#include "string/string.h" -#include "scenelib.h" -#include "nameable.h" -#include "signal/isignal.h" -#include "generic/object.h" - -#include "gtkutil/widget.h" -#include "gtkutil/window.h" -#include "gtkutil/idledraw.h" -#include "gtkutil/accelerator.h" -#include "gtkutil/closure.h" - -#include "treemodel.h" - -void RedrawEntityList(); - -typedef FreeCaller RedrawEntityListCaller; - - -class EntityList { -public: -enum EDirty { - eDefault, - eSelection, - eInsertRemove, -}; - -EDirty m_dirty; - -IdleDraw m_idleDraw; -WindowPositionTracker m_positionTracker; - -ui::Window m_window; -ui::TreeView m_tree_view{ui::null}; -ui::TreeModel m_tree_model{ui::null}; -bool m_selection_disabled; - -EntityList() : - m_dirty(EntityList::eDefault), - m_idleDraw(RedrawEntityListCaller()), - m_window(ui::null), - m_selection_disabled(false) -{ -} - -bool visible() -{ - return m_window.visible(); -} -}; - -namespace { -EntityList *g_EntityList; - -inline EntityList &getEntityList() -{ - ASSERT_NOTNULL(g_EntityList); - return *g_EntityList; -} -} - - -inline Nameable *Node_getNameable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -const char *node_get_name(scene::Node &node) -{ - Nameable *nameable = Node_getNameable(node); - return (nameable != 0) - ? nameable->name() - : "node"; -} - -template -inline void gtk_tree_model_get_pointer(ui::TreeModel model, GtkTreeIter *iter, gint column, value_type **pointer) -{ - GValue value = GValue_default(); - gtk_tree_model_get_value(model, iter, column, &value); - *pointer = (value_type *) g_value_get_pointer(&value); -} - - -void entitylist_treeviewcolumn_celldatafunc(ui::TreeViewColumn column, ui::CellRenderer renderer, ui::TreeModel model, - GtkTreeIter *iter, gpointer data) -{ - scene::Node *node; - gtk_tree_model_get_pointer(model, iter, 0, &node); - scene::Instance *instance; - gtk_tree_model_get_pointer(model, iter, 1, &instance); - if (node != 0) { - gtk_cell_renderer_set_fixed_size(renderer, -1, -1); - char *name = const_cast( node_get_name(*node)); - g_object_set(G_OBJECT(renderer), "text", name, "visible", TRUE, NULL); - - //globalOutputStream() << "rendering cell " << makeQuoted(name) << "\n"; - auto style = gtk_widget_get_style(ui::TreeView(getEntityList().m_tree_view)); - if (instance->childSelected()) { - g_object_set(G_OBJECT(renderer), "cell-background-gdk", &style->base[GTK_STATE_ACTIVE], NULL); - } else { - g_object_set(G_OBJECT(renderer), "cell-background-gdk", &style->base[GTK_STATE_NORMAL], NULL); - } - } else { - gtk_cell_renderer_set_fixed_size(renderer, -1, 0); - g_object_set(G_OBJECT(renderer), "text", "", "visible", FALSE, NULL); - } -} - -static gboolean entitylist_tree_select(ui::TreeSelection selection, ui::TreeModel model, ui::TreePath path, - gboolean path_currently_selected, gpointer data) -{ - GtkTreeIter iter; - gtk_tree_model_get_iter(model, &iter, path); - scene::Node *node; - gtk_tree_model_get_pointer(model, &iter, 0, &node); - scene::Instance *instance; - gtk_tree_model_get_pointer(model, &iter, 1, &instance); - Selectable *selectable = Instance_getSelectable(*instance); - - if (node == 0) { - if (path_currently_selected != FALSE) { - getEntityList().m_selection_disabled = true; - GlobalSelectionSystem().setSelectedAll(false); - getEntityList().m_selection_disabled = false; - } - } else if (selectable != 0) { - getEntityList().m_selection_disabled = true; - selectable->setSelected(path_currently_selected == FALSE); - getEntityList().m_selection_disabled = false; - return TRUE; - } - - return FALSE; -} - -static gboolean entitylist_tree_select_null(ui::TreeSelection selection, ui::TreeModel model, ui::TreePath path, - gboolean path_currently_selected, gpointer data) -{ - return TRUE; -} - -void EntityList_ConnectSignals(ui::TreeView view) -{ - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_select_function(select, reinterpret_cast(entitylist_tree_select), NULL, - 0); -} - -void EntityList_DisconnectSignals(ui::TreeView view) -{ - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_select_function(select, reinterpret_cast(entitylist_tree_select_null), - 0, 0); -} - - -gboolean treemodel_update_selection(ui::TreeModel model, ui::TreePath path, GtkTreeIter *iter, gpointer data) -{ - auto view = ui::TreeView::from(data); - - scene::Instance *instance; - gtk_tree_model_get_pointer(model, iter, 1, &instance); - Selectable *selectable = Instance_getSelectable(*instance); - - if (selectable != 0) { - auto selection = gtk_tree_view_get_selection(view); - if (selectable->isSelected()) { - gtk_tree_selection_select_path(selection, path); - } else { - gtk_tree_selection_unselect_path(selection, path); - } - } - - return FALSE; -} - -void EntityList_UpdateSelection(ui::TreeModel model, ui::TreeView view) -{ - EntityList_DisconnectSignals(view); - gtk_tree_model_foreach(model, reinterpret_cast(treemodel_update_selection), view._handle); - EntityList_ConnectSignals(view); -} - - -void RedrawEntityList() -{ - switch (getEntityList().m_dirty) { - case EntityList::eInsertRemove: - case EntityList::eSelection: - EntityList_UpdateSelection(getEntityList().m_tree_model, getEntityList().m_tree_view); - default: - break; - } - getEntityList().m_dirty = EntityList::eDefault; -} - -void entitylist_queue_draw() -{ - getEntityList().m_idleDraw.queueDraw(); -} - -void EntityList_SelectionUpdate() -{ - if (getEntityList().m_selection_disabled) { - return; - } - - if (getEntityList().m_dirty < EntityList::eSelection) { - getEntityList().m_dirty = EntityList::eSelection; - } - entitylist_queue_draw(); -} - -void EntityList_SelectionChanged(const Selectable &selectable) -{ - EntityList_SelectionUpdate(); -} - -void entitylist_treeview_rowcollapsed(ui::TreeView view, GtkTreeIter *iter, ui::TreePath path, gpointer user_data) -{ -} - -void entitylist_treeview_row_expanded(ui::TreeView view, GtkTreeIter *iter, ui::TreePath path, gpointer user_data) -{ - EntityList_SelectionUpdate(); -} - - -void EntityList_SetShown(bool shown) -{ - getEntityList().m_window.visible(shown); -} - -void EntityList_toggleShown() -{ - EntityList_SetShown(!getEntityList().visible()); -} - -gint graph_tree_model_compare_name(ui::TreeModel model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) -{ - scene::Node *first; - gtk_tree_model_get(model, a, 0, (gpointer *) &first, -1); - scene::Node *second; - gtk_tree_model_get(model, b, 0, (gpointer *) &second, -1); - int result = 0; - if (first != 0 && second != 0) { - result = string_compare(node_get_name(*first), node_get_name(*second)); - } - if (result == 0) { - return (first < second) ? -1 : (second < first) ? 1 : 0; - } - return result; -} - -extern GraphTreeModel *scene_graph_get_tree_model(); - -void AttachEntityTreeModel() -{ - getEntityList().m_tree_model = ui::TreeModel::from(scene_graph_get_tree_model()); - - gtk_tree_view_set_model(getEntityList().m_tree_view, getEntityList().m_tree_model); -} - -void DetachEntityTreeModel() -{ - getEntityList().m_tree_model = ui::TreeModel(ui::null); - - gtk_tree_view_set_model(getEntityList().m_tree_view, 0); -} - -void EntityList_constructWindow(ui::Window main_window) -{ - ASSERT_TRUE(!getEntityList().m_window); - - auto window = ui::Window(create_persistent_floating_window("Entity List", main_window)); - - window.add_accel_group(global_accel); - - getEntityList().m_positionTracker.connect(window); - - - getEntityList().m_window = window; - - { - auto scr = create_scrolled_window(ui::Policy::AUTOMATIC, ui::Policy::AUTOMATIC); - window.add(scr); - - { - auto view = ui::TreeView(ui::New); - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - auto column = gtk_tree_view_column_new(); - gtk_tree_view_column_pack_start(column, renderer, TRUE); - gtk_tree_view_column_set_cell_data_func(column, renderer, - reinterpret_cast(entitylist_treeviewcolumn_celldatafunc), - 0, 0); - - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(select, GTK_SELECTION_MULTIPLE); - - view.connect("row_expanded", G_CALLBACK(entitylist_treeview_row_expanded), 0); - view.connect("row_collapsed", G_CALLBACK(entitylist_treeview_rowcollapsed), 0); - - gtk_tree_view_append_column(view, column); - - view.show(); - scr.add(view); - getEntityList().m_tree_view = view; - } - } - - EntityList_ConnectSignals(getEntityList().m_tree_view); - AttachEntityTreeModel(); -} - -void EntityList_destroyWindow() -{ - DetachEntityTreeModel(); - EntityList_DisconnectSignals(getEntityList().m_tree_view); - destroy_floating_window(getEntityList().m_window); -} - -#include "preferencesystem.h" - -#include "iselection.h" - -namespace { -scene::Node *nullNode = 0; -} - -class NullSelectedInstance : public scene::Instance, public Selectable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -public: -typedef LazyStatic StaticTypeCasts; - -NullSelectedInstance() : Instance(scene::Path(makeReference(*nullNode)), 0, this, StaticTypeCasts::instance().get()) -{ -} - -void setSelected(bool select) -{ - ERROR_MESSAGE("error"); -} - -bool isSelected() const -{ - return true; -} -}; - -typedef LazyStatic StaticNullSelectedInstance; - - -void EntityList_Construct() -{ - graph_tree_model_insert(scene_graph_get_tree_model(), StaticNullSelectedInstance::instance()); - - g_EntityList = new EntityList; - - getEntityList().m_positionTracker.setPosition(c_default_window_pos); - - GlobalPreferenceSystem().registerPreference("EntityInfoDlg", make_property( - getEntityList().m_positionTracker)); - - typedef FreeCaller EntityListSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(EntityListSelectionChangedCaller()); -} - -void EntityList_Destroy() -{ - delete g_EntityList; - - graph_tree_model_erase(scene_graph_get_tree_model(), StaticNullSelectedInstance::instance()); -} diff --git a/src/entitylist.h b/src/entitylist.h deleted file mode 100644 index 38ee587..0000000 --- a/src/entitylist.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_ENTITYLIST_H ) -#define INCLUDED_ENTITYLIST_H - -void EntityList_Construct(); - -void EntityList_Destroy(); - -void EntityList_constructWindow(ui::Window main_window); - -void EntityList_destroyWindow(); - -void EntityList_toggleShown(); - -#endif diff --git a/src/environment.cpp b/src/environment.cpp deleted file mode 100644 index 3d87ef2..0000000 --- a/src/environment.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "environment.h" -#include "globaldefs.h" - -#include "stream/textstream.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "debugging/debugging.h" -#include "os/path.h" -#include "os/file.h" -#include "cmdlib.h" - -int g_argc; -char const **g_argv; - -void args_init(int argc, char const *argv[]) -{ - int i, j, k; - - for (i = 1; i < argc; i++) { - for (k = i; k < argc; k++) { - if (argv[k] != 0) { - break; - } - } - - if (k > i) { - k -= i; - for (j = i + k; j < argc; j++) { - argv[j - k] = argv[j]; - } - argc -= k; - } - } - - g_argc = argc; - g_argv = argv; -} - -char const *gamedetect_argv_buffer[1024]; - -void gamedetect_found_game(char const *game, char *path) -{ - int argc; - static char buf[128]; - - if (g_argv == gamedetect_argv_buffer) { - return; - } - - globalOutputStream() << "Detected game " << game << " in " << path << "\n"; - - sprintf(buf, "-%s-EnginePath", game); - argc = 0; - gamedetect_argv_buffer[argc++] = "-global-gamefile"; - gamedetect_argv_buffer[argc++] = game; - gamedetect_argv_buffer[argc++] = buf; - gamedetect_argv_buffer[argc++] = path; - if ((size_t) (argc + g_argc) >= sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - 1) { - g_argc = sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - g_argc - 1; - } - memcpy(gamedetect_argv_buffer + 4, g_argv, sizeof(*gamedetect_argv_buffer) * g_argc); - g_argc += argc; - g_argv = gamedetect_argv_buffer; -} - -bool gamedetect_check_game(char const *gamefile, const char *checkfile1, const char *checkfile2, - char *buf /* must have 64 bytes free after bufpos */, int bufpos) -{ - buf[bufpos] = '/'; - - strcpy(buf + bufpos + 1, checkfile1); - globalOutputStream() << "Checking for a game file in " << buf << "\n"; - if (!file_exists(buf)) { - return false; - } - - if (checkfile2) { - strcpy(buf + bufpos + 1, checkfile2); - globalOutputStream() << "Checking for a game file in " << buf << "\n"; - if (!file_exists(buf)) { - return false; - } - } - - buf[bufpos + 1] = 0; - gamedetect_found_game(gamefile, buf); - return true; -} - -void gamedetect() -{ - // if we're inside a Nexuiz install - // default to nexuiz.game (unless the user used an option to inhibit this) - bool nogamedetect = false; - int i; - for (i = 1; i < g_argc - 1; ++i) { - if (g_argv[i][0] == '-') { - if (!strcmp(g_argv[i], "-gamedetect")) { - nogamedetect = !strcmp(g_argv[i + 1], "false"); - } - ++i; - } - } - if (!nogamedetect) { - static char buf[1024 + 64]; - strncpy(buf, environment_get_app_path(), sizeof(buf)); - buf[sizeof(buf) - 1 - 64] = 0; - if (!strlen(buf)) { - return; - } - - char *p = buf + strlen(buf) - 1; // point directly on the slash of get_app_path - while (p != buf) { - // we found nothing - // go backwards - --p; - while (p != buf && *p != '/' && *p != '\\') { - --p; - } - } - } -} - -namespace { -CopiedString app_path; -} - -const char *environment_get_app_path() -{ - return app_path.c_str(); -} - -bool portable_app_setup() -{ - StringOutputStream confdir(256); - confdir << app_path.c_str() << "settings/"; - if (file_exists(confdir.c_str())) { - return true; - } - return false; -} - -#if GDEF_OS_POSIX - -#include -#include -#include - -#include - -const char *LINK_NAME = -#if GDEF_OS_LINUX - "/proc/self/exe" -#else // FreeBSD and OSX - "/proc/curproc/file" -#endif -; - -/// brief Returns the filename of the executable belonging to the current process, or 0 if not found. -char const *getexename(char *buf) -{ - /* Now read the symbolic link */ - int ret = readlink(LINK_NAME, buf, PATH_MAX); - - if (ret == -1) { - globalOutputStream() << "getexename: falling back to argv[0]: " << makeQuoted(g_argv[0]); - const char *path = realpath(g_argv[0], buf); - if (path == 0) { - /* In case of an error, leave the handling up to the caller */ - return ""; - } - } - - /* Ensure proper NUL termination */ - buf[ret] = 0; - - /* delete the program name */ - *(strrchr(buf, '/')) = '\0'; - - // NOTE: we build app path with a trailing '/' - // it's a general convention in Radiant to have the slash at the end of directories - if (buf[strlen(buf) - 1] != '/') { - strcat(buf, "/"); - } - - return buf; -} - -void environment_init(int argc, char const *argv[]) -{ - // Give away unnecessary root privileges. - // Important: must be done before calling gtk_init(). - char *loginname; - struct passwd *pw; - seteuid(getuid()); - if (geteuid() == 0 && (loginname = getlogin()) != 0 && - (pw = getpwnam(loginname)) != 0) { - setuid(pw->pw_uid); - } - - args_init(argc, argv); - - { - char real[PATH_MAX]; - app_path = getexename(real); - ASSERT_MESSAGE(!string_empty(app_path.c_str()), "failed to deduce app path"); - } - - gamedetect(); -} - -#elif GDEF_OS_WINDOWS - -#include - -void environment_init( int argc, char const* argv[] ){ - args_init( argc, argv ); - - // get path to the editor - char filename[MAX_PATH + 1]; - GetModuleFileName( 0, filename, MAX_PATH ); - char* last_separator = strrchr( filename, '\\' ); - if ( last_separator != 0 ) { - *( last_separator + 1 ) = '\0'; - } else { - filename[0] = '\0'; - } - - StringOutputStream app( 256 ); - app << PathCleaned( filename ); - app_path = app.c_str(); - gamedetect(); -} - -#else -#error "unsupported platform" -#endif diff --git a/src/environment.h b/src/environment.h deleted file mode 100644 index 173c2ab..0000000 --- a/src/environment.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENVIRONMENT_H ) -#define INCLUDED_ENVIRONMENT_H - -void environment_init(int argc, char const *argv[]); - -const char *environment_get_home_path(); - -const char *environment_get_app_path(); - -extern int g_argc; -extern char const **g_argv; - -#endif diff --git a/src/error.cpp b/src/error.cpp deleted file mode 100644 index d867d7b..0000000 --- a/src/error.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "error.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" -#include "igl.h" - -#include "gtkutil/messagebox.h" -#include "console.h" -#include "preferences.h" - - -#if GDEF_OS_WINDOWS -#define UNICODE -#include -#else - -#include -#include - -#endif - - - -/* - ================= - Error - - For abnormal program terminations - ================= - */ - -/*! - \todo - FIXME the prompt wether to do prefs dialog, may not even be possible - if the crash happens before the game is loaded - */ - -void Error(const char *error, ...) -{ - va_list argptr; - char text[4096]; - - va_start(argptr, error); - vsprintf(text, error, argptr); - va_end(argptr); - - strcat(text, "\n"); - -#if GDEF_OS_WINDOWS - if ( GetLastError() != 0 ) { - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - 0, - GetLastError(), - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language - (LPTSTR) &lpMsgBuf, - 0, - 0 - ); - strcat( text, "GetLastError: " ); - /* - Gtk will only crunch 0<=char<=127 - this is a bit hackish, but I didn't find useful functions in win32 API for this - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=516 - */ - TCHAR *scan, *next = (TCHAR*)lpMsgBuf; - do - { - scan = next; - text[strlen( text ) + 1] = '\0'; - if ( ( scan[0] >= 0 ) && ( scan[0] <= 127 ) ) { - text[strlen( text )] = char(scan[0]); - } - else{ - text[strlen( text )] = '?'; - } - next = CharNext( scan ); - } while ( next != scan ); - strcat( text, "\n" ); - LocalFree( lpMsgBuf ); - } -#else - if (errno != 0) { - strcat(text, "errno: "); - strcat(text, strerror(errno)); - strcat(text, "\n"); - } -#endif - - -#if 0 - // we need to have a current context to call glError() - if ( g_glwindow_globals.d_glBase != 0 ) { - // glGetError .. can record several errors, clears after calling - //++timo TODO: be able to deal with several errors if necessary, for now I'm just warning about pending error messages - // NOTE: forget that, most boards don't seem to follow the OpenGL standard - GLenum iGLError = glGetError(); - if ( iGLError != GL_NO_ERROR ) { - // use our own gluErrorString - strcat( text, "gluErrorString: " ); - strcat( text, (char*)gluErrorString( iGLError ) ); - strcat( text, "\n" ); - } - } -#endif - - strcat(text, "An unrecoverable error has occured.\n"); - - ERROR_MESSAGE(text); - - _exit(1); -} diff --git a/src/error.h b/src/error.h deleted file mode 100644 index 43acdb5..0000000 --- a/src/error.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ERROR_H ) -#define INCLUDED_ERROR_H - -void Error(const char *error, ...); - -#endif diff --git a/tools/vmap/exportents.c b/src/exportents.c similarity index 100% rename from tools/vmap/exportents.c rename to src/exportents.c diff --git a/tools/vmap/facebsp.c b/src/facebsp.c similarity index 100% rename from tools/vmap/facebsp.c rename to src/facebsp.c diff --git a/src/feedback.cpp b/src/feedback.cpp deleted file mode 100644 index d1164b5..0000000 --- a/src/feedback.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// classes used for describing geometry information from q3map feedback -// - -#include "feedback.h" - -#include - -#include "debugging/debugging.h" - -#include "igl.h" -#include "iselection.h" - -#include "map.h" -#include "dialog.h" -#include "mainframe.h" - - -CDbgDlg g_DbgDlg; - -void Feedback_draw2D(VIEWTYPE viewType) -{ - g_DbgDlg.draw2D(viewType); -} - -void CSelectMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "select")) { - // read the message - ESelectState = SELECT_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "brush"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(ESelectState == SELECT_MESSAGE, "FEEDBACK PARSE ERROR"); - ESelectState = SELECT_BRUSH; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CSelectMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "select")) { - } -} - -void CSelectMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (ESelectState == SELECT_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - brush.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CSelectMsg::Highlight() -{ - GlobalSelectionSystem().setSelectedAll(false); - int entitynum, brushnum; - if (sscanf(reinterpret_cast( brush.c_str()), "%i %i", &entitynum, &brushnum) == 2) { - SelectBrush(entitynum, brushnum); - } - return 0; -} - -void CPointMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "pointmsg")) { - // read the message - EPointState = POINT_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "point"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(EPointState == POINT_MESSAGE, "FEEDBACK PARSE ERROR"); - EPointState = POINT_POINT; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CPointMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "pointmsg")) { - } else if (string_equal(reinterpret_cast( name ), "point")) { - sscanf(point.c_str(), "%g %g %g", &(pt[0]), &(pt[1]), &(pt[2])); - point.clear(); - } -} - -void CPointMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (EPointState == POINT_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - ASSERT_MESSAGE(EPointState == POINT_POINT, "FEEDBACK PARSE ERROR"); - point.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CPointMsg::Highlight() -{ - return this; -} - -void CPointMsg::DropHighlight() -{ -} - -void CPointMsg::Draw2D(VIEWTYPE vt) -{ - int nDim1 = (vt == YZ) ? 1 : 0; - int nDim2 = (vt == XY) ? 1 : 2; - glPointSize(4); - glColor3f(1.0f, 0.0f, 0.0f); - glBegin(GL_POINTS); - glVertex2f(pt[nDim1], pt[nDim2]); - glEnd(); - glBegin(GL_LINE_LOOP); - glVertex2f(pt[nDim1] - 8, pt[nDim2] - 8); - glVertex2f(pt[nDim1] + 8, pt[nDim2] - 8); - glVertex2f(pt[nDim1] + 8, pt[nDim2] + 8); - glVertex2f(pt[nDim1] - 8, pt[nDim2] + 8); - glEnd(); -} - -void CWindingMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "windingmsg")) { - // read the message - EPointState = WINDING_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "winding"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(EPointState == WINDING_MESSAGE, "FEEDBACK PARSE ERROR"); - EPointState = WINDING_WINDING; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CWindingMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "windingmsg")) { - } else if (string_equal(reinterpret_cast( name ), "winding")) { - const char *c = winding.c_str(); - sscanf(c, "%i ", &numpoints); - - int i = 0; - for (; i < numpoints; i++) { - c = strchr(c + 1, '('); - if (c) { // even if we are given the number of points when the cycle begins .. don't trust it too much - sscanf(c, "(%g %g %g)", &wt[i][0], &wt[i][1], &wt[i][2]); - } else { - break; - } - } - numpoints = i; - } -} - -void CWindingMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (EPointState == WINDING_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - ASSERT_MESSAGE(EPointState == WINDING_WINDING, "FEEDBACK PARSE ERROR"); - winding.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CWindingMsg::Highlight() -{ - return this; -} - -void CWindingMsg::DropHighlight() -{ -} - -void CWindingMsg::Draw2D(VIEWTYPE vt) -{ - int i; - - int nDim1 = (vt == YZ) ? 1 : 0; - int nDim2 = (vt == XY) ? 1 : 2; - glColor3f(1.0f, 0.f, 0.0f); - - glPointSize(4); - glBegin(GL_POINTS); - for (i = 0; i < numpoints; i++) - glVertex2f(wt[i][nDim1], wt[i][nDim2]); - glEnd(); - glPointSize(1); - - glEnable(GL_BLEND); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.133f, 0.4f, 1.0f, 0.5f); - glBegin(GL_POLYGON); - for (i = 0; i < numpoints; i++) - glVertex2f(wt[i][nDim1], wt[i][nDim2]); - glEnd(); - glDisable(GL_BLEND); -} - -// triggered when the user selects an entry in the feedback box -static void feedback_selection_changed(ui::TreeSelection selection, gpointer data) -{ - g_DbgDlg.DropHighlight(); - - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - auto path = gtk_tree_model_get_path(model, &selected); - g_DbgDlg.SetHighlight(gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - } -} - -void CDbgDlg::DropHighlight() -{ - if (m_pHighlight != 0) { - m_pHighlight->DropHighlight(); - m_pHighlight = 0; - m_pDraw2D = 0; - } -} - -void CDbgDlg::SetHighlight(gint row) -{ - ISAXHandler *h = GetElement(row); - if (h != NULL) { - m_pDraw2D = h->Highlight(); - m_pHighlight = h; - } -} - -ISAXHandler *CDbgDlg::GetElement(std::size_t row) -{ - return static_cast(g_ptr_array_index(m_pFeedbackElements, gint( row )) ); -} - -void CDbgDlg::Init() -{ - DropHighlight(); - - // free all the ISAXHandler*, clean it - while (m_pFeedbackElements->len) { - static_cast(g_ptr_array_index(m_pFeedbackElements, 0) )->Release(); - g_ptr_array_remove_index(m_pFeedbackElements, 0); - } - - if (m_clist) { - m_clist.clear(); - } -} - -void CDbgDlg::Push(ISAXHandler *pHandler) -{ - // push in the list - g_ptr_array_add(m_pFeedbackElements, (void *) pHandler); - - if (!GetWidget()) { - Create(); - } - - // put stuff in the list - m_clist.clear(); - for (std::size_t i = 0; i < static_cast( m_pFeedbackElements->len ); ++i) { - m_clist.append(0, GetElement(i)->getName()); - } - - ShowDlg(); -} - -ui::Window CDbgDlg::BuildDialog() -{ - auto window = MainFrame_getWindow().create_floating_window("Q3Map debug window"); - - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - window.add(scr); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - selection.connect("changed", G_CALLBACK(feedback_selection_changed), NULL); - } - - view.show(); - - scr.add(view); - - store.unref(); - - m_clist = store; - } - - return window; -} diff --git a/src/feedback.h b/src/feedback.h deleted file mode 100644 index 56c2d7f..0000000 --- a/src/feedback.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// classes used for describing geometry information from q3map feedback -// - -#ifndef __Q3MAP_FEEDBACK__ -#define __Q3MAP_FEEDBACK__ - -#include "math/vector.h" -#include "stream/stringstream.h" -#include "xmlstuff.h" -#include "dialog.h" -#include "xywindow.h" - -// we use these classes to let plugins draw inside the Radiant windows -// 2D window like YZ XZ XY -class IGL2DWindow { -public: -virtual ~IGL2DWindow() = default; - -// Increment the number of references to this object -virtual void IncRef() = 0; - -// Decrement the reference count -virtual void DecRef() = 0; - -virtual void Draw2D(VIEWTYPE vt) = 0; -}; - -// 3D window -class IGL3DWindow { -public: -// Increment the number of references to this object -virtual void IncRef() = 0; - -// Decrement the reference count -virtual void DecRef() = 0; - -virtual void Draw3D() = 0; -}; - -// a select message with a brush/entity select information -class CSelectMsg : public ISAXHandler { -enum { SELECT_MESSAGE, SELECT_BRUSH } ESelectState; -StringOutputStream message; -StringOutputStream brush; -public: -CSelectMsg() -{ - ESelectState = SELECT_MESSAGE; -} - -// SAX interface -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight() -{ -} -}; - -class CPointMsg : public ISAXHandler, public IGL2DWindow { -enum { POINT_MESSAGE, POINT_POINT } EPointState; -StringOutputStream message; -StringOutputStream point; -Vector3 pt; -int refCount; -public: -CPointMsg() -{ - EPointState = POINT_MESSAGE; - refCount = 0; -} - -// SAX interface -void Release() -{ - delete this; -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight(); - -// IGL2DWindow interface -------------------------------- -// Increment the number of references to this object -void IncRef() -{ - refCount++; -} - -// Decrement the reference count -void DecRef() -{ - refCount--; - if (refCount <= 0) { - delete this; - } -} - -void Draw2D(VIEWTYPE vt); -}; - -class CWindingMsg : public ISAXHandler, public IGL2DWindow { -enum { WINDING_MESSAGE, WINDING_WINDING } EPointState; -StringOutputStream message; -StringOutputStream winding; -Vector3 wt[256]; -int numpoints; -int refCount; -public: -CWindingMsg() -{ - EPointState = WINDING_MESSAGE; - refCount = 0; - numpoints = 0; -} - -// SAX interface -void Release() -{ - delete this; -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight(); - -// IGL2DWindow interface -------------------------------- -// Increment the number of references to this object -void IncRef() -{ - refCount++; -} - -// Decrement the reference count -void DecRef() -{ - refCount--; - if (refCount <= 0) { - delete this; - } -} - -void Draw2D(VIEWTYPE vt); -}; - - -class CDbgDlg : public Dialog { -GPtrArray *m_pFeedbackElements; -// the list widget we use in the dialog -ui::ListStore m_clist{ui::null}; -ISAXHandler *m_pHighlight; -IGL2DWindow *m_pDraw2D; -public: -CDbgDlg() -{ - m_pFeedbackElements = g_ptr_array_new(); - m_pHighlight = NULL; - m_pDraw2D = NULL; -} - -// refresh items -void Push(ISAXHandler *); - -// clean the debug window, release all ISAXHanlders we have -void Init(); - -ISAXHandler *GetElement(std::size_t row); - -void SetHighlight(gint row); - -void DropHighlight(); - -void draw2D(VIEWTYPE viewType) -{ - if (m_pDraw2D != 0) { - m_pDraw2D->Draw2D(viewType); - } -} - -void destroyWindow() -{ - if (GetWidget()) { - Destroy(); - } -} -// void HideDlg(); -protected: -ui::Window BuildDialog(); -}; - -extern CDbgDlg g_DbgDlg; - -void Feedback_draw2D(VIEWTYPE viewType); - -#endif diff --git a/src/filetypes.cpp b/src/filetypes.cpp deleted file mode 100644 index d0c985b..0000000 --- a/src/filetypes.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filetypes.h" - -#include "debugging/debugging.h" - -#include "ifiletypes.h" - -#include "string/string.h" -#include "os/path.h" -#include -#include - -class RadiantFileTypeRegistry : public IFileTypeRegistry { -struct filetype_copy_t { - filetype_copy_t(const char *moduleName, const filetype_t other) - : m_can_load(other.can_load), m_can_import(other.can_import), m_can_save(other.can_save), - m_moduleName(moduleName), m_name(other.name), m_pattern(other.pattern) - { - } - - const char *getModuleName() const - { - return m_moduleName.c_str(); - } - - filetype_t getType() const - { - return filetype_t(m_name.c_str(), m_pattern.c_str(), m_can_load, m_can_save, m_can_import); - } - - bool m_can_load; - bool m_can_import; - bool m_can_save; -private: - CopiedString m_moduleName; - CopiedString m_name; - CopiedString m_pattern; -}; - -typedef std::vector filetype_list_t; -std::map m_typelists; -public: -RadiantFileTypeRegistry() -{ - addType("*", "*", filetype_t("All Files", "*.*")); -} - -void addType(const char *moduleType, const char *moduleName, filetype_t type) -{ - m_typelists[moduleType].push_back(filetype_copy_t(moduleName, type)); -} - -void getTypeList(const char *moduleType, IFileTypeList *typelist, bool want_load, bool want_import, bool want_save) -{ - filetype_list_t &list_ref = m_typelists[moduleType]; - for (filetype_list_t::iterator i = list_ref.begin(); i != list_ref.end(); ++i) { - if (want_load && !(*i).m_can_load) { - return; - } - if (want_import && !(*i).m_can_import) { - return; - } - if (want_save && !(*i).m_can_save) { - return; - } - typelist->addType((*i).getModuleName(), (*i).getType()); - } -} -}; - -static RadiantFileTypeRegistry g_patterns; - -IFileTypeRegistry *GetFileTypeRegistry() -{ - return &g_patterns; -} - -const char *findModuleName(IFileTypeRegistry *registry, const char *moduleType, const char *extension) -{ - class SearchFileTypeList : public IFileTypeList { - char m_pattern[128]; - const char *m_moduleName; -public: - SearchFileTypeList(const char *ext) - : m_moduleName("") - { - m_pattern[0] = '*'; - m_pattern[1] = '.'; - strncpy(m_pattern + 2, ext, 125); - m_pattern[127] = '\0'; - } - - void addType(const char *moduleName, filetype_t type) - { - if (extension_equal(m_pattern, type.pattern)) { - m_moduleName = moduleName; - } - } - - const char *getModuleName() - { - return m_moduleName; - } - } search(extension); - registry->getTypeList(moduleType, &search); - return search.getModuleName(); -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class FiletypesAPI { -IFileTypeRegistry *m_filetypes; -public: -typedef IFileTypeRegistry Type; - -STRING_CONSTANT(Name, "*"); - -FiletypesAPI() -{ - m_filetypes = GetFileTypeRegistry(); -} - -IFileTypeRegistry *getTable() -{ - return m_filetypes; -} -}; - -typedef SingletonModule FiletypesModule; -typedef Static StaticFiletypesModule; -StaticRegisterModule staticRegisterFiletypes(StaticFiletypesModule::instance()); diff --git a/src/filetypes.h b/src/filetypes.h deleted file mode 100644 index 60cabca..0000000 --- a/src/filetypes.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FILETYPES_H ) -#define INCLUDED_FILETYPES_H - -class IFileTypeRegistry; - -IFileTypeRegistry *GetFileTypeRegistry(); - -const char *findModuleName(IFileTypeRegistry *registry, const char *moduleType, const char *extension); - -#endif diff --git a/src/filters.cpp b/src/filters.cpp deleted file mode 100644 index 78cb0ea..0000000 --- a/src/filters.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filters.h" - -#include "debugging/debugging.h" - -#include "ifilter.h" - -#include "scenelib.h" - -#include -#include - -#include "gtkutil/widget.h" -#include "gtkutil/menu.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "commands.h" -#include "preferences.h" - -struct filters_globals_t { - std::size_t exclude; - - filters_globals_t() : - exclude(0) - { - } -}; - -filters_globals_t g_filters_globals; - -inline bool filter_active(int mask) -{ - return (g_filters_globals.exclude & mask) > 0; -} - -class FilterWrapper { -public: -FilterWrapper(Filter &filter, int mask) : m_filter(filter), m_mask(mask) -{ -} - -void update() -{ - m_filter.setActive(filter_active(m_mask)); -} - -private: -Filter &m_filter; -int m_mask; -}; - -typedef std::list Filters; -Filters g_filters; - -typedef std::set Filterables; -Filterables g_filterables; - -void UpdateFilters() -{ - { - for (Filters::iterator i = g_filters.begin(); i != g_filters.end(); ++i) { - (*i).update(); - } - } - - { - for (Filterables::iterator i = g_filterables.begin(); i != g_filterables.end(); ++i) { - (*i)->updateFiltered(); - } - } -} - - -class BasicFilterSystem : public FilterSystem { -public: -void addFilter(Filter &filter, int mask) -{ - g_filters.push_back(FilterWrapper(filter, mask)); - g_filters.back().update(); -} - -void registerFilterable(Filterable &filterable) -{ - ASSERT_MESSAGE(g_filterables.find(&filterable) == g_filterables.end(), "filterable already registered"); - filterable.updateFiltered(); - g_filterables.insert(&filterable); -} - -void unregisterFilterable(Filterable &filterable) -{ - ASSERT_MESSAGE(g_filterables.find(&filterable) != g_filterables.end(), "filterable not registered"); - g_filterables.erase(&filterable); -} -}; - -BasicFilterSystem g_FilterSystem; - -FilterSystem &GetFilterSystem() -{ - return g_FilterSystem; -} - -void PerformFiltering() -{ - UpdateFilters(); - SceneChangeNotify(); -} - -class ToggleFilterFlag { -const unsigned int m_mask; -public: -ToggleItem m_item; - -ToggleFilterFlag(unsigned int mask) : m_mask(mask), m_item(ActiveCaller(*this)) -{ -} - -ToggleFilterFlag(const ToggleFilterFlag &other) : m_mask(other.m_mask), m_item(ActiveCaller(*this)) -{ -} - -void active(const Callback &importCallback) -{ - importCallback((g_filters_globals.exclude & m_mask) != 0); -} - -typedef MemberCaller &), &ToggleFilterFlag::active> ActiveCaller; - -void toggle() -{ - g_filters_globals.exclude ^= m_mask; - m_item.update(); - PerformFiltering(); -} - -void reset() -{ - g_filters_globals.exclude = 0; - m_item.update(); - PerformFiltering(); -} - -typedef MemberCaller ToggleCaller; -}; - - -typedef std::list ToggleFilterFlags; -ToggleFilterFlags g_filter_items; - -void add_filter_command(unsigned int flag, const char *command, const Accelerator &accelerator) -{ - g_filter_items.push_back(ToggleFilterFlag(flag)); - GlobalToggles_insert(command, ToggleFilterFlag::ToggleCaller(g_filter_items.back()), - ToggleItem::AddCallbackCaller(g_filter_items.back().m_item), accelerator); -} - -void InvertFilters() -{ - std::list::iterator iter; - - for (iter = g_filter_items.begin(); iter != g_filter_items.end(); ++iter) { - iter->toggle(); - } -} - -void ResetFilters() -{ - std::list::iterator iter; - - for (iter = g_filter_items.begin(); iter != g_filter_items.end(); ++iter) { - iter->reset(); - } -} - -void Filters_constructMenu(ui::Menu menu_in_menu) -{ - create_check_menu_item_with_mnemonic(menu_in_menu, "World", "FilterWorldBrushes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Groups", "FilterGroupBrushes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Entities", "FilterEntities"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Areaportals", "FilterAreaportals"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Translucent", "FilterTranslucent"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Liquids", "FilterLiquids"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Caulk", "FilterCaulk"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Clips", "FilterClips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Paths", "FilterPaths"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Clusterportals", "FilterClusterportals"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Lights", "FilterLights"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Structural", "FilterStructural"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Lightgrid", "FilterLightgrid"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Patches", "FilterPatches"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Details", "FilterDetails"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Hints", "FilterHintsSkips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Models", "FilterModels"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Triggers", "FilterTriggers"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Botclips", "FilterBotClips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Decals", "FilterDecals"); - - // filter manipulation - menu_separator(menu_in_menu); - create_menu_item_with_mnemonic(menu_in_menu, "Invert filters", "InvertFilters"); - create_menu_item_with_mnemonic(menu_in_menu, "Reset filters", "ResetFilters"); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void ConstructFilters() -{ - GlobalPreferenceSystem().registerPreference("SI_Exclude", make_property_string(g_filters_globals.exclude)); - - GlobalCommands_insert("InvertFilters", makeCallbackF(InvertFilters)); - GlobalCommands_insert("ResetFilters", makeCallbackF(ResetFilters)); - - add_filter_command(EXCLUDE_WORLD, "FilterWorldBrushes", Accelerator('1', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_GROUP, "FilterGroupBrushes", accelerator_null()); - add_filter_command(EXCLUDE_ENT, "FilterEntities", Accelerator('2', (GdkModifierType) GDK_MOD1_MASK)); - if (g_pGameDescription->mGameType == "doom3") { - add_filter_command(EXCLUDE_VISPORTALS, "FilterVisportals", Accelerator('3', (GdkModifierType) GDK_MOD1_MASK)); - } else { - add_filter_command(EXCLUDE_AREAPORTALS, "FilterAreaportals", Accelerator('3', (GdkModifierType) GDK_MOD1_MASK)); - } - add_filter_command(EXCLUDE_TRANSLUCENT, "FilterTranslucent", Accelerator('4', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_LIQUIDS, "FilterLiquids", Accelerator('5', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_CAULK, "FilterCaulk", Accelerator('6', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_CLIP, "FilterClips", Accelerator('7', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_PATHS, "FilterPaths", Accelerator('8', (GdkModifierType) GDK_MOD1_MASK)); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_CLUSTERPORTALS, "FilterClusterportals", - Accelerator('9', (GdkModifierType) GDK_MOD1_MASK)); - } - add_filter_command(EXCLUDE_LIGHTS, "FilterLights", Accelerator('0', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_STRUCTURAL, "FilterStructural", - Accelerator('D', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_LIGHTGRID, "FilterLightgrid", accelerator_null()); - } - add_filter_command(EXCLUDE_CURVES, "FilterPatches", Accelerator('P', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_DETAILS, "FilterDetails", Accelerator('D', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_HINTSSKIPS, "FilterHintsSkips", Accelerator('H', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_MODELS, "FilterModels", Accelerator('M', (GdkModifierType) GDK_SHIFT_MASK)); - add_filter_command(EXCLUDE_TRIGGERS, "FilterTriggers", - Accelerator('T', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_BOTCLIP, "FilterBotClips", Accelerator('M', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_DECALS, "FilterDecals", Accelerator('D', (GdkModifierType) GDK_SHIFT_MASK)); - } - - PerformFiltering(); -} - -void DestroyFilters() -{ - g_filters.clear(); -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class FilterAPI { -FilterSystem *m_filter; -public: -typedef FilterSystem Type; - -STRING_CONSTANT(Name, "*"); - -FilterAPI() -{ - ConstructFilters(); - - m_filter = &GetFilterSystem(); -} - -~FilterAPI() -{ - DestroyFilters(); -} - -FilterSystem *getTable() -{ - return m_filter; -} -}; - -typedef SingletonModule FilterModule; -typedef Static StaticFilterModule; -StaticRegisterModule staticRegisterFilter(StaticFilterModule::instance()); diff --git a/src/filters.h b/src/filters.h deleted file mode 100644 index 12c71cd..0000000 --- a/src/filters.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_FILTERS_H ) -#define INCLUDED_FILTERS_H - -void Filters_constructMenu(ui::Menu menu_in_menu); - -#endif diff --git a/src/findtexturedialog.cpp b/src/findtexturedialog.cpp deleted file mode 100644 index 4c7a4f3..0000000 --- a/src/findtexturedialog.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Find/Replace textures dialogs -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "findtexturedialog.h" - -#include - -#include "debugging/debugging.h" - -#include "ishaders.h" - -#include "gtkutil/window.h" -#include "stream/stringstream.h" - -#include "commands.h" -#include "dialog.h" -#include "select.h" -#include "textureentry.h" - - -class FindTextureDialog : public Dialog { -public: -static void setReplaceStr(const char *name); - -static void setFindStr(const char *name); - -static bool isOpen(); - -static void show(); - -typedef FreeCaller ShowCaller; - -static void updateTextures(const char *name); - -FindTextureDialog(); - -virtual ~FindTextureDialog(); - -ui::Window BuildDialog(); - -void constructWindow(ui::Window parent) -{ - m_parent = parent; - Create(); -} - -void destroyWindow() -{ - Destroy(); -} - - -bool m_bSelectedOnly; -CopiedString m_strFind; -CopiedString m_strReplace; -}; - -FindTextureDialog g_FindTextureDialog; -static bool g_bFindActive = true; - -namespace { -void FindTextureDialog_apply() -{ - StringOutputStream find(256); - StringOutputStream replace(256); - - find << "textures/" << g_FindTextureDialog.m_strFind.c_str(); - replace << "textures/" << g_FindTextureDialog.m_strReplace.c_str(); - FindReplaceTextures(find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly); -} - -static void OnApply(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); -} - -static void OnFind(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); -} - -static void OnOK(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); - g_FindTextureDialog.HideDlg(); -} - -static void OnClose(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.HideDlg(); -} - - -static gint find_focus_in(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - g_bFindActive = true; - return FALSE; -} - -static gint replace_focus_in(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - g_bFindActive = false; - return FALSE; -} -} - -// ============================================================================= -// FindTextureDialog class - -FindTextureDialog::FindTextureDialog() -{ - m_bSelectedOnly = FALSE; -} - -FindTextureDialog::~FindTextureDialog() -{ -} - -ui::Window FindTextureDialog::BuildDialog() -{ - ui::Widget label{ui::null}; - ui::Widget button{ui::null}; - ui::Entry entry{ui::null}; - - auto dlg = ui::Window(create_floating_window("Find / Replace Texture(s)", m_parent)); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - dlg.add(hbox); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - hbox.pack_start(vbox, TRUE, TRUE, 0); - - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - label = ui::Label("Find:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - - label = ui::Label("Replace:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - - entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - entry.connect("focus_in_event", - G_CALLBACK(find_focus_in), 0); - AddDialogData(entry, m_strFind); - GlobalTextureEntryCompletion::instance().connect(entry); - - entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - entry.connect("focus_in_event", - G_CALLBACK(replace_focus_in), 0); - AddDialogData(entry, m_strReplace); - GlobalTextureEntryCompletion::instance().connect(entry); - - auto check = ui::CheckButton("Within selected brushes only"); - check.show(); - vbox.pack_start(check, TRUE, TRUE, 0); - AddDialogData(check, m_bSelectedOnly); - - vbox = ui::VBox(FALSE, 5); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - button = ui::Button("Apply"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(OnApply), 0); - button.dimensions(60, -1); - - button = ui::Button("Close"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(OnClose), 0); - button.dimensions(60, -1); - - return dlg; -} - -void FindTextureDialog::updateTextures(const char *name) -{ - if (isOpen()) { - if (g_bFindActive) { - setFindStr(name + 9); - } else { - setReplaceStr(name + 9); - } - } -} - -bool FindTextureDialog::isOpen() -{ - return g_FindTextureDialog.GetWidget().visible(); -} - -void FindTextureDialog::setFindStr(const char *name) -{ - g_FindTextureDialog.exportData(); - g_FindTextureDialog.m_strFind = name; - g_FindTextureDialog.importData(); -} - -void FindTextureDialog::setReplaceStr(const char *name) -{ - g_FindTextureDialog.exportData(); - g_FindTextureDialog.m_strReplace = name; - g_FindTextureDialog.importData(); -} - -void FindTextureDialog::show() -{ - g_FindTextureDialog.ShowDlg(); -} - - -void FindTextureDialog_constructWindow(ui::Window main_window) -{ - g_FindTextureDialog.constructWindow(main_window); -} - -void FindTextureDialog_destroyWindow() -{ - g_FindTextureDialog.destroyWindow(); -} - -bool FindTextureDialog_isOpen() -{ - return g_FindTextureDialog.isOpen(); -} - -void FindTextureDialog_selectTexture(const char *name) -{ - g_FindTextureDialog.updateTextures(name); -} - -void FindTextureDialog_Construct() -{ - GlobalCommands_insert("FindReplaceTextures", FindTextureDialog::ShowCaller()); -} - -void FindTextureDialog_Destroy() -{ -} diff --git a/src/findtexturedialog.h b/src/findtexturedialog.h deleted file mode 100644 index a367c15..0000000 --- a/src/findtexturedialog.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_FINDTEXTUREDIALOG_H ) -#define INCLUDED_FINDTEXTUREDIALOG_H - -void FindTextureDialog_Construct(); - -void FindTextureDialog_Destroy(); - -void FindTextureDialog_constructWindow(ui::Window main_window); - -void FindTextureDialog_destroyWindow(); - -bool FindTextureDialog_isOpen(); - -void FindTextureDialog_selectTexture(const char *name); - -#endif diff --git a/tools/vmap/fixaas.c b/src/fixaas.c similarity index 100% rename from tools/vmap/fixaas.c rename to src/fixaas.c diff --git a/tools/vmap/fog.c b/src/fog.c similarity index 100% rename from tools/vmap/fog.c rename to src/fog.c diff --git a/tools/vmap/game__null.h b/src/game__null.h similarity index 100% rename from tools/vmap/game__null.h rename to src/game__null.h diff --git a/tools/vmap/game_fte.h b/src/game_fte.h similarity index 100% rename from tools/vmap/game_fte.h rename to src/game_fte.h diff --git a/src/glwidget.cpp b/src/glwidget.cpp deleted file mode 100644 index 59d53cf..0000000 --- a/src/glwidget.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "glwidget.h" - -#include "igtkgl.h" -#include "modulesystem.h" -#include "gtkutil/glwidget.h" - -class GtkGLAPI { -_QERGtkGLTable m_gtkgl; -public: -typedef _QERGtkGLTable Type; - -STRING_CONSTANT(Name, "*"); - -GtkGLAPI() -{ - m_gtkgl.glwidget_new = &glwidget_new; - m_gtkgl.glwidget_swap_buffers = &glwidget_swap_buffers; - m_gtkgl.glwidget_make_current = &glwidget_make_current; - m_gtkgl.glwidget_destroy_context = &glwidget_destroy_context; - m_gtkgl.glwidget_create_context = &glwidget_create_context; -} - -_QERGtkGLTable *getTable() -{ - return &m_gtkgl; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule GtkGLModule; -typedef Static StaticGtkGLModule; -StaticRegisterModule staticRegisterGtkGL(StaticGtkGLModule::instance()); diff --git a/src/glwidget.h b/src/glwidget.h deleted file mode 100644 index 0adad26..0000000 --- a/src/glwidget.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GLWIDGET_H ) -#define INCLUDED_GLWIDGET_H - -#endif diff --git a/src/grid.cpp b/src/grid.cpp deleted file mode 100644 index 57cc84b..0000000 --- a/src/grid.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "grid.h" - -#include -#include -#include - -#include "preferencesystem.h" - -#include "gtkutil/widget.h" -#include "signal/signal.h" -#include "stringio.h" - -#include "gtkmisc.h" -#include "commands.h" -#include "preferences.h" - - -Signal0 g_gridChange_callbacks; - -void AddGridChangeCallback(const SignalHandler &handler) -{ - g_gridChange_callbacks.connectLast(handler); - handler(); -} - -void GridChangeNotify() -{ - g_gridChange_callbacks(); -} - -enum GridPower { - GRIDPOWER_0125 = -3, - GRIDPOWER_025 = -2, - GRIDPOWER_05 = -1, - GRIDPOWER_1 = 0, - GRIDPOWER_2 = 1, - GRIDPOWER_4 = 2, - GRIDPOWER_8 = 3, - GRIDPOWER_16 = 4, - GRIDPOWER_32 = 5, - GRIDPOWER_64 = 6, - GRIDPOWER_128 = 7, - GRIDPOWER_256 = 8, -}; - - -typedef const char *GridName; -// this must match the GridPower enumeration -const GridName g_gridnames[] = { - "0.125", - "0.25", - "0.5", - "1", - "2", - "4", - "8", - "16", - "32", - "64", - "128", - "256", -}; - -inline GridPower GridPower_forGridDefault(int gridDefault) -{ - return static_cast( gridDefault - 3 ); -} - -inline int GridDefault_forGridPower(GridPower gridPower) -{ - return gridPower + 3; -} - -int g_grid_default = GridDefault_forGridPower(GRIDPOWER_8); - -int g_grid_power = GridPower_forGridDefault(g_grid_default); - -bool g_grid_snap = true; - -int Grid_getPower() -{ - return g_grid_power; -} - -inline float GridSize_forGridPower(int gridPower) -{ - return pow(2.0f, gridPower); -} - -float g_gridsize = GridSize_forGridPower(g_grid_power); - -float GetSnapGridSize() -{ - return g_grid_snap ? g_gridsize : 0; -} - -float GetGridSize() -{ - return g_gridsize; -} - - -void setGridPower(GridPower power); - -class GridMenuItem { -GridPower m_id; - -GridMenuItem(const GridMenuItem &other); // NOT COPYABLE -GridMenuItem &operator=(const GridMenuItem &other); // NOT ASSIGNABLE -public: -ToggleItem m_item; - -GridMenuItem(GridPower id) : m_id(id), m_item(ExportCaller(*this)) -{ -} - -void set() -{ - g_grid_power = m_id; - m_item.update(); - setGridPower(m_id); -} - -typedef MemberCaller SetCaller; - -void active(const Callback &importCallback) -{ - importCallback(g_grid_power == m_id); -} - -typedef MemberCaller &), &GridMenuItem::active> ExportCaller; -}; - -GridMenuItem g_gridMenu0125(GRIDPOWER_0125); -GridMenuItem g_gridMenu025(GRIDPOWER_025); -GridMenuItem g_gridMenu05(GRIDPOWER_05); -GridMenuItem g_gridMenu1(GRIDPOWER_1); -GridMenuItem g_gridMenu2(GRIDPOWER_2); -GridMenuItem g_gridMenu4(GRIDPOWER_4); -GridMenuItem g_gridMenu8(GRIDPOWER_8); -GridMenuItem g_gridMenu16(GRIDPOWER_16); -GridMenuItem g_gridMenu32(GRIDPOWER_32); -GridMenuItem g_gridMenu64(GRIDPOWER_64); -GridMenuItem g_gridMenu128(GRIDPOWER_128); -GridMenuItem g_gridMenu256(GRIDPOWER_256); - -void setGridPower(GridPower power) -{ - g_grid_snap = true; - g_gridsize = GridSize_forGridPower(power); - - g_gridMenu0125.m_item.update(); - g_gridMenu025.m_item.update(); - g_gridMenu05.m_item.update(); - g_gridMenu1.m_item.update(); - g_gridMenu2.m_item.update(); - g_gridMenu4.m_item.update(); - g_gridMenu8.m_item.update(); - g_gridMenu16.m_item.update(); - g_gridMenu32.m_item.update(); - g_gridMenu64.m_item.update(); - g_gridMenu128.m_item.update(); - g_gridMenu256.m_item.update(); - GridChangeNotify(); -} - -void GridPrev() -{ - g_grid_snap = true; - if (g_grid_power > GRIDPOWER_0125) { - setGridPower(static_cast( --g_grid_power )); - } -} - -void GridNext() -{ - g_grid_snap = true; - if (g_grid_power < GRIDPOWER_256) { - setGridPower(static_cast( ++g_grid_power )); - } -} - -void ToggleGridSnap() -{ - g_grid_snap = !g_grid_snap; - GridChangeNotify(); -} - -void Grid_registerCommands() -{ - GlobalCommands_insert("GridDown", makeCallbackF(GridPrev), Accelerator('[')); - GlobalCommands_insert("GridUp", makeCallbackF(GridNext), Accelerator(']')); - - GlobalCommands_insert("ToggleGridSnap", makeCallbackF(ToggleGridSnap)); - - GlobalToggles_insert("SetGrid0.125", GridMenuItem::SetCaller(g_gridMenu0125), - ToggleItem::AddCallbackCaller(g_gridMenu0125.m_item)); - GlobalToggles_insert("SetGrid0.25", GridMenuItem::SetCaller(g_gridMenu025), - ToggleItem::AddCallbackCaller(g_gridMenu025.m_item)); - GlobalToggles_insert("SetGrid0.5", GridMenuItem::SetCaller(g_gridMenu05), - ToggleItem::AddCallbackCaller(g_gridMenu05.m_item)); - GlobalToggles_insert("SetGrid1", GridMenuItem::SetCaller(g_gridMenu1), - ToggleItem::AddCallbackCaller(g_gridMenu1.m_item), Accelerator('1')); - GlobalToggles_insert("SetGrid2", GridMenuItem::SetCaller(g_gridMenu2), - ToggleItem::AddCallbackCaller(g_gridMenu2.m_item), Accelerator('2')); - GlobalToggles_insert("SetGrid4", GridMenuItem::SetCaller(g_gridMenu4), - ToggleItem::AddCallbackCaller(g_gridMenu4.m_item), Accelerator('3')); - GlobalToggles_insert("SetGrid8", GridMenuItem::SetCaller(g_gridMenu8), - ToggleItem::AddCallbackCaller(g_gridMenu8.m_item), Accelerator('4')); - GlobalToggles_insert("SetGrid16", GridMenuItem::SetCaller(g_gridMenu16), - ToggleItem::AddCallbackCaller(g_gridMenu16.m_item), Accelerator('5')); - GlobalToggles_insert("SetGrid32", GridMenuItem::SetCaller(g_gridMenu32), - ToggleItem::AddCallbackCaller(g_gridMenu32.m_item), Accelerator('6')); - GlobalToggles_insert("SetGrid64", GridMenuItem::SetCaller(g_gridMenu64), - ToggleItem::AddCallbackCaller(g_gridMenu64.m_item), Accelerator('7')); - GlobalToggles_insert("SetGrid128", GridMenuItem::SetCaller(g_gridMenu128), - ToggleItem::AddCallbackCaller(g_gridMenu128.m_item), Accelerator('8')); - GlobalToggles_insert("SetGrid256", GridMenuItem::SetCaller(g_gridMenu256), - ToggleItem::AddCallbackCaller(g_gridMenu256.m_item), Accelerator('9')); -} - - -void Grid_constructMenu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "Grid0.125", "SetGrid0.125"); - create_check_menu_item_with_mnemonic(menu, "Grid0.25", "SetGrid0.25"); - create_check_menu_item_with_mnemonic(menu, "Grid0.5", "SetGrid0.5"); - create_check_menu_item_with_mnemonic(menu, "Grid1", "SetGrid1"); - create_check_menu_item_with_mnemonic(menu, "Grid2", "SetGrid2"); - create_check_menu_item_with_mnemonic(menu, "Grid4", "SetGrid4"); - create_check_menu_item_with_mnemonic(menu, "Grid8", "SetGrid8"); - create_check_menu_item_with_mnemonic(menu, "Grid16", "SetGrid16"); - create_check_menu_item_with_mnemonic(menu, "Grid32", "SetGrid32"); - create_check_menu_item_with_mnemonic(menu, "Grid64", "SetGrid64"); - create_check_menu_item_with_mnemonic(menu, "Grid128", "SetGrid128"); - create_check_menu_item_with_mnemonic(menu, "Grid256", "SetGrid256"); -} - -void Grid_registerShortcuts() -{ - command_connect_accelerator("ToggleGrid"); - command_connect_accelerator("GridDown"); - command_connect_accelerator("GridUp"); - command_connect_accelerator("ToggleGridSnap"); -} - -void Grid_constructPreferences(PreferencesPage &page) -{ - page.appendCombo( - "Default grid spacing", - g_grid_default, - ARRAY_RANGE(g_gridnames) - ); -} - -void Grid_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Grid", "Grid Settings")); - Grid_constructPreferences(page); -} - -void Grid_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Grid_constructPage)); -} - -void Grid_construct() -{ - Grid_registerPreferencesPage(); - - g_grid_default = GridDefault_forGridPower(GRIDPOWER_8); - - GlobalPreferenceSystem().registerPreference("GridDefault", make_property_string(g_grid_default)); - - g_grid_power = GridPower_forGridDefault(g_grid_default); - g_gridsize = GridSize_forGridPower(g_grid_power); -} - -void Grid_destroy() -{ -} diff --git a/src/grid.h b/src/grid.h deleted file mode 100644 index 513f4a0..0000000 --- a/src/grid.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GRID_H ) -#define INCLUDED_GRID_H - -#include -#include "signal/signalfwd.h" - -float GetSnapGridSize(); - -float GetGridSize(); - -int Grid_getPower(); - -void AddGridChangeCallback(const SignalHandler &handler); - -void Grid_registerCommands(); - -void Grid_constructMenu(ui::Menu menu); - -void Grid_registerShortcuts(); - -void Grid_construct(); - -void Grid_destroy(); - -#endif diff --git a/src/groupdialog.cpp b/src/groupdialog.cpp deleted file mode 100644 index 318bcb3..0000000 --- a/src/groupdialog.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Floating dialog that contains a notebook with at least Entities and Group tabs -// I merged the 2 MS Windows dialogs in a single class -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "groupdialog.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "gtkutil/widget.h" -#include "gtkutil/accelerator.h" -#include "entityinspector.h" -#include "gtkmisc.h" -#include "multimon.h" -#include "console.h" -#include "commands.h" - - -#include "gtkutil/window.h" - -class GroupDlg { -public: -ui::Widget m_pNotebook{ui::null}; -ui::Window m_window{ui::null}; - -GroupDlg(); - -void Create(ui::Window parent); - -void Show() -{ - // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event - m_position_tracker.sync(m_window); - m_window.show(); -} - -void Hide() -{ - m_window.hide(); -} - -WindowPositionTracker m_position_tracker; -}; - -namespace { -GroupDlg g_GroupDlg; - -std::size_t g_current_page; -std::vector &)> > g_pages; -} - -void GroupDialog_updatePageTitle(ui::Window window, std::size_t pageIndex) -{ - if (pageIndex < g_pages.size()) { - g_pages[pageIndex](PointerCaller(window)); - } -} - -static gboolean switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer data) -{ - GroupDialog_updatePageTitle(ui::Window::from(data), page_num); - g_current_page = page_num; - - return FALSE; -} - -GroupDlg::GroupDlg() : m_window(ui::null) -{ - m_position_tracker.setPosition(c_default_window_pos); -} - -void GroupDlg::Create(ui::Window parent) -{ - ASSERT_MESSAGE(!m_window, "dialog already created"); - - auto window = ui::Window(create_persistent_floating_window("Entities", parent)); - gtk_window_set_keep_above(GTK_WINDOW(window), TRUE); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - m_window = window; - -#if GDEF_OS_WINDOWS - if ( g_multimon_globals.m_bStartOnPrimMon ) { - WindowPosition pos( m_position_tracker.getPosition() ); - PositionWindowOnPrimaryScreen( pos ); - m_position_tracker.setPosition( pos ); - } -#endif - m_position_tracker.connect(window); - - { - ui::Widget notebook = ui::Widget::from(gtk_notebook_new()); - notebook.show(); - window.add(notebook); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM); - m_pNotebook = notebook; - - notebook.connect("switch_page", G_CALLBACK(switch_page), (gpointer) window); - } -} - - -ui::Widget GroupDialog_addPage(const char *tabLabel, ui::Widget widget, - const Callback &)> &title) -{ - ui::Widget w = ui::Label(tabLabel); - w.show(); - auto page = ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), - gtk_notebook_insert_page( - GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), widget, w, - -1))); - g_pages.push_back(title); - - return page; -} - - -bool GroupDialog_isShown() -{ - return g_GroupDlg.m_window.visible(); -} - -void GroupDialog_setShown(bool shown) -{ - shown ? g_GroupDlg.Show() : g_GroupDlg.Hide(); -} - -void GroupDialog_ToggleShow() -{ - GroupDialog_setShown(!GroupDialog_isShown()); -} - -void GroupDialog_constructWindow(ui::Window main_window) -{ - g_GroupDlg.Create(main_window); -} - -void GroupDialog_destroyWindow() -{ - ASSERT_TRUE(g_GroupDlg.m_window); - destroy_floating_window(g_GroupDlg.m_window); - g_GroupDlg.m_window = ui::Window{ui::null}; -} - - -ui::Window GroupDialog_getWindow() -{ - return ui::Window(g_GroupDlg.m_window); -} - -void GroupDialog_show() -{ - g_GroupDlg.Show(); -} - -ui::Widget GroupDialog_getPage() -{ - return ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page))); -} - -void GroupDialog_setPage(ui::Widget page) -{ - g_current_page = gtk_notebook_page_num(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), page); - gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page)); -} - -void GroupDialog_showPage(ui::Widget page) -{ - if (GroupDialog_getPage() == page) { - GroupDialog_ToggleShow(); - } else { - g_GroupDlg.m_window.show(); - GroupDialog_setPage(page); - } -} - -void GroupDialog_cycle() -{ - g_current_page = (g_current_page + 1) % g_pages.size(); - gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page)); -} - -void GroupDialog_updatePageTitle(ui::Widget page) -{ - if (GroupDialog_getPage() == page) { - GroupDialog_updatePageTitle(g_GroupDlg.m_window, g_current_page); - } -} - - -#include "preferencesystem.h" - -void GroupDialog_Construct() -{ - GlobalPreferenceSystem().registerPreference("EntityWnd", make_property( - g_GroupDlg.m_position_tracker)); - - GlobalCommands_insert("ViewEntityInfo", makeCallbackF(GroupDialog_ToggleShow), Accelerator('N')); -} - -void GroupDialog_Destroy() -{ -} diff --git a/src/groupdialog.h b/src/groupdialog.h deleted file mode 100644 index bf0026c..0000000 --- a/src/groupdialog.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GROUPDIALOG_H ) -#define INCLUDED_GROUPDIALOG_H - -#include -#include "property.h" -#include "generic/callback.h" - -void GroupDialog_Construct(); - -void GroupDialog_Destroy(); - -void GroupDialog_constructWindow(ui::Window main_window); - -void GroupDialog_destroyWindow(); - -ui::Window GroupDialog_getWindow(); - -void GroupDialog_show(); - -inline void RawStringExport(const char *string, const Callback &importer) -{ - importer(string); -} - -typedef ConstPointerCaller &), RawStringExport> RawStringExportCaller; - -ui::Widget GroupDialog_addPage(const char *tabLabel, ui::Widget widget, - const Callback &)> &title); - -void GroupDialog_showPage(ui::Widget page); - -void GroupDialog_updatePageTitle(ui::Widget page); - -bool GroupDialog_isShown(); - -ui::Widget GroupDialog_getPage(); - -#endif diff --git a/src/gtkdlgs.cpp b/src/gtkdlgs.cpp deleted file mode 100644 index c6ad9d7..0000000 --- a/src/gtkdlgs.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Some small dialogs that don't need much -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "gtkdlgs.h" -#include "globaldefs.h" - -#include - -#include "debugging/debugging.h" - -#include "igl.h" -#include "iscenegraph.h" -#include "iselection.h" - -#include -#include - -#include "os/path.h" -#include "math/aabb.h" -#include "container/array.h" -#include "generic/static.h" -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/image.h" - -#include "gtkmisc.h" -#include "brushmanip.h" -#include "build.h" -#include "qe3.h" -#include "texwindow.h" -#include "xywindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "url.h" -#include "cmdlib.h" - - - -// ============================================================================= -// Project settings dialog - -class GameComboConfiguration { -public: -const char *basegame_dir; -const char *basegame; -const char *known_dir; -const char *known; -const char *custom; - -GameComboConfiguration() : - basegame_dir(g_pGameDescription->getRequiredKeyValue("basegame")), - basegame(g_pGameDescription->getRequiredKeyValue("basegamename")), - known_dir(g_pGameDescription->getKeyValue("knowngame")), - known(g_pGameDescription->getKeyValue("knowngamename")), - custom(g_pGameDescription->getRequiredKeyValue("unknowngamename")) -{ -} -}; - -typedef LazyStatic LazyStaticGameComboConfiguration; - -inline GameComboConfiguration &globalGameComboConfiguration() -{ - return LazyStaticGameComboConfiguration::instance(); -} - - -struct gamecombo_t { - gamecombo_t(int _game, const char *_fs_game, bool _sensitive) - : game(_game), fs_game(_fs_game), sensitive(_sensitive) - { - } - - int game; - const char *fs_game; - bool sensitive; -}; - -gamecombo_t gamecombo_for_dir(const char *dir) -{ - if (string_equal(dir, globalGameComboConfiguration().basegame_dir)) { - return gamecombo_t(0, "", false); - } else if (string_equal(dir, globalGameComboConfiguration().known_dir)) { - return gamecombo_t(1, dir, false); - } else { - return gamecombo_t(string_empty(globalGameComboConfiguration().known_dir) ? 1 : 2, dir, true); - } -} - -gamecombo_t gamecombo_for_gamename(const char *gamename) -{ - if ((strlen(gamename) == 0) || !strcmp(gamename, globalGameComboConfiguration().basegame)) { - return gamecombo_t(0, "", false); - } else if (!strcmp(gamename, globalGameComboConfiguration().known)) { - return gamecombo_t(1, globalGameComboConfiguration().known_dir, false); - } else { - return gamecombo_t(string_empty(globalGameComboConfiguration().known_dir) ? 1 : 2, "", true); - } -} - -inline void path_copy_clean(char *destination, const char *source) -{ - char *i = destination; - - while (*source != '\0') { - *i++ = (*source == '\\') ? '/' : *source; - ++source; - } - - if (i != destination && *(i - 1) != '/') { - *(i++) = '/'; - } - - *i = '\0'; -} - - -struct GameCombo { - ui::ComboBoxText game_select{ui::null}; - ui::Entry fsgame_entry{ui::null}; -}; - -gboolean OnSelchangeComboWhatgame(ui::Widget widget, GameCombo *combo) -{ - const char *gamename; - { - GtkTreeIter iter; - gtk_combo_box_get_active_iter(combo->game_select, &iter); - gtk_tree_model_get(gtk_combo_box_get_model(combo->game_select), &iter, 0, (gpointer *) &gamename, -1); - } - - gamecombo_t gamecombo = gamecombo_for_gamename(gamename); - - combo->fsgame_entry.text(gamecombo.fs_game); - gtk_widget_set_sensitive(combo->fsgame_entry, gamecombo.sensitive); - - return FALSE; -} - -class MappingMode { -public: -bool do_mapping_mode; -const char *sp_mapping_mode; -const char *mp_mapping_mode; - -MappingMode() : - do_mapping_mode(!string_empty(g_pGameDescription->getKeyValue("show_gamemode"))), - sp_mapping_mode("Single Player mapping mode"), - mp_mapping_mode("Multiplayer mapping mode") -{ -} -}; - -typedef LazyStatic LazyStaticMappingMode; - -inline MappingMode &globalMappingMode() -{ - return LazyStaticMappingMode::instance(); -} - -class ProjectSettingsDialog { -public: -GameCombo game_combo; -ui::ComboBox gamemode_combo{ui::null}; -}; - -ui::Window ProjectSettingsDialog_construct(ProjectSettingsDialog &dialog, ModalDialog &modal) -{ - auto window = MainFrame_getWindow().create_dialog_window("Project Settings", G_CALLBACK(dialog_delete_callback), - &modal); - - { - auto table1 = create_dialog_table(1, 2, 4, 4, 4); - window.add(table1); - { - auto vbox = create_dialog_vbox(4); - table1.attach(vbox, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL}); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - { - auto frame = create_dialog_frame("Project settings"); - table1.attach(frame, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL}); - { - auto table2 = create_dialog_table((globalMappingMode().do_mapping_mode) ? 4 : 3, 2, 4, 4, 4); - frame.add(table2); - - { - auto label = ui::Label("Select mod"); - label.show(); - table2.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - } - { - dialog.game_combo.game_select = ui::ComboBoxText(ui::New); - - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().basegame); - if (globalGameComboConfiguration().known[0] != '\0') { - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().known); - } - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().custom); - - dialog.game_combo.game_select.show(); - table2.attach(dialog.game_combo.game_select, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.game_combo.game_select.connect("changed", G_CALLBACK(OnSelchangeComboWhatgame), - &dialog.game_combo); - } - - { - auto label = ui::Label("fs_game"); - label.show(); - table2.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table2.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.game_combo.fsgame_entry = entry; - } - - if (globalMappingMode().do_mapping_mode) { - auto label = ui::Label("Mapping mode"); - label.show(); - table2.attach(label, {0, 1, 3, 4}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - - auto combo = ui::ComboBoxText(ui::New); - gtk_combo_box_text_append_text(combo, globalMappingMode().sp_mapping_mode); - gtk_combo_box_text_append_text(combo, globalMappingMode().mp_mapping_mode); - - combo.show(); - table2.attach(combo, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.gamemode_combo = combo; - } - } - } - } - - // initialise the fs_game selection from the project settings into the dialog - const char *dir = gamename_get(); - gamecombo_t gamecombo = gamecombo_for_dir(dir); - - gtk_combo_box_set_active(dialog.game_combo.game_select, gamecombo.game); - dialog.game_combo.fsgame_entry.text(gamecombo.fs_game); - gtk_widget_set_sensitive(dialog.game_combo.fsgame_entry, gamecombo.sensitive); - - if (globalMappingMode().do_mapping_mode) { - const char *gamemode = gamemode_get(); - if (string_empty(gamemode) || string_equal(gamemode, "sp")) { - gtk_combo_box_set_active(dialog.gamemode_combo, 0); - } else { - gtk_combo_box_set_active(dialog.gamemode_combo, 1); - } - } - - return window; -} - -void ProjectSettingsDialog_ok(ProjectSettingsDialog &dialog) -{ - const char *dir = gtk_entry_get_text(dialog.game_combo.fsgame_entry); - - const char *new_gamename = path_equal(dir, globalGameComboConfiguration().basegame_dir) - ? "" - : dir; - - if (!path_equal(new_gamename, gamename_get())) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Game Name"); - - EnginePath_Unrealise(); - - gamename_set(new_gamename); - - EnginePath_Realise(); - } - - if (globalMappingMode().do_mapping_mode) { - // read from gamemode_combo - int active = gtk_combo_box_get_active(dialog.gamemode_combo); - if (active == -1 || active == 0) { - gamemode_set("sp"); - } else { - gamemode_set("mp"); - } - } -} - -void DoProjectSettings() -{ - if (ConfirmModified("Edit Project Settings")) { - ModalDialog modal; - ProjectSettingsDialog dialog; - - ui::Window window = ProjectSettingsDialog_construct(dialog, modal); - - if (modal_dialog_show(window, modal) == eIDOK) { - ProjectSettingsDialog_ok(dialog); - } - - window.destroy(); - } -} - -// ============================================================================= -// Arbitrary Sides dialog - -void DoSides(int type, int axis) -{ - ModalDialog dialog; - - auto window = MainFrame_getWindow().create_dialog_window("Arbitrary sides", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto sides_entry = ui::Entry(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto label = ui::Label("Sides:"); - label.show(); - hbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = sides_entry; - entry.show(); - hbox.pack_start(entry, FALSE, FALSE, 0); - gtk_widget_grab_focus(entry); - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - if (modal_dialog_show(window, dialog) == eIDOK) { - const char *str = gtk_entry_get_text(sides_entry); - - Scene_BrushConstructPrefab(GlobalSceneGraph(), (EBrushPrefab) type, atoi(str), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - - window.destroy(); -} - -// ============================================================================= -// About dialog (no program is complete without one) -void DoAbout() -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - - auto window = MainFrame_getWindow().create_modal_dialog_window("About WorldSpawn", dialog); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, TRUE, FALSE, 0); - { - auto frame = create_dialog_frame(0, ui::Shadow::IN); - vbox2.pack_start(frame, FALSE, FALSE, 0); - { - auto image = new_local_image("logo.xpm"); - image.show(); - frame.add(image); - } - } - } - - { - char const *label_text = "WorldSpawn 1.0\n" - "Build " __DATE__ "\n\n" - "Copyright (c) Vera Visions, LLC.\n\n" - "This product contains software\n" - "technology from id Software, Inc.\n\n" - "id Technology (c) 2000 id Software, Inc."; - - auto label = ui::Label(label_text); - - label.show(); - hbox.pack_start(label, FALSE, FALSE, 0); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - } - - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, FALSE, TRUE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox2.pack_start(button, FALSE, FALSE, 0); - } - } - } - { - auto frame = create_dialog_frame("OpenGL Properties"); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = create_dialog_table(3, 2, 4, 4, 4); - frame.add(table); - { - auto label = ui::Label("Vendor:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Version:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Renderer:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_VENDOR))); - label.show(); - table.attach(label, {1, 2, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_VERSION))); - label.show(); - table.attach(label, {1, 2, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_RENDERER))); - label.show(); - table.attach(label, {1, 2, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - { - auto frame = create_dialog_frame("OpenGL Extensions"); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto sc_extensions = create_scrolled_window(ui::Policy::AUTOMATIC, ui::Policy::ALWAYS, 4); - frame.add(sc_extensions); - { - auto text_extensions = ui::TextView(ui::New); - gtk_text_view_set_editable(text_extensions, FALSE); - sc_extensions.add(text_extensions); - text_extensions.text(reinterpret_cast(glGetString(GL_EXTENSIONS))); - gtk_text_view_set_wrap_mode(text_extensions, GTK_WRAP_WORD); - text_extensions.show(); - } - } - } - } - } - - modal_dialog_show(window, dialog); - - window.destroy(); -} - -// ============================================================================= -// TextureLayout dialog - -// Last used texture scale values -static float last_used_texture_layout_scale_x = 4.0; -static float last_used_texture_layout_scale_y = 4.0; - -EMessageBoxReturn DoTextureLayout(float *fx, float *fy) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - - auto window = MainFrame_getWindow().create_modal_dialog_window("Patch texture layout", dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto label = ui::Label("Texture will be fit across the patch based\n" - "on the x and y values given. Values of 1x1\n" - "will \"fit\" the texture. 2x2 will repeat\n" - "it twice, etc."); - label.show(); - vbox.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - } - { - auto table = create_dialog_table(2, 2, 4, 4); - table.show(); - vbox.pack_start(table, TRUE, TRUE, 0); - { - auto label = ui::Label("Texture x:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Texture y:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - y = entry; - } - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize with last used values - char buf[16]; - - sprintf(buf, "%f", last_used_texture_layout_scale_x); - x.text(buf); - - sprintf(buf, "%f", last_used_texture_layout_scale_y); - y.text(buf); - - // Set focus after intializing the values - gtk_widget_grab_focus(x); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *fx = static_cast( atof(gtk_entry_get_text(x))); - *fy = static_cast( atof(gtk_entry_get_text(y))); - - // Remember last used values - last_used_texture_layout_scale_x = *fx; - last_used_texture_layout_scale_y = *fy; - } - - window.destroy(); - - return ret; -} - -// ============================================================================= -// Text Editor dialog - -// master window widget -static ui::Window text_editor{ui::null}; -static ui::Widget text_widget{ui::null}; // slave, text widget from the gtk editor - -static gint editor_delete(ui::Widget widget, gpointer data) -{ - if (ui::alert(widget.window(), "Close the shader editor ?", "V-Editor", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::NO) { - return TRUE; - } - - text_editor.hide(); - - return TRUE; -} - -static void editor_save(ui::Widget widget, gpointer data) -{ - FILE *f = fopen((char *) g_object_get_data(G_OBJECT(data), "filename"), "w"); - gpointer text = g_object_get_data(G_OBJECT(data), "text"); - - if (f == 0) { - ui::alert(ui::Widget::from(data).window(), "Error saving file !"); - return; - } - - char *str = gtk_editable_get_chars(GTK_EDITABLE(text), 0, -1); - fwrite(str, 1, strlen(str), f); - fclose(f); -} - -static void editor_close(ui::Widget widget, gpointer data) -{ - if (ui::alert(text_editor.window(), "Close the shader editor ?", "V-Editor", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::NO) { - return; - } - - text_editor.hide(); -} - -static void CreateGtkTextEditor() -{ - auto dlg = ui::Window(ui::window_type::TOP); - - dlg.connect("delete_event", - G_CALLBACK(editor_delete), 0); - gtk_window_set_default_size(dlg, 600, 300); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - vbox.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - auto text = ui::TextView(ui::New); - scr.add(text); - text.show(); - g_object_set_data(G_OBJECT(dlg), "text", (gpointer) text); - gtk_text_view_set_editable(text, TRUE); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - auto button = ui::Button("Close"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(editor_close), dlg); - button.dimensions(60, -1); - - button = ui::Button("Save"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(editor_save), dlg); - button.dimensions(60, -1); - - text_editor = dlg; - text_widget = text; -} - -static void DoGtkTextEditor(const char *filename, guint cursorpos) -{ - if (!text_editor) { - CreateGtkTextEditor(); // build it the first time we need it - - } - // Load file - FILE *f = fopen(filename, "r"); - - if (f == 0) { - globalOutputStream() << "Unable to load file " << filename << " in shader editor.\n"; - text_editor.hide(); - } else { - fseek(f, 0, SEEK_END); - int len = ftell(f); - void *buf = malloc(len); - void *old_filename; - - rewind(f); - fread(buf, 1, len, f); - - gtk_window_set_title(text_editor, filename); - - auto text_buffer = gtk_text_view_get_buffer(ui::TextView::from(text_widget)); - gtk_text_buffer_set_text(text_buffer, (char *) buf, len); - - old_filename = g_object_get_data(G_OBJECT(text_editor), "filename"); - if (old_filename) { - free(old_filename); - } - g_object_set_data(G_OBJECT(text_editor), "filename", strdup(filename)); - - // trying to show later - text_editor.show(); - -#if GDEF_OS_WINDOWS - ui::process(); -#endif - - // only move the cursor if it's not exceeding the size.. - // NOTE: this is erroneous, cursorpos is the offset in bytes, not in characters - // len is the max size in bytes, not in characters either, but the character count is below that limit.. - // thinking .. the difference between character count and byte count would be only because of CR/LF? - { - GtkTextIter text_iter; - // character offset, not byte offset - gtk_text_buffer_get_iter_at_offset(text_buffer, &text_iter, cursorpos); - gtk_text_buffer_place_cursor(text_buffer, &text_iter); - } - -#if GDEF_OS_WINDOWS - gtk_widget_queue_draw( text_widget ); -#endif - - free(buf); - fclose(f); - } -} - -// ============================================================================= -// Light Intensity dialog - -EMessageBoxReturn DoLightIntensityDlg(int *intensity) -{ - ModalDialog dialog; - ui::Entry intensity_entry{ui::null}; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Light intensity", dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto label = ui::Label("ESC for default, ENTER to validate"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - vbox.pack_start(entry, TRUE, TRUE, 0); - - gtk_widget_grab_focus(entry); - - intensity_entry = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - char buf[16]; - sprintf(buf, "%d", *intensity); - intensity_entry.text(buf); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *intensity = atoi(gtk_entry_get_text(intensity_entry)); - } - - window.destroy(); - - return ret; -} - -// ============================================================================= -// Add new shader tag dialog - -EMessageBoxReturn DoShaderTagDlg(CopiedString *tag, const char *title) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - - auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - auto textentry = ui::Entry(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - //GtkLabel* label = GTK_LABEL(gtk_label_new("Enter one ore more tags separated by spaces")); - auto label = ui::Label("ESC to cancel, ENTER to validate"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = textentry; - entry.show(); - vbox.pack_start(entry, TRUE, TRUE, 0); - - gtk_widget_grab_focus(entry); - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *tag = gtk_entry_get_text(textentry); - } - - window.destroy(); - - return ret; -} - -EMessageBoxReturn DoShaderInfoDlg(const char *name, const char *filename, const char *title) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - - auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto label = ui::Label("The selected shader"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label(name); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label("is located in file"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label(filename); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - - window.destroy(); - - return ret; -} - - -#if GDEF_OS_WINDOWS -#include -#endif - -#if GDEF_OS_WINDOWS -// use the file associations to open files instead of builtin Gtk editor -bool g_TextEditor_useWin32Editor = true; -#else -// custom shader editor -bool g_TextEditor_useCustomEditor = false; -CopiedString g_TextEditor_editorCommand(""); -#endif - -void DoTextEditor(const char *filename, int cursorpos) -{ -#if GDEF_OS_WINDOWS - if ( g_TextEditor_useWin32Editor ) { - globalOutputStream() << "opening file '" << filename << "' (line " << cursorpos << " info ignored)\n"; - ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( MainFrame_getWindow() ) ), "open", filename, 0, 0, SW_SHOW ); - return; - } -#else - // check if a custom editor is set - if (g_TextEditor_useCustomEditor && !g_TextEditor_editorCommand.empty()) { - StringOutputStream strEditCommand(256); - strEditCommand << g_TextEditor_editorCommand.c_str() << " \"" << filename << "\""; - - globalOutputStream() << "Launching: " << strEditCommand.c_str() << "\n"; - // note: linux does not return false if the command failed so it will assume success - if (Q_Exec(0, const_cast( strEditCommand.c_str()), 0, true, false) == false) { - globalOutputStream() << "Failed to execute " << strEditCommand.c_str() << ", using default\n"; - } else { - // the command (appeared) to run successfully, no need to do anything more - return; - } - } -#endif - - DoGtkTextEditor(filename, cursorpos); -} diff --git a/src/gtkdlgs.h b/src/gtkdlgs.h deleted file mode 100644 index fa8ac88..0000000 --- a/src/gtkdlgs.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_GTKDLGS_H ) -#define INCLUDED_GTKDLGS_H - -#include "globaldefs.h" -#include "qerplugin.h" -#include "string/string.h" - -EMessageBoxReturn DoLightIntensityDlg(int *intensity); - -EMessageBoxReturn DoShaderTagDlg(CopiedString *tag, const char *title); - -EMessageBoxReturn DoShaderInfoDlg(const char *name, const char *filename, const char *title); - -EMessageBoxReturn DoTextureLayout(float *fx, float *fy); - -void DoTextEditor(const char *filename, int cursorpos); - -void DoProjectSettings(); - -void DoFind(); - -void DoSides(int type, int axis); - -void DoAbout(); - - -#if GDEF_OS_WINDOWS -extern bool g_TextEditor_useWin32Editor; -#else - -#include "string/stringfwd.h" - -extern bool g_TextEditor_useCustomEditor; -extern CopiedString g_TextEditor_editorCommand; -#endif - - -#endif diff --git a/src/gtkmisc.cpp b/src/gtkmisc.cpp deleted file mode 100644 index 0e70633..0000000 --- a/src/gtkmisc.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Small functions to help with GTK -// - -#include -#include "gtkmisc.h" - -#include "uilib/uilib.h" - -#include "math/vector.h" -#include "os/path.h" - -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/menu.h" -#include "gtkutil/toolbar.h" -#include "commands.h" - - -// ============================================================================= -// Misc stuff - -void command_connect_accelerator(const char *name) -{ - const Command &command = GlobalCommands_find(name); - GlobalShortcuts_register(name, 1); - global_accel_group_connect(command.m_accelerator, command.m_callback); -} - -void command_disconnect_accelerator(const char *name) -{ - const Command &command = GlobalCommands_find(name); - global_accel_group_disconnect(command.m_accelerator, command.m_callback); -} - -void toggle_add_accelerator(const char *name) -{ - const Toggle &toggle = GlobalToggles_find(name); - GlobalShortcuts_register(name, 2); - global_accel_group_connect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); -} - -void toggle_remove_accelerator(const char *name) -{ - const Toggle &toggle = GlobalToggles_find(name); - global_accel_group_disconnect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); -} - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName) -{ - GlobalShortcuts_register(commandName, 2); - const Toggle &toggle = GlobalToggles_find(commandName); - global_accel_group_connect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); - return create_check_menu_item_with_mnemonic(menu, mnemonic, toggle); -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName) -{ - GlobalShortcuts_register(commandName, 1); - const Command &command = GlobalCommands_find(commandName); - global_accel_group_connect(command.m_accelerator, command.m_callback); - return create_menu_item_with_mnemonic(menu, mnemonic, command); -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName) -{ - return toolbar_append_button(toolbar, description, icon, GlobalCommands_find(commandName)); -} - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName) -{ - return toolbar_append_toggle_button(toolbar, description, icon, GlobalToggles_find(commandName)); -} - -// ============================================================================= -// File dialog - -bool color_dialog(ui::Window parent, Vector3 &color, const char *title) -{ - GdkColor clr = {0, guint16(color[0] * 65535), guint16(color[1] * 65535), guint16(color[2] * 65535)}; - ModalDialog dialog; - - auto dlg = ui::Window::from(gtk_color_selection_dialog_new(title)); - gtk_color_selection_set_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), &dialog); - GtkWidget *ok_button, *cancel_button; - g_object_get(G_OBJECT(dlg), "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr); - ui::Widget::from(ok_button).connect("clicked", G_CALLBACK(dialog_button_ok), &dialog); - ui::Widget::from(cancel_button).connect("clicked", G_CALLBACK(dialog_button_cancel), &dialog); - - if (parent) { - gtk_window_set_transient_for(dlg, parent); - } - - bool ok = modal_dialog_show(dlg, dialog) == eIDOK; - if (ok) { - gtk_color_selection_get_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), - &clr); - color[0] = clr.red / 65535.0f; - color[1] = clr.green / 65535.0f; - color[2] = clr.blue / 65535.0f; - } - - dlg.destroy(); - - return ok; -} - -void button_clicked_entry_browse_file(ui::Widget widget, ui::Entry entry) -{ - const char *filename = widget.file_dialog(TRUE, "Choose File", gtk_entry_get_text(entry)); - - if (filename != 0) { - entry.text(filename); - } -} - -void button_clicked_entry_browse_directory(ui::Widget widget, ui::Entry entry) -{ - const char *text = gtk_entry_get_text(entry); - char *dir = dir_dialog(widget.window(), "Choose Directory", path_is_absolute(text) ? text : ""); - - if (dir != 0) { - gchar *converted = g_filename_to_utf8(dir, -1, 0, 0, 0); - entry.text(converted); - g_free(dir); - g_free(converted); - } -} diff --git a/src/gtkmisc.h b/src/gtkmisc.h deleted file mode 100644 index 0379797..0000000 --- a/src/gtkmisc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_GTKMISC_H ) -#define INCLUDED_GTKMISC_H - -#include - -void command_connect_accelerator(const char *commandName); - -void command_disconnect_accelerator(const char *commandName); - -void toggle_add_accelerator(const char *commandName); - -void toggle_remove_accelerator(const char *name); - -// this also sets up the shortcut using command_connect_accelerator -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName); - -// this also sets up the shortcut using command_connect_accelerator -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName); - - -// this DOES NOT set up the shortcut using command_connect_accelerator -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName); - -// this DOES NOT set up the shortcut using command_connect_accelerator -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName); - - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -bool color_dialog(ui::Window parent, Vector3 &color, const char *title = "Choose Color"); - -void button_clicked_entry_browse_file(ui::Widget widget, ui::Entry entry); - -void button_clicked_entry_browse_directory(ui::Widget widget, ui::Entry entry); - -#endif diff --git a/tools/vmap/help.c b/src/help.c similarity index 100% rename from tools/vmap/help.c rename to src/help.c diff --git a/src/help.cpp b/src/help.cpp deleted file mode 100644 index 2578209..0000000 --- a/src/help.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "help.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "libxml/parser.h" -#include "generic/callback.h" -#include "gtkutil/menu.h" -#include "stream/stringstream.h" -#include "os/file.h" - -#include "url.h" -#include "preferences.h" -#include "mainframe.h" - - -/*! - needed for hooking in Gtk+ - */ -void Help_OpenVV(void) -{ - OpenURL("https://www.vera-visions.com/"); -} -void Help_OpenMAT(void) -{ - OpenURL("https://www.vera-visions.com/docs/materials/"); -} - - -void create_game_help_menu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Vera Visions", makeCallbackF(Help_OpenVV)); - create_menu_item_with_mnemonic(menu, "Material Manual", makeCallbackF(Help_OpenMAT)); -} diff --git a/src/help.h b/src/help.h deleted file mode 100644 index e16cb8b..0000000 --- a/src/help.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_HELP_H ) -#define INCLUDED_HELP_H - -void create_game_help_menu(ui::Menu menu); - -#endif diff --git a/tools/vmap/image.c b/src/image.c similarity index 100% rename from tools/vmap/image.c rename to src/image.c diff --git a/src/image.cpp b/src/image.cpp deleted file mode 100644 index 099c258..0000000 --- a/src/image.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "image.h" - -#include "modulesystem.h" -#include "iimage.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "generic/reference.h" -#include "os/path.h" -#include "stream/stringstream.h" - - -typedef Modules<_QERPlugImageTable> ImageModules; - -ImageModules &Textures_getImageModules(); - -/// \brief Returns a new image for the first file matching \p name in one of the available texture formats, or 0 if no file is found. -Image *QERApp_LoadImage(void *environment, const char *name) -{ - Image *image = 0; - class LoadImageVisitor : public ImageModules::Visitor { - const char *m_name; - Image *&m_image; -public: - LoadImageVisitor(const char *name, Image *&image) - : m_name(name), m_image(image) - { - } - - void visit(const char *name, const _QERPlugImageTable &table) const - { - if (m_image == 0) { - StringOutputStream fullname(256); - fullname << m_name << '.' << name; - ArchiveFile *file = GlobalFileSystem().openFile(fullname.c_str()); - if (file != 0) { - m_image = table.loadImage(*file); - file->release(); - } - } - } - }; - - Textures_getImageModules().foreachModule(LoadImageVisitor(name, image)); - - return image; -} diff --git a/src/image.h b/src/image.h deleted file mode 100644 index b05323b..0000000 --- a/src/image.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_IMAGE_H ) -#define INCLUDED_IMAGE_H - -class Image; - -Image *QERApp_LoadImage(void *environment, const char *name); - -#endif diff --git a/tools/vmap/leakfile.c b/src/leakfile.c similarity index 100% rename from tools/vmap/leakfile.c rename to src/leakfile.c diff --git a/tools/vmap/light.c b/src/light.c similarity index 100% rename from tools/vmap/light.c rename to src/light.c diff --git a/tools/vmap/light_bounce.c b/src/light_bounce.c similarity index 100% rename from tools/vmap/light_bounce.c rename to src/light_bounce.c diff --git a/tools/vmap/light_shadows.c b/src/light_shadows.c similarity index 100% rename from tools/vmap/light_shadows.c rename to src/light_shadows.c diff --git a/tools/vmap/light_trace.c b/src/light_trace.c similarity index 100% rename from tools/vmap/light_trace.c rename to src/light_trace.c diff --git a/tools/vmap/light_ydnar.c b/src/light_ydnar.c similarity index 100% rename from tools/vmap/light_ydnar.c rename to src/light_ydnar.c diff --git a/tools/vmap/lightmaps.c b/src/lightmaps.c similarity index 100% rename from tools/vmap/lightmaps.c rename to src/lightmaps.c diff --git a/tools/vmap/lightmaps_ydnar.c b/src/lightmaps_ydnar.c similarity index 100% rename from tools/vmap/lightmaps_ydnar.c rename to src/lightmaps_ydnar.c diff --git a/tools/vmap/main.c b/src/main.c similarity index 100% rename from tools/vmap/main.c rename to src/main.c diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 4a3dca9..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! \mainpage GtkRadiant Documentation Index - - \section intro_sec Introduction - - This documentation is generated from comments in the source code. - - \section links_sec Useful Links - - \link include/itextstream.h include/itextstream.h \endlink - Global output and error message streams, similar to std::cout and std::cerr. \n - - FileInputStream - similar to std::ifstream (binary mode) \n - FileOutputStream - similar to std::ofstream (binary mode) \n - TextFileInputStream - similar to std::ifstream (text mode) \n - TextFileOutputStream - similar to std::ofstream (text mode) \n - StringOutputStream - similar to std::stringstream \n - - \link string/string.h string/string.h \endlink - C-style string comparison and memory management. \n - \link os/path.h os/path.h \endlink - Path manipulation for radiant's standard path format \n - \link os/file.h os/file.h \endlink - OS file-system access. \n - - ::CopiedString - automatic string memory management \n - Array - automatic array memory management \n - HashTable - generic hashtable, similar to std::hash_map \n - - \link math/vector.h math/vector.h \endlink - Vectors \n - \link math/matrix.h math/matrix.h \endlink - Matrices \n - \link math/quaternion.h math/quaternion.h \endlink - Quaternions \n - \link math/plane.h math/plane.h \endlink - Planes \n - \link math/aabb.h math/aabb.h \endlink - AABBs \n - - Callback MemberCaller0 FunctionCaller - callbacks similar to using boost::function with boost::bind \n - SmartPointer SmartReference - smart-pointer and smart-reference similar to Loki's SmartPtr \n - - \link generic/bitfield.h generic/bitfield.h \endlink - Type-safe bitfield \n - \link generic/enumeration.h generic/enumeration.h \endlink - Type-safe enumeration \n - - DefaultAllocator - Memory allocation using new/delete, compliant with std::allocator interface \n - - \link debugging/debugging.h debugging/debugging.h \endlink - Debugging macros \n - - */ - -#include "main.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "iundo.h" - -#include "uilib/uilib.h" - -#include "cmdlib.h" -#include "os/file.h" -#include "os/path.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" - -#include "gtkutil/messagebox.h" -#include "gtkutil/image.h" -#include "console.h" -#include "texwindow.h" -#include "map.h" -#include "mainframe.h" -#include "commands.h" -#include "preferences.h" -#include "environment.h" -#include "referencecache.h" -#include "stacktrace.h" - -#if GDEF_OS_WINDOWS -#include -#endif - -void show_splash(); - -void hide_splash(); - -void error_redirect(const gchar *domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) -{ - gboolean in_recursion; - gboolean is_fatal; - char buf[256]; - - in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; - is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; - log_level = (GLogLevelFlags) (log_level & G_LOG_LEVEL_MASK); - - if (!message) { - message = "(0) message"; - } - - if (domain) { - strcpy(buf, domain); - } else { - strcpy(buf, "**"); - } - strcat(buf, "-"); - - switch (log_level) { - case G_LOG_LEVEL_ERROR: - if (in_recursion) { - strcat(buf, "ERROR (recursed) **: "); - } else { - strcat(buf, "ERROR **: "); - } - break; - case G_LOG_LEVEL_CRITICAL: - if (in_recursion) { - strcat(buf, "CRITICAL (recursed) **: "); - } else { - strcat(buf, "CRITICAL **: "); - } - break; - case G_LOG_LEVEL_WARNING: - if (in_recursion) { - strcat(buf, "WARNING (recursed) **: "); - } else { - strcat(buf, "WARNING **: "); - } - break; - case G_LOG_LEVEL_MESSAGE: - if (in_recursion) { - strcat(buf, "Message (recursed): "); - } else { - strcat(buf, "Message: "); - } - break; - case G_LOG_LEVEL_INFO: - if (in_recursion) { - strcat(buf, "INFO (recursed): "); - } else { - strcat(buf, "INFO: "); - } - break; - case G_LOG_LEVEL_DEBUG: - if (in_recursion) { - strcat(buf, "DEBUG (recursed): "); - } else { - strcat(buf, "DEBUG: "); - } - break; - default: - /* we are used for a log level that is not defined by GLib itself, - * try to make the best out of it. - */ - if (in_recursion) { - strcat(buf, "LOG (recursed:"); - } else { - strcat(buf, "LOG ("); - } - if (log_level) { - gchar string[] = "0x00): "; - gchar *p = string + 2; - guint i; - - i = g_bit_nth_msf(log_level, -1); - *p = i >> 4; - p++; - *p = '0' + (i & 0xf); - if (*p > '9') { - *p += 'A' - '9' - 1; - } - - strcat(buf, string); - } else { - strcat(buf, "): "); - } - } - - strcat(buf, message); - if (is_fatal) { - strcat(buf, "\naborting...\n"); - } else { - strcat(buf, "\n"); - } - - // spam it... - globalErrorStream() << buf << "\n"; - - if (is_fatal) { - ERROR_MESSAGE("GTK+ error: " << buf); - } -} - -#if GDEF_COMPILER_MSVC && GDEF_DEBUG -#include "crtdbg.h" -#endif - -void crt_init() -{ -#if GDEF_COMPILER_MSVC && GDEF_DEBUG - _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#endif -} - -class Lock { -bool m_locked; -public: -Lock() : m_locked(false) -{ -} - -void lock() -{ - m_locked = true; -} - -void unlock() -{ - m_locked = false; -} - -bool locked() const -{ - return m_locked; -} -}; - -class ScopedLock { -Lock &m_lock; -public: -ScopedLock(Lock &lock) : m_lock(lock) -{ - m_lock.lock(); -} - -~ScopedLock() -{ - m_lock.unlock(); -} -}; - -class LineLimitedTextOutputStream : public TextOutputStream { -TextOutputStream &outputStream; -std::size_t count; -public: -LineLimitedTextOutputStream(TextOutputStream &outputStream, std::size_t count) - : outputStream(outputStream), count(count) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - if (count != 0) { - const char *p = buffer; - const char *end = buffer + length; - for (;;) { - p = std::find(p, end, '\n'); - if (p == end) { - break; - } - ++p; - if (--count == 0) { - length = p - buffer; - break; - } - } - outputStream.write(buffer, length); - } - return length; -} -}; - -class PopupDebugMessageHandler : public DebugMessageHandler { -StringOutputStream m_buffer; -Lock m_lock; -public: -TextOutputStream &getOutputStream() -{ - if (!m_lock.locked()) { - return m_buffer; - } - return globalErrorStream(); -} - -bool handleMessage() -{ - getOutputStream() << "----------------\n"; - LineLimitedTextOutputStream outputStream(getOutputStream(), 24); - write_stack_trace(outputStream); - getOutputStream() << "----------------\n"; - globalErrorStream() << m_buffer.c_str(); - if (!m_lock.locked()) { - ScopedLock lock(m_lock); - if (GDEF_DEBUG) { - m_buffer << "Break into the debugger?\n"; - bool handled = ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::YESNO, - ui::alert_icon::Error) == ui::alert_response::NO; - m_buffer.clear(); - return handled; - } else { - m_buffer << "Please report this error to the developers\n"; - ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::OK, - ui::alert_icon::Error); - m_buffer.clear(); - } - } - return true; -} -}; - -typedef Static GlobalPopupDebugMessageHandler; - -void streams_init() -{ - GlobalErrorStream::instance().setOutputStream(getSysPrintErrorStream()); - GlobalOutputStream::instance().setOutputStream(getSysPrintOutputStream()); -} - -void paths_init() -{ - //g_strSettingsPath = environment_get_home_path(); - g_strSettingsPath = environment_get_app_path(); - - Q_mkdir(g_strSettingsPath.c_str()); - - g_strAppPath = environment_get_app_path(); - - // radiant is installed in the parent dir of "tools/" - // NOTE: this is not very easy for debugging - // maybe add options to lookup in several places? - // (for now I had to create symlinks) - { - StringOutputStream path(256); - path << g_strAppPath.c_str() << "bitmaps/"; - BitmapsPath_set(path.c_str()); - } - - // we will set this right after the game selection is done - g_strGameToolsPath = g_strAppPath; -} - -void create_global_pid() -{ - /*! - the global prefs loading / game selection dialog might fail for any reason we don't know about - we need to catch when it happens, to cleanup the stateful prefs which might be killing it - and to turn on console logging for lookup of the problem - this is the first part of the two step .pid system - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ - StringOutputStream g_pidFile(256); ///< the global .pid file (only for global part of the startup) - - g_pidFile << SettingsPath_get() << "radiant.pid"; - - FILE *pid; - pid = fopen(g_pidFile.c_str(), "r"); - if (pid != 0) { - fclose(pid); - - if (remove(g_pidFile.c_str()) == -1) { - StringOutputStream msg(256); - msg << "WARNING: Could not delete " << g_pidFile.c_str(); - ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error); - } - - // in debug, never prompt to clean registry, turn console logging auto after a failed start - if (!GDEF_DEBUG) { - StringOutputStream msg(256); - msg << "Radiant failed to start properly the last time it was run.\n" - "The failure may be related to current global preferences.\n" - "Do you want to reset global preferences to defaults?"; - - if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::YES) { - g_GamesDialog.Reset(); - } - - msg.clear(); - msg << "Logging console output to " << SettingsPath_get() - << "radiant.log\nRefer to the log if Radiant fails to start again."; - - ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK); - } - } - - // create a primary .pid for global init run - pid = fopen(g_pidFile.c_str(), "w"); - if (pid) { - fclose(pid); - } -} - -void remove_global_pid() -{ - StringOutputStream g_pidFile(256); - g_pidFile << SettingsPath_get() << "radiant.pid"; - - // close the primary - if (remove(g_pidFile.c_str()) == -1) { - StringOutputStream msg(256); - msg << "WARNING: Could not delete " << g_pidFile.c_str(); - ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error); - } -} - -/*! - now the secondary game dependant .pid file - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ -void create_local_pid() -{ - StringOutputStream g_pidGameFile(256); ///< the game-specific .pid file - g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid"; - - FILE *pid = fopen(g_pidGameFile.c_str(), "r"); - if (pid != 0) { - fclose(pid); - if (remove(g_pidGameFile.c_str()) == -1) { - StringOutputStream msg; - msg << "WARNING: Could not delete " << g_pidGameFile.c_str(); - ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error); - } - - // in debug, never prompt to clean registry, turn console logging auto after a failed start - if (!GDEF_DEBUG) { - StringOutputStream msg; - msg << "Radiant failed to start properly the last time it was run.\n" - "The failure may be caused by current preferences.\n" - "Do you want to reset all preferences to defaults?"; - - if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::YES) { - Preferences_Reset(); - } - - msg.clear(); - msg << "Logging console output to " << SettingsPath_get() - << "radiant.log\nRefer to the log if Radiant fails to start again."; - - ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK); - } - } else { - // create one, will remove right after entering message loop - pid = fopen(g_pidGameFile.c_str(), "w"); - if (pid) { - fclose(pid); - } - } -} - - -/*! - now the secondary game dependant .pid file - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ -void remove_local_pid() -{ - StringOutputStream g_pidGameFile(256); - g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid"; - remove(g_pidGameFile.c_str()); -} - -void user_shortcuts_init() -{ - StringOutputStream shortpath(256); - StringOutputStream path(256); - shortpath << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/'; - - LoadCommandMap(shortpath.c_str(), SettingsPath_get()); - SaveCommandMap(shortpath.c_str()); -} - -void user_shortcuts_save() -{ - StringOutputStream path(256); - path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/'; - SaveCommandMap(path.c_str()); -} - -int main(int argc, char *argv[]) -{ - crt_init(); - - streams_init(); - -#if GDEF_OS_WINDOWS - HMODULE lib; - lib = LoadLibrary( "dwmapi.dll" ); - if ( lib != 0 ) { - void ( WINAPI *qDwmEnableComposition )( bool bEnable ) = ( void (WINAPI *) ( bool bEnable ) )GetProcAddress( lib, "DwmEnableComposition" ); - if ( qDwmEnableComposition ) { - qDwmEnableComposition( FALSE ); - } - FreeLibrary( lib ); - } -#endif - - const char *mapname = NULL; - char const *error = NULL; - if (!ui::init(&argc, &argv, "", &error)) { - g_print("%s\n", error); - return -1; - } - - // Gtk already removed parsed `--options` - if (argc == 2) { - if (strlen(argv[1]) > 1) { - if (g_str_has_suffix(argv[1], ".map")) { - if (g_path_is_absolute(argv[1])) { - mapname = argv[1]; - } else { - mapname = g_build_filename(g_get_current_dir(), argv[1], NULL); - } - } else { - g_print("bad file name, will not load: %s\n", argv[1]); - } - } - } else if (argc > 2) { - g_print("%s\n", "too many arguments"); - return -1; - } - - // redirect Gtk warnings to the console - g_log_set_handler("Gdk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("Gtk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("GtkGLExt", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("GLib", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler(0, (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - - GlobalDebugMessageHandler::instance().setHandler(GlobalPopupDebugMessageHandler::instance()); - - environment_init(argc, (char const **) argv); - - paths_init(); - - create_global_pid(); - - GlobalPreferences_Init(); - - g_GamesDialog.Init(); - - if (g_GamesDialog.m_bGamePrompt == false) { - show_splash(); - } - - g_strGameToolsPath = g_pGameDescription->mGameToolsPath; - - remove_global_pid(); - - g_Preferences.Init(); // must occur before create_local_pid() to allow preferences to be reset - - create_local_pid(); - - Radiant_Initialise(); - - user_shortcuts_init(); - - g_pParentWnd = 0; - g_pParentWnd = new MainFrame(); - - hide_splash(); - - if (mapname != NULL) { - Map_LoadFile(mapname); - } else if (g_bLoadLastMap && !g_strLastMap.empty()) { - Map_LoadFile(g_strLastMap.c_str()); - } else { - Map_New(); - } - - // load up shaders now that we have the map loaded - // eviltypeguy - TextureBrowser_ShowStartupShaders(GlobalTextureBrowser()); - - - remove_local_pid(); - - ui::main(); - - // avoid saving prefs when the app is minimized - if (g_pParentWnd->IsSleeping()) { - globalOutputStream() << "Shutdown while sleeping, not saving prefs\n"; - g_preferences_globals.disable_ini = true; - } - - Map_Free(); - - if (!Map_Unnamed(g_map)) { - g_strLastMap = Map_Name(g_map); - } - - delete g_pParentWnd; - - user_shortcuts_save(); - - Radiant_Shutdown(); - - return EXIT_SUCCESS; -} diff --git a/src/main.h b/src/main.h deleted file mode 100644 index d87b7a8..0000000 --- a/src/main.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAIN_H ) -#define INCLUDED_MAIN_H - -#endif diff --git a/src/mainframe.cpp b/src/mainframe.cpp deleted file mode 100644 index ef4f2c4..0000000 --- a/src/mainframe.cpp +++ /dev/null @@ -1,3388 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Main Window for Q3Radiant -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "mainframe.h" -#include "globaldefs.h" - -#include - -#include "ifilesystem.h" -#include "iundo.h" -#include "editable.h" -#include "ientity.h" -#include "ishaders.h" -#include "igl.h" -#include "moduleobserver.h" - -#include - -#include - - -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "signal/isignal.h" -#include "os/path.h" -#include "os/file.h" -#include "eclasslib.h" -#include "moduleobservers.h" - -#include "gtkutil/clipboard.h" -#include "gtkutil/frame.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/image.h" -#include "gtkutil/menu.h" -#include "gtkutil/paned.h" - -#include "autosave.h" -#include "build.h" -#include "brushmanip.h" -#include "brushmodule.h" -#include "camwindow.h" -#include "csg.h" -#include "commands.h" -#include "entity.h" -#include "entityinspector.h" -#include "entitylist.h" -#include "filters.h" -#include "findtexturedialog.h" -#include "grid.h" -#include "groupdialog.h" -#include "gtkdlgs.h" -#include "gtkmisc.h" -#include "help.h" -#include "map.h" -#include "mru.h" -#include "multimon.h" -#include "patchdialog.h" -#include "patchmanip.h" -#include "plugin.h" -#include "pluginmanager.h" -#include "pluginmenu.h" -#include "plugintoolbar.h" -#include "preferences.h" -#include "qe3.h" -#include "qgl.h" -#include "select.h" -#include "server.h" -#include "surfacedialog.h" -#include "textures.h" -#include "texwindow.h" -#include "url.h" -#include "xywindow.h" -#include "windowobservers.h" -#include "renderstate.h" -#include "feedback.h" -#include "referencecache.h" -#include "texwindow.h" - - -struct layout_globals_t { - WindowPosition m_position; - - - int nXYHeight; - int nXYWidth; - int nCamWidth; - int nCamHeight; - int nState; - - layout_globals_t() : - m_position(-1, -1, 640, 480), - - nXYHeight(300), - nXYWidth(300), - nCamWidth(200), - nCamHeight(200) - { - } -}; - -layout_globals_t g_layout_globals; -glwindow_globals_t g_glwindow_globals; - - -// VFS - -bool g_vfsInitialized = false; - -void VFS_Init() -{ - if (g_vfsInitialized) { return; } - QE_InitVFS(); - GlobalFileSystem().initialise(); - g_vfsInitialized = true; -} - -void VFS_Shutdown() -{ - if (!g_vfsInitialized) { return; } - GlobalFileSystem().shutdown(); - g_vfsInitialized = false; -} - -void VFS_Refresh() -{ - if (!g_vfsInitialized) { return; } - GlobalFileSystem().clear(); - QE_InitVFS(); - GlobalFileSystem().refresh(); - g_vfsInitialized = true; - // also refresh models - RefreshReferences(); - // also refresh texture browser - TextureBrowser_RefreshShaders(); - // also show textures (all or common) - TextureBrowser_ShowStartupShaders( GlobalTextureBrowser() ); -} - -void VFS_Restart() -{ - VFS_Shutdown(); - VFS_Init(); -} - -class VFSModuleObserver : public ModuleObserver { -public: -void realise() -{ - VFS_Init(); -} - -void unrealise() -{ - VFS_Shutdown(); -} -}; - -VFSModuleObserver g_VFSModuleObserver; - -void VFS_Construct() -{ -} - -void VFS_Destroy() -{ -} - -// Engine Path - -CopiedString g_strEnginePath; -ModuleObservers g_enginePathObservers; -std::size_t g_enginepath_unrealised = 1; - -void Radiant_attachEnginePathObserver(ModuleObserver &observer) -{ - g_enginePathObservers.attach(observer); -} - -void Radiant_detachEnginePathObserver(ModuleObserver &observer) -{ - g_enginePathObservers.detach(observer); -} - - -void EnginePath_Realise() -{ - if (--g_enginepath_unrealised == 0) { - g_enginePathObservers.realise(); - } -} - - -const char *EnginePath_get() -{ - if (g_enginepath_unrealised == 0) { - g_enginePathObservers.realise(); - } - return g_strEnginePath.c_str(); -} - -void EnginePath_Unrealise() -{ - if (++g_enginepath_unrealised == 1) { - g_enginePathObservers.unrealise(); - } -} - -void setEnginePath(const char *path) -{ - StringOutputStream buffer(256); - buffer << DirectoryCleaned(path); - if (!path_equal(buffer.c_str(), g_strEnginePath.c_str())) { -#if 0 - while ( !ConfirmModified( "Paths Changed" ) ) - { - if ( Map_Unnamed( g_map ) ) { - Map_SaveAs(); - } - else - { - Map_Save(); - } - } - Map_RegionOff(); -#endif - - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Nuclide Path"); - - EnginePath_Unrealise(); - - g_strEnginePath = buffer.c_str(); - - EnginePath_Realise(); - } -} - -// App Path - -CopiedString g_strAppPath; //< holds the full path of the executable - -const char *AppPath_get() -{ - return g_strAppPath.c_str(); -} - -/// the path to the local rc-dir -const char *LocalRcPath_get(void) -{ - static CopiedString rc_path; - if (rc_path.empty()) { - StringOutputStream stream(256); - stream << GlobalRadiant().getSettingsPath() << g_pGameDescription->mGameFile.c_str() << "/"; - rc_path = stream.c_str(); - } - return rc_path.c_str(); -} - -/// directory for temp files -/// NOTE: on *nix this is were we check for .pid -CopiedString g_strSettingsPath; - -const char *SettingsPath_get() -{ - return g_strSettingsPath.c_str(); -} - - -/*! - points to the game tools directory, for instance - C:/Program Files/Quake III Arena/GtkRadiant - (or other games) - this is one of the main variables that are configured by the game selection on startup - [GameToolsPath]/plugins - and also q3map, bspc - */ -CopiedString g_strGameToolsPath; ///< this is set by g_GamesDialog - -const char *GameToolsPath_get() -{ - return g_strGameToolsPath.c_str(); -} - -struct EnginePath { - static void Export(const CopiedString &self, const Callback &returnz) - { - returnz(self.c_str()); - } - - static void Import(CopiedString &self, const char *value) - { - setEnginePath(value); - } -}; - -void Paths_constructPreferences(PreferencesPage &page) -{ - page.appendPathEntry("Nuclide Path", true, make_property(g_strEnginePath)); -} - -void Paths_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Paths", "Path Settings")); - Paths_constructPreferences(page); -} - -void Paths_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Paths_constructPage)); -} - - -class PathsDialog : public Dialog { -public: -ui::Window BuildDialog() -{ - auto frame = create_dialog_frame("Path settings", ui::Shadow::ETCHED_IN); - - auto vbox2 = create_dialog_vbox(0, 4); - frame.add(vbox2); - - { - PreferencesPage preferencesPage(*this, vbox2); - Paths_constructPreferences(preferencesPage); - } - - return ui::Window(create_simple_modal_dialog_window("Nuclide Path Not Found", m_modal, frame)); -} -}; - -PathsDialog g_PathsDialog; - -void EnginePath_verify() -{ - if (!file_exists(g_strEnginePath.c_str())) { - g_PathsDialog.Create(); - g_PathsDialog.DoModal(); - g_PathsDialog.Destroy(); - } -} - -namespace { -CopiedString g_gamename; -CopiedString g_gamemode; -ModuleObservers g_gameNameObservers; -ModuleObservers g_gameModeObservers; -} - -void Radiant_attachGameNameObserver(ModuleObserver &observer) -{ - g_gameNameObservers.attach(observer); -} - -void Radiant_detachGameNameObserver(ModuleObserver &observer) -{ - g_gameNameObservers.detach(observer); -} - -const char *basegame_get() -{ - return g_pGameDescription->getRequiredKeyValue("basegame"); -} - -const char *gamename_get() -{ - const char *gamename = g_gamename.c_str(); - if (string_empty(gamename)) { - return basegame_get(); - } - return gamename; -} - -void gamename_set(const char *gamename) -{ - if (!string_equal(gamename, g_gamename.c_str())) { - g_gameNameObservers.unrealise(); - g_gamename = gamename; - g_gameNameObservers.realise(); - } -} - -void Radiant_attachGameModeObserver(ModuleObserver &observer) -{ - g_gameModeObservers.attach(observer); -} - -void Radiant_detachGameModeObserver(ModuleObserver &observer) -{ - g_gameModeObservers.detach(observer); -} - -const char *gamemode_get() -{ - return g_gamemode.c_str(); -} - -void gamemode_set(const char *gamemode) -{ - if (!string_equal(gamemode, g_gamemode.c_str())) { - g_gameModeObservers.unrealise(); - g_gamemode = gamemode; - g_gameModeObservers.realise(); - } -} - - -#include "os/dir.h" - -const char *const c_library_extension = -#if defined( CMAKE_SHARED_MODULE_SUFFIX ) - CMAKE_SHARED_MODULE_SUFFIX -#elif GDEF_OS_WINDOWS - "dll" -#elif GDEF_OS_MACOS - "dylib" -#elif GDEF_OS_LINUX || GDEF_OS_BSD - "so" -#endif -; - -void Radiant_loadModules(const char *path) -{ - Directory_forEach(path, matchFileExtension(c_library_extension, [&](const char *name) { - char fullname[1024]; - ASSERT_MESSAGE(strlen(path) + strlen(name) < 1024, ""); - strcpy(fullname, path); - strcat(fullname, name); - globalOutputStream() << "Found '" << fullname << "'\n"; - GlobalModuleServer_loadModule(fullname); - })); -} - -void Radiant_loadModulesFromRoot(const char *directory) -{ - { - StringOutputStream path(256); - path << directory << g_pluginsDir; - Radiant_loadModules(path.c_str()); - } -} - -//! Make COLOR_BRUSHES override worldspawn eclass colour. -void SetWorldspawnColour(const Vector3 &colour) -{ - EntityClass *worldspawn = GlobalEntityClassManager().findOrInsert("worldspawn", true); - eclass_release_state(worldspawn); - worldspawn->color = colour; - eclass_capture_state(worldspawn); -} - - -class WorldspawnColourEntityClassObserver : public ModuleObserver { -std::size_t m_unrealised; -public: -WorldspawnColourEntityClassObserver() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - SetWorldspawnColour(g_xywindow_globals.color_brushes); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - } -} -}; - -WorldspawnColourEntityClassObserver g_WorldspawnColourEntityClassObserver; - - -ModuleObservers g_gameToolsPathObservers; - -void Radiant_attachGameToolsPathObserver(ModuleObserver &observer) -{ - g_gameToolsPathObservers.attach(observer); -} - -void Radiant_detachGameToolsPathObserver(ModuleObserver &observer) -{ - g_gameToolsPathObservers.detach(observer); -} - -void Radiant_Initialise() -{ - GlobalModuleServer_Initialise(); - - Radiant_loadModulesFromRoot(AppPath_get()); - - Preferences_Load(); - - bool success = Radiant_Construct(GlobalModuleServer_get()); - ASSERT_MESSAGE(success, "module system failed to initialise - see radiant.log for error messages"); - - g_gameToolsPathObservers.realise(); - g_gameModeObservers.realise(); - g_gameNameObservers.realise(); -} - -void Radiant_Shutdown() -{ - g_gameNameObservers.unrealise(); - g_gameModeObservers.unrealise(); - g_gameToolsPathObservers.unrealise(); - - if (!g_preferences_globals.disable_ini) { - Preferences_Save(); - } - - Radiant_Destroy(); - - GlobalModuleServer_Shutdown(); -} - -void Exit() -{ - if (ConfirmModified("Exit WorldSpawn")) { - gtk_main_quit(); - } -} - - -void Undo() -{ - GlobalUndoSystem().undo(); - SceneChangeNotify(); -} - -void Redo() -{ - GlobalUndoSystem().redo(); - SceneChangeNotify(); -} - -void deleteSelection() -{ - UndoableCommand undo("deleteSelected"); - Select_Delete(); -} - -void Map_ExportSelected(TextOutputStream &ostream) -{ - Map_ExportSelected(ostream, Map_getFormat(g_map)); -} - -void Map_ImportSelected(TextInputStream &istream) -{ - Map_ImportSelected(istream, Map_getFormat(g_map)); -} - -void Selection_Copy() -{ - clipboard_copy(Map_ExportSelected); -} - -void Selection_Paste() -{ - clipboard_paste(Map_ImportSelected); -} - -void Copy() -{ - if (SelectedFaces_empty()) { - Selection_Copy(); - } else { - SelectedFaces_copyTexture(); - } -} - - - -enum ENudgeDirection { - eNudgeUp = 1, - eNudgeDown = 3, - eNudgeLeft = 0, - eNudgeRight = 2, -}; - - -void NudgeSelection(ENudgeDirection direction, float fAmount, VIEWTYPE viewtype); - -void Paste() -{ - if (SelectedFaces_empty()) { - UndoableCommand undo("paste"); - - GlobalSelectionSystem().setSelectedAll(false); - Selection_Paste(); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } else { - SelectedFaces_pasteTexture(); - } -} - -void PasteToCamera() -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - GlobalSelectionSystem().setSelectedAll(false); - - UndoableCommand undo("pasteToCamera"); - - Selection_Paste(); - - // Work out the delta - Vector3 mid; - Select_GetMid(mid); - Vector3 delta = vector3_subtracted(vector3_snapped(Camera_getOrigin(camwnd), GetSnapGridSize()), mid); - - // Move to camera - GlobalSelectionSystem().translateSelected(delta); -} - - -void ColorScheme_WorldSpawn() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.15f, 0.15f, 0.15f)); - - g_camwindow_globals.color_cameraback = Vector3(0.15f, 0.15f, 0.15f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f); - g_xywindow_globals.color_gridmajor = Vector3(0.45f, 0.45f, 0.45f); - g_xywindow_globals.color_gridblock = Vector3(0.39f, 0.18f, 0.0f); - g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_brushes = Vector3(0.55f, 0.55f, 0.55f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f); - XY_UpdateAllWindows(); -} - -void ColorScheme_Original() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridminor = Vector3(0.75f, 0.75f, 0.75f); - g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f); - g_xywindow_globals.color_gridminor_alt = Vector3(0.5f, 0.0f, 0.0f); - g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -void ColorScheme_QER() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridminor = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -void ColorScheme_Black() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f); - g_xywindow_globals.color_gridmajor = Vector3(0.3f, 0.5f, 0.5f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_brushes = Vector3(1.0f, 1.0f, 1.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f); - XY_UpdateAllWindows(); -} - -/* ydnar: to emulate maya/max/lightwave color schemes */ -void ColorScheme_Ydnar() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.77f, 0.77f, 0.77f); - g_xywindow_globals.color_gridminor = Vector3(0.83f, 0.83f, 0.83f); - g_xywindow_globals.color_gridmajor = Vector3(0.89f, 0.89f, 0.89f); - g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -typedef Callback GetColourCallback; -typedef Callback SetColourCallback; - -class ChooseColour { -GetColourCallback m_get; -SetColourCallback m_set; -public: -ChooseColour(const GetColourCallback &get, const SetColourCallback &set) - : m_get(get), m_set(set) -{ -} - -void operator()() -{ - Vector3 colour; - m_get(colour); - color_dialog(MainFrame_getWindow(), colour); - m_set(colour); -} -}; - - -void Colour_get(const Vector3 &colour, Vector3 &other) -{ - other = colour; -} - -typedef ConstReferenceCaller ColourGetCaller; - -void Colour_set(Vector3 &colour, const Vector3 &other) -{ - colour = other; - SceneChangeNotify(); -} - -typedef ReferenceCaller ColourSetCaller; - -void BrushColour_set(const Vector3 &other) -{ - g_xywindow_globals.color_brushes = other; - SetWorldspawnColour(g_xywindow_globals.color_brushes); - SceneChangeNotify(); -} - -typedef FreeCaller BrushColourSetCaller; - -void ClipperColour_set(const Vector3 &other) -{ - g_xywindow_globals.color_clipper = other; - Brush_clipperColourChanged(); - SceneChangeNotify(); -} - -typedef FreeCaller ClipperColourSetCaller; - -void TextureBrowserColour_get(Vector3 &other) -{ - other = TextureBrowser_getBackgroundColour(GlobalTextureBrowser()); -} - -typedef FreeCaller TextureBrowserColourGetCaller; - -void TextureBrowserColour_set(const Vector3 &other) -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), other); -} - -typedef FreeCaller TextureBrowserColourSetCaller; - - -class ColoursMenu { -public: -ChooseColour m_textureback; -ChooseColour m_xyback; -ChooseColour m_gridmajor; -ChooseColour m_gridminor; -ChooseColour m_gridmajor_alt; -ChooseColour m_gridminor_alt; -ChooseColour m_gridtext; -ChooseColour m_gridblock; -ChooseColour m_cameraback; -ChooseColour m_brush; -ChooseColour m_selectedbrush; -ChooseColour m_selectedbrush3d; -ChooseColour m_clipper; -ChooseColour m_viewname; - -ColoursMenu() : - m_textureback(TextureBrowserColourGetCaller(), TextureBrowserColourSetCaller()), - m_xyback(ColourGetCaller(g_xywindow_globals.color_gridback), - ColourSetCaller(g_xywindow_globals.color_gridback)), - m_gridmajor(ColourGetCaller(g_xywindow_globals.color_gridmajor), - ColourSetCaller(g_xywindow_globals.color_gridmajor)), - m_gridminor(ColourGetCaller(g_xywindow_globals.color_gridminor), - ColourSetCaller(g_xywindow_globals.color_gridminor)), - m_gridmajor_alt(ColourGetCaller(g_xywindow_globals.color_gridmajor_alt), - ColourSetCaller(g_xywindow_globals.color_gridmajor_alt)), - m_gridminor_alt(ColourGetCaller(g_xywindow_globals.color_gridminor_alt), - ColourSetCaller(g_xywindow_globals.color_gridminor_alt)), - m_gridtext(ColourGetCaller(g_xywindow_globals.color_gridtext), - ColourSetCaller(g_xywindow_globals.color_gridtext)), - m_gridblock(ColourGetCaller(g_xywindow_globals.color_gridblock), - ColourSetCaller(g_xywindow_globals.color_gridblock)), - m_cameraback(ColourGetCaller(g_camwindow_globals.color_cameraback), - ColourSetCaller(g_camwindow_globals.color_cameraback)), - m_brush(ColourGetCaller(g_xywindow_globals.color_brushes), BrushColourSetCaller()), - m_selectedbrush(ColourGetCaller(g_xywindow_globals.color_selbrushes), - ColourSetCaller(g_xywindow_globals.color_selbrushes)), - m_selectedbrush3d(ColourGetCaller(g_camwindow_globals.color_selbrushes3d), - ColourSetCaller(g_camwindow_globals.color_selbrushes3d)), - m_clipper(ColourGetCaller(g_xywindow_globals.color_clipper), ClipperColourSetCaller()), - m_viewname(ColourGetCaller(g_xywindow_globals.color_viewname), - ColourSetCaller(g_xywindow_globals.color_viewname)) -{ -} -}; - -ColoursMenu g_ColoursMenu; - -ui::MenuItem create_colours_menu() -{ - auto colours_menu_item = new_sub_menu_item_with_mnemonic("Colors"); - auto menu_in_menu = ui::Menu::from(gtk_menu_item_get_submenu(colours_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - - auto menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Themes"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_3); - }*/ - - create_menu_item_with_mnemonic(menu_3, "Default", "ColorSchemeWS"); - create_menu_item_with_mnemonic(menu_3, "QE4 Original", "ColorSchemeOriginal"); - create_menu_item_with_mnemonic(menu_3, "Q3Radiant Original", "ColorSchemeQER"); - create_menu_item_with_mnemonic(menu_3, "Black and Green", "ColorSchemeBlackAndGreen"); - create_menu_item_with_mnemonic(menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar"); - - menu_separator(menu_in_menu); - - create_menu_item_with_mnemonic(menu_in_menu, "_Texture Background...", "ChooseTextureBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Background...", "ChooseGridBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Major...", "ChooseGridMajorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor...", "ChooseGridMinorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Major Small...", "ChooseSmallGridMajorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor Small...", "ChooseSmallGridMinorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Text...", "ChooseGridTextColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Block...", "ChooseGridBlockColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Default Brush...", "ChooseBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Camera Background...", "ChooseCameraBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush...", "ChooseSelectedBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush (Camera)...", "ChooseCameraSelectedBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Clipper...", "ChooseClipperColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Active View name...", "ChooseOrthoViewNameColor"); - - return colours_menu_item; -} - - -void Restart() -{ - PluginsMenu_clear(); - PluginToolbar_clear(); - - Radiant_Shutdown(); - Radiant_Initialise(); - - PluginsMenu_populate(); - - PluginToolbar_populate(); -} - - -void thunk_OnSleep() -{ - g_pParentWnd->OnSleep(); -} - -void OpenHelpURL() -{ - OpenURL("https://www.vera-visions.com/developer/"); -} - -void OpenBugReportURL() -{ - OpenURL("https://www.vera-visions.com/developer/"); -} - - -ui::Widget g_page_entity{ui::null}; - -void EntityInspector_ToggleShow() -{ - GroupDialog_showPage(g_page_entity); -} - - -void SetClipMode(bool enable); - -void ModeChangeNotify(); - -typedef void ( *ToolMode )(); - -ToolMode g_currentToolMode = 0; -bool g_currentToolModeSupportsComponentEditing = false; -ToolMode g_defaultToolMode = 0; - - -void SelectionSystem_DefaultMode() -{ - GlobalSelectionSystem().SetMode(SelectionSystem::ePrimitive); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eDefault); - ModeChangeNotify(); -} - - -bool EdgeMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge; -} - -bool VertexMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex; -} - -bool FaceMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace; -} - -template -class BoolFunctionExport { -public: -static void apply(const Callback &importCallback) -{ - importCallback(BoolFunction()); -} -}; - -typedef FreeCaller &), &BoolFunctionExport::apply> EdgeModeApplyCaller; -EdgeModeApplyCaller g_edgeMode_button_caller; -Callback &)> g_edgeMode_button_callback(g_edgeMode_button_caller); -ToggleItem g_edgeMode_button(g_edgeMode_button_callback); - -typedef FreeCaller &), &BoolFunctionExport::apply> VertexModeApplyCaller; -VertexModeApplyCaller g_vertexMode_button_caller; -Callback &)> g_vertexMode_button_callback(g_vertexMode_button_caller); -ToggleItem g_vertexMode_button(g_vertexMode_button_callback); - -typedef FreeCaller &), &BoolFunctionExport::apply> FaceModeApplyCaller; -FaceModeApplyCaller g_faceMode_button_caller; -Callback &)> g_faceMode_button_callback(g_faceMode_button_caller); -ToggleItem g_faceMode_button(g_faceMode_button_callback); - -void ComponentModeChanged() -{ - g_edgeMode_button.update(); - g_vertexMode_button.update(); - g_faceMode_button.update(); -} - -void ComponentMode_SelectionChanged(const Selectable &selectable) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().countSelected() == 0) { - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - } -} - -void SelectEdgeMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (EdgeMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eEdge); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectVertexMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (VertexMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eVertex); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectFaceMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (FaceMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eFace); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - - -class CloneSelected : public scene::Graph::Walker { -bool doMakeUnique; -NodeSmartReference worldspawn; -public: -CloneSelected(bool d) : doMakeUnique(d), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.size() == 1) { - return true; - } - - // ignore worldspawn, but keep checking children - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return true; - } - - if (!path.top().get().isRoot()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - return false; - } - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.size() == 1) { - return; - } - - // ignore worldspawn, but keep checking children - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return; - } - - if (!path.top().get().isRoot()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - NodeSmartReference clone(Node_Clone(path.top())); - if (doMakeUnique) { - Map_gatherNamespaced(clone); - } - Node_getTraversable(path.parent().get())->insert(clone); - } - } -} -}; - -void Scene_Clone_Selected(scene::Graph &graph, bool doMakeUnique) -{ - graph.traverse(CloneSelected(doMakeUnique)); - - Map_mergeClonedNames(); -} - -struct AxisBase { - Vector3 x; - Vector3 y; - Vector3 z; - - AxisBase(const Vector3 &x_, const Vector3 &y_, const Vector3 &z_) - : x(x_), y(y_), z(z_) - { - } -}; - -AxisBase AxisBase_forViewType(VIEWTYPE viewtype) -{ - switch (viewtype) { - case XY: - return AxisBase(g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z); - case XZ: - return AxisBase(g_vector3_axis_x, g_vector3_axis_z, g_vector3_axis_y); - case YZ: - return AxisBase(g_vector3_axis_y, g_vector3_axis_z, g_vector3_axis_x); - } - - ERROR_MESSAGE("invalid viewtype"); - return AxisBase(Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0)); -} - -Vector3 AxisBase_axisForDirection(const AxisBase &axes, ENudgeDirection direction) -{ - switch (direction) { - case eNudgeLeft: - return vector3_negated(axes.x); - case eNudgeUp: - return axes.y; - case eNudgeRight: - return axes.x; - case eNudgeDown: - return vector3_negated(axes.y); - } - - ERROR_MESSAGE("invalid direction"); - return Vector3(0, 0, 0); -} - -void NudgeSelection(ENudgeDirection direction, float fAmount, VIEWTYPE viewtype) -{ - AxisBase axes(AxisBase_forViewType(viewtype)); - Vector3 view_direction(vector3_negated(axes.z)); - Vector3 nudge(vector3_scaled(AxisBase_axisForDirection(axes, direction), fAmount)); - GlobalSelectionSystem().NudgeManipulator(nudge, view_direction); -} - -void Selection_Clone() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - UndoableCommand undo("cloneSelected"); - - Scene_Clone_Selected(GlobalSceneGraph(), false); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } -} - -void Selection_Clone_MakeUnique() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - UndoableCommand undo("cloneSelectedMakeUnique"); - - Scene_Clone_Selected(GlobalSceneGraph(), true); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } -} - -// called when the escape key is used (either on the main window or on an inspector) -void Selection_Deselect() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } else { - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - } - } else { - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } else { - GlobalSelectionSystem().setSelectedAll(false); - } - } -} - - -void Selection_NudgeUp() -{ - UndoableCommand undo("nudgeSelectedUp"); - NudgeSelection(eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeDown() -{ - UndoableCommand undo("nudgeSelectedDown"); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeLeft() -{ - UndoableCommand undo("nudgeSelectedLeft"); - NudgeSelection(eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeRight() -{ - UndoableCommand undo("nudgeSelectedRight"); - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - - -void TranslateToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate); -} - -void RotateToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate); -} - -void ScaleToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale); -} - -void DragToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag); -} - -void ClipperToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip); -} - -FreeCaller &), TranslateToolExport> g_translatemode_button_caller; -Callback &)> g_translatemode_button_callback(g_translatemode_button_caller); -ToggleItem g_translatemode_button(g_translatemode_button_callback); - -FreeCaller &), RotateToolExport> g_rotatemode_button_caller; -Callback &)> g_rotatemode_button_callback(g_rotatemode_button_caller); -ToggleItem g_rotatemode_button(g_rotatemode_button_callback); - -FreeCaller &), ScaleToolExport> g_scalemode_button_caller; -Callback &)> g_scalemode_button_callback(g_scalemode_button_caller); -ToggleItem g_scalemode_button(g_scalemode_button_callback); - -FreeCaller &), DragToolExport> g_dragmode_button_caller; -Callback &)> g_dragmode_button_callback(g_dragmode_button_caller); -ToggleItem g_dragmode_button(g_dragmode_button_callback); - -FreeCaller &), ClipperToolExport> g_clipper_button_caller; -Callback &)> g_clipper_button_callback(g_clipper_button_caller); -ToggleItem g_clipper_button(g_clipper_button_callback); - -void ToolChanged() -{ - g_translatemode_button.update(); - g_rotatemode_button.update(); - g_scalemode_button.update(); - g_dragmode_button.update(); - g_clipper_button.update(); -} -const char *const c_ResizeMode_status = "Drag Tool: move and resize objects"; - -void DragMode() -{ - if (g_currentToolMode == DragMode && g_defaultToolMode != DragMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = DragMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_ResizeMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eDrag); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char *const c_TranslateMode_status = "Translate Tool: translate objects and components"; - -void TranslateMode() -{ - if (g_currentToolMode == TranslateMode && g_defaultToolMode != TranslateMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = TranslateMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_TranslateMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eTranslate); - ToolChanged(); - ModeChangeNotify(); - } -} - -const char *const c_RotateMode_status = "Rotate Tool: rotate objects and components"; - -void RotateMode() -{ - if (g_currentToolMode == RotateMode && g_defaultToolMode != RotateMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = RotateMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_RotateMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eRotate); - ToolChanged(); - ModeChangeNotify(); - } -} - -const char *const c_ScaleMode_status = "Scale Tool: scale objects and components"; - -void ScaleMode() -{ - if (g_currentToolMode == ScaleMode && g_defaultToolMode != ScaleMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = ScaleMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_ScaleMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eScale); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char *const c_ClipperMode_status = "Clipper Tool: apply clip planes to objects"; - - -void ClipperMode() -{ - if (g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = ClipperMode; - g_currentToolModeSupportsComponentEditing = false; - - SelectionSystem_DefaultMode(); - - OnClipMode(true); - - Sys_Status(c_ClipperMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eClip); - ToolChanged(); - ModeChangeNotify(); - } -} - -static int g_modifier_state; - -void Modifier1Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 0); -} -void Modifier2Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 1); -} -void Modifier3Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 3); -} - -FreeCaller &), Modifier1Export> g_modifier1_button_caller; -Callback &)> g_modifier1_button_callback(g_modifier1_button_caller); -ToggleItem g_modifier1_button(g_modifier1_button_callback); - -FreeCaller &), Modifier2Export> g_modifier2_button_caller; -Callback &)> g_modifier2_button_callback(g_modifier2_button_caller); -ToggleItem g_modifier2_button(g_modifier2_button_callback); - -FreeCaller &), Modifier3Export> g_modifier3_button_caller; -Callback &)> g_modifier3_button_callback(g_modifier3_button_caller); -ToggleItem g_modifier3_button(g_modifier3_button_callback); - -void ModifierChanged() -{ - g_modifier1_button.update(); - g_modifier2_button.update(); - g_modifier3_button.update(); -} - -void Modifier1() -{ - g_modifier_state = 0; - ModifierChanged(); - ModeChangeNotify(); -} -void Modifier2() -{ - g_modifier_state = 1; - ModifierChanged(); - ModeChangeNotify(); -} -void Modifier3() -{ - g_modifier_state = 3; - ModifierChanged(); - ModeChangeNotify(); -} - -int -Get_Modifier_State(void) -{ - return g_modifier_state; -} - - -void Texdef_Rotate(float angle) -{ - StringOutputStream command; - command << "brushRotateTexture -angle " << angle; - UndoableCommand undo(command.c_str()); - Select_RotateTexture(angle); -} - -void Texdef_RotateClockwise() -{ - Texdef_Rotate(static_cast( fabs(g_si_globals.rotate))); -} - -void Texdef_RotateAntiClockwise() -{ - Texdef_Rotate(static_cast( -fabs(g_si_globals.rotate))); -} - -void Texdef_Scale(float x, float y) -{ - StringOutputStream command; - command << "brushScaleTexture -x " << x << " -y " << y; - UndoableCommand undo(command.c_str()); - Select_ScaleTexture(x, y); -} - -void Texdef_ScaleUp() -{ - Texdef_Scale(0, g_si_globals.scale[1]); -} - -void Texdef_ScaleDown() -{ - Texdef_Scale(0, -g_si_globals.scale[1]); -} - -void Texdef_ScaleLeft() -{ - Texdef_Scale(-g_si_globals.scale[0], 0); -} - -void Texdef_ScaleRight() -{ - Texdef_Scale(g_si_globals.scale[0], 0); -} - -void Texdef_Shift(float x, float y) -{ - StringOutputStream command; - command << "brushShiftTexture -x " << x << " -y " << y; - UndoableCommand undo(command.c_str()); - Select_ShiftTexture(x, y); -} - -void Texdef_ShiftLeft() -{ - Texdef_Shift(-g_si_globals.shift[0], 0); -} - -void Texdef_ShiftRight() -{ - Texdef_Shift(g_si_globals.shift[0], 0); -} - -void Texdef_ShiftUp() -{ - Texdef_Shift(0, g_si_globals.shift[1]); -} - -void Texdef_ShiftDown() -{ - Texdef_Shift(0, -g_si_globals.shift[1]); -} - - -class SnappableSnapToGridSelected : public scene::Graph::Walker { -float m_snap; -public: -SnappableSnapToGridSelected(float snap) - : m_snap(snap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Snappable *snappable = Node_getSnappable(path.top()); - if (snappable != 0 - && Instance_getSelectable(instance)->isSelected()) { - snappable->snapto(m_snap); - } - } - return true; -} -}; - -void Scene_SnapToGrid_Selected(scene::Graph &graph, float snap) -{ - graph.traverse(SnappableSnapToGridSelected(snap)); -} - -class ComponentSnappableSnapToGridSelected : public scene::Graph::Walker { -float m_snap; -public: -ComponentSnappableSnapToGridSelected(float snap) - : m_snap(snap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - ComponentSnappable *componentSnappable = Instance_getComponentSnappable(instance); - if (componentSnappable != 0 - && Instance_getSelectable(instance)->isSelected()) { - componentSnappable->snapComponents(m_snap); - } - } - return true; -} -}; - -void Scene_SnapToGrid_Component_Selected(scene::Graph &graph, float snap) -{ - graph.traverse(ComponentSnappableSnapToGridSelected(snap)); -} - -void Selection_SnapToGrid() -{ - StringOutputStream command; - command << "snapSelected -grid " << GetGridSize(); - UndoableCommand undo(command.c_str()); - - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - Scene_SnapToGrid_Component_Selected(GlobalSceneGraph(), GetGridSize()); - } else { - Scene_SnapToGrid_Selected(GlobalSceneGraph(), GetGridSize()); - } -} - - -static gint qe_every_second(gpointer data) -{ - GdkModifierType mask; - - gdk_window_get_pointer(0, 0, 0, &mask); - - if ((mask & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0) { - QE_CheckAutoSave(); - } - - return TRUE; -} - -guint s_qe_every_second_id = 0; - -void EverySecondTimer_enable() -{ - if (s_qe_every_second_id == 0) { - s_qe_every_second_id = g_timeout_add(1000, qe_every_second, 0); - } -} - -void EverySecondTimer_disable() -{ - if (s_qe_every_second_id != 0) { - g_source_remove(s_qe_every_second_id); - s_qe_every_second_id = 0; - } -} - -gint window_realize_remove_decoration(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), - (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE | - GDK_DECOR_MAXIMIZE)); - return FALSE; -} - -class WaitDialog { -public: -ui::Window m_window{ui::null}; -ui::Label m_label{ui::null}; -}; - -WaitDialog create_wait_dialog(const char *title, const char *text) -{ - WaitDialog dialog; - - dialog.m_window = MainFrame_getWindow().create_floating_window(title); - gtk_window_set_resizable(dialog.m_window, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(dialog.m_window), 0); - gtk_window_set_position(dialog.m_window, GTK_WIN_POS_CENTER_ON_PARENT); - - dialog.m_window.connect("realize", G_CALLBACK(window_realize_remove_decoration), 0); - - { - dialog.m_label = ui::Label(text); - gtk_misc_set_alignment(GTK_MISC(dialog.m_label), 0.0, 0.5); - gtk_label_set_justify(dialog.m_label, GTK_JUSTIFY_LEFT); - dialog.m_label.show(); - dialog.m_label.dimensions(200, -1); - - dialog.m_window.add(dialog.m_label); - } - return dialog; -} - -namespace { -clock_t g_lastRedrawTime = 0; -const clock_t c_redrawInterval = clock_t(CLOCKS_PER_SEC / 10); - -bool redrawRequired() -{ - clock_t currentTime = std::clock(); - if (currentTime - g_lastRedrawTime >= c_redrawInterval) { - g_lastRedrawTime = currentTime; - return true; - } - return false; -} -} - -bool MainFrame_isActiveApp() -{ - //globalOutputStream() << "listing\n"; - GList *list = gtk_window_list_toplevels(); - for (GList *i = list; i != 0; i = g_list_next(i)) { - //globalOutputStream() << "toplevel.. "; - if (gtk_window_is_active(ui::Window::from(i->data))) { - //globalOutputStream() << "is active\n"; - return true; - } - //globalOutputStream() << "not active\n"; - } - return false; -} - -typedef std::list StringStack; -StringStack g_wait_stack; -WaitDialog g_wait; - -bool ScreenUpdates_Enabled() -{ - return g_wait_stack.empty(); -} - -void ScreenUpdates_process() -{ - if (redrawRequired() && g_wait.m_window.visible()) { - ui::process(); - } -} - - -void ScreenUpdates_Disable(const char *message, const char *title) -{ - if (g_wait_stack.empty()) { - EverySecondTimer_disable(); - - ui::process(); - - bool isActiveApp = MainFrame_isActiveApp(); - - g_wait = create_wait_dialog(title, message); - gtk_grab_add(g_wait.m_window); - - if (isActiveApp) { - g_wait.m_window.show(); - ScreenUpdates_process(); - } - } else if (g_wait.m_window.visible()) { - g_wait.m_label.text(message); - ScreenUpdates_process(); - } - g_wait_stack.push_back(message); -} - -void ScreenUpdates_Enable() -{ - ASSERT_MESSAGE(!ScreenUpdates_Enabled(), "screen updates already enabled"); - g_wait_stack.pop_back(); - if (g_wait_stack.empty()) { - EverySecondTimer_enable(); - //gtk_widget_set_sensitive(MainFrame_getWindow(), TRUE); - - gtk_grab_remove(g_wait.m_window); - destroy_floating_window(g_wait.m_window); - g_wait.m_window = ui::Window{ui::null}; - - //gtk_window_present(MainFrame_getWindow()); - } else if (g_wait.m_window.visible()) { - g_wait.m_label.text(g_wait_stack.back().c_str()); - ScreenUpdates_process(); - } -} - - -void GlobalCamera_UpdateWindow() -{ - if (g_pParentWnd != 0) { - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - } -} - -void XY_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetXYWnd() != 0) { - XYWnd_Update(*mainframe.GetXYWnd()); - } -} - -void XZ_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetXZWnd() != 0) { - XYWnd_Update(*mainframe.GetXZWnd()); - } -} - -void YZ_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetYZWnd() != 0) { - XYWnd_Update(*mainframe.GetYZWnd()); - } -} - -void XY_UpdateAllWindows(MainFrame &mainframe) -{ - XY_UpdateWindow(mainframe); - XZ_UpdateWindow(mainframe); - YZ_UpdateWindow(mainframe); -} - -void XY_UpdateAllWindows() -{ - if (g_pParentWnd != 0) { - XY_UpdateAllWindows(*g_pParentWnd); - } -} - -void XYZ_SetOrigin(const Vector3 &origin) -{ - g_pParentWnd->GetXYWnd()->SetOrigin(origin); - g_pParentWnd->GetXZWnd()->SetOrigin(origin); - g_pParentWnd->GetYZWnd()->SetOrigin(origin); -} - -void UpdateAllWindows() -{ - GlobalCamera_UpdateWindow(); - XY_UpdateAllWindows(); -} - - -void ModeChangeNotify() -{ - SceneChangeNotify(); -} - -void ClipperChangeNotify() -{ - GlobalCamera_UpdateWindow(); - XY_UpdateAllWindows(); -} - -LatchedValue g_Layout_enablePluginToolbar(true, "Plugin Toolbar"); - - -ui::MenuItem create_file_menu() -{ - // File menu - auto file_menu_item = new_sub_menu_item_with_mnemonic("_File"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(file_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "_New Map", "NewMap"); - menu_separator(menu); - -#if 0 - //++timo temporary experimental stuff for sleep mode.. - create_menu_item_with_mnemonic( menu, "_Sleep", "Sleep" ); - menu_separator( menu ); - // end experimental -#endif - - create_menu_item_with_mnemonic(menu, "_Open...", "OpenMap"); - - create_menu_item_with_mnemonic(menu, "_Import...", "ImportMap"); - create_menu_item_with_mnemonic(menu, "_Save", "SaveMap"); - create_menu_item_with_mnemonic(menu, "Save _as...", "SaveMapAs"); - create_menu_item_with_mnemonic(menu, "_Export selected...", "ExportSelected"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Save re_gion...", "SaveRegion"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Refresh assets", "RefreshReferences"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Pro_ject settings...", "ProjectSettings"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Pointfile...", "TogglePointfile"); - menu_separator(menu); - MRU_constructMenu(menu); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "E_xit", "Exit"); - - return file_menu_item; -} - -ui::MenuItem undobutton{ui::null}; -void -Undo_SetButtonlabel(const char *title) -{ - StringOutputStream name(128); - name << "Undo ("<< title << ")"; - gtk_menu_item_set_label(undobutton, name.c_str()); - gtk_widget_set_sensitive(undobutton, true); -} -void -Undo_DisableButton(void) -{ - gtk_menu_item_set_label(undobutton, "Undo"); - gtk_widget_set_sensitive(undobutton, false); -} - -ui::MenuItem redobutton{ui::null}; -void -Redo_SetButtonlabel(const char *title) -{ - StringOutputStream name(128); - name << "Redo (" << title << ")"; - gtk_menu_item_set_label(redobutton, name.c_str()); - gtk_widget_set_sensitive(redobutton, true); -} -void -Redo_DisableButton(void) -{ - gtk_menu_item_set_label(redobutton, "Redo"); - gtk_widget_set_sensitive(redobutton, false); -} - -ui::MenuItem create_edit_menu() -{ - // Edit menu - auto edit_menu_item = new_sub_menu_item_with_mnemonic("_Edit"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(edit_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - undobutton = create_menu_item_with_mnemonic(menu, "_Undo", "Undo"); - redobutton = create_menu_item_with_mnemonic(menu, "_Redo", "Redo"); - Undo_DisableButton(); - Redo_DisableButton(); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Copy", "Copy"); - create_menu_item_with_mnemonic(menu, "_Paste", "Paste"); - create_menu_item_with_mnemonic(menu, "P_aste To Camera", "PasteToCamera"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Duplicate", "CloneSelection"); - create_menu_item_with_mnemonic(menu, "Duplicate, make uni_que", "CloneSelectionAndMakeUnique"); - create_menu_item_with_mnemonic(menu, "D_elete", "DeleteSelection"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Pa_rent", "ParentSelection"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "C_lear Selection", "UnSelectSelection"); - create_menu_item_with_mnemonic(menu, "_Invert Selection", "InvertSelection"); - create_menu_item_with_mnemonic(menu, "Select i_nside", "SelectInside"); - create_menu_item_with_mnemonic(menu, "Select _touching", "SelectTouching"); - - create_check_menu_item_with_mnemonic(menu, "Auto-Expand Selection", "ToggleExpansion"); - create_check_menu_item_with_mnemonic(menu, "Additive Selection", "ToggleAddSelect"); - - auto convert_menu = create_sub_menu_with_mnemonic(menu, "E_xpand Selection"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(convert_menu); - }*/ - create_menu_item_with_mnemonic(convert_menu, "To Whole _Entities", "ExpandSelectionToEntities"); - - create_menu_item_with_mnemonic(menu, "Select all of model type", "SelectAllOfModel"); - - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Pre_ferences...", "Preferences"); - - return edit_menu_item; -} - -void fill_view_xy_top_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "XY (Top) View", "ToggleView"); -} - - -void fill_view_yz_side_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "YZ (Side) View", "ToggleSideView"); -} - - -void fill_view_xz_front_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "XZ (Front) View", "ToggleFrontView"); -} - - -ui::Widget g_toggle_z_item{ui::null}; -ui::Widget g_toggle_entity_item{ui::null}; -ui::Widget g_toggle_entitylist_item{ui::null}; - -ui::MenuItem create_view_menu() -{ - // View menu - auto view_menu_item = new_sub_menu_item_with_mnemonic("Vie_w"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(view_menu_item)); - - - /*fill_view_camera_menu(menu); - fill_view_xy_top_menu(menu); - fill_view_yz_side_menu(menu); - fill_view_xz_front_menu(menu);*/ - - create_menu_item_with_mnemonic(menu, "Map Info", "MapInfo"); - create_menu_item_with_mnemonic(menu, "Texture Browser", "ToggleTextures"); - create_menu_item_with_mnemonic(menu, "Entity Inspector", "ToggleEntityInspector"); - - - create_menu_item_with_mnemonic(menu, "_Surface Inspector", "SurfaceInspector"); - create_menu_item_with_mnemonic(menu, "Entity List", "EntityList"); - - menu_separator(menu); - menu.add(create_colours_menu()); - { - auto camera_menu = create_sub_menu_with_mnemonic(menu, "Camera"); - - create_menu_item_with_mnemonic(camera_menu, "_Center", "CenterView"); - create_menu_item_with_mnemonic(camera_menu, "_Up Floor", "UpFloor"); - create_menu_item_with_mnemonic(camera_menu, "_Down Floor", "DownFloor"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane In", "CubicClipZoomIn"); - create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane Out", "CubicClipZoomOut"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Next leak spot", "NextLeakSpot"); - create_menu_item_with_mnemonic(camera_menu, "Previous leak spot", "PrevLeakSpot"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Look Through Selected", "LookThroughSelected"); - create_menu_item_with_mnemonic(camera_menu, "Look Through Camera", "LookThroughCamera"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Move to [0,0,0]", "GoToZero"); - } - - { - auto orthographic_menu = create_sub_menu_with_mnemonic(menu, "Orthographic"); - - create_menu_item_with_mnemonic(orthographic_menu, "_Next (XY, YZ, XY)", "NextView"); - create_menu_item_with_mnemonic(orthographic_menu, "XY (Top)", "ViewTop"); - create_menu_item_with_mnemonic(orthographic_menu, "YZ", "ViewSide"); - create_menu_item_with_mnemonic(orthographic_menu, "XZ", "ViewFront"); - menu_separator(orthographic_menu); - - - create_menu_item_with_mnemonic(orthographic_menu, "_XY 100%", "Zoom100"); - create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _In", "ZoomIn"); - create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _Out", "ZoomOut"); - } - - menu_separator(menu); - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Show"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Angles", "ShowAngles"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Names", "ShowNames"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Blocks", "ShowBlocks"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show C_oordinates", "ShowCoordinates"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Window Outline", "ShowWindowOutline"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Axes", "ShowAxes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Workzone", "ShowWorkzone"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Lighting", "ShowLighting"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Alpha", "ShowAlpha"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Stats", "ShowStats"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Patch Balls", "ShowPatchBalls"); - } - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Filter"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - Filters_constructMenu(menu_in_menu); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Hide/Show"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Hide Selected", "HideSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Hide Unselected", "HideUnselected"); - create_menu_item_with_mnemonic(menu_in_menu, "Show Hidden", "ShowHidden"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Region"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "_Off", "RegionOff"); - create_menu_item_with_mnemonic(menu_in_menu, "_Set XY", "RegionSetXY"); - create_menu_item_with_mnemonic(menu_in_menu, "Set _Brush", "RegionSetBrush"); - create_menu_item_with_mnemonic(menu_in_menu, "Set Se_lected Brushes", "RegionSetSelection"); - } - - command_connect_accelerator("CenterXYView"); - - return view_menu_item; -} - -ui::MenuItem create_selection_menu() -{ - // Selection menu - auto selection_menu_item = new_sub_menu_item_with_mnemonic("M_odify"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(selection_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Components"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_check_menu_item_with_mnemonic(menu_in_menu, "_Edges", "DragEdges"); - create_check_menu_item_with_mnemonic(menu_in_menu, "_Vertices", "DragVertices"); - create_check_menu_item_with_mnemonic(menu_in_menu, "_Faces", "DragFaces"); - } - - menu_separator(menu); - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Nudge"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Left", "SelectNudgeLeft"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Right", "SelectNudgeRight"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Up", "SelectNudgeUp"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Down", "SelectNudgeDown"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Rotate"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Rotate X", "RotateSelectionX"); - create_menu_item_with_mnemonic(menu_in_menu, "Rotate Y", "RotateSelectionY"); - create_menu_item_with_mnemonic(menu_in_menu, "Rotate Z", "RotateSelectionZ"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Flip"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Flip _X", "MirrorSelectionX"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip _Y", "MirrorSelectionY"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip _Z", "MirrorSelectionZ"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Arbitrary move...", "ArbitraryMove"); - create_menu_item_with_mnemonic(menu, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu, "Arbitrary scale...", "ArbitraryScale"); - create_menu_item_with_mnemonic(menu, "Find brush...", "FindBrush"); - return selection_menu_item; -} - -ui::MenuItem create_bsp_menu() -{ - // BSP menu - auto bsp_menu_item = new_sub_menu_item_with_mnemonic("_Build"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(bsp_menu_item)); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Customize...", "BuildMenuCustomize"); - - menu_separator(menu); - - Build_constructMenu(menu); - - g_bsp_menu = menu; - - return bsp_menu_item; -} - -ui::MenuItem create_grid_menu() -{ - // Grid menu - auto grid_menu_item = new_sub_menu_item_with_mnemonic("_Grid"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(grid_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Grid_constructMenu(menu); - - return grid_menu_item; -} - -ui::MenuItem create_entity_menu() -{ - // Brush menu - auto entity_menu_item = new_sub_menu_item_with_mnemonic("E_ntity"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(entity_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Entity_constructMenu(menu); - - return entity_menu_item; -} - -ui::MenuItem create_brush_menu() -{ - // Brush menu - auto brush_menu_item = new_sub_menu_item_with_mnemonic("B_rush"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(brush_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Brush_constructMenu(menu); - - return brush_menu_item; -} - -ui::MenuItem create_patch_menu() -{ - // Curve menu - auto patch_menu_item = new_sub_menu_item_with_mnemonic("_Curve"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(patch_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Patch_constructMenu(menu); - - return patch_menu_item; -} - -ui::MenuItem create_help_menu() -{ - // Help menu - auto help_menu_item = new_sub_menu_item_with_mnemonic("_Help"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(help_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - // this creates all the per-game drop downs for the game pack helps - // it will take care of hooking the Sys_OpenURL calls etc. - create_game_help_menu(menu); - - create_menu_item_with_mnemonic(menu, "Shortcuts list", makeCallbackF(DoCommandListDlg)); - create_menu_item_with_mnemonic(menu, "_About", makeCallbackF(DoAbout)); - - return help_menu_item; -} - -ui::MenuBar create_main_menu() -{ - auto menu_bar = ui::MenuBar::from(gtk_menu_bar_new()); - menu_bar.show(); - menu_bar.add(create_file_menu()); - menu_bar.add(create_edit_menu()); - menu_bar.add(create_view_menu()); - menu_bar.add(create_selection_menu()); - menu_bar.add(create_bsp_menu()); - menu_bar.add(create_grid_menu()); - menu_bar.add(create_entity_menu()); - menu_bar.add(create_brush_menu()); - menu_bar.add(create_patch_menu()); - menu_bar.add(create_plugins_menu()); - menu_bar.add(create_help_menu()); - return menu_bar; -} - - -void PatchInspector_registerShortcuts() -{ - command_connect_accelerator("PatchInspector"); -} - -void Patch_registerShortcuts() -{ - command_connect_accelerator("InvertCurveTextureX"); - command_connect_accelerator("InvertCurveTextureY"); - command_connect_accelerator("PatchInsertInsertColumn"); - command_connect_accelerator("PatchInsertInsertRow"); - command_connect_accelerator("PatchDeleteLastColumn"); - command_connect_accelerator("PatchDeleteLastRow"); - command_connect_accelerator("NaturalizePatch"); - //command_connect_accelerator("CapCurrentCurve"); -} - -void Manipulators_registerShortcuts() -{ - toggle_add_accelerator("MouseRotate"); - toggle_add_accelerator("MouseTranslate"); - toggle_add_accelerator("MouseScale"); - toggle_add_accelerator("MouseDrag"); - toggle_add_accelerator("ToggleClipper"); -} - -void TexdefNudge_registerShortcuts() -{ - command_connect_accelerator("TexRotateClock"); - command_connect_accelerator("TexRotateCounter"); - command_connect_accelerator("TexScaleUp"); - command_connect_accelerator("TexScaleDown"); - command_connect_accelerator("TexScaleLeft"); - command_connect_accelerator("TexScaleRight"); - command_connect_accelerator("TexShiftUp"); - command_connect_accelerator("TexShiftDown"); - command_connect_accelerator("TexShiftLeft"); - command_connect_accelerator("TexShiftRight"); -} - -void SelectNudge_registerShortcuts() -{ - command_connect_accelerator("MoveSelectionDOWN"); - command_connect_accelerator("MoveSelectionUP"); - //command_connect_accelerator("SelectNudgeLeft"); - //command_connect_accelerator("SelectNudgeRight"); - //command_connect_accelerator("SelectNudgeUp"); - //command_connect_accelerator("SelectNudgeDown"); -} - -void SnapToGrid_registerShortcuts() -{ - command_connect_accelerator("SnapToGrid"); -} - -void SelectByType_registerShortcuts() -{ - command_connect_accelerator("SelectAllOfType"); -} - -void SurfaceInspector_registerShortcuts() -{ - command_connect_accelerator("FitTexture"); -} - - -void register_shortcuts() -{ - PatchInspector_registerShortcuts(); - Patch_registerShortcuts(); - Grid_registerShortcuts(); - XYWnd_registerShortcuts(); - CamWnd_registerShortcuts(); - Manipulators_registerShortcuts(); - SurfaceInspector_registerShortcuts(); - TexdefNudge_registerShortcuts(); - SelectNudge_registerShortcuts(); - SnapToGrid_registerShortcuts(); - SelectByType_registerShortcuts(); -} - -void File_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "New map", "file_new.xpm", "NewMap"); - toolbar_append_button(toolbar, "Open an existing map", "file_open.xpm", "OpenMap"); - toolbar_append_button(toolbar, "Save the active map", "file_save.xpm", "SaveMap"); -} - -void UndoRedo_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Undo (CTRL + Z)", "undo.xpm", "Undo"); - toolbar_append_button(toolbar, "Redo (CTRL + Y)", "redo.xpm", "Redo"); -} - -void Rotate_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "x-axis Rotate", "brush_rotatex.xpm", "RotateSelectionX"); - toolbar_append_button(toolbar, "y-axis Rotate", "brush_rotatey.xpm", "RotateSelectionZ"); - toolbar_append_button(toolbar, "z-axis Rotate", "brush_rotatez.xpm", "RotateSelectionY"); -} - -void Flip_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "x-axis Flip", "brush_flipx.xpm", "MirrorSelectionX"); - toolbar_append_button(toolbar, "y-axis Flip", "brush_flipy.xpm", "MirrorSelectionY"); - toolbar_append_button(toolbar, "z-axis Flip", "brush_flipz.xpm", "MirrorSelectionZ"); -} - -void Select_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Select touching", "selection_selecttouching.xpm", "SelectTouching"); - toolbar_append_button(toolbar, "Select inside", "selection_selectinside.xpm", "SelectInside"); -} - -void CSG_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "CSG Subtract", "selection_csgsubtract.xpm", "CSGSubtract"); - toolbar_append_button(toolbar, "CSG Merge", "selection_csgmerge.xpm", "CSGMerge"); - toolbar_append_button(toolbar, "Make Hollow", "selection_makehollow.xpm", "CSGMakeHollow"); - toolbar_append_button(toolbar, "Make Room", "selection_makeroom.xpm", "CSGMakeRoom"); -} - -void ComponentModes_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_toggle_button(toolbar, "Select Vertices", "modify_vertices.xpm", "DragVertices"); - toolbar_append_toggle_button(toolbar, "Select Edges", "modify_edges.xpm", "DragEdges"); - toolbar_append_toggle_button(toolbar, "Select Faces", "modify_faces.xpm", "DragFaces"); -} - -void XYWnd_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Change views", "view_change.xpm", "NextView"); -} - - -void PluginToolbar_AddToMain(ui::Toolbar toolbar); -ui::Toolbar create_main_toolbar() -{ - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - - toolbar.show(); - - auto space = [&]() { - auto btn = ui::ToolItem::from(gtk_separator_tool_item_new()); - btn.show(); - toolbar.add(btn); - }; - - File_constructToolbar(toolbar); - space(); - UndoRedo_constructToolbar(toolbar); - space(); - Rotate_constructToolbar(toolbar); - space(); - Flip_constructToolbar(toolbar); - space(); - Select_constructToolbar(toolbar); - space(); - CSG_constructToolbar(toolbar); - space(); - ComponentModes_constructToolbar(toolbar); - space(); - XYWnd_constructToolbar(toolbar); - space(); - CamWnd_constructToolbar(toolbar); - space(); - Patch_constructToolbar(toolbar); - - space(); - toolbar_append_toggle_button(toolbar, "Texture Lock", "texture_lock.xpm", "TogTexLock"); - space(); - toolbar_append_button(toolbar, "Refresh Assets", "refresh_models.xpm", - "RefreshReferences"); - - toolbar_append_toggle_button(toolbar, "Auto-Expand Selection", "select_autoexpand.xpm", - "ToggleExpansion"); - toolbar_append_toggle_button(toolbar, "Additive Selection", "select_additive.xpm", - "ToggleAddSelect"); - - PluginToolbar_AddToMain(toolbar); - - - return toolbar; -} - -ui::Toolbar create_main_sidebar() -{ - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_VERTICAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - toolbar.show(); - - auto space = [&]() { - auto btn = ui::ToolItem::from(gtk_separator_tool_item_new()); - btn.show(); - toolbar.add(btn); - }; - - toolbar_append_toggle_button(toolbar, "Create", "side_select.png", "Modifier1"); - toolbar_append_toggle_button(toolbar, "Select Face", "side_selectface.png", "Modifier3"); - toolbar_append_toggle_button(toolbar, "Select-Whole", "side_selectwhole.png", "Modifier2"); - space(); - toolbar_append_toggle_button(toolbar, "Resize (Q)", "side_resize.png", "MouseDrag"); - toolbar_append_toggle_button(toolbar, "Translate (W)", "side_move.png", "MouseTranslate"); - toolbar_append_toggle_button(toolbar, "Rotate (R)", "side_rotate.png", "MouseRotate"); - toolbar_append_toggle_button(toolbar, "Scale", "side_scale.png", "MouseScale"); - toolbar_append_toggle_button(toolbar, "Clipper", "side_cut.png", "ToggleClipper"); - space(); - toolbar_append_button(toolbar, "Texture Browser", "side_tex.png", "ToggleTextures"); - toolbar_append_button(toolbar, "Entity Inspector", "side_entspec.png", "ToggleEntityInspector"); - toolbar_append_button(toolbar, "Surface Inspector", "side_surfspec.png", "SurfaceInspector"); - toolbar_append_button(toolbar, "Patch Inspector", "side_patchspec.png", "PatchInspector"); - return toolbar; -} - -ui::Widget create_main_statusbar(ui::Widget pStatusLabel[c_count_status]) -{ - auto table = ui::Table(1, c_count_status, FALSE); - table.show(); - - { - auto label = ui::Label("Label"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label), 4, 2); - label.show(); - table.attach(label, {0, 1, 0, 1}); - pStatusLabel[c_command_status] = ui::Widget(label); - } - - for (unsigned int i = 1; (int) i < c_count_status; ++i) { - auto frame = ui::Frame(); - frame.show(); - table.attach(frame, {i, i + 1, 0, 1}); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - - auto label = ui::Label("Label"); - gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label), 4, 2); - label.show(); - frame.add(label); - pStatusLabel[i] = ui::Widget(label); - } - - return ui::Widget(table); -} - -#if 0 - - -WidgetFocusPrinter g_mainframeWidgetFocusPrinter( "mainframe" ); - -class WindowFocusPrinter -{ -const char* m_name; - -static gboolean frame_event( ui::Widget widget, GdkEvent* event, WindowFocusPrinter* self ){ - globalOutputStream() << self->m_name << " frame_event\n"; - return FALSE; -} -static gboolean keys_changed( ui::Widget widget, WindowFocusPrinter* self ){ - globalOutputStream() << self->m_name << " keys_changed\n"; - return FALSE; -} -static gboolean notify( ui::Window window, gpointer dummy, WindowFocusPrinter* self ){ - if ( gtk_window_is_active( window ) ) { - globalOutputStream() << self->m_name << " takes toplevel focus\n"; - } - else - { - globalOutputStream() << self->m_name << " loses toplevel focus\n"; - } - return FALSE; -} -public: -WindowFocusPrinter( const char* name ) : m_name( name ){ -} -void connect( ui::Window toplevel_window ){ - toplevel_window.connect( "notify::has_toplevel_focus", G_CALLBACK( notify ), this ); - toplevel_window.connect( "notify::is_active", G_CALLBACK( notify ), this ); - toplevel_window.connect( "keys_changed", G_CALLBACK( keys_changed ), this ); - toplevel_window.connect( "frame_event", G_CALLBACK( frame_event ), this ); -} -}; - -WindowFocusPrinter g_mainframeFocusPrinter( "mainframe" ); - -#endif - -class MainWindowActive { -static gboolean notify(ui::Window window, gpointer dummy, MainWindowActive *self) -{ - if (g_wait.m_window && gtk_window_is_active(window) && !g_wait.m_window.visible()) { - g_wait.m_window.show(); - } - - return FALSE; -} - -public: -void connect(ui::Window toplevel_window) -{ - toplevel_window.connect("notify::is-active", G_CALLBACK(notify), this); -} -}; - -MainWindowActive g_MainWindowActive; - -SignalHandlerId XYWindowDestroyed_connect(const SignalHandler &handler) -{ - return g_pParentWnd->GetXYWnd()->onDestroyed.connectFirst(handler); -} - -void XYWindowDestroyed_disconnect(SignalHandlerId id) -{ - g_pParentWnd->GetXYWnd()->onDestroyed.disconnect(id); -} - -MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler &handler) -{ - return g_pParentWnd->GetXYWnd()->onMouseDown.connectFirst(handler); -} - -void XYWindowMouseDown_disconnect(MouseEventHandlerId id) -{ - g_pParentWnd->GetXYWnd()->onMouseDown.disconnect(id); -} - -// ============================================================================= -// MainFrame class - -MainFrame *g_pParentWnd = 0; - -ui::Window MainFrame_getWindow() -{ - return g_pParentWnd ? g_pParentWnd->m_window : ui::Window{ui::null}; -} - -std::vector g_floating_windows; - -MainFrame::MainFrame() : m_idleRedrawStatusText(RedrawStatusTextCaller(*this)) -{ - m_pXYWnd = 0; - m_pCamWnd = 0; - m_pZWnd = 0; - m_pYZWnd = 0; - m_pXZWnd = 0; - m_pActiveXY = 0; - - for (auto &n : m_pStatusLabel) { - n = NULL; - } - - m_bSleeping = false; - - Create(); -} - -MainFrame::~MainFrame() -{ - SaveWindowInfo(); - - m_window.hide(); - - Shutdown(); - - for (std::vector::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i) { - i->destroy(); - } - - m_window.destroy(); -} - -void MainFrame::SetActiveXY(XYWnd *p) -{ - if (m_pActiveXY) { - m_pActiveXY->SetActive(false); - } - - m_pActiveXY = p; - - if (m_pActiveXY) { - m_pActiveXY->SetActive(true); - } - -} - -void MainFrame::ReleaseContexts() -{ -#if 0 - if ( m_pXYWnd ) { - m_pXYWnd->DestroyContext(); - } - if ( m_pYZWnd ) { - m_pYZWnd->DestroyContext(); - } - if ( m_pXZWnd ) { - m_pXZWnd->DestroyContext(); - } - if ( m_pCamWnd ) { - m_pCamWnd->DestroyContext(); - } - if ( m_pTexWnd ) { - m_pTexWnd->DestroyContext(); - } - if ( m_pZWnd ) { - m_pZWnd->DestroyContext(); - } -#endif -} - -void MainFrame::CreateContexts() -{ -#if 0 - if ( m_pCamWnd ) { - m_pCamWnd->CreateContext(); - } - if ( m_pXYWnd ) { - m_pXYWnd->CreateContext(); - } - if ( m_pYZWnd ) { - m_pYZWnd->CreateContext(); - } - if ( m_pXZWnd ) { - m_pXZWnd->CreateContext(); - } - if ( m_pTexWnd ) { - m_pTexWnd->CreateContext(); - } - if ( m_pZWnd ) { - m_pZWnd->CreateContext(); - } -#endif -} - -#if GDEF_DEBUG -//#define DBG_SLEEP -#endif - -void MainFrame::OnSleep() -{ -#if 0 - m_bSleeping ^= 1; - if ( m_bSleeping ) { - // useful when trying to debug crashes in the sleep code - globalOutputStream() << "Going into sleep mode..\n"; - - globalOutputStream() << "Dispatching sleep msg..."; - DispatchRadiantMsg( RADIANT_SLEEP ); - globalOutputStream() << "Done.\n"; - - gtk_window_iconify( m_window ); - GlobalSelectionSystem().setSelectedAll( false ); - - GlobalShaderCache().unrealise(); - Shaders_Free(); - GlobalOpenGL_debugAssertNoErrors(); - ScreenUpdates_Disable(); - - // release contexts - globalOutputStream() << "Releasing contexts..."; - ReleaseContexts(); - globalOutputStream() << "Done.\n"; - } - else - { - globalOutputStream() << "Waking up\n"; - - gtk_window_deiconify( m_window ); - - // create contexts - globalOutputStream() << "Creating contexts..."; - CreateContexts(); - globalOutputStream() << "Done.\n"; - - globalOutputStream() << "Making current on camera..."; - m_pCamWnd->MakeCurrent(); - globalOutputStream() << "Done.\n"; - - globalOutputStream() << "Reloading shaders..."; - Shaders_Load(); - GlobalShaderCache().realise(); - globalOutputStream() << "Done.\n"; - - ScreenUpdates_Enable(); - - globalOutputStream() << "Dispatching wake msg..."; - DispatchRadiantMsg( RADIANT_WAKEUP ); - globalOutputStream() << "Done\n"; - } -#endif -} - - -ui::Window create_splash() -{ - auto window = ui::Window(ui::window_type::TOP); - gtk_window_set_decorated(window, false); - gtk_window_set_resizable(window, false); - gtk_window_set_modal(window, true); - gtk_window_set_default_size(window, -1, -1); - gtk_window_set_position(window, GTK_WIN_POS_CENTER); - gtk_container_set_border_width(window, 0); - - auto image = new_local_image("splash.xpm"); - image.show(); - window.add(image); - - window.dimensions(-1, -1); - window.show(); - - return window; -} - -static ui::Window splash_screen{ui::null}; - -void show_splash() -{ - splash_screen = create_splash(); - - ui::process(); -} - -void hide_splash() -{ - splash_screen.destroy(); -} - -WindowPositionTracker g_posCamWnd; -WindowPositionTracker g_posXYWnd; -WindowPositionTracker g_posXZWnd; -WindowPositionTracker g_posYZWnd; - -static gint mainframe_delete(ui::Widget widget, GdkEvent *event, gpointer data) -{ - if (ConfirmModified("Exit WorldSpawn")) { - gtk_main_quit(); - } - - return TRUE; -} - -void MainFrame::Create() -{ - ui::Window window = ui::Window(ui::window_type::TOP); - GlobalWindowObservers_connectTopLevel(window); - gtk_window_set_transient_for(splash_screen, window); - -#if !GDEF_OS_WINDOWS - { - GdkPixbuf *pixbuf = pixbuf_new_from_file_with_mask("bitmaps/icon.xpm"); - if (pixbuf != 0) { - gtk_window_set_icon(window, pixbuf); - g_object_unref(pixbuf); - } - } -#endif - - gtk_widget_add_events(window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK); - window.connect("delete_event", G_CALLBACK(mainframe_delete), this); - m_position_tracker.connect(window); - -#if 0 - g_mainframeWidgetFocusPrinter.connect( window ); - g_mainframeFocusPrinter.connect( window ); -#endif - - g_MainWindowActive.connect(window); - - GetPlugInMgr().Init(window); - - auto vbox = ui::VBox(FALSE, 0); - auto hbox = ui::HBox(FALSE, 0); - window.add(vbox); - window.add(hbox); - vbox.show(); - hbox.show(); - - global_accel_connect_window(window); - - register_shortcuts(); - - auto main_menu = create_main_menu(); - vbox.pack_start(main_menu, FALSE, FALSE, 0); - - auto main_toolbar = create_main_toolbar(); - vbox.pack_start(main_toolbar, FALSE, FALSE, 0); - - auto main_sidebar = create_main_sidebar(); - hbox.pack_start(main_sidebar, FALSE, FALSE, 0); - - /*if (!g_Layout_enablePluginToolbar.m_value) { - plugin_toolbar.hide(); - }*/ - - ui::Widget main_statusbar = create_main_statusbar(reinterpret_cast(m_pStatusLabel)); - vbox.pack_end(main_statusbar, FALSE, TRUE, 2); - - GroupDialog_constructWindow(window); - g_page_entity = GroupDialog_addPage("Entities", EntityInspector_constructWindow(GroupDialog_getWindow()), - RawStringExportCaller("Entities")); - - m_window = window; - - window.show(); - - m_pCamWnd = NewCamWnd(); - GlobalCamera_setCamWnd(*m_pCamWnd); - CamWnd_setParent(*m_pCamWnd, window); - - ui::Widget camera = CamWnd_getWidget(*m_pCamWnd); - - m_pYZWnd = new XYWnd(); - m_pYZWnd->SetViewType(YZ); - - ui::Widget yz = m_pYZWnd->GetWidget(); - - m_pXYWnd = new XYWnd(); - m_pXYWnd->SetViewType(XY); - - ui::Widget xy = m_pXYWnd->GetWidget(); - - m_pXZWnd = new XYWnd(); - m_pXZWnd->SetViewType(XZ); - - ui::Widget xz = m_pXZWnd->GetWidget(); - - auto split = create_split_views(camera, yz, xy, xz); - vbox.pack_start(hbox, TRUE, TRUE, 0); - - hbox.pack_start(split, TRUE, TRUE, 0); - - { - auto frame = create_framed_widget(TextureBrowser_constructWindow(window)); - g_page_textures = GroupDialog_addPage("Textures", frame, TextureBrowserExportTitleCaller()); - } - - #if GDEF_OS_WINDOWS - if ( g_multimon_globals.m_bStartOnPrimMon ) { - PositionWindowOnPrimaryScreen( g_layout_globals.m_position ); - window_set_position( window, g_layout_globals.m_position ); - } - #endif - -#if 1 - if (g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED) { - WindowPosition default_position(-1, -1, 640, 480); - window_set_position(window, default_position); - gtk_window_maximize(window); - } else { - window_set_position(window, g_layout_globals.m_position); - gtk_window_resize(window, g_layout_globals.m_position.w, g_layout_globals.m_position.h); - } - UpdateAllWindows(); -#else - WindowPosition default_position(-1, -1, 640, 480); - window_set_position(window, default_position); -#endif - - EntityList_constructWindow(window); - PreferencesDialog_constructWindow(window); - FindTextureDialog_constructWindow(window); - SurfaceInspector_constructWindow(window); - PatchInspector_constructWindow(window); - SetActiveXY(m_pXYWnd); - AddGridChangeCallback(SetGridStatusCaller(*this)); - AddGridChangeCallback(ReferenceCaller(*this)); - g_defaultToolMode = DragMode; - g_defaultToolMode(); - SetStatusText(m_command_status, c_TranslateMode_status); - EverySecondTimer_enable(); -} - -void MainFrame::SaveWindowInfo() -{ - /*if (!FloatingGroupDialog()) { - g_layout_globals.nXYHeight = gtk_paned_get_position(GTK_PANED(m_vSplit)); - - if (CurrentStyle() != eRegular) { - g_layout_globals.nCamWidth = gtk_paned_get_position(GTK_PANED(m_hSplit)); - } else { - g_layout_globals.nXYWidth = gtk_paned_get_position(GTK_PANED(m_hSplit)); - } - - g_layout_globals.nCamHeight = gtk_paned_get_position(GTK_PANED(m_vSplit2)); - }*/ - - g_layout_globals.m_position = m_position_tracker.getPosition(); - g_layout_globals.nState = gdk_window_get_state(gtk_widget_get_window(m_window)); -} - -void MainFrame::Shutdown() -{ - EverySecondTimer_disable(); - - EntityList_destroyWindow(); - - delete m_pXYWnd; - m_pXYWnd = 0; - delete m_pYZWnd; - m_pYZWnd = 0; - delete m_pXZWnd; - m_pXZWnd = 0; - - TextureBrowser_destroyWindow(); - - DeleteCamWnd(m_pCamWnd); - m_pCamWnd = 0; - - PreferencesDialog_destroyWindow(); - SurfaceInspector_destroyWindow(); - FindTextureDialog_destroyWindow(); - PatchInspector_destroyWindow(); - - g_DbgDlg.destroyWindow(); - - // destroying group-dialog last because it may contain texture-browser - GroupDialog_destroyWindow(); -} - -void MainFrame::RedrawStatusText() -{ - ui::Label::from(m_pStatusLabel[c_command_status]).text(m_command_status.c_str()); - ui::Label::from(m_pStatusLabel[c_position_status]).text(m_position_status.c_str()); - ui::Label::from(m_pStatusLabel[c_brushcount_status]).text(m_brushcount_status.c_str()); - ui::Label::from(m_pStatusLabel[c_texture_status]).text(m_texture_status.c_str()); - ui::Label::from(m_pStatusLabel[c_grid_status]).text(m_grid_status.c_str()); -} - -void MainFrame::UpdateStatusText() -{ - m_idleRedrawStatusText.queueDraw(); -} - -void MainFrame::SetStatusText(CopiedString &status_text, const char *pText) -{ - status_text = pText; - UpdateStatusText(); -} - -void Sys_Status(const char *status) -{ - if (g_pParentWnd != 0) { - g_pParentWnd->SetStatusText(g_pParentWnd->m_command_status, status); - } -} - -int getRotateIncrement() -{ - return static_cast( g_si_globals.rotate ); -} - -int getFarClipDistance() -{ - return g_camwindow_globals.m_nCubicScale; -} - -float ( *GridStatus_getGridSize )() = GetGridSize; - -int ( *GridStatus_getRotateIncrement )() = getRotateIncrement; - -int ( *GridStatus_getFarClipDistance )() = getFarClipDistance; - -bool ( *GridStatus_getTextureLockEnabled )(); - -void MainFrame::SetGridStatus() -{ - StringOutputStream status(64); - const char *lock = (GridStatus_getTextureLockEnabled()) ? "ON" : "OFF"; - status << (GetSnapGridSize() > 0 ? "G:" : "g:") << GridStatus_getGridSize() - << " R:" << GridStatus_getRotateIncrement() - << " C:" << GridStatus_getFarClipDistance() - << " L:" << lock; - SetStatusText(m_grid_status, status.c_str()); -} - -void GridStatus_onTextureLockEnabledChanged() -{ - if (g_pParentWnd != 0) { - g_pParentWnd->SetGridStatus(); - } -} - -void GlobalGL_sharedContextCreated() -{ - GLFont *g_font = NULL; - - // report OpenGL information -#if 0 - globalOutputStream() << "GL_VENDOR: " << reinterpret_cast( glGetString(GL_VENDOR)) << "\n"; - globalOutputStream() << "GL_RENDERER: " << reinterpret_cast( glGetString(GL_RENDERER)) << "\n"; - globalOutputStream() << "GL_VERSION: " << reinterpret_cast( glGetString(GL_VERSION)) << "\n"; - const auto extensions = reinterpret_cast( glGetString(GL_EXTENSIONS)); - globalOutputStream() << "GL_EXTENSIONS: " << (extensions ? extensions : "") << "\n"; -#endif - - QGL_sharedContextCreated(GlobalOpenGL()); - - ShaderCache_extensionsInitialised(); - - GlobalShaderCache().realise(); - Textures_Realise(); - - g_font = glfont_create("Misc Fixed 12"); - - GlobalOpenGL().m_font = g_font; -} - -void GlobalGL_sharedContextDestroyed() -{ - Textures_Unrealise(); - GlobalShaderCache().unrealise(); - - QGL_sharedContextDestroyed(GlobalOpenGL()); -} - - -void Layout_constructPreferences(PreferencesPage &page) -{ - - page.appendCheckBox( - "", "Plugin Toolbar", - make_property(g_Layout_enablePluginToolbar) - ); -} - -void Layout_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Layout", "Layout Preferences")); - Layout_constructPreferences(page); -} - -void Layout_registerPreferencesPage() -{ - PreferencesDialog_addInterfacePage(makeCallbackF(Layout_constructPage)); -} - -/* eukara: this makes things more sane */ -bool g_expansion_enabled = true; -Callback g_expansion_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_expansion_caller( - g_expansion_enabled); -ToggleItem g_expansion_item(g_expansion_caller); - -void Texdef_ToggleExpansion() -{ - g_expansion_enabled = !g_expansion_enabled; - g_expansion_item.update(); - g_expansion_status_changed(); -} - -/* eukara: requested by Xylemon */ -bool g_addselect_enabled = true; -Callback g_addselect_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_addselect_caller( - g_addselect_enabled); -ToggleItem g_addselect_item(g_addselect_caller); - -void Texdef_ToggleAddSelect() -{ - g_addselect_enabled = !g_addselect_enabled; - g_addselect_item.update(); - g_addselect_status_changed(); -} - -#include "preferencesystem.h" -#include "stringio.h" - -void MainFrame_Construct() -{ - /*GlobalCommands_insert("Sleep", makeCallbackF(thunk_OnSleep), - Accelerator('P', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK)));*/ - GlobalCommands_insert("NewMap", makeCallbackF(NewMap)); - GlobalCommands_insert("OpenMap", makeCallbackF(OpenMap), Accelerator('O', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("ImportMap", makeCallbackF(ImportMap)); - GlobalCommands_insert("SaveMap", makeCallbackF(SaveMap), Accelerator('S', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("SaveMapAs", makeCallbackF(SaveMapAs)); - GlobalCommands_insert("ExportSelected", makeCallbackF(ExportMap)); - GlobalCommands_insert("SaveRegion", makeCallbackF(SaveRegion)); - GlobalCommands_insert("RefreshReferences", makeCallbackF(VFS_Refresh)); - GlobalCommands_insert("ProjectSettings", makeCallbackF(DoProjectSettings)); - GlobalCommands_insert("Exit", makeCallbackF(Exit)); - - GlobalCommands_insert("Undo", makeCallbackF(Undo), Accelerator('Z', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Redo", makeCallbackF(Redo), Accelerator('Y', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Copy", makeCallbackF(Copy), Accelerator('C', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Paste", makeCallbackF(Paste), Accelerator('V', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PasteToCamera", makeCallbackF(PasteToCamera), - Accelerator('V', (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("CloneSelection", makeCallbackF(Selection_Clone), Accelerator(GDK_KEY_space)); - GlobalCommands_insert("CloneSelectionAndMakeUnique", makeCallbackF(Selection_Clone_MakeUnique), - Accelerator(GDK_KEY_space, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("DeleteSelection", makeCallbackF(deleteSelection), Accelerator(GDK_KEY_BackSpace)); - GlobalCommands_insert("ParentSelection", makeCallbackF(Scene_parentSelected)); - GlobalCommands_insert("UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator(GDK_KEY_Escape)); - GlobalCommands_insert("InvertSelection", makeCallbackF(Select_Invert), Accelerator('I')); - GlobalCommands_insert("SelectInside", makeCallbackF(Select_Inside)); - GlobalCommands_insert("SelectTouching", makeCallbackF(Select_Touching)); - GlobalCommands_insert("ExpandSelectionToEntities", makeCallbackF(Scene_ExpandSelectionToEntities), - Accelerator('E', (GdkModifierType) (GDK_MOD1_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("Preferences", makeCallbackF(PreferencesDialog_showDialog)); - - GlobalCommands_insert("ToggleEntityInspector", makeCallbackF(EntityInspector_ToggleShow), Accelerator('N')); - GlobalCommands_insert("EntityList", makeCallbackF(EntityList_toggleShown), Accelerator('L')); - - GlobalCommands_insert("ShowHidden", makeCallbackF(Select_ShowAllHidden), - Accelerator('H', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("HideSelected", makeCallbackF(HideSelected), Accelerator('H')); - GlobalCommands_insert("HideUnselected", makeCallbackF(HideUnselected)); - - GlobalToggles_insert("DragVertices", makeCallbackF(SelectVertexMode), - ToggleItem::AddCallbackCaller(g_vertexMode_button), Accelerator('V')); - GlobalToggles_insert("DragEdges", makeCallbackF(SelectEdgeMode), ToggleItem::AddCallbackCaller(g_edgeMode_button), - Accelerator('E')); - GlobalToggles_insert("DragFaces", makeCallbackF(SelectFaceMode), ToggleItem::AddCallbackCaller(g_faceMode_button), - Accelerator('F')); - - GlobalCommands_insert("MirrorSelectionX", makeCallbackF(Selection_Flipx)); - GlobalCommands_insert("RotateSelectionX", makeCallbackF(Selection_Rotatex)); - GlobalCommands_insert("MirrorSelectionY", makeCallbackF(Selection_Flipy)); - GlobalCommands_insert("RotateSelectionY", makeCallbackF(Selection_Rotatey)); - GlobalCommands_insert("MirrorSelectionZ", makeCallbackF(Selection_Flipz)); - GlobalCommands_insert("RotateSelectionZ", makeCallbackF(Selection_Rotatez)); - - GlobalCommands_insert("ArbitraryMove", makeCallbackF(DoMoveDlg)); - GlobalCommands_insert("ArbitraryRotation", makeCallbackF(DoRotateDlg)); - GlobalCommands_insert("ArbitraryScale", makeCallbackF(DoScaleDlg)); - - GlobalCommands_insert("BuildMenuCustomize", makeCallbackF(DoBuildMenu)); - - GlobalCommands_insert("FindBrush", makeCallbackF(DoFind)); - - GlobalCommands_insert("MapInfo", makeCallbackF(DoMapInfo), Accelerator('M')); - - GlobalToggles_insert("ToggleExpansion", makeCallbackF(Texdef_ToggleExpansion), - ToggleItem::AddCallbackCaller(g_expansion_item)); - - GlobalToggles_insert("ToggleAddSelect", makeCallbackF(Texdef_ToggleAddSelect), - ToggleItem::AddCallbackCaller(g_addselect_item)); - - GlobalToggles_insert("ToggleClipper", makeCallbackF(ClipperMode), ToggleItem::AddCallbackCaller(g_clipper_button), - Accelerator('X')); - - GlobalToggles_insert("MouseTranslate", makeCallbackF(TranslateMode), - ToggleItem::AddCallbackCaller(g_translatemode_button)); - GlobalToggles_insert("MouseRotate", makeCallbackF(RotateMode), ToggleItem::AddCallbackCaller(g_rotatemode_button), - Accelerator('R')); - GlobalToggles_insert("MouseScale", makeCallbackF(ScaleMode), ToggleItem::AddCallbackCaller(g_scalemode_button)); - GlobalToggles_insert("MouseDrag", makeCallbackF(DragMode), ToggleItem::AddCallbackCaller(g_dragmode_button), - Accelerator('Q')); - - - GlobalToggles_insert("Modifier1", makeCallbackF(Modifier1), ToggleItem::AddCallbackCaller(g_modifier1_button)); - GlobalToggles_insert("Modifier2", makeCallbackF(Modifier2), ToggleItem::AddCallbackCaller(g_modifier2_button)); - GlobalToggles_insert("Modifier3", makeCallbackF(Modifier3), ToggleItem::AddCallbackCaller(g_modifier3_button)); - - GlobalCommands_insert("ColorSchemeWS", makeCallbackF(ColorScheme_WorldSpawn)); - GlobalCommands_insert("ColorSchemeOriginal", makeCallbackF(ColorScheme_Original)); - GlobalCommands_insert("ColorSchemeQER", makeCallbackF(ColorScheme_QER)); - GlobalCommands_insert("ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black)); - GlobalCommands_insert("ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar)); - GlobalCommands_insert("ChooseTextureBackgroundColor", makeCallback(g_ColoursMenu.m_textureback)); - GlobalCommands_insert("ChooseGridBackgroundColor", makeCallback(g_ColoursMenu.m_xyback)); - GlobalCommands_insert("ChooseGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor)); - GlobalCommands_insert("ChooseGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor)); - GlobalCommands_insert("ChooseSmallGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor_alt)); - GlobalCommands_insert("ChooseSmallGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor_alt)); - GlobalCommands_insert("ChooseGridTextColor", makeCallback(g_ColoursMenu.m_gridtext)); - GlobalCommands_insert("ChooseGridBlockColor", makeCallback(g_ColoursMenu.m_gridblock)); - GlobalCommands_insert("ChooseBrushColor", makeCallback(g_ColoursMenu.m_brush)); - GlobalCommands_insert("ChooseCameraBackgroundColor", makeCallback(g_ColoursMenu.m_cameraback)); - GlobalCommands_insert("ChooseSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush)); - GlobalCommands_insert("ChooseCameraSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush3d)); - GlobalCommands_insert("ChooseClipperColor", makeCallback(g_ColoursMenu.m_clipper)); - GlobalCommands_insert("ChooseOrthoViewNameColor", makeCallback(g_ColoursMenu.m_viewname)); - - - GlobalCommands_insert("CSGSubtract", makeCallbackF(CSG_Subtract), - Accelerator('U', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CSGMerge", makeCallbackF(CSG_Merge), Accelerator('U', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CSGMakeHollow", makeCallbackF(CSG_MakeHollow)); - GlobalCommands_insert("CSGMakeRoom", makeCallbackF(CSG_MakeRoom)); - - Grid_registerCommands(); - - GlobalCommands_insert("SnapToGrid", makeCallbackF(Selection_SnapToGrid), - Accelerator('G', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("SelectAllOfType", makeCallbackF(Select_AllOfType), - Accelerator('A', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("SelectAllOfModel", makeCallbackF(Select_AllOfModel)); - - GlobalCommands_insert("TexRotateClock", makeCallbackF(Texdef_RotateClockwise), - Accelerator(GDK_KEY_Next, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexRotateCounter", makeCallbackF(Texdef_RotateAntiClockwise), - Accelerator(GDK_KEY_Prior, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexScaleUp", makeCallbackF(Texdef_ScaleUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleDown", makeCallbackF(Texdef_ScaleDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleLeft", makeCallbackF(Texdef_ScaleLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleRight", makeCallbackF(Texdef_ScaleRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexShiftUp", makeCallbackF(Texdef_ShiftUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftDown", makeCallbackF(Texdef_ShiftDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftLeft", makeCallbackF(Texdef_ShiftLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftRight", makeCallbackF(Texdef_ShiftRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("MoveSelectionDOWN", makeCallbackF(Selection_MoveDown), Accelerator(GDK_KEY_KP_Subtract)); - GlobalCommands_insert("MoveSelectionUP", makeCallbackF(Selection_MoveUp), Accelerator(GDK_KEY_KP_Add)); - - GlobalCommands_insert("SelectNudgeLeft", makeCallbackF(Selection_NudgeLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeRight", makeCallbackF(Selection_NudgeRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeUp", makeCallbackF(Selection_NudgeUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeDown", makeCallbackF(Selection_NudgeDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_MOD1_MASK)); - - Patch_registerCommands(); - XYShow_registerCommands(); - - typedef FreeCaller ComponentModeSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(ComponentModeSelectionChangedCaller()); - - GlobalPreferenceSystem().registerPreference("PluginToolBar", - make_property_string(g_Layout_enablePluginToolbar.m_latched)); - GlobalPreferenceSystem().registerPreference("XYHeight", make_property_string(g_layout_globals.nXYHeight)); - GlobalPreferenceSystem().registerPreference("XYWidth", make_property_string(g_layout_globals.nXYWidth)); - GlobalPreferenceSystem().registerPreference("CamWidth", make_property_string(g_layout_globals.nCamWidth)); - GlobalPreferenceSystem().registerPreference("CamHeight", make_property_string(g_layout_globals.nCamHeight)); - - GlobalPreferenceSystem().registerPreference("State", make_property_string(g_layout_globals.nState)); - GlobalPreferenceSystem().registerPreference("PositionX", make_property_string(g_layout_globals.m_position.x)); - GlobalPreferenceSystem().registerPreference("PositionY", make_property_string(g_layout_globals.m_position.y)); - GlobalPreferenceSystem().registerPreference("Width", make_property_string(g_layout_globals.m_position.w)); - GlobalPreferenceSystem().registerPreference("Height", make_property_string(g_layout_globals.m_position.h)); - - GlobalPreferenceSystem().registerPreference("CamWnd", make_property(g_posCamWnd)); - GlobalPreferenceSystem().registerPreference("XYWnd", make_property(g_posXYWnd)); - GlobalPreferenceSystem().registerPreference("YZWnd", make_property(g_posYZWnd)); - GlobalPreferenceSystem().registerPreference("XZWnd", make_property(g_posXZWnd)); - - { - const char *ENGINEPATH_ATTRIBUTE = -#if GDEF_OS_WINDOWS - "enginepath_win32" -#elif GDEF_OS_MACOS - "enginepath_macos" -#elif GDEF_OS_LINUX || GDEF_OS_BSD - "enginepath_linux" -#else -#error "unknown platform" -#endif - ; - StringOutputStream path(256); - path << DirectoryCleaned(g_pGameDescription->getRequiredKeyValue(ENGINEPATH_ATTRIBUTE)); - g_strEnginePath = path.c_str(); - } - - GlobalPreferenceSystem().registerPreference("EnginePath", make_property_string(g_strEnginePath)); - - g_Layout_enablePluginToolbar.useLatched(); - - Layout_registerPreferencesPage(); - Paths_registerPreferencesPage(); - - g_brushCount.setCountChangedCallback(makeCallbackF(QE_brushCountChanged)); - g_entityCount.setCountChangedCallback(makeCallbackF(QE_entityCountChanged)); - GlobalEntityCreator().setCounter(&g_entityCount); - - GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated; - GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed; - - GlobalEntityClassManager().attach(g_WorldspawnColourEntityClassObserver); -} - -void MainFrame_Destroy() -{ - GlobalEntityClassManager().detach(g_WorldspawnColourEntityClassObserver); - - GlobalEntityCreator().setCounter(0); - g_entityCount.setCountChangedCallback(Callback()); - g_brushCount.setCountChangedCallback(Callback()); -} - - -void GLWindow_Construct() -{ - GlobalPreferenceSystem().registerPreference("MouseButtons", make_property_string(g_glwindow_globals.m_nMouseType)); -} - -void GLWindow_Destroy() -{ -} diff --git a/src/mainframe.h b/src/mainframe.h deleted file mode 100644 index 9954e73..0000000 --- a/src/mainframe.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAINFRAME_H ) -#define INCLUDED_MAINFRAME_H - -#include -#include "gtkutil/window.h" -#include "gtkutil/idledraw.h" -#include "gtkutil/widget.h" -#include "string/string.h" - -#include "qerplugin.h" - -class IPlugIn; -class IToolbarButton; -class XYWnd; -class CamWnd; -class ZWnd; - - -const int c_command_status = 0; -const int c_position_status = 1; -const int c_brushcount_status = 2; -const int c_texture_status = 3; -const int c_grid_status = 4; -const int c_count_status = 5; - -class MainFrame { -public: -enum EViewStyle { - eRegular = 0, - eFloating = 1, - eSplit = 2, - eRegularLeft = 3, -}; - -MainFrame(); - -~MainFrame(); - -ui::Window m_window{ui::null}; - -CopiedString m_command_status; -CopiedString m_position_status; -CopiedString m_brushcount_status; -CopiedString m_texture_status; -CopiedString m_grid_status; -private: - -void Create(); - -void SaveWindowInfo(); - -void Shutdown(); - -ui::Widget m_vSplit{ui::null}; -ui::Widget m_hSplit{ui::null}; -ui::Widget m_vSplit2{ui::null}; - -XYWnd *m_pXYWnd; -XYWnd *m_pYZWnd; -XYWnd *m_pXZWnd; -CamWnd *m_pCamWnd; -ZWnd *m_pZWnd; -XYWnd *m_pActiveXY; - -bool m_bSleeping; - -void *m_pStatusLabel[c_count_status]; - -WindowPositionTracker m_position_tracker; - -IdleDraw m_idleRedrawStatusText; - -public: - -bool IsSleeping() -{ - return m_bSleeping; -} - -void OnSleep(); - -void SetStatusText(CopiedString &status_text, const char *pText); - -void UpdateStatusText(); - -void RedrawStatusText(); - -typedef MemberCaller RedrawStatusTextCaller; - -void SetGridStatus(); - -typedef MemberCaller SetGridStatusCaller; - -void SetActiveXY(XYWnd *p); - -XYWnd *ActiveXY() -{ - return m_pActiveXY; -}; - -XYWnd *GetXYWnd() -{ - return m_pXYWnd; -} - -XYWnd *GetXZWnd() -{ - return m_pXZWnd; -} - -XYWnd *GetYZWnd() -{ - return m_pYZWnd; -} - -ZWnd *GetZWnd() -{ - return m_pZWnd; -} - -CamWnd *GetCamWnd() -{ - return m_pCamWnd; -} - -void ReleaseContexts(); - -void CreateContexts(); -}; - -extern MainFrame *g_pParentWnd; - -ui::Window MainFrame_getWindow(); - -enum EMouseButtonMode { - ETwoButton = 0, - EThreeButton = 1, -}; - -struct glwindow_globals_t { - int m_nMouseType; - - glwindow_globals_t() : - m_nMouseType(EThreeButton) - { - } -}; - -void GLWindow_Construct(); - -void GLWindow_Destroy(); - -extern glwindow_globals_t g_glwindow_globals; - -template -class LatchedValue; - -extern LatchedValue g_Layout_enableOpenStepUX; - -void deleteSelection(); - - -void Sys_Status(const char *status); - - -void ScreenUpdates_Disable(const char *message, const char *title); - -void ScreenUpdates_Enable(); - -bool ScreenUpdates_Enabled(); - -void ScreenUpdates_process(); - -class ScopeDisableScreenUpdates { -public: -ScopeDisableScreenUpdates(const char *message, const char *title) -{ - ScreenUpdates_Disable(message, title); -} - -~ScopeDisableScreenUpdates() -{ - ScreenUpdates_Enable(); -} -}; - - -void EnginePath_Realise(); - -void EnginePath_Unrealise(); - -class ModuleObserver; - -void Radiant_attachEnginePathObserver(ModuleObserver &observer); - -void Radiant_detachEnginePathObserver(ModuleObserver &observer); - -void Radiant_attachGameToolsPathObserver(ModuleObserver &observer); - -void Radiant_detachGameToolsPathObserver(ModuleObserver &observer); - -extern CopiedString g_strEnginePath; - -void EnginePath_verify(); - -const char *EnginePath_get(); - -const char *QERApp_GetGamePath(); - -extern bool g_disableEnginePath; - -extern CopiedString g_strAppPath; - -const char *AppPath_get(); - -extern CopiedString g_strSettingsPath; - -const char *SettingsPath_get(); - -const char *LocalRcPath_get(void); - -const char *const g_pluginsDir = "plugins/"; ///< name of plugins directory, always sub-directory of toolspath - -extern CopiedString g_strGameToolsPath; - -const char *GameToolsPath_get(); - -void Radiant_Initialise(); - -void Radiant_Shutdown(); - -void SaveMapAs(); - - -void XY_UpdateAllWindows(); - -void UpdateAllWindows(); - - -void ClipperChangeNotify(); - -void DefaultMode(); - -const char *basegame_get(); - -const char *gamename_get(); - -void gamename_set(const char *gamename); - -void Radiant_attachGameNameObserver(ModuleObserver &observer); - -void Radiant_detachGameNameObserver(ModuleObserver &observer); - -const char *gamemode_get(); - -void gamemode_set(const char *gamemode); - -void Radiant_attachGameModeObserver(ModuleObserver &observer); - -void Radiant_detachGameModeObserver(ModuleObserver &observer); - -void VFS_Refresh(); - -void VFS_Restart(); - -void VFS_Construct(); - -void VFS_Destroy(); - - -void MainFrame_Construct(); - -void MainFrame_Destroy(); - - -extern float ( *GridStatus_getGridSize )(); - -extern int ( *GridStatus_getRotateIncrement )(); - -extern int ( *GridStatus_getFarClipDistance )(); - -extern bool ( *GridStatus_getTextureLockEnabled )(); - -void GridStatus_onTextureLockEnabledChanged(); - -SignalHandlerId XYWindowDestroyed_connect(const SignalHandler &handler); - -void XYWindowDestroyed_disconnect(SignalHandlerId id); - -MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler &handler); - -void XYWindowMouseDown_disconnect(MouseEventHandlerId id); - -extern ui::Widget g_page_entity; - -#endif diff --git a/tools/vmap/map.c b/src/map.c similarity index 100% rename from tools/vmap/map.c rename to src/map.c diff --git a/src/map.cpp b/src/map.cpp deleted file mode 100644 index aa0907e..0000000 --- a/src/map.cpp +++ /dev/null @@ -1,2386 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "map.h" - -#include - -#include "debugging/debugging.h" - -#include "imap.h" - -MapModules &ReferenceAPI_getMapModules(); - -#include "iselection.h" -#include "iundo.h" -#include "ibrush.h" -#include "ifilter.h" -#include "ireference.h" -#include "ifiletypes.h" -#include "ieclass.h" -#include "irender.h" -#include "ientity.h" -#include "editable.h" -#include "iarchive.h" -#include "ifilesystem.h" -#include "namespace.h" -#include "moduleobserver.h" - -#include - -#include -#include "uilib/uilib.h" - -#include "scenelib.h" -#include "transformlib.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "traverselib.h" -#include "maplib.h" -#include "eclasslib.h" -#include "cmdlib.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "uniquenames.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" -#include "stream/stringstream.h" -#include "signal/signal.h" - -#include "gtkutil/filechooser.h" -#include "timer.h" -#include "select.h" -#include "plugin.h" -#include "filetypes.h" -#include "gtkdlgs.h" -#include "entityinspector.h" -#include "points.h" -#include "qe3.h" -#include "camwindow.h" -#include "xywindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "preferencesystem.h" -#include "referencecache.h" -#include "mru.h" -#include "commands.h" -#include "autosave.h" -#include "brushmodule.h" -#include "brush.h" - -class NameObserver { -UniqueNames &m_names; -CopiedString m_name; - -void construct() -{ - if (!empty()) { - //globalOutputStream() << "construct " << makeQuoted(c_str()) << "\n"; - m_names.insert(name_read(c_str())); - } -} - -void destroy() -{ - if (!empty()) { - //globalOutputStream() << "destroy " << makeQuoted(c_str()) << "\n"; - m_names.erase(name_read(c_str())); - } -} - -NameObserver &operator=(const NameObserver &other); - -public: -NameObserver(UniqueNames &names) : m_names(names) -{ - construct(); -} - -NameObserver(const NameObserver &other) : m_names(other.m_names), m_name(other.m_name) -{ - construct(); -} - -~NameObserver() -{ - destroy(); -} - -bool empty() const -{ - return string_empty(c_str()); -} - -const char *c_str() const -{ - return m_name.c_str(); -} - -void nameChanged(const char *name) -{ - destroy(); - m_name = name; - construct(); -} - -typedef MemberCaller NameChangedCaller; -}; - -class BasicNamespace : public Namespace { -typedef std::map Names; -Names m_names; -UniqueNames m_uniqueNames; -public: -~BasicNamespace() -{ - ASSERT_MESSAGE(m_names.empty(), "namespace: names still registered at shutdown"); -} - -void attach(const NameCallback &setName, const NameCallbackCallback &attachObserver) -{ - std::pair result = m_names.insert(Names::value_type(setName, m_uniqueNames)); - ASSERT_MESSAGE(result.second, "cannot attach name"); - attachObserver(NameObserver::NameChangedCaller((*result.first).second)); - //globalOutputStream() << "attach: " << reinterpret_cast(setName) << "\n"; -} - -void detach(const NameCallback &setName, const NameCallbackCallback &detachObserver) -{ - Names::iterator i = m_names.find(setName); - ASSERT_MESSAGE(i != m_names.end(), "cannot detach name"); - //globalOutputStream() << "detach: " << reinterpret_cast(setName) << "\n"; - detachObserver(NameObserver::NameChangedCaller((*i).second)); - m_names.erase(i); -} - -void makeUnique(const char *name, const NameCallback &setName) const -{ - char buffer[1024]; - name_write(buffer, m_uniqueNames.make_unique(name_read(name))); - setName(buffer); -} - -void mergeNames(const BasicNamespace &other) const -{ - typedef std::list SetNameCallbacks; - typedef std::map NameGroups; - NameGroups groups; - - UniqueNames uniqueNames(other.m_uniqueNames); - - for (Names::const_iterator i = m_names.begin(); i != m_names.end(); ++i) { - groups[(*i).second.c_str()].push_back((*i).first); - } - - for (NameGroups::iterator i = groups.begin(); i != groups.end(); ++i) { - name_t uniqueName(uniqueNames.make_unique(name_read((*i).first.c_str()))); - uniqueNames.insert(uniqueName); - - char buffer[1024]; - name_write(buffer, uniqueName); - - //globalOutputStream() << "renaming " << makeQuoted((*i).first.c_str()) << " to " << makeQuoted(buffer) << "\n"; - - SetNameCallbacks &setNameCallbacks = (*i).second; - - for (SetNameCallbacks::const_iterator j = setNameCallbacks.begin(); j != setNameCallbacks.end(); ++j) { - (*j)(buffer); - } - } -} -}; - -BasicNamespace g_defaultNamespace; -BasicNamespace g_cloneNamespace; - -class NamespaceAPI { -Namespace *m_namespace; -public: -typedef Namespace Type; - -STRING_CONSTANT(Name, "*"); - -NamespaceAPI() -{ - m_namespace = &g_defaultNamespace; -} - -Namespace *getTable() -{ - return m_namespace; -} -}; - -typedef SingletonModule NamespaceModule; -typedef Static StaticNamespaceModule; -StaticRegisterModule staticRegisterDefaultNamespace(StaticNamespaceModule::instance()); - - -std::list g_cloned; - -inline Namespaced *Node_getNamespaced(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -void Node_gatherNamespaced(scene::Node &node) -{ - Namespaced *namespaced = Node_getNamespaced(node); - if (namespaced != 0) { - g_cloned.push_back(namespaced); - } -} - -class GatherNamespaced : public scene::Traversable::Walker { -public: -bool pre(scene::Node &node) const -{ - Node_gatherNamespaced(node); - return true; -} -}; - -void Map_gatherNamespaced(scene::Node &root) -{ - Node_traverseSubgraph(root, GatherNamespaced()); -} - -void Map_mergeClonedNames() -{ - for (std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) { - (*i)->setNamespace(g_cloneNamespace); - } - g_cloneNamespace.mergeNames(g_defaultNamespace); - for (std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) { - (*i)->setNamespace(g_defaultNamespace); - } - - g_cloned.clear(); -} - -class WorldNode { -scene::Node *m_node; -public: -WorldNode() - : m_node(0) -{ -} - -void set(scene::Node *node) -{ - if (m_node != 0) { - m_node->DecRef(); - } - m_node = node; - if (m_node != 0) { - m_node->IncRef(); - } -} - -scene::Node *get() const -{ - return m_node; -} -}; - -class Map; - -void Map_SetValid(Map &map, bool valid); - -void Map_UpdateTitle(const Map &map); - -void Map_SetWorldspawn(Map &map, scene::Node *node); - - -class Map : public ModuleObserver { -public: -CopiedString m_name; -Resource *m_resource; -bool m_valid; - -bool m_modified; - -void ( *m_modified_changed )(const Map &); - -Signal0 m_mapValidCallbacks; - -WorldNode m_world_node; // "classname" "worldspawn" ! - -Map() : m_resource(0), m_valid(false), m_modified_changed(Map_UpdateTitle) -{ -} - -void realise() -{ - if (m_resource != 0) { - if (Map_Unnamed(*this)) { - g_map.m_resource->setNode(NewMapRoot("").get_pointer()); - MapFile *map = Node_getMapFile(*g_map.m_resource->getNode()); - if (map != 0) { - map->save(); - } - } else { - m_resource->load(); - } - - GlobalSceneGraph().insert_root(*m_resource->getNode()); - - AutoSave_clear(); - - Map_SetValid(g_map, true); - } -} - -void unrealise() -{ - if (m_resource != 0) { - Map_SetValid(g_map, false); - Map_SetWorldspawn(g_map, 0); - - - GlobalUndoSystem().clear(); - - GlobalSceneGraph().erase_root(); - } -} -}; - -Map g_map; -Map *g_currentMap = 0; - -void Map_addValidCallback(Map &map, const SignalHandler &handler) -{ - map.m_mapValidCallbacks.connectLast(handler); -} - -bool Map_Valid(const Map &map) -{ - return map.m_valid; -} - -void Map_SetValid(Map &map, bool valid) -{ - map.m_valid = valid; - map.m_mapValidCallbacks(); -} - - -const char *Map_Name(const Map &map) -{ - return map.m_name.c_str(); -} - -bool Map_Unnamed(const Map &map) -{ - return string_equal(Map_Name(map), "unnamed.map"); -} - -inline const MapFormat &MapFormat_forFile(const char *filename) -{ - const char *moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), path_get_extension(filename)); - MapFormat *format = Radiant_getMapModules().findModule(moduleName); - ASSERT_MESSAGE(format != 0, "map format not found for file " << makeQuoted(filename)); - return *format; -} - -const MapFormat &Map_getFormat(const Map &map) -{ - return MapFormat_forFile(Map_Name(map)); -} - - -bool Map_Modified(const Map &map) -{ - return map.m_modified; -} - -void Map_SetModified(Map &map, bool modified) -{ - if (map.m_modified ^ modified) { - map.m_modified = modified; - - map.m_modified_changed(map); - } -} - -void Map_UpdateTitle(const Map &map) -{ - Sys_SetTitle(map.m_name.c_str(), Map_Modified(map)); -} - - -scene::Node *Map_GetWorldspawn(const Map &map) -{ - return map.m_world_node.get(); -} - -void Map_SetWorldspawn(Map &map, scene::Node *node) -{ - map.m_world_node.set(node); -} - - -// TTimo -// need that in a variable, will have to tweak depending on the game -float g_MaxWorldCoord = 64 * 1024; -float g_MinWorldCoord = -64 * 1024; - -void AddRegionBrushes(void); - -void RemoveRegionBrushes(void); - - -/* - ================ - Map_Free - free all map elements, reinitialize the structures that depend on them - ================ - */ -void Map_Free() -{ - Pointfile_Clear(); - - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); - g_map.m_resource = 0; - - FlushReferences(); - - g_currentMap = 0; - Brush_unlatchPreferences(); -} - -class EntityFindByClassname : public scene::Graph::Walker { -const char *m_name; -Entity *&m_entity; -public: -EntityFindByClassname(const char *name, Entity *&entity) : m_name(name), m_entity(entity) -{ - m_entity = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (m_entity == 0) { - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && string_equal(m_name, entity->getKeyValue("classname"))) { - m_entity = entity; - } - } - return true; -} -}; - -Entity *Scene_FindEntityByClass(const char *name) -{ - Entity *entity; - GlobalSceneGraph().traverse(EntityFindByClassname(name, entity)); - return entity; -} - -#if 0 -// TODO: We probably want to make this game-specific and put it into the game definitions! -Entity *Scene_FindPlayerStart() -{ - typedef const char *StaticString; - StaticString strings[] = { - "info_player_start", - "info_player_deathmatch", - "team_CTF_redplayer", - "team_CTF_blueplayer", - "team_CTF_redspawn", - "team_CTF_bluespawn", - }; - typedef const StaticString *StaticStringIterator; - for (StaticStringIterator i = strings, end = strings + (sizeof(strings) / sizeof(StaticString)); i != end; ++i) { - Entity *entity = Scene_FindEntityByClass(*i); - if (entity != 0) { - return entity; - } - } - return 0; -} -#endif - -void FocusViews(const Vector3 &point, float angle) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, point); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = angle; - Camera_setAngles(camwnd, angles); - - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetOrigin(point); -} - -#include "stringio.h" - -// -// move the view to a start position -// -void GlobalCamera_GoToZero(); -void Map_StartPosition() -{ - GlobalCamera_GoToZero(); -} - -inline bool node_is_worldspawn(scene::Node &node) -{ - Entity *entity = Node_getEntity(node); - return entity != 0 && string_equal(entity->getKeyValue("classname"), "worldspawn"); -} - - -// use first worldspawn -class entity_updateworldspawn : public scene::Traversable::Walker { -public: -bool pre(scene::Node &node) const -{ - if (node_is_worldspawn(node)) { - if (Map_GetWorldspawn(g_map) == 0) { - Map_SetWorldspawn(g_map, &node); - } - } - return false; -} -}; - -scene::Node *Map_FindWorldspawn(Map &map) -{ - Map_SetWorldspawn(map, 0); - - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); - - return Map_GetWorldspawn(map); -} - - -class CollectAllWalker : public scene::Traversable::Walker { -scene::Node &m_root; -UnsortedNodeSet &m_nodes; -public: -CollectAllWalker(scene::Node &root, UnsortedNodeSet &nodes) : m_root(root), m_nodes(nodes) -{ -} - -bool pre(scene::Node &node) const -{ - m_nodes.insert(NodeSmartReference(node)); - Node_getTraversable(m_root)->erase(node); - return false; -} -}; - -void Node_insertChildFirst(scene::Node &parent, scene::Node &child) -{ - UnsortedNodeSet nodes; - Node_getTraversable(parent)->traverse(CollectAllWalker(parent, nodes)); - Node_getTraversable(parent)->insert(child); - - for (UnsortedNodeSet::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node_getTraversable(parent)->insert((*i)); - } -} - -scene::Node &createWorldspawn() -{ - NodeSmartReference worldspawn( - GlobalEntityCreator().createEntity(GlobalEntityClassManager().findOrInsert("worldspawn", true))); - Node_insertChildFirst(GlobalSceneGraph().root(), worldspawn); - return worldspawn; -} - -void Map_UpdateWorldspawn(Map &map) -{ - if (Map_FindWorldspawn(map) == 0) { - Map_SetWorldspawn(map, &createWorldspawn()); - } -} - -scene::Node &Map_FindOrInsertWorldspawn(Map &map) -{ - Map_UpdateWorldspawn(map); - return *Map_GetWorldspawn(map); -} - - -class MapMergeAll : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -MapMergeAll(const scene::Path &root) - : m_path(root) -{ -} - -bool pre(scene::Node &node) const -{ - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - selectPath(m_path, true); - return false; -} - -void post(scene::Node &node) const -{ - m_path.pop(); -} -}; - -class MapMergeEntities : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -MapMergeEntities(const scene::Path &root) - : m_path(root) -{ -} - -bool pre(scene::Node &node) const -{ - if (node_is_worldspawn(node)) { - scene::Node *world_node = Map_FindWorldspawn(g_map); - if (world_node == 0) { - Map_SetWorldspawn(g_map, &node); - Node_getTraversable(m_path.top().get())->insert(node); - m_path.push(makeReference(node)); - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } else { - m_path.push(makeReference(*world_node)); - Node_getTraversable(node)->traverse(MapMergeAll(m_path)); - } - } else { - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - if (node_is_group(node)) { - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } else { - selectPath(m_path, true); - } - } - return false; -} - -void post(scene::Node &node) const -{ - m_path.pop(); -} -}; - -class BasicContainer : public scene::Node::Symbiot { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - -scene::Node m_node; -TraversableNodeSet m_traverse; -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_traverse; -} - -BasicContainer() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} -}; - -/// Merges the map graph rooted at \p node into the global scene-graph. -void MergeMap(scene::Node &node) -{ - Node_getTraversable(node)->traverse(MapMergeEntities(scene::Path(makeReference(GlobalSceneGraph().root())))); -} - -void Map_ImportSelected(TextInputStream &in, const MapFormat &format) -{ - NodeSmartReference node((new BasicContainer)->node()); - format.readGraph(node, in, GlobalEntityCreator()); - Map_gatherNamespaced(node); - Map_mergeClonedNames(); - MergeMap(node); -} - -inline scene::Cloneable *Node_getCloneable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline scene::Node &node_clone(scene::Node &node) -{ - scene::Cloneable *cloneable = Node_getCloneable(node); - if (cloneable != 0) { - return cloneable->clone(); - } - - return (new scene::NullNode)->node(); -} - -class CloneAll : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -CloneAll(scene::Node &root) - : m_path(makeReference(root)) -{ -} - -bool pre(scene::Node &node) const -{ - if (node.isRoot()) { - return false; - } - - m_path.push(makeReference(node_clone(node))); - m_path.top().get().IncRef(); - - return true; -} - -void post(scene::Node &node) const -{ - if (node.isRoot()) { - return; - } - - Node_getTraversable(m_path.parent())->insert(m_path.top()); - - m_path.top().get().DecRef(); - m_path.pop(); -} -}; - -scene::Node &Node_Clone(scene::Node &node) -{ - scene::Node &clone = node_clone(node); - scene::Traversable *traversable = Node_getTraversable(node); - if (traversable != 0) { - traversable->traverse(CloneAll(clone)); - } - return clone; -} - - -typedef std::map EntityBreakdown; - -class EntityBreakdownWalker : public scene::Graph::Walker { -EntityBreakdown &m_entitymap; -public: -EntityBreakdownWalker(EntityBreakdown &entitymap) - : m_entitymap(entitymap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0) { - const EntityClass &eclass = entity->getEntityClass(); - if (m_entitymap.find(eclass.name()) == m_entitymap.end()) { - m_entitymap[eclass.name()] = 1; - } else { ++m_entitymap[eclass.name()]; } - } - return true; -} -}; - -void Scene_EntityBreakdown(EntityBreakdown &entitymap) -{ - GlobalSceneGraph().traverse(EntityBreakdownWalker(entitymap)); -} - - -WindowPosition g_posMapInfoWnd(c_default_window_pos); - -void DoMapInfo() -{ - ModalDialog dialog; - ui::Entry brushes_entry{ui::null}; - ui::Entry entities_entry{ui::null}; - ui::ListStore EntityBreakdownWalker{ui::null}; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Map Info", G_CALLBACK(dialog_delete_callback), - &dialog); - - window_set_position(window, g_posMapInfoWnd); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - { - auto table = create_dialog_table(2, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - - brushes_entry = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - - entities_entry = entry; - } - { - ui::Widget label = ui::Label("Total Brushes"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - ui::Widget label = ui::Label("Total Entities"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, FALSE, FALSE, 0); - - { - auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_ok), &dialog); - vbox2.pack_start(button, FALSE, FALSE, 0); - } - } - } - { - ui::Widget label = ui::Label("Entity breakdown"); - label.show(); - vbox.pack_start(label, FALSE, TRUE, 0); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - vbox.pack_start(scr, TRUE, TRUE, 0); - - { - auto store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_clickable(view, TRUE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Entity", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_sort_column_id(column, 0); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Count", renderer, {{"text", 1}}); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_sort_column_id(column, 1); - } - - view.show(); - - scr.add(view); - - EntityBreakdownWalker = store; - } - } - } - - // Initialize fields - - { - EntityBreakdown entitymap; - Scene_EntityBreakdown(entitymap); - - for (EntityBreakdown::iterator i = entitymap.begin(); i != entitymap.end(); ++i) { - char tmp[16]; - sprintf(tmp, "%u", Unsigned((*i).second)); - EntityBreakdownWalker.append(0, (*i).first.c_str(), 1, tmp); - } - } - - EntityBreakdownWalker.unref(); - - char tmp[16]; - sprintf(tmp, "%u", Unsigned(g_brushCount.get())); - brushes_entry.text(tmp); - sprintf(tmp, "%u", Unsigned(g_entityCount.get())); - entities_entry.text(tmp); - - modal_dialog_show(window, dialog); - - // save before exit - window_get_position(window, g_posMapInfoWnd); - - window.destroy(); -} - - -class ScopeTimer { -Timer m_timer; -const char *m_message; -public: -ScopeTimer(const char *message) - : m_message(message) -{ - m_timer.start(); -} - -~ScopeTimer() -{ - double elapsed_time = m_timer.elapsed_msec() / 1000.f; - globalOutputStream() << m_message << " timer: " << FloatFormat(elapsed_time, 5, 2) << " second(s) elapsed\n"; -} -}; - -CopiedString g_strLastFolder = ""; - -/* - ================ - Map_LoadFile - ================ - */ - -void Map_LoadFile(const char *filename) -{ - globalOutputStream() << "Loading map from " << filename << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - MRU_AddFile(filename); - g_strLastFolder = g_path_get_dirname(filename); - - { - ScopeTimer timer("map load"); - - const MapFormat *format = NULL; - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), path_get_extension(filename)); - if (string_not_empty(moduleName)) { - format = ReferenceAPI_getMapModules().findModule(moduleName); - } - - for (int i = 0; i < Brush_toggleFormatCount(); ++i) { - if (i) { - Map_Free(); - } - Brush_toggleFormat(i); - g_map.m_name = filename; - Map_UpdateTitle(g_map); - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); - if (format) { - format->wrongFormat = false; - } - g_map.m_resource->attach(g_map); - if (format) { - if (!format->wrongFormat) { - break; - } - } - } - - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); - } - - globalOutputStream() << "--- LoadMapFile ---\n"; - globalOutputStream() << g_map.m_name.c_str() << "\n"; - - globalOutputStream() << Unsigned(g_brushCount.get()) << " primitive\n"; - globalOutputStream() << Unsigned(g_entityCount.get()) << " entities\n"; - - //GlobalEntityCreator().printStatistics(); - - // - // move the view to a start position - // - Map_StartPosition(); - - g_currentMap = &g_map; - - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); -} - -class Excluder { -public: -virtual bool excluded(scene::Node &node) const = 0; -}; - -class ExcludeWalker : public scene::Traversable::Walker { -const scene::Traversable::Walker &m_walker; -const Excluder *m_exclude; -mutable bool m_skip; -public: -ExcludeWalker(const scene::Traversable::Walker &walker, const Excluder &exclude) - : m_walker(walker), m_exclude(&exclude), m_skip(false) -{ -} - -bool pre(scene::Node &node) const -{ - if (m_exclude->excluded(node) || node.isRoot()) { - m_skip = true; - return false; - } else { - m_walker.pre(node); - } - return true; -} - -void post(scene::Node &node) const -{ - if (m_skip) { - m_skip = false; - } else { - m_walker.post(node); - } -} -}; - -class AnyInstanceSelected : public scene::Instantiable::Visitor { -bool &m_selected; -public: -AnyInstanceSelected(bool &selected) : m_selected(selected) -{ - m_selected = false; -} - -void visit(scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - m_selected = true; - } -} -}; - -bool Node_instanceSelected(scene::Node &node) -{ - scene::Instantiable *instantiable = Node_getInstantiable(node); - ASSERT_NOTNULL(instantiable); - bool selected; - instantiable->forEachInstance(AnyInstanceSelected(selected)); - return selected; -} - -class SelectedDescendantWalker : public scene::Traversable::Walker { -bool &m_selected; -public: -SelectedDescendantWalker(bool &selected) : m_selected(selected) -{ - m_selected = false; -} - -bool pre(scene::Node &node) const -{ - if (node.isRoot()) { - return false; - } - - if (Node_instanceSelected(node)) { - m_selected = true; - } - - return true; -} -}; - -bool Node_selectedDescendant(scene::Node &node) -{ - bool selected; - Node_traverseSubgraph(node, SelectedDescendantWalker(selected)); - return selected; -} - -class SelectionExcluder : public Excluder { -public: -bool excluded(scene::Node &node) const -{ - return !Node_selectedDescendant(node); -} -}; - -class IncludeSelectedWalker : public scene::Traversable::Walker { -const scene::Traversable::Walker &m_walker; -mutable std::size_t m_selected; -mutable bool m_skip; - -bool selectedParent() const -{ - return m_selected != 0; -} - -public: -IncludeSelectedWalker(const scene::Traversable::Walker &walker) - : m_walker(walker), m_selected(0), m_skip(false) -{ -} - -bool pre(scene::Node &node) const -{ - // include node if: - // node is not a 'root' AND ( node is selected OR any child of node is selected OR any parent of node is selected ) - if (!node.isRoot() && (Node_selectedDescendant(node) || selectedParent())) { - if (Node_instanceSelected(node)) { - ++m_selected; - } - m_walker.pre(node); - return true; - } else { - m_skip = true; - return false; - } -} - -void post(scene::Node &node) const -{ - if (m_skip) { - m_skip = false; - } else { - if (Node_instanceSelected(node)) { - --m_selected; - } - m_walker.post(node); - } -} -}; - -void Map_Traverse_Selected(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { -#if 0 - traversable->traverse( ExcludeWalker( walker, SelectionExcluder() ) ); -#else - traversable->traverse(IncludeSelectedWalker(walker)); -#endif - } -} - -void Map_ExportSelected(TextOutputStream &out, const MapFormat &format) -{ - format.writeGraph(GlobalSceneGraph().root(), Map_Traverse_Selected, out); -} - -void Map_Traverse(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { - traversable->traverse(walker); - } -} - -class RegionExcluder : public Excluder { -public: -bool excluded(scene::Node &node) const -{ - return node.excluded(); -} -}; - -void Map_Traverse_Region(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { - traversable->traverse(ExcludeWalker(walker, RegionExcluder())); - } -} - -bool Map_SaveRegion(const char *filename) -{ - AddRegionBrushes(); - - bool success = MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Region, - filename); - - RemoveRegionBrushes(); - - return success; -} - - -void Map_RenameAbsolute(const char *absolute) -{ - Resource *resource = GlobalReferenceCache().capture(absolute); - NodeSmartReference clone(NewMapRoot(path_make_relative(absolute, GlobalFileSystem().findRoot(absolute)))); - resource->setNode(clone.get_pointer()); - - { - //ScopeTimer timer("clone subgraph"); - Node_getTraversable(GlobalSceneGraph().root())->traverse(CloneAll(clone)); - } - - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); - - g_map.m_resource = resource; - - g_map.m_name = absolute; - Map_UpdateTitle(g_map); - - g_map.m_resource->attach(g_map); - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); -} - -void Map_Rename(const char *filename) -{ - if (!string_equal(g_map.m_name.c_str(), filename)) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - - Map_RenameAbsolute(filename); - - SceneChangeNotify(); - } else { - SaveReferences(); - } -} - -bool Map_Save() -{ - Pointfile_Clear(); - - ScopeTimer timer("map save"); - SaveReferences(); - return true; // assume success.. -} - -/* - =========== - Map_New - - =========== - */ -void Map_New() -{ - //globalOutputStream() << "Map_New\n"; - - g_map.m_name = "unnamed.map"; - Map_UpdateTitle(g_map); - - { - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); -// ASSERT_MESSAGE(g_map.m_resource->getNode() == 0, "bleh"); - g_map.m_resource->attach(g_map); - - SceneChangeNotify(); - } - - FocusViews(g_vector3_identity, 0); - - g_currentMap = &g_map; - - // restart VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Restart(); -} - -extern void ConstructRegionBrushes(scene::Node *brushes[6], const Vector3 ®ion_mins, const Vector3 ®ion_maxs); - -void ConstructRegionStartpoint(scene::Node *startpoint, const Vector3 ®ion_mins, const Vector3 ®ion_maxs) -{ - /*! - \todo we need to make sure that the player start IS inside the region and bail out if it's not - the compiler will refuse to compile a map with a player_start somewhere in empty space.. - for now, let's just print an error - */ - - Vector3 vOrig(Camera_getOrigin(*g_pParentWnd->GetCamWnd())); - - for (int i = 0; i < 3; i++) { - if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i]) { - globalErrorStream() << "Camera is NOT in the region, it's likely that the region won't compile correctly\n"; - break; - } - } - - // write the info_playerstart - char sTmp[1024]; - sprintf(sTmp, "%d %d %d", (int) vOrig[0], (int) vOrig[1], (int) vOrig[2]); - Node_getEntity(*startpoint)->setKeyValue("origin", sTmp); - sprintf(sTmp, "%d", (int) Camera_getAngles(*g_pParentWnd->GetCamWnd())[CAMERA_YAW]); - Node_getEntity(*startpoint)->setKeyValue("angle", sTmp); -} - -/* - =========================================================== - - REGION - - =========================================================== - */ -bool region_active; -Vector3 region_mins(g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord); -Vector3 region_maxs(g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord); - -scene::Node *region_sides[6]; -scene::Node *region_startpoint = 0; - -/* - =========== - AddRegionBrushes - a regioned map will have temp walls put up at the region boundary - \todo TODO TTimo old implementation of region brushes - we still add them straight in the worldspawn and take them out after the map is saved - with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module - =========== - */ -void AddRegionBrushes(void) -{ - int i; - - for (i = 0; i < 6; i++) { - region_sides[i] = &GlobalBrushCreator().createBrush(); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(NodeSmartReference(*region_sides[i])); - } - - region_startpoint = &GlobalEntityCreator().createEntity( - GlobalEntityClassManager().findOrInsert("info_player_start", false)); - - ConstructRegionBrushes(region_sides, region_mins, region_maxs); - ConstructRegionStartpoint(region_startpoint, region_mins, region_maxs); - - Node_getTraversable(GlobalSceneGraph().root())->insert(NodeSmartReference(*region_startpoint)); -} - -void RemoveRegionBrushes(void) -{ - for (std::size_t i = 0; i < 6; i++) { - Node_getTraversable(*Map_GetWorldspawn(g_map))->erase(*region_sides[i]); - } - Node_getTraversable(GlobalSceneGraph().root())->erase(*region_startpoint); -} - -inline void exclude_node(scene::Node &node, bool exclude) -{ - exclude - ? node.enable(scene::Node::eExcluded) - : node.disable(scene::Node::eExcluded); -} - -class ExcludeAllWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeAllWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node(path.top(), m_exclude); - - return true; -} -}; - -void Scene_Exclude_All(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeAllWalker(exclude)); -} - -bool Instance_isSelected(const scene::Instance &instance) -{ - const Selectable *selectable = Instance_getSelectable(instance); - return selectable != 0 && selectable->isSelected(); -} - -class ExcludeSelectedWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeSelectedWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node(path.top(), - (instance.isSelected() || instance.childSelected() || instance.parentSelected()) == m_exclude); - return true; -} -}; - -void Scene_Exclude_Selected(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeSelectedWalker(exclude)); -} - -class ExcludeRegionedWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeRegionedWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node( - path.top(), - !( - ( - aabb_intersects_aabb( - instance.worldAABB(), - aabb_for_minmax(region_mins, region_maxs) - ) != 0 - ) ^ m_exclude - ) - ); - - return true; -} -}; - -void Scene_Exclude_Region(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeRegionedWalker(exclude)); -} - -/* - =========== - Map_RegionOff - - Other filtering options may still be on - =========== - */ -void Map_RegionOff() -{ - region_active = false; - - region_maxs[0] = g_MaxWorldCoord - 64; - region_mins[0] = g_MinWorldCoord + 64; - region_maxs[1] = g_MaxWorldCoord - 64; - region_mins[1] = g_MinWorldCoord + 64; - region_maxs[2] = g_MaxWorldCoord - 64; - region_mins[2] = g_MinWorldCoord + 64; - - Scene_Exclude_All(false); -} - -void Map_ApplyRegion(void) -{ - region_active = true; - - Scene_Exclude_Region(false); -} - - -/* - ======================== - Map_RegionSelectedBrushes - ======================== - */ -void Map_RegionSelectedBrushes(void) -{ - Map_RegionOff(); - - if (GlobalSelectionSystem().countSelected() != 0 - && GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - region_active = true; - Select_GetBounds(region_mins, region_maxs); - - Scene_Exclude_Selected(false); - - GlobalSelectionSystem().setSelectedAll(false); - } -} - - -/* - =========== - Map_RegionXY - =========== - */ -void Map_RegionXY(float x_min, float y_min, float x_max, float y_max) -{ - Map_RegionOff(); - - region_mins[0] = x_min; - region_maxs[0] = x_max; - region_mins[1] = y_min; - region_maxs[1] = y_max; - region_mins[2] = g_MinWorldCoord + 64; - region_maxs[2] = g_MaxWorldCoord - 64; - - Map_ApplyRegion(); -} - -void Map_RegionBounds(const AABB &bounds) -{ - Map_RegionOff(); - - region_mins = vector3_subtracted(bounds.origin, bounds.extents); - region_maxs = vector3_added(bounds.origin, bounds.extents); - - deleteSelection(); - - Map_ApplyRegion(); -} - -/* - =========== - Map_RegionBrush - =========== - */ -void Map_RegionBrush(void) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - Map_RegionBounds(instance.worldAABB()); - } -} - -// -//================ -//Map_ImportFile -//================ -// -bool Map_ImportFile(const char *filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - g_strLastFolder = g_path_get_dirname(filename); - - bool success = false; - - if (extension_equal(path_get_extension(filename), "bsp")) { - goto tryDecompile; - } - - { - const MapFormat *format = NULL; - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), path_get_extension(filename)); - if (string_not_empty(moduleName)) { - format = ReferenceAPI_getMapModules().findModule(moduleName); - } - - if (format) { - format->wrongFormat = false; - } - Resource *resource = GlobalReferenceCache().capture(filename); - resource->refresh(); // avoid loading old version if map has changed on disk since last import - if (!resource->load()) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - if (format) { - if (format->wrongFormat) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - } - NodeSmartReference clone(NewMapRoot("")); - Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone)); - Map_gatherNamespaced(clone); - Map_mergeClonedNames(); - MergeMap(clone); - success = true; - GlobalReferenceCache().release(filename); - } - - SceneChangeNotify(); - - return success; - -tryDecompile: - - const char *type = GlobalRadiant().getGameDescriptionKeyValue("q3map2_type"); - int n = string_length(path_get_extension(filename)); - if (n && (extension_equal(path_get_extension(filename), "bsp") || - extension_equal(path_get_extension(filename), "map"))) { - StringBuffer output; - output.push_string(AppPath_get()); - output.push_string("vmap"); - output.push_string(" -v -game "); - output.push_string((type && *type) ? type : "quake3"); - output.push_string(" -fs_basepath \""); - output.push_string(EnginePath_get()); - output.push_string("\""); - - output.push_string(" -fs_game "); - output.push_string(gamename_get()); - output.push_string(" -convert -format "); - output.push_string(Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map"); - if (extension_equal(path_get_extension(filename), "map")) { - output.push_string(" -readmap "); - } - output.push_string(" \""); - output.push_string(filename); - output.push_string("\""); - - // run - Q_Exec(NULL, output.c_str(), NULL, false, true); - - // rebuild filename as "filenamewithoutext_converted.map" - output.clear(); - output.push_range(filename, filename + string_length(filename) - (n + 1)); - output.push_string("_converted.map"); - filename = output.c_str(); - - // open - Resource *resource = GlobalReferenceCache().capture(filename); - resource->refresh(); // avoid loading old version if map has changed on disk since last import - if (!resource->load()) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - NodeSmartReference clone(NewMapRoot("")); - Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone)); - Map_gatherNamespaced(clone); - Map_mergeClonedNames(); - MergeMap(clone); - success = true; - GlobalReferenceCache().release(filename); - } - - SceneChangeNotify(); - return success; -} - -/* - =========== - Map_SaveFile - =========== - */ -bool Map_SaveFile(const char *filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - bool success = MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse, filename); - if (success) { - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); - } - return success; -} - -// -//=========== -//Map_SaveSelected -//=========== -// -// Saves selected world brushes and whole entities with partial/full selections -// -bool Map_SaveSelected(const char *filename) -{ - return MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Selected, - filename); -} - - -class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker { -scene::Node &m_parent; -public: -ParentSelectedBrushesToEntityWalker(scene::Node &parent) : m_parent(parent) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1) { - return false; - } - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1) { - scene::Node &parent = path.parent(); - if (&parent != &m_parent) { - NodeSmartReference node(path.top().get()); - Node_getTraversable(parent)->erase(node); - Node_getTraversable(m_parent)->insert(node); - } - } - } -} -}; - -void Scene_parentSelectedBrushesToEntity(scene::Graph &graph, scene::Node &parent) -{ - graph.traverse(ParentSelectedBrushesToEntityWalker(parent)); -} - -class CountSelectedBrushes : public scene::Graph::Walker { -std::size_t &m_count; -mutable std::size_t m_depth; -public: -CountSelectedBrushes(std::size_t &count) : m_count(count), m_depth(0) -{ - m_count = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (++m_depth != 1 && path.top().get().isRoot()) { - return false; - } - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && Node_isPrimitive(path.top())) { - ++m_count; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -std::size_t Scene_countSelectedBrushes(scene::Graph &graph) -{ - std::size_t count; - graph.traverse(CountSelectedBrushes(count)); - return count; -} - - - -class CountHiddenBrushes : public scene::Graph::Walker { -std::size_t &m_count; -mutable std::size_t m_depth; -public: -CountHiddenBrushes(std::size_t &count) : m_count(count), m_depth(0) -{ - m_count = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (++m_depth != 1 && path.top().get().isRoot()) { - return false; - } - - if (Node_isHidden(path.top())) { - ++m_count; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -std::size_t Scene_countHiddenBrushes(scene::Graph &graph) -{ - std::size_t count; - graph.traverse(CountHiddenBrushes(count)); - return count; -} - -enum ENodeType { - eNodeUnknown, - eNodeMap, - eNodeEntity, - eNodePrimitive, -}; - -const char *nodetype_get_name(ENodeType type) -{ - if (type == eNodeMap) { - return "map"; - } - if (type == eNodeEntity) { - return "entity"; - } - if (type == eNodePrimitive) { - return "primitive"; - } - return "unknown"; -} - -ENodeType node_get_nodetype(scene::Node &node) -{ - if (Node_isEntity(node)) { - return eNodeEntity; - } - if (Node_isPrimitive(node)) { - return eNodePrimitive; - } - return eNodeUnknown; -} - -bool contains_entity(scene::Node &node) -{ - return Node_getTraversable(node) != 0 && !Node_isBrush(node) && !Node_isPatch(node) && !Node_isEntity(node); -} - -bool contains_primitive(scene::Node &node) -{ - return Node_isEntity(node) && Node_getTraversable(node) != 0 && Node_getEntity(node)->isContainer(); -} - -ENodeType node_get_contains(scene::Node &node) -{ - if (contains_entity(node)) { - return eNodeEntity; - } - if (contains_primitive(node)) { - return eNodePrimitive; - } - return eNodeUnknown; -} - -void Path_parent(const scene::Path &parent, const scene::Path &child) -{ - ENodeType contains = node_get_contains(parent.top()); - ENodeType type = node_get_nodetype(child.top()); - - if (contains != eNodeUnknown && contains == type) { - NodeSmartReference node(child.top().get()); - Path_deleteTop(child); - Node_getTraversable(parent.top())->insert(node); - SceneChangeNotify(); - } else { - globalErrorStream() << "failed - " << nodetype_get_name(type) << " cannot be parented to " - << nodetype_get_name(contains) << " container.\n"; - } -} - -void Scene_parentSelected() -{ - UndoableCommand undo("parentSelected"); - - if (GlobalSelectionSystem().countSelected() > 1) { - class ParentSelectedBrushesToEntityWalker : public SelectionSystem::Visitor { - const scene::Path &m_parent; -public: - ParentSelectedBrushesToEntityWalker(const scene::Path &parent) : m_parent(parent) - { - } - - void visit(scene::Instance &instance) const - { - if (&m_parent != &instance.path()) { - Path_parent(m_parent, instance.path()); - } - } - }; - - ParentSelectedBrushesToEntityWalker visitor(GlobalSelectionSystem().ultimateSelected().path()); - GlobalSelectionSystem().foreachSelected(visitor); - } else { - globalOutputStream() << "failed - did not find two selected nodes.\n"; - } -} - - -void NewMap() -{ - if (ConfirmModified("New Map")) { - Map_RegionOff(); - Map_Free(); - Map_New(); - } -} - -CopiedString g_mapsPath; - -const char *getMapsPath() -{ - return g_mapsPath.c_str(); -} - -const char *getLastFolderPath() -{ - if (g_strLastFolder.empty()) { - GlobalPreferenceSystem().registerPreference("LastFolder", make_property_string(g_strLastFolder)); - if (g_strLastFolder.empty()) { - g_strLastFolder = EnginePath_get(); - } - } - return g_strLastFolder.c_str(); -} - -const char *map_open(const char *title) -{ - return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), true, false, false); -} - -const char *map_import(const char *title) -{ - return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), false, true, false); -} - -const char *map_save(const char *title) -{ - return MainFrame_getWindow().file_dialog(FALSE, title, getLastFolderPath(), MapFormat::Name(), false, false, true); -} - -void OpenMap() -{ - if (!ConfirmModified("Open Map")) { - return; - } - - const char *filename = map_open("Open Map"); - - if (filename != NULL) { - MRU_AddFile(filename); - Map_RegionOff(); - Map_Free(); - Map_LoadFile(filename); - } -} - -void ImportMap() -{ - const char *filename = map_import("Import Map"); - - if (filename != NULL) { - UndoableCommand undo("mapImport"); - Map_ImportFile(filename); - } -} - -bool Map_SaveAs() -{ - const char *filename = map_save("Save Map"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - MRU_AddFile(filename); - Map_Rename(filename); - return Map_Save(); - } - return false; -} - -void SaveMapAs() -{ - Map_SaveAs(); -} - -void SaveMap() -{ - if (Map_Unnamed(g_map)) { - SaveMapAs(); - } else /*if (Map_Modified(g_map))*/ { - Map_Save(); - } -} - -void ExportMap() -{ - const char *filename = map_save("Export Selection"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - Map_SaveSelected(filename); - } -} - -void SaveRegion() -{ - const char *filename = map_save("Export Region"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - Map_SaveRegion(filename); - } -} - - -void RegionOff() -{ - Map_RegionOff(); - SceneChangeNotify(); -} - -void RegionXY() -{ - Map_RegionXY( - g_pParentWnd->GetXYWnd()->GetOrigin()[0] - - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] - - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[0] + - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] + - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale() - ); - SceneChangeNotify(); -} - -void RegionBrush() -{ - Map_RegionBrush(); - SceneChangeNotify(); -} - -void RegionSelected() -{ - Map_RegionSelectedBrushes(); - SceneChangeNotify(); -} - - -class BrushFindByIndexWalker : public scene::Traversable::Walker { -mutable std::size_t m_index; -scene::Path &m_path; -public: -BrushFindByIndexWalker(std::size_t index, scene::Path &path) - : m_index(index), m_path(path) -{ -} - -bool pre(scene::Node &node) const -{ - if (Node_isPrimitive(node) && m_index-- == 0) { - m_path.push(makeReference(node)); - } - return false; -} -}; - -class EntityFindByIndexWalker : public scene::Traversable::Walker { -mutable std::size_t m_index; -scene::Path &m_path; -public: -EntityFindByIndexWalker(std::size_t index, scene::Path &path) - : m_index(index), m_path(path) -{ -} - -bool pre(scene::Node &node) const -{ - if (Node_isEntity(node) && m_index-- == 0) { - m_path.push(makeReference(node)); - } - return false; -} -}; - -void Scene_FindEntityBrush(std::size_t entity, std::size_t brush, scene::Path &path) -{ - path.push(makeReference(GlobalSceneGraph().root())); - { - Node_getTraversable(path.top())->traverse(EntityFindByIndexWalker(entity, path)); - } - if (path.size() == 2) { - scene::Traversable *traversable = Node_getTraversable(path.top()); - if (traversable != 0) { - traversable->traverse(BrushFindByIndexWalker(brush, path)); - } - } -} - -inline bool Node_hasChildren(scene::Node &node) -{ - scene::Traversable *traversable = Node_getTraversable(node); - return traversable != 0 && !traversable->empty(); -} - -void SelectBrush(int entitynum, int brushnum) -{ - scene::Path path; - Scene_FindEntityBrush(entitynum, brushnum, path); - if (path.size() == 3 || (path.size() == 2 && !Node_hasChildren(path.top()))) { - scene::Instance *instance = GlobalSceneGraph().find(path); - ASSERT_MESSAGE(instance != 0, "SelectBrush: path not found in scenegraph"); - Selectable *selectable = Instance_getSelectable(*instance); - ASSERT_MESSAGE(selectable != 0, "SelectBrush: path not selectable"); - selectable->setSelected(true); - g_pParentWnd->GetXYWnd()->PositionView(instance->worldAABB().origin); - } -} - - -class BrushFindIndexWalker : public scene::Graph::Walker { -mutable const scene::Node *m_node; -std::size_t &m_count; -public: -BrushFindIndexWalker(const scene::Node &node, std::size_t &count) - : m_node(&node), m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (Node_isPrimitive(path.top())) { - if (m_node == path.top().get_pointer()) { - m_node = 0; - } - if (m_node) { - ++m_count; - } - } - return true; -} -}; - -class EntityFindIndexWalker : public scene::Graph::Walker { -mutable const scene::Node *m_node; -std::size_t &m_count; -public: -EntityFindIndexWalker(const scene::Node &node, std::size_t &count) - : m_node(&node), m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (Node_isEntity(path.top())) { - if (m_node == path.top().get_pointer()) { - m_node = 0; - } - if (m_node) { - ++m_count; - } - } - return true; -} -}; - -static void GetSelectionIndex(int *ent, int *brush) -{ - std::size_t count_brush = 0; - std::size_t count_entity = 0; - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - GlobalSceneGraph().traverse(BrushFindIndexWalker(path.top(), count_brush)); - GlobalSceneGraph().traverse(EntityFindIndexWalker(path.parent(), count_entity)); - } - *brush = int(count_brush); - *ent = int(count_entity); -} - -void DoFind() -{ - ModalDialog dialog; - ui::Entry entity{ui::null}; - ui::Entry brush{ui::null}; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Find Brush", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - { - auto table = create_dialog_table(2, 2, 4, 4); - vbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label("Entity number"); - label.show(); - (table).attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label("Brush number"); - label.show(); - (table).attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_grab_focus(entry); - entity = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - brush = entry; - } - } - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("Find", G_CALLBACK(dialog_button_ok), &dialog); - hbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_cancel), &dialog); - hbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize dialog - char buf[16]; - int ent, br; - - GetSelectionIndex(&ent, &br); - sprintf(buf, "%i", ent); - entity.text(buf); - sprintf(buf, "%i", br); - brush.text(buf); - - if (modal_dialog_show(window, dialog) == eIDOK) { - const char *entstr = gtk_entry_get_text(entity); - const char *brushstr = gtk_entry_get_text(brush); - SelectBrush(atoi(entstr), atoi(brushstr)); - } - - window.destroy(); -} - -void Map_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Load last map on open", g_bLoadLastMap); -} - - -class MapEntityClasses : public ModuleObserver { -std::size_t m_unrealised; -public: -MapEntityClasses() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - if (g_map.m_resource != 0) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - g_map.m_resource->realise(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (g_map.m_resource != 0) { - g_map.m_resource->flush(); - g_map.m_resource->unrealise(); - } - } -} -}; - -MapEntityClasses g_MapEntityClasses; - - -class MapModuleObserver : public ModuleObserver { -std::size_t m_unrealised; -public: -MapModuleObserver() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - ASSERT_MESSAGE(!string_empty(g_qeglobals.m_userGamePath.c_str()), - "maps_directory: user-game-path is empty"); - StringOutputStream buffer(256); - buffer << g_qeglobals.m_userGamePath.c_str() << "maps/"; - Q_mkdir(buffer.c_str()); - g_mapsPath = buffer.c_str(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - g_mapsPath = ""; - } -} -}; - -MapModuleObserver g_MapModuleObserver; - -CopiedString g_strLastMap; -bool g_bLoadLastMap = false; - -void Map_Construct() -{ - GlobalCommands_insert("RegionOff", makeCallbackF(RegionOff)); - GlobalCommands_insert("RegionSetXY", makeCallbackF(RegionXY)); - GlobalCommands_insert("RegionSetBrush", makeCallbackF(RegionBrush)); - GlobalCommands_insert("RegionSetSelection", makeCallbackF(RegionSelected), - Accelerator('R', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - - GlobalPreferenceSystem().registerPreference("LastMap", make_property_string(g_strLastMap)); - GlobalPreferenceSystem().registerPreference("LoadLastMap", make_property_string(g_bLoadLastMap)); - GlobalPreferenceSystem().registerPreference("MapInfoDlg", make_property(g_posMapInfoWnd)); - - PreferencesDialog_addSettingsPreferences(makeCallbackF(Map_constructPreferences)); - - GlobalEntityClassManager().attach(g_MapEntityClasses); -} - -void Map_Destroy() -{ - GlobalEntityClassManager().detach(g_MapEntityClasses); -} diff --git a/src/map.h b/src/map.h deleted file mode 100644 index e2b1731..0000000 --- a/src/map.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAP_H ) -#define INCLUDED_MAP_H - -#include "iscenegraph.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "string/stringfwd.h" - -class Map; - -extern Map g_map; - -class MapFormat; - -void Map_addValidCallback(Map &map, const SignalHandler &handler); - -bool Map_Valid(const Map &map); - -class DeferredDraw { -Callback m_draw; -bool m_defer; -bool m_deferred; -public: -DeferredDraw(const Callback &draw) : m_draw(draw), m_defer(false), m_deferred(false) -{ -} - -void defer() -{ - m_defer = true; -} - -void draw() -{ - if (m_defer) { - m_deferred = true; - } else { - m_draw(); - } -} - -void flush() -{ - if (m_defer && m_deferred) { - m_draw(); - } - m_deferred = false; - m_defer = false; -} -}; - -inline void DeferredDraw_onMapValidChanged(DeferredDraw &self) -{ - if (Map_Valid(g_map)) { - self.flush(); - } else { - self.defer(); - } -} - -typedef ReferenceCaller DeferredDrawOnMapValidChangedCaller; - - -const char *Map_Name(const Map &map); - -const MapFormat &Map_getFormat(const Map &map); - -bool Map_Unnamed(const Map &map); - - -namespace scene { -class Node; - -class Graph; -} - -scene::Node *Map_GetWorldspawn(const Map &map); - -scene::Node *Map_FindWorldspawn(Map &map); - -scene::Node &Map_FindOrInsertWorldspawn(Map &map); - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -extern Vector3 region_mins, region_maxs; -extern bool region_active; - -// used to be #defines, multiple engine support suggests we should go towards dynamic -extern float g_MaxWorldCoord; -extern float g_MinWorldCoord; - -void Map_LoadFile(const char *filename); - -bool Map_SaveFile(const char *filename); - -void Map_New(); - -void Map_Free(); - -void Map_RegionOff(); - -bool Map_SaveRegion(const char *filename); - -class TextInputStream; - -class TextOutputStream; - -void Map_ImportSelected(TextInputStream &in, const MapFormat &format); - -void Map_ExportSelected(TextOutputStream &out, const MapFormat &format); - -bool Map_Modified(const Map &map); - -void Map_SetModified(Map &map, bool modified); - -bool Map_Save(); - -bool Map_SaveAs(); - -scene::Node &Node_Clone(scene::Node &node); - -void DoMapInfo(); - -void Scene_parentSelectedBrushesToEntity(scene::Graph &graph, scene::Node &parent); - -std::size_t Scene_countSelectedBrushes(scene::Graph &graph); - -void Scene_parentSelected(); - -void OnUndoSizeChanged(); - -void NewMap(); - -void OpenMap(); - -void ImportMap(); - -void SaveMapAs(); - -void SaveMap(); - -void ExportMap(); - -void SaveRegion(); - - -void Map_Traverse(scene::Node &root, const scene::Traversable::Walker &walker); - - -void SelectBrush(int entitynum, int brushnum); - -extern CopiedString g_strLastMap; -extern bool g_bLoadLastMap; - -void Map_Construct(); - -void Map_Destroy(); - - -void Map_gatherNamespaced(scene::Node &root); - -void Map_mergeClonedNames(); - - -const char *getMapsPath(); - -#endif diff --git a/tools/vmap/mesh.c b/src/mesh.c similarity index 100% rename from tools/vmap/mesh.c rename to src/mesh.c diff --git a/tools/vmap/model.c b/src/model.c similarity index 100% rename from tools/vmap/model.c rename to src/model.c diff --git a/src/mru.cpp b/src/mru.cpp deleted file mode 100644 index 20545ed..0000000 --- a/src/mru.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mru.h" - -#include -#include -#include - -#include "os/file.h" -#include "generic/callback.h" -#include "stream/stringstream.h" -#include "convert.h" - -#include "gtkutil/menu.h" -#include "map.h" -#include "qe3.h" - -const int MRU_MAX = 4; -namespace { -GtkMenuItem *MRU_items[MRU_MAX]; -std::size_t MRU_used; -typedef CopiedString MRU_filename_t; -MRU_filename_t MRU_filenames[MRU_MAX]; -typedef const char *MRU_key_t; -MRU_key_t MRU_keys[MRU_MAX] = {"File0", "File1", "File2", "File3"}; -} - -inline const char *MRU_GetText(std::size_t index) -{ - return MRU_filenames[index].c_str(); -} - -class EscapedMnemonic { -StringBuffer m_buffer; -public: -EscapedMnemonic(std::size_t capacity) : m_buffer(capacity) -{ - m_buffer.push_back('_'); -} - -const char *c_str() const -{ - return m_buffer.c_str(); -} - -void push_back(char c) -{ // not escaped - m_buffer.push_back(c); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - for (const char *end = buffer + length; buffer != end; ++buffer) { - if (*buffer == '_') { - m_buffer.push_back('_'); - } - - m_buffer.push_back(*buffer); - } - return length; -} -}; - -template -inline EscapedMnemonic &operator<<(EscapedMnemonic &ostream, const T &t) -{ - return ostream_write(ostream, t); -} - - -void MRU_updateWidget(std::size_t index, const char *filename) -{ - EscapedMnemonic mnemonic(64); - mnemonic << Unsigned(index + 1) << "- " << filename; - gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(MRU_items[index]))), mnemonic.c_str()); -} - -void MRU_SetText(std::size_t index, const char *filename) -{ - MRU_filenames[index] = filename; - MRU_updateWidget(index, filename); -} - -void MRU_AddFile(const char *str) -{ - std::size_t i; - const char *text; - - // check if file is already in our list - for (i = 0; i < MRU_used; i++) { - text = MRU_GetText(i); - - if (strcmp(text, str) == 0) { - // reorder menu - for (; i > 0; i--) { - MRU_SetText(i, MRU_GetText(i - 1)); - } - - MRU_SetText(0, str); - - return; - } - } - - if (MRU_used < MRU_MAX) { - MRU_used++; - } - - // move items down - for (i = MRU_used - 1; i > 0; i--) { - MRU_SetText(i, MRU_GetText(i - 1)); - } - - MRU_SetText(0, str); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), TRUE); - ui::MenuItem::from(MRU_items[MRU_used - 1]).show(); -} - -void MRU_Init() -{ - if (MRU_used > MRU_MAX) { - MRU_used = MRU_MAX; - } -} - -void MRU_AddWidget(ui::MenuItem widget, std::size_t pos) -{ - if (pos < MRU_MAX) { - MRU_items[pos] = widget; - if (pos < MRU_used) { - MRU_updateWidget(pos, MRU_GetText(pos)); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), TRUE); - ui::MenuItem::from(MRU_items[pos]).show(); - } - } -} - -void MRU_Activate(std::size_t index) -{ - char text[1024]; - strcpy(text, MRU_GetText(index)); - - if (file_readable(text)) { //\todo Test 'map load succeeds' instead of 'file is readable'. - MRU_AddFile(text); - Map_RegionOff(); - Map_Free(); - Map_LoadFile(text); - } else { - MRU_used--; - - for (std::size_t i = index; i < MRU_used; i++) { - MRU_SetText(i, MRU_GetText(i + 1)); - } - - if (MRU_used == 0) { - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(MRU_items[0]))); - label.text("Recent Files"); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), FALSE); - } else { - ui::MenuItem::from(MRU_items[MRU_used]).hide(); - } - } -} - - -class LoadMRU { -std::size_t m_number; -public: -LoadMRU(std::size_t number) - : m_number(number) -{ -} - -void load() -{ - if (ConfirmModified("Open Map")) { - MRU_Activate(m_number - 1); - } -} -}; - -typedef MemberCaller LoadMRUCaller; - -LoadMRU g_load_mru1(1); -LoadMRU g_load_mru2(2); -LoadMRU g_load_mru3(3); -LoadMRU g_load_mru4(4); - -void MRU_constructMenu(ui::Menu menu) -{ - { - auto item = create_menu_item_with_mnemonic(menu, "_1", LoadMRUCaller(g_load_mru1)); - gtk_widget_set_sensitive(item, FALSE); - MRU_AddWidget(item, 0); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_2", LoadMRUCaller(g_load_mru2)); - item.hide(); - MRU_AddWidget(item, 1); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_3", LoadMRUCaller(g_load_mru3)); - item.hide(); - MRU_AddWidget(item, 2); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_4", LoadMRUCaller(g_load_mru4)); - item.hide(); - MRU_AddWidget(item, 3); - } -} - -#include "preferencesystem.h" -#include "stringio.h" - -void MRU_Construct() -{ - GlobalPreferenceSystem().registerPreference("Count", make_property_string(MRU_used)); - - for (std::size_t i = 0; i != MRU_MAX; ++i) { - GlobalPreferenceSystem().registerPreference(MRU_keys[i], make_property_string(MRU_filenames[i])); - } - - MRU_Init(); -} - -void MRU_Destroy() -{ -} diff --git a/src/mru.h b/src/mru.h deleted file mode 100644 index 64d2cd3..0000000 --- a/src/mru.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_MRU_H ) -#define INCLUDED_MRU_H - -void MRU_AddFile(const char *str); - -void MRU_constructMenu(ui::Menu menu); - -void MRU_Construct(); - -void MRU_Destroy(); - -#endif diff --git a/src/multimon.cpp b/src/multimon.cpp deleted file mode 100644 index ae9dbe7..0000000 --- a/src/multimon.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if defined(GDEF_OS_WINDOWS) - -#include "multimon.h" -#include "debugging/debugging.h" -#include "gtkutil/window.h" -#include "preferences.h" - -multimon_globals_t g_multimon_globals; - -LatchedValue g_Multimon_enableSysMenuPopups(false, "Floating windows sysmenu icons"); - -void MultiMonitor_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton primary_monitor = page.appendCheckBox("Multi Monitor", "Start on Primary Monitor", - g_multimon_globals.m_bStartOnPrimMon); - ui::CheckButton popup = page.appendCheckBox( - "", "Disable system menu on popup windows", - make_property(g_Multimon_enableSysMenuPopups) - ); - Widget_connectToggleDependency(popup, primary_monitor); -} - -#include "preferencesystem.h" -#include "stringio.h" - -#include - -namespace { -GdkRectangle primaryMonitor; -} - -void PositionWindowOnPrimaryScreen(WindowPosition &position) -{ - if (position.w >= primaryMonitor.width - 12) { - position.w = primaryMonitor.width - 12; - } - if (position.h >= primaryMonitor.height - 24) { - position.h = primaryMonitor.height - 48; - } - if (position.x <= primaryMonitor.x || position.x + position.w >= (primaryMonitor.x + primaryMonitor.width) - 12) { - position.x = primaryMonitor.x + 6; - } - if (position.y <= primaryMonitor.y || position.y + position.h >= (primaryMonitor.y + primaryMonitor.height) - 48) { - position.y = primaryMonitor.y + 24; - } -} - -void MultiMon_Construct() -{ - // detect multiple monitors - - GdkScreen *screen = gdk_display_get_default_screen(gdk_display_get_default()); - gint m = gdk_screen_get_n_monitors(screen); - globalOutputStream() << "default screen has " << m << " monitors\n"; - for (int j = 0; j != m; ++j) { - GdkRectangle geom; - gdk_screen_get_monitor_geometry(screen, j, &geom); - globalOutputStream() << "monitor " << j << " geometry: " << geom.x << ", " << geom.y << ", " << geom.width - << ", " << geom.height << "\n"; - if (j == 0) { - // I am making the assumption that monitor 0 is always the primary monitor on win32. Tested on WinXP with gtk+-2.4. - primaryMonitor = geom; - } - } - - if (m > 1) { - g_multimon_globals.m_bStartOnPrimMon = true; - } - - GlobalPreferenceSystem().registerPreference("StartOnPrimMon", - make_property_string(g_multimon_globals.m_bStartOnPrimMon)); - GlobalPreferenceSystem().registerPreference("NoSysMenuPopups", - make_property_string(g_Multimon_enableSysMenuPopups.m_latched)); - - g_Multimon_enableSysMenuPopups.useLatched(); - - PreferencesDialog_addInterfacePreferences(makeCallbackF(MultiMonitor_constructPreferences)); -} - -void MultiMon_Destroy() -{ -} -#endif diff --git a/src/multimon.h b/src/multimon.h deleted file mode 100644 index 2122690..0000000 --- a/src/multimon.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MULTIMON_H ) -#define INCLUDED_MULTIMON_H - -#include "globaldefs.h" - -struct WindowPosition; - -void PositionWindowOnPrimaryScreen(WindowPosition &position); - -struct multimon_globals_t { - bool m_bStartOnPrimMon; - - multimon_globals_t() : - m_bStartOnPrimMon(false) - { - } -}; - -extern multimon_globals_t g_multimon_globals; - -#if GDEF_OS_WINDOWS -void MultiMon_Construct(); -void MultiMon_Destroy(); -#else - -inline void MultiMon_Construct() -{ -} - -inline void MultiMon_Destroy() -{ -} - -#endif - -#endif diff --git a/src/nullmodel.cpp b/src/nullmodel.cpp deleted file mode 100644 index e36af95..0000000 --- a/src/nullmodel.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "nullmodel.h" - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iundo.h" -#include "ientity.h" -#include "ireference.h" -#include "igl.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" - -#include "math/frustum.h" -#include "scenelib.h" -#include "instancelib.h" -#include "entitylib.h" - -class NullModel : - public Bounded, - public Cullable { -Shader *m_state; -AABB m_aabb_local; -RenderableSolidAABB m_aabb_solid; -RenderableWireframeAABB m_aabb_wire; -public: -NullModel() : m_aabb_local(Vector3(0, 0, 0), Vector3(8, 8, 8)), m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local) -{ - m_state = GlobalShaderCache().capture(""); -} - -~NullModel() -{ - GlobalShaderCache().release(""); -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - renderer.addRenderable(m_aabb_solid, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.addRenderable(m_aabb_wire, localToWorld); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_local, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} -}; - -class NullModelInstance : public scene::Instance, public Renderable, public SelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -NullModel &m_nullmodel; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_nullmodel; -} - -Cullable &get(NullType) -{ - return m_nullmodel; -} - -NullModelInstance(const scene::Path &path, scene::Instance *parent, NullModel &nullmodel) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_nullmodel(nullmodel) -{ -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_nullmodel.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_nullmodel.renderWireframe(renderer, volume, Instance::localToWorld()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_nullmodel.testSelect(selector, test, Instance::localToWorld()); -} -}; - -class NullModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -NullModel m_nullmodel; -public: - -typedef LazyStatic StaticTypeCasts; - -NullModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ - m_node.m_isRoot = true; -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new NullModelInstance(path, parent, m_nullmodel); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -NodeSmartReference NewNullModel() -{ - return NodeSmartReference((new NullModelNode)->node()); -} - -void NullModel_construct() -{ -} - -void NullModel_destroy() -{ -} diff --git a/src/nullmodel.h b/src/nullmodel.h deleted file mode 100644 index 3fb5daf..0000000 --- a/src/nullmodel.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_NULLMODEL_H ) -#define INCLUDED_NULLMODEL_H - -namespace scene { -class Node; -} - -#include "generic/referencecounted.h" - -typedef SmartReference > NodeSmartReference; - -NodeSmartReference NewNullModel(); - -void NullModel_construct(); - -void NullModel_destroy(); - -#endif diff --git a/src/parse.cpp b/src/parse.cpp deleted file mode 100644 index 9afaa02..0000000 --- a/src/parse.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parse.h" - -#include "script/scripttokeniser.h" -#include "script/scripttokenwriter.h" - -class ScriptLibraryAPI { -_QERScripLibTable m_scriptlibrary; -public: -typedef _QERScripLibTable Type; - -STRING_CONSTANT(Name, "*"); - -ScriptLibraryAPI() -{ - m_scriptlibrary.m_pfnNewScriptTokeniser = &NewScriptTokeniser; - m_scriptlibrary.m_pfnNewSimpleTokeniser = &NewSimpleTokeniser; - m_scriptlibrary.m_pfnNewSimpleTokenWriter = &NewSimpleTokenWriter; -} - -_QERScripLibTable *getTable() -{ - return &m_scriptlibrary; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule ScriptLibraryModule; -typedef Static StaticScriptLibraryModule; -StaticRegisterModule staticRegisterScriptLibrary(StaticScriptLibraryModule::instance()); diff --git a/src/parse.h b/src/parse.h deleted file mode 100644 index bf9f2be..0000000 --- a/src/parse.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PARSE_H ) -#define INCLUDED_PARSE_H - -#endif diff --git a/tools/vmap/patch.c b/src/patch.c similarity index 100% rename from tools/vmap/patch.c rename to src/patch.c diff --git a/src/patch.cpp b/src/patch.cpp deleted file mode 100644 index 28306ac..0000000 --- a/src/patch.cpp +++ /dev/null @@ -1,2960 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _USE_MATH_DEFINES -#include "patch.h" - -#include -#include "preferences.h" -#include "brush_primit.h" -#include "signal/signal.h" - - -Signal0 g_patchTextureChangedCallbacks; - -void Patch_addTextureChangedCallback(const SignalHandler &handler) -{ - g_patchTextureChangedCallbacks.connectLast(handler); -} - -void Patch_textureChanged() -{ - g_patchTextureChangedCallbacks(); -} - - -Shader *PatchInstance::m_state_selpoint; -Shader *Patch::m_state_ctrl; -Shader *Patch::m_state_lattice; -EPatchType Patch::m_type; - - -std::size_t MAX_PATCH_WIDTH = 0; -std::size_t MAX_PATCH_HEIGHT = 0; - -int g_PatchSubdivideThreshold = 4; - -void BezierCurveTree_Delete(BezierCurveTree *pCurve) -{ - if (pCurve) { - BezierCurveTree_Delete(pCurve->left); - BezierCurveTree_Delete(pCurve->right); - delete pCurve; - } -} - -std::size_t BezierCurveTree_Setup(BezierCurveTree *pCurve, std::size_t index, std::size_t stride) -{ - if (pCurve) { - if (pCurve->left && pCurve->right) { - index = BezierCurveTree_Setup(pCurve->left, index, stride); - pCurve->index = index * stride; - index++; - index = BezierCurveTree_Setup(pCurve->right, index, stride); - } else { - pCurve->index = BEZIERCURVETREE_MAX_INDEX; - } - } - - return index; -} - -bool BezierCurve_IsCurved(BezierCurve *pCurve) -{ - Vector3 vTemp(vector3_subtracted(pCurve->right, pCurve->left)); - Vector3 v1(vector3_subtracted(pCurve->crd, pCurve->left)); - Vector3 v2(vector3_subtracted(pCurve->right, pCurve->crd)); - - if (vector3_equal(v1, g_vector3_identity) || vector3_equal(vTemp, v1)) { // return 0 if 1->2 == 0 or 1->2 == 1->3 - return false; - } - - vector3_normalise(v1); - vector3_normalise(v2); - if (vector3_equal(v1, v2)) { - return false; - } - - Vector3 v3(vTemp); - const double width = vector3_length(v3); - vector3_scale(v3, 1.0 / width); - - if (vector3_equal(v1, v3) && vector3_equal(v2, v3)) { - return false; - } - - const double angle = acos(vector3_dot(v1, v2)) / c_pi; - - const double index = width * angle; - - if (index > static_cast( g_PatchSubdivideThreshold )) { - return true; - } - return false; -} - -void BezierInterpolate(BezierCurve *pCurve) -{ - pCurve->left = vector3_mid(pCurve->left, pCurve->crd); - pCurve->right = vector3_mid(pCurve->crd, pCurve->right); - pCurve->crd = vector3_mid(pCurve->left, pCurve->right); -} - -const std::size_t PATCH_MAX_SUBDIVISION_DEPTH = 16; - -void BezierCurveTree_FromCurveList(BezierCurveTree *pTree, GSList *pCurveList, std::size_t depth = 0) -{ - GSList *pLeftList = 0; - GSList *pRightList = 0; - BezierCurve *pCurve, *pLeftCurve, *pRightCurve; - bool bSplit = false; - - for (GSList *l = pCurveList; l; l = l->next) { - pCurve = (BezierCurve *) (l->data); - if (bSplit || BezierCurve_IsCurved(pCurve)) { - bSplit = true; - pLeftCurve = new BezierCurve; - pRightCurve = new BezierCurve; - pLeftCurve->left = pCurve->left; - pRightCurve->right = pCurve->right; - BezierInterpolate(pCurve); - pLeftCurve->crd = pCurve->left; - pRightCurve->crd = pCurve->right; - pLeftCurve->right = pCurve->crd; - pRightCurve->left = pCurve->crd; - - pLeftList = g_slist_prepend(pLeftList, pLeftCurve); - pRightList = g_slist_prepend(pRightList, pRightCurve); - } - } - - if (pLeftList != 0 && pRightList != 0 && depth != PATCH_MAX_SUBDIVISION_DEPTH) { - pTree->left = new BezierCurveTree; - pTree->right = new BezierCurveTree; - BezierCurveTree_FromCurveList(pTree->left, pLeftList, depth + 1); - BezierCurveTree_FromCurveList(pTree->right, pRightList, depth + 1); - - for (GSList *l = pLeftList; l != 0; l = g_slist_next(l)) { - delete (BezierCurve *) l->data; - } - - for (GSList *l = pRightList; l != 0; l = g_slist_next(l)) { - delete (BezierCurve *) l->data; - } - - g_slist_free(pLeftList); - g_slist_free(pRightList); - } else { - pTree->left = 0; - pTree->right = 0; - } -} - - -int Patch::m_CycleCapIndex = 0; - - -void Patch::setDims(std::size_t w, std::size_t h) -{ - if ((w % 2) == 0) { - w -= 1; - } - ASSERT_MESSAGE(w <= MAX_PATCH_WIDTH, "patch too wide"); - if (w > MAX_PATCH_WIDTH) { - w = MAX_PATCH_WIDTH; - } else if (w < MIN_PATCH_WIDTH) { - w = MIN_PATCH_WIDTH; - } - - if ((h % 2) == 0) { - m_height -= 1; - } - ASSERT_MESSAGE(h <= MAX_PATCH_HEIGHT, "patch too tall"); - if (h > MAX_PATCH_HEIGHT) { - h = MAX_PATCH_HEIGHT; - } else if (h < MIN_PATCH_HEIGHT) { - h = MIN_PATCH_HEIGHT; - } - - m_width = w; - m_height = h; - - if (m_width * m_height != m_ctrl.size()) { - m_ctrl.resize(m_width * m_height); - onAllocate(m_ctrl.size()); - } -} - -inline const Colour4b &colour_for_index(std::size_t i, std::size_t width) -{ - return (i % 2 || (i / width) % 2) ? colour_inside : colour_corner; -} - -inline bool float_valid(float f) -{ - return f == f; -} - -bool Patch::isValid() const -{ - if (!m_width || !m_height) { - return false; - } - - for (const_iterator i = m_ctrl.begin(); i != m_ctrl.end(); ++i) { - if (!float_valid((*i).m_vertex.x()) - || !float_valid((*i).m_vertex.y()) - || !float_valid((*i).m_vertex.z()) - || !float_valid((*i).m_texcoord.x()) - || !float_valid((*i).m_texcoord.y())) { - globalErrorStream() << "patch has invalid control points\n"; - return false; - } - } - return true; -} - -void Patch::UpdateCachedData() -{ - m_ctrl_vertices.clear(); - m_lattice_indices.clear(); - - if (!isValid()) { - m_tess.m_numStrips = 0; - m_tess.m_lenStrips = 0; - m_tess.m_nArrayHeight = 0; - m_tess.m_nArrayWidth = 0; - m_tess.m_curveTreeU.resize(0); - m_tess.m_curveTreeV.resize(0); - m_tess.m_indices.resize(0); - m_tess.m_vertices.resize(0); - m_tess.m_arrayHeight.resize(0); - m_tess.m_arrayWidth.resize(0); - m_aabb_local = AABB(); - return; - } - - BuildTesselationCurves(ROW); - BuildTesselationCurves(COL); - BuildVertexArray(); - AccumulateBBox(); - - IndexBuffer ctrl_indices; - - m_lattice_indices.reserve(((m_width * (m_height - 1)) + (m_height * (m_width - 1))) << 1); - ctrl_indices.reserve(m_ctrlTransformed.size()); - { - UniqueVertexBuffer inserter(m_ctrl_vertices); - for (iterator i = m_ctrlTransformed.begin(); i != m_ctrlTransformed.end(); ++i) { - ctrl_indices.insert(inserter.insert(pointvertex_quantised( - PointVertex(reinterpret_cast((*i).m_vertex ), - colour_for_index(i - m_ctrlTransformed.begin(), m_width))))); - } - } - { - for (IndexBuffer::iterator i = ctrl_indices.begin(); i != ctrl_indices.end(); ++i) { - if (std::size_t(i - ctrl_indices.begin()) % m_width) { - m_lattice_indices.insert(*(i - 1)); - m_lattice_indices.insert(*i); - } - if (std::size_t(i - ctrl_indices.begin()) >= m_width) { - m_lattice_indices.insert(*(i - m_width)); - m_lattice_indices.insert(*i); - } - } - } - -#if 0 - { - Array::iterator first = m_tess.m_indices.begin(); - for ( std::size_t s = 0; s < m_tess.m_numStrips; s++ ) - { - Array::iterator last = first + m_tess.m_lenStrips; - - for ( Array::iterator i( first ); i + 2 != last; i += 2 ) - { - ArbitraryMeshTriangle_sumTangents( m_tess.m_vertices[*( i + 0 )], m_tess.m_vertices[*( i + 1 )], m_tess.m_vertices[*( i + 2 )] ); - ArbitraryMeshTriangle_sumTangents( m_tess.m_vertices[*( i + 2 )], m_tess.m_vertices[*( i + 1 )], m_tess.m_vertices[*( i + 3 )] ); - } - - first = last; - } - - for ( Array::iterator i = m_tess.m_vertices.begin(); i != m_tess.m_vertices.end(); ++i ) - { - vector3_normalise( reinterpret_cast( ( *i ).tangent ) ); - vector3_normalise( reinterpret_cast( ( *i ).bitangent ) ); - } - } -#endif - - SceneChangeNotify(); -} - -void Patch::InvertMatrix() -{ - undoSave(); - - PatchControlArray_invert(m_ctrl, m_width, m_height); - - controlPointsChanged(); -} - -void Patch::TransposeMatrix() -{ - undoSave(); - - { - Array tmp(m_width * m_height); - copy_ctrl(tmp.data(), m_ctrl.data(), m_ctrl.data() + m_width * m_height); - - PatchControlIter from = tmp.data(); - for (std::size_t h = 0; h != m_height; ++h) { - PatchControlIter to = m_ctrl.data() + h; - for (std::size_t w = 0; w != m_width; ++w, ++from, to += m_height) { - *to = *from; - } - } - } - - { - std::size_t tmp = m_width; - m_width = m_height; - m_height = tmp; - } - - controlPointsChanged(); -} - -void Patch::Redisperse(EMatrixMajor mt) -{ - std::size_t w, h, width, height, row_stride, col_stride; - PatchControl *p1, *p2, *p3; - - undoSave(); - - switch (mt) { - case COL: - width = (m_width - 1) >> 1; - height = m_height; - col_stride = 1; - row_stride = m_width; - break; - case ROW: - width = (m_height - 1) >> 1; - height = m_width; - col_stride = m_width; - row_stride = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride); - for (w = 0; w < width; w++) { - p2 = p1 + col_stride; - p3 = p2 + col_stride; - p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - p1 = p3; - } - } - - controlPointsChanged(); -} - -void Patch::Smooth(EMatrixMajor mt) -{ - std::size_t w, h, width, height, row_stride, col_stride; - bool wrap; - PatchControl *p1, *p2, *p3, *p2b; - - undoSave(); - - switch (mt) { - case COL: - width = (m_width - 1) >> 1; - height = m_height; - col_stride = 1; - row_stride = m_width; - break; - case ROW: - width = (m_height - 1) >> 1; - height = m_width; - col_stride = m_width; - row_stride = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - wrap = true; - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride); - p2 = p1 + (2 * width) * col_stride; - //globalErrorStream() << "compare " << p1->m_vertex << " and " << p2->m_vertex << "\n"; - if (vector3_length_squared(vector3_subtracted(p1->m_vertex, p2->m_vertex)) > 1.0) { - //globalErrorStream() << "too far\n"; - wrap = false; - break; - } - } - - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride) + col_stride; - for (w = 0; w < width - 1; w++) { - p2 = p1 + col_stride; - p3 = p2 + col_stride; - p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - p1 = p3; - } - if (wrap) { - p1 = m_ctrl.data() + (h * row_stride) + (2 * width - 1) * col_stride; - p2 = m_ctrl.data() + (h * row_stride); - p2b = m_ctrl.data() + (h * row_stride) + (2 * width) * col_stride; - p3 = m_ctrl.data() + (h * row_stride) + col_stride; - p2->m_vertex = p2b->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - } - } - - controlPointsChanged(); -} - -void Patch::InsertRemove(bool bInsert, bool bColumn, bool bFirst) -{ - undoSave(); - - if (bInsert) { - if (bColumn && (m_width + 2 <= MAX_PATCH_WIDTH)) { - InsertPoints(COL, bFirst); - } else if (m_height + 2 <= MAX_PATCH_HEIGHT) { - InsertPoints(ROW, bFirst); - } - } else { - if (bColumn && (m_width - 2 >= MIN_PATCH_WIDTH)) { - RemovePoints(COL, bFirst); - } else if (m_height - 2 >= MIN_PATCH_HEIGHT) { - RemovePoints(ROW, bFirst); - } - } - - controlPointsChanged(); -} - -Patch *Patch::MakeCap(Patch *patch, EPatchCap eType, EMatrixMajor mt, bool bFirst) -{ - std::size_t i, width, height; - - switch (mt) { - case ROW: - width = m_width; - height = m_height; - break; - case COL: - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return 0; - } - - Array p(width); - - std::size_t nIndex = (bFirst) ? 0 : height - 1; - if (mt == ROW) { - for (i = 0; i < width; i++) { - p[(bFirst) ? i : (width - 1) - i] = ctrlAt(nIndex, i).m_vertex; - } - } else { - for (i = 0; i < width; i++) { - p[(bFirst) ? i : (width - 1) - i] = ctrlAt(i, nIndex).m_vertex; - } - } - - patch->ConstructSeam(eType, p.data(), width); - return patch; -} - -void Patch::FlipTexture(int nAxis) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[nAxis] = -(*i).m_texcoord[nAxis]; - } - - controlPointsChanged(); -} - -void Patch::TranslateTexture(float s, float t) -{ - undoSave(); - - s = -1 * s / m_state->getTexture().width; - t = t / m_state->getTexture().height; - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] += s; - (*i).m_texcoord[1] += t; - } - - controlPointsChanged(); -} - -void Patch::ScaleTexture(float s, float t) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] *= s; - (*i).m_texcoord[1] *= t; - } - - controlPointsChanged(); -} - -void Patch::RotateTexture(float angle) -{ - undoSave(); - - const float s = static_cast( sin(degrees_to_radians(angle))); - const float c = static_cast( cos(degrees_to_radians(angle))); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - const float x = (*i).m_texcoord[0]; - const float y = (*i).m_texcoord[1]; - (*i).m_texcoord[0] = (x * c) - (y * s); - (*i).m_texcoord[1] = (y * c) + (x * s); - } - - controlPointsChanged(); -} - - -void Patch::SetTextureRepeat(float s, float t) -{ - std::size_t w, h; - float si, ti, sc, tc; - PatchControl *pDest; - - undoSave(); - - si = s / (float) (m_width - 1); - ti = t / (float) (m_height - 1); - - pDest = m_ctrl.data(); - for (h = 0, tc = 0.0f; h < m_height; h++, tc += ti) { - for (w = 0, sc = 0.0f; w < m_width; w++, sc += si) { - pDest->m_texcoord[0] = sc; - pDest->m_texcoord[1] = tc; - pDest++; - } - } - - controlPointsChanged(); -} - -/* - void Patch::SetTextureInfo(texdef_t *pt) - { - if(pt->getShift()[0] || pt->getShift()[1]) - TranslateTexture (pt->getShift()[0], pt->getShift()[1]); - else if(pt->getScale()[0] || pt->getScale()[1]) - { - if(pt->getScale()[0] == 0.0f) pt->setScale(0, 1.0f); - if(pt->getScale()[1] == 0.0f) pt->setScale(1, 1.0f); - ScaleTexture (pt->getScale()[0], pt->getScale()[1]); - } - else if(pt->rotate) - RotateTexture (pt->rotate); - } - */ - -inline int texture_axis(const Vector3 &normal) -{ - // axis dominance order: Z, X, Y - return (normal.x() >= normal.y()) ? (normal.x() > normal.z()) ? 0 : 2 : (normal.y() > normal.z()) ? 1 : 2; -} - -void Patch::CapTexture() -{ - const PatchControl &p1 = m_ctrl[m_width]; - const PatchControl &p2 = m_ctrl[m_width * (m_height - 1)]; - const PatchControl &p3 = m_ctrl[(m_width * m_height) - 1]; - - - Vector3 normal(g_vector3_identity); - - { - Vector3 tmp(vector3_cross( - vector3_subtracted(p2.m_vertex, m_ctrl[0].m_vertex), - vector3_subtracted(p3.m_vertex, m_ctrl[0].m_vertex) - )); - if (!vector3_equal(tmp, g_vector3_identity)) { - vector3_add(normal, tmp); - } - } - { - Vector3 tmp(vector3_cross( - vector3_subtracted(p1.m_vertex, p3.m_vertex), - vector3_subtracted(m_ctrl[0].m_vertex, p3.m_vertex) - )); - if (!vector3_equal(tmp, g_vector3_identity)) { - vector3_add(normal, tmp); - } - } - - ProjectTexture(texture_axis(normal)); -} - -// uses longest parallel chord to calculate texture coords for each row/col -void Patch::NaturalTexture() -{ - undoSave(); - - { - float fSize = (float) m_state->getTexture().width * Texdef_getDefaultTextureScale(); - - double texBest = 0; - double tex = 0; - PatchControl *pWidth = m_ctrl.data(); - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - { - PatchControl *pHeight = pWidth; - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - pHeight->m_texcoord[0] = static_cast( tex ); - } - } - - if (w + 1 == m_width) { - break; - } - - { - PatchControl *pHeight = pWidth; - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - Vector3 v(vector3_subtracted(pHeight->m_vertex, (pHeight + 1)->m_vertex)); - double length = tex + (vector3_length(v) / fSize); - if (fabs(length) > texBest) { - texBest = length; - } - } - } - - tex = texBest; - } - } - - { - float fSize = -(float) m_state->getTexture().height * Texdef_getDefaultTextureScale(); - - double texBest = 0; - double tex = 0; - PatchControl *pHeight = m_ctrl.data(); - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - { - PatchControl *pWidth = pHeight; - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - pWidth->m_texcoord[1] = static_cast( tex ); - } - } - - if (h + 1 == m_height) { - break; - } - - { - PatchControl *pWidth = pHeight; - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - Vector3 v(vector3_subtracted(pWidth->m_vertex, (pWidth + m_width)->m_vertex)); - double length = tex + (vector3_length(v) / fSize); - if (fabs(length) > texBest) { - texBest = length; - } - } - } - - tex = texBest; - } - } - - controlPointsChanged(); -} - -void Patch::IdentityColour() -{ - PatchControl *pCtrl = m_ctrl.data(); - - for (std::size_t h = 0; h < m_height; h++) { - for (std::size_t w = 0; w < m_width; w++, ++pCtrl) { - pCtrl->m_color = Vector4(1,1,1,1); - } - } -} - - -// private: - -void Patch::AccumulateBBox() -{ - m_aabb_local = AABB(); - - for (PatchControlArray::iterator i = m_ctrlTransformed.begin(); i != m_ctrlTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, (*i).m_vertex); - } - - m_boundsChanged(); - m_lightsChanged(); -} - -void Patch::InsertPoints(EMatrixMajor mt, bool bFirst) -{ - std::size_t width, height, row_stride, col_stride; - - switch (mt) { - case ROW: - col_stride = 1; - row_stride = m_width; - width = m_width; - height = m_height; - break; - case COL: - col_stride = m_width; - row_stride = 1; - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - std::size_t pos = 0; - { - PatchControl *p1 = m_ctrl.data(); - /* - if(GlobalSelectionSystem().countSelected() != 0) - { - scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); - PatchInstance* patch = Instance_getPatch(instance); - patch->m_selectable.isSelected(); - } - */ - for (std::size_t w = 0; w != width; ++w, p1 += col_stride) { - { - PatchControl *p2 = p1; - for (std::size_t h = 1; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - - { - PatchControl *p2 = p1; - for (std::size_t h = 0; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - } - } - - Array tmp(m_ctrl); - - std::size_t row_stride2, col_stride2; - switch (mt) { - case ROW: - setDims(m_width, m_height + 2); - col_stride2 = 1; - row_stride2 = m_width; - break; - case COL: - setDims(m_width + 2, m_height); - col_stride2 = m_width; - row_stride2 = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - if (bFirst) { - pos = height - 1; - } else { - pos = 2; - } - - if (pos >= height) { - if (bFirst) { - pos = height - 1; - } else { - pos = 2; - } - } else if (pos == 0) { - pos = 2; - } else if (pos % 2) { - ++pos; - } - - - for (std::size_t w = 0; w != width; ++w) { - PatchControl *p1 = tmp.data() + (w * col_stride); - PatchControl *p2 = m_ctrl.data() + (w * col_stride2); - for (std::size_t h = 0; h != height; ++h, p2 += row_stride2, p1 += row_stride) { - if (h == pos) { - p2 += 2 * row_stride2; - } - *p2 = *p1; - } - - p1 = tmp.data() + (w * col_stride + pos * row_stride); - p2 = m_ctrl.data() + (w * col_stride2 + pos * row_stride2); - - PatchControl *r2a = (p2 + row_stride2); - PatchControl *r2b = (p2 - row_stride2); - PatchControl *c2a = (p1 - 2 * row_stride); - PatchControl *c2b = (p1 - row_stride); - - // set two new row points - *(p2 + 2 * row_stride2) = *p1; - *r2a = *c2b; - - for (std::size_t i = 0; i != 3; ++i) { - r2a->m_vertex[i] = float_mid(c2b->m_vertex[i], p1->m_vertex[i]); - - r2b->m_vertex[i] = float_mid(c2a->m_vertex[i], c2b->m_vertex[i]); - - p2->m_vertex[i] = float_mid(r2a->m_vertex[i], r2b->m_vertex[i]); - } - for (std::size_t i = 0; i != 2; ++i) { - r2a->m_texcoord[i] = float_mid(c2b->m_texcoord[i], p1->m_texcoord[i]); - - r2b->m_texcoord[i] = float_mid(c2a->m_texcoord[i], c2b->m_texcoord[i]); - - p2->m_texcoord[i] = float_mid(r2a->m_texcoord[i], r2b->m_texcoord[i]); - } - for (std::size_t i = 0; i != 4; ++i) { - r2a->m_color[i] = float_mid(c2b->m_color[i], p1->m_color[i]); - - r2b->m_color[i] = float_mid(c2a->m_color[i], c2b->m_color[i]); - - p2->m_color[i] = float_mid(r2a->m_color[i], r2b->m_color[i]); - } - } -} - -void Patch::RemovePoints(EMatrixMajor mt, bool bFirst) -{ - std::size_t width, height, row_stride, col_stride; - - switch (mt) { - case ROW: - col_stride = 1; - row_stride = m_width; - width = m_width; - height = m_height; - break; - case COL: - col_stride = m_width; - row_stride = 1; - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - std::size_t pos = 0; - { - PatchControl *p1 = m_ctrl.data(); - for (std::size_t w = 0; w != width; ++w, p1 += col_stride) { - { - PatchControl *p2 = p1; - for (std::size_t h = 1; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - - { - PatchControl *p2 = p1; - for (std::size_t h = 0; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - } - } - - Array tmp(m_ctrl); - - std::size_t row_stride2, col_stride2; - switch (mt) { - case ROW: - setDims(m_width, m_height - 2); - col_stride2 = 1; - row_stride2 = m_width; - break; - case COL: - setDims(m_width - 2, m_height); - col_stride2 = m_width; - row_stride2 = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - if (bFirst) { - pos = height - 3; - } else { - pos = 2; - } - if (pos >= height) { - if (bFirst) { - pos = height - 3; - } else { - pos = 2; - } - } else if (pos == 0) { - pos = 2; - } else if (pos > height - 3) { - pos = height - 3; - } else if (pos % 2) { - ++pos; - } - - for (std::size_t w = 0; w != width; w++) { - PatchControl *p1 = tmp.data() + (w * col_stride); - PatchControl *p2 = m_ctrl.data() + (w * col_stride2); - for (std::size_t h = 0; h != height; ++h, p2 += row_stride2, p1 += row_stride) { - if (h == pos) { - p1 += 2 * row_stride2; - h += 2; - } - *p2 = *p1; - } - - p1 = tmp.data() + (w * col_stride + pos * row_stride); - p2 = m_ctrl.data() + (w * col_stride2 + pos * row_stride2); - - for (std::size_t i = 0; i < 3; i++) { - (p2 - row_stride2)->m_vertex[i] = - ((p1 + 2 * row_stride)->m_vertex[i] + (p1 - 2 * row_stride)->m_vertex[i]) * 0.5f; - - (p2 - row_stride2)->m_vertex[i] = - (p2 - row_stride2)->m_vertex[i] + (2.0f * ((p1)->m_vertex[i] - (p2 - row_stride2)->m_vertex[i])); - } - for (std::size_t i = 0; i < 2; i++) { - (p2 - row_stride2)->m_texcoord[i] = - ((p1 + 2 * row_stride)->m_texcoord[i] + (p1 - 2 * row_stride)->m_texcoord[i]) * 0.5f; - - (p2 - row_stride2)->m_texcoord[i] = (p2 - row_stride2)->m_texcoord[i] + - (2.0f * ((p1)->m_texcoord[i] - (p2 - row_stride2)->m_texcoord[i])); - } - } -} - -void Patch::ConstructSeam(EPatchCap eType, Vector3 *p, std::size_t width) -{ - switch (eType) { - case eCapIBevel: { - setDims(3, 3); - m_ctrl[0].m_vertex = p[0]; - m_ctrl[1].m_vertex = p[1]; - m_ctrl[2].m_vertex = p[1]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[1]; - m_ctrl[5].m_vertex = p[1]; - m_ctrl[6].m_vertex = p[2]; - m_ctrl[7].m_vertex = p[1]; - m_ctrl[8].m_vertex = p[1]; - } - break; - case eCapBevel: { - setDims(3, 3); - Vector3 p3(vector3_added(p[2], vector3_subtracted(p[0], p[1]))); - m_ctrl[0].m_vertex = p3; - m_ctrl[1].m_vertex = p3; - m_ctrl[2].m_vertex = p[2]; - m_ctrl[3].m_vertex = p3; - m_ctrl[4].m_vertex = p3; - m_ctrl[5].m_vertex = p[1]; - m_ctrl[6].m_vertex = p3; - m_ctrl[7].m_vertex = p3; - m_ctrl[8].m_vertex = p[0]; - } - break; - case eCapEndCap: { - Vector3 p5(vector3_mid(p[0], p[4])); - - setDims(3, 3); - m_ctrl[0].m_vertex = p[0]; - m_ctrl[1].m_vertex = p5; - m_ctrl[2].m_vertex = p[4]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[2]; - m_ctrl[5].m_vertex = p[3]; - m_ctrl[6].m_vertex = p[2]; - m_ctrl[7].m_vertex = p[2]; - m_ctrl[8].m_vertex = p[2]; - } - break; - case eCapIEndCap: { - setDims(5, 3); - m_ctrl[0].m_vertex = p[4]; - m_ctrl[1].m_vertex = p[3]; - m_ctrl[2].m_vertex = p[2]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[0]; - m_ctrl[5].m_vertex = p[3]; - m_ctrl[6].m_vertex = p[3]; - m_ctrl[7].m_vertex = p[2]; - m_ctrl[8].m_vertex = p[1]; - m_ctrl[9].m_vertex = p[1]; - m_ctrl[10].m_vertex = p[3]; - m_ctrl[11].m_vertex = p[3]; - m_ctrl[12].m_vertex = p[2]; - m_ctrl[13].m_vertex = p[1]; - m_ctrl[14].m_vertex = p[1]; - } - break; - case eCapCylinder: { - std::size_t mid = (width - 1) >> 1; - - bool degenerate = (mid % 2) != 0; - - std::size_t newHeight = mid + (degenerate ? 2 : 1); - - setDims(3, newHeight); - - if (degenerate) { - ++mid; - for (std::size_t i = width; i != width + 2; ++i) { - p[i] = p[width - 1]; - } - } - - { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t i = 0; i != m_height; ++i, pCtrl += m_width) { - pCtrl->m_vertex = p[i]; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + 2; - std::size_t h = m_height - 1; - for (std::size_t i = 0; i != m_height; ++i, pCtrl += m_width) { - pCtrl->m_vertex = p[h + (h - i)]; - } - } - - Redisperse(COL); - } - break; - default: - ERROR_MESSAGE("invalid patch-cap type"); - return; - } - CapTexture(); - controlPointsChanged(); -} - -void Patch::ProjectTexture(int nAxis) -{ - undoSave(); - - int s, t; - - switch (nAxis) { - case 2: - s = 0; - t = 1; - break; - case 0: - s = 1; - t = 2; - break; - case 1: - s = 0; - t = 2; - break; - default: - ERROR_MESSAGE("invalid axis"); - return; - } - - float fWidth = 1 / (m_state->getTexture().width * Texdef_getDefaultTextureScale()); - float fHeight = 1 / (m_state->getTexture().height * -Texdef_getDefaultTextureScale()); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] = (*i).m_vertex[s] * fWidth; - (*i).m_texcoord[1] = (*i).m_vertex[t] * fHeight; - } - - controlPointsChanged(); -} - -void Patch::constructPlane(const AABB &aabb, int axis, std::size_t width, std::size_t height) -{ - setDims(width, height); - - int x, y, z; - switch (axis) { - case 2: - x = 0; - y = 1; - z = 2; - break; - case 1: - x = 0; - y = 2; - z = 1; - break; - case 0: - x = 1; - y = 2; - z = 0; - break; - default: - ERROR_MESSAGE("invalid view-type"); - return; - } - - if (m_width < MIN_PATCH_WIDTH || m_width > MAX_PATCH_WIDTH) { - m_width = 3; - } - if (m_height < MIN_PATCH_HEIGHT || m_height > MAX_PATCH_HEIGHT) { - m_height = 3; - } - - Vector3 vStart; - vStart[x] = aabb.origin[x] - aabb.extents[x]; - vStart[y] = aabb.origin[y] - aabb.extents[y]; - vStart[z] = aabb.origin[z]; - - float xAdj = fabsf((vStart[x] - (aabb.origin[x] + aabb.extents[x])) / (float) (m_width - 1)); - float yAdj = fabsf((vStart[y] - (aabb.origin[y] + aabb.extents[y])) / (float) (m_height - 1)); - - Vector3 vTmp; - vTmp[z] = vStart[z]; - PatchControl *pCtrl = m_ctrl.data(); - - vTmp[y] = vStart[y]; - for (std::size_t h = 0; h < m_height; h++) { - vTmp[x] = vStart[x]; - for (std::size_t w = 0; w < m_width; w++, ++pCtrl) { - pCtrl->m_vertex = vTmp; - vTmp[x] += xAdj; - } - vTmp[y] += yAdj; - } - - IdentityColour(); - NaturalTexture(); -} - -void Patch::ConstructPrefab(const AABB &aabb, EPatchPrefab eType, int axis, std::size_t width, std::size_t height) -{ - Vector3 vPos[3]; - - if (eType != ePlane) { - vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - vPos[1] = aabb.origin; - vPos[2] = vector3_added(aabb.origin, aabb.extents); - } - - if (eType == ePlane) { - constructPlane(aabb, axis, width, height); - } else if (eType == eSqCylinder - || eType == eCylinder - || eType == eDenseCylinder - || eType == eVeryDenseCylinder - || eType == eCone - || eType == eSphere) { - unsigned char *pIndex; - unsigned char pCylIndex[] = - { - 0, 0, - 1, 0, - 2, 0, - 2, 1, - 2, 2, - 1, 2, - 0, 2, - 0, 1, - 0, 0 - }; - - - PatchControl *pStart; - switch (eType) { - case eSqCylinder: - setDims(9, 3); - pStart = m_ctrl.data(); - break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: - setDims(9, 3); - pStart = m_ctrl.data() + 1; - break; - case eCone: - setDims(9, 3); - pStart = m_ctrl.data() + 1; - break; - case eSphere: - setDims(9, 5); - pStart = m_ctrl.data() + (9 + 1); - break; - default: - ERROR_MESSAGE("this should be unreachable"); - return; - } - - for (std::size_t h = 0; h < 3; h++, pStart += 9) { - pIndex = pCylIndex; - PatchControl *pCtrl = pStart; - for (std::size_t w = 0; w < 8; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - pIndex += 2; - } - } - - switch (eType) { - case eSqCylinder: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[8].m_vertex = pCtrl[0].m_vertex; - } - } - break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - break; - case eCone: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 2; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + 9 * 2; - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[2][2]; - } - } - break; - case eSphere: { - PatchControl *pCtrl = m_ctrl.data() + 9; - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[0][2]; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + (9 * 4); - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[2][2]; - } - } - break; - default: - ERROR_MESSAGE("this should be unreachable"); - return; - } - } else if (eType == eXactCylinder) { - int n = (width - 1) / 2; // n = number of segments - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; // 0 to 2pi - float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) * cos(angle) * ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) * sin(angle) * ((i & 1) ? f : 1.0f); - for (std::size_t j = 0; j < height; ++j) { - float z = vPos[0][2] + (vPos[2][2] - vPos[0][2]) * (j / (float) (height - 1)); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eXactCone) { - int n = (width - 1) / 2; // n = number of segments - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; - for (std::size_t j = 0; j < height; ++j) { - float x = vPos[1][0] + (1.0f - (j / (float) (height - 1))) * (vPos[2][0] - vPos[1][0]) * cos(angle) * - ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (1.0f - (j / (float) (height - 1))) * (vPos[2][1] - vPos[1][1]) * sin(angle) * - ((i & 1) ? f : 1.0f); - float z = vPos[0][2] + (vPos[2][2] - vPos[0][2]) * (j / (float) (height - 1)); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eXactSphere) { - int n = (width - 1) / 2; // n = number of segments (yaw) - int m = (height - 1) / 2; // m = number of segments (pitch) - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - float g = 1 / cos(M_PI / (2 * m)); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; - for (std::size_t j = 0; j < height; ++j) { - float angle2 = (M_PI * j) / (2 * m); - float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) * sin(angle2) * ((j & 1) ? g : 1.0f) * cos(angle) * - ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) * sin(angle2) * ((j & 1) ? g : 1.0f) * sin(angle) * - ((i & 1) ? f : 1.0f); - float z = vPos[1][2] + (vPos[2][2] - vPos[1][2]) * -cos(angle2) * ((j & 1) ? g : 1.0f); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eBevel) { - unsigned char *pIndex; - unsigned char pBevIndex[] = - { - 0, 0, - 2, 0, - 2, 2, - }; - - setDims(3, 3); - - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++) { - pIndex = pBevIndex; - for (std::size_t w = 0; w < 3; w++, pIndex += 2, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - } - } - } else if (eType == eEndCap) { - unsigned char *pIndex; - unsigned char pEndIndex[] = - { - 2, 0, - 2, 2, - 1, 2, - 0, 2, - 0, 0, - }; - - setDims(5, 3); - - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++) { - pIndex = pEndIndex; - for (std::size_t w = 0; w < 5; w++, pIndex += 2, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - } - } - } - - if (eType == eDenseCylinder) { - InsertRemove(true, false, true); - } - - if (eType == eVeryDenseCylinder) { - InsertRemove(true, false, false); - InsertRemove(true, false, true); - } - - IdentityColour(); - NaturalTexture(); -} - -void Patch::RenderDebug(RenderStateFlags state) const -{ - for (std::size_t i = 0; i < m_tess.m_numStrips; i++) { - glBegin(GL_QUAD_STRIP); - for (std::size_t j = 0; j < m_tess.m_lenStrips; j++) { - glNormal3fv(normal3f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->normal)); - glTexCoord2fv(texcoord2f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->texcoord)); - glVertex3fv(vertex3f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->vertex)); - } - glEnd(); - } -} - -#include "patchdialog.h" - -bool PatchInspector_IsSelected(int x, int y); -void patch_draw_sphere(const Vector3 origin, float radius, int sides) -{ - if (radius <= 0) { - return; - } - - const double dt = c_2pi / static_cast( sides ); - const double dp = c_pi / static_cast( sides ); - - for (int i = 0; i <= sides - 1; ++i) { - for (int j = 0; j <= sides - 2; ++j) { - const double t = i * dt; - const double p = (j * dp) - (c_pi / 2.0); - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - - { - const double p = (sides - 1) * dp - (c_pi / 2.0); - for (int i = 0; i <= sides - 1; ++i) { - const double t = i * dt; - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } -} - -bool PatchBalls_Visible(void); -void RenderablePatchFixedSolid::RenderNormals() const -{ - const std::size_t width = m_tess.m_numStrips + 1; - const std::size_t height = m_tess.m_lenStrips >> 1; - - glBegin(GL_TRIANGLES); - for (std::size_t i = 0; i < width; i++) { - for (std::size_t j = 0; j < height; j++) { - Vector3 pos = (m_tess.m_vertices.data() + (j * width + i))->vertex; - Vector4 colour = (m_tess.m_vertices.data() + (j * width + i))->colour; - - /* color the currently selected bit */ - if (PatchBalls_Visible()) { - if (PatchInspector_IsSelected((int)i, (int)j)) { - glColor3f(1,0,0); - patch_draw_sphere(pos, 8, 4); - } else { - glColor3f(1,1,1); - patch_draw_sphere(pos, 2, 4); - } - } - - /*{ - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->vertex), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->normal), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - } - { - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->vertex), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->tangent), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - } - { - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3(), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->bitangent), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - }*/ - } - } - glEnd(); - glColor3f( 1, 1, 1 ); -} - -const int DEGEN_0a = 0x01; -const int DEGEN_1a = 0x02; -const int DEGEN_2a = 0x04; -const int DEGEN_0b = 0x08; -const int DEGEN_1b = 0x10; -const int DEGEN_2b = 0x20; -const int SPLIT = 0x40; -const int AVERAGE = 0x80; - - -unsigned int subarray_get_degen(PatchControlIter subarray, std::size_t strideU, std::size_t strideV) -{ - unsigned int nDegen = 0; - const PatchControl *p1; - const PatchControl *p2; - - p1 = subarray; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_0a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_0b; - } - - p1 = subarray + strideV; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_1a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_1b; - } - - p1 = subarray + (strideV << 1); - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_2a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_2b; - } - - return nDegen; -} - - -inline void -deCasteljau3(const Vector3 &P0, const Vector3 &P1, const Vector3 &P2, Vector3 &P01, Vector3 &P12, Vector3 &P012) -{ - P01 = vector3_mid(P0, P1); - P12 = vector3_mid(P1, P2); - P012 = vector3_mid(P01, P12); -} - -inline void BezierInterpolate4(const Vector4 &start, Vector4 &left, Vector4 &mid, Vector4 &right, const Vector4 &end) -{ - left = vector4_mid(start, mid); - right = vector4_mid(mid, end); - mid = vector4_mid(left, right); -} - -inline void BezierInterpolate3(const Vector3 &start, Vector3 &left, Vector3 &mid, Vector3 &right, const Vector3 &end) -{ - left = vector3_mid(start, mid); - right = vector3_mid(mid, end); - mid = vector3_mid(left, right); -} - -inline void BezierInterpolate2(const Vector2 &start, Vector2 &left, Vector2 &mid, Vector2 &right, const Vector2 &end) -{ - left[0] = float_mid(start[0], mid[0]); - left[1] = float_mid(start[1], mid[1]); - right[0] = float_mid(mid[0], end[0]); - right[1] = float_mid(mid[1], end[1]); - mid[0] = float_mid(left[0], right[0]); - mid[1] = float_mid(left[1], right[1]); -} - - -inline Vector2 &texcoord_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].texcoord ); -} - -inline Vector4 &colour_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].colour ); -} - -inline Vector3 &vertex_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].vertex ); -} - -inline Vector3 &normal_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].normal ); -} - -inline Vector3 &tangent_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].tangent ); -} - -inline Vector3 &bitangent_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].bitangent ); -} - -inline const Vector2 &texcoord_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].texcoord ); -} - -inline const Vector4 &colour_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].colour ); -} - -inline const Vector3 &vertex_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].vertex ); -} - -inline const Vector3 &normal_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].normal ); -} - -inline const Vector3 &tangent_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].tangent ); -} - -inline const Vector3 &bitangent_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].bitangent ); -} - -#include "math/curve.h" - -inline PatchControl QuadraticBezier_evaluate(const PatchControl *firstPoint, double t) -{ - PatchControl result = {Vector3(0, 0, 0), Vector2(0, 0), Vector4(0, 0, 0, 0)}; - double denominator = 0; - - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[0].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[0].m_texcoord, weight)); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[1].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[1].m_texcoord, weight)); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[2].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[2].m_texcoord, weight)); - denominator += weight; - } - - vector3_divide(result.m_vertex, denominator); - vector2_divide(result.m_texcoord, denominator); - return result; -} - -inline Vector3 vector3_linear_interpolated(const Vector3 &a, const Vector3 &b, double t) -{ - return vector3_added(vector3_scaled(a, 1.0 - t), vector3_scaled(b, t)); -} - -inline Vector2 vector2_linear_interpolated(const Vector2 &a, const Vector2 &b, double t) -{ - return vector2_added(vector2_scaled(a, 1.0 - t), vector2_scaled(b, t)); -} - -void normalise_safe(Vector3 &normal) -{ - if (!vector3_equal(normal, g_vector3_identity)) { - vector3_normalise(normal); - } -} - -inline void QuadraticBezier_evaluate(const PatchControl &a, const PatchControl &b, const PatchControl &c, double t, - PatchControl &point, PatchControl &left, PatchControl &right) -{ - left.m_vertex = vector3_linear_interpolated(a.m_vertex, b.m_vertex, t); - left.m_texcoord = vector2_linear_interpolated(a.m_texcoord, b.m_texcoord, t); - right.m_vertex = vector3_linear_interpolated(b.m_vertex, c.m_vertex, t); - right.m_texcoord = vector2_linear_interpolated(b.m_texcoord, c.m_texcoord, t); - point.m_vertex = vector3_linear_interpolated(left.m_vertex, right.m_vertex, t); - point.m_texcoord = vector2_linear_interpolated(left.m_texcoord, right.m_texcoord, t); -} - -void Patch::TesselateSubMatrixFixed(ArbitraryMeshVertex *vertices, std::size_t strideX, std::size_t strideY, - unsigned int nFlagsX, unsigned int nFlagsY, PatchControl *subMatrix[3][3]) -{ - double incrementU = 1.0 / m_subdivisions_x; - double incrementV = 1.0 / m_subdivisions_y; - const std::size_t width = m_subdivisions_x + 1; - const std::size_t height = m_subdivisions_y + 1; - - for (std::size_t i = 0; i != width; ++i) { - double tU = (i + 1 == width) ? 1 : i * incrementU; - PatchControl pointX[3]; - PatchControl leftX[3]; - PatchControl rightX[3]; - QuadraticBezier_evaluate(*subMatrix[0][0], *subMatrix[0][1], *subMatrix[0][2], tU, pointX[0], leftX[0], - rightX[0]); - QuadraticBezier_evaluate(*subMatrix[1][0], *subMatrix[1][1], *subMatrix[1][2], tU, pointX[1], leftX[1], - rightX[1]); - QuadraticBezier_evaluate(*subMatrix[2][0], *subMatrix[2][1], *subMatrix[2][2], tU, pointX[2], leftX[2], - rightX[2]); - - ArbitraryMeshVertex *p = vertices + i * strideX; - for (std::size_t j = 0; j != height; ++j) { - if ((j == 0 || j + 1 == height) && (i == 0 || i + 1 == width)) { - } else { - double tV = (j + 1 == height) ? 1 : j * incrementV; - - PatchControl pointY[3]; - PatchControl leftY[3]; - PatchControl rightY[3]; - QuadraticBezier_evaluate(*subMatrix[0][0], *subMatrix[1][0], *subMatrix[2][0], tV, pointY[0], leftY[0], - rightY[0]); - QuadraticBezier_evaluate(*subMatrix[0][1], *subMatrix[1][1], *subMatrix[2][1], tV, pointY[1], leftY[1], - rightY[1]); - QuadraticBezier_evaluate(*subMatrix[0][2], *subMatrix[1][2], *subMatrix[2][2], tV, pointY[2], leftY[2], - rightY[2]); - - PatchControl point; - PatchControl left; - PatchControl right; - QuadraticBezier_evaluate(pointX[0], pointX[1], pointX[2], tV, point, left, right); - PatchControl up; - PatchControl down; - QuadraticBezier_evaluate(pointY[0], pointY[1], pointY[2], tU, point, up, down); - - vertex3f_to_vector3(p->vertex) = point.m_vertex; - texcoord2f_to_vector2(p->texcoord) = point.m_texcoord; - colour4f_to_vector4(p->colour) = point.m_color; - - ArbitraryMeshVertex a, b, c; - - a.vertex = vertex3f_for_vector3(left.m_vertex); - a.texcoord = texcoord2f_for_vector2(left.m_texcoord); - b.vertex = vertex3f_for_vector3(right.m_vertex); - b.texcoord = texcoord2f_for_vector2(right.m_texcoord); - - if (i != 0) { - c.vertex = vertex3f_for_vector3(up.m_vertex); - c.texcoord = texcoord2f_for_vector2(up.m_texcoord); - } else { - c.vertex = vertex3f_for_vector3(down.m_vertex); - c.texcoord = texcoord2f_for_vector2(down.m_texcoord); - } - - Vector3 normal = vector3_normalised( - vector3_cross(right.m_vertex - left.m_vertex, up.m_vertex - down.m_vertex)); - - Vector3 tangent, bitangent; - ArbitraryMeshTriangle_calcTangents(a, b, c, tangent, bitangent); - vector3_normalise(tangent); - vector3_normalise(bitangent); - - if (((nFlagsX & AVERAGE) != 0 && i == 0) || ((nFlagsY & AVERAGE) != 0 && j == 0)) { - normal3f_to_vector3(p->normal) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->normal), normal)); - normal3f_to_vector3(p->tangent) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->tangent), tangent)); - normal3f_to_vector3(p->bitangent) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->bitangent), bitangent)); - } else { - normal3f_to_vector3(p->normal) = normal; - normal3f_to_vector3(p->tangent) = tangent; - normal3f_to_vector3(p->bitangent) = bitangent; - } - } - - p += strideY; - } - } -} - -void Patch::TesselateSubMatrix(const BezierCurveTree *BX, const BezierCurveTree *BY, - std::size_t offStartX, std::size_t offStartY, - std::size_t offEndX, std::size_t offEndY, - std::size_t nFlagsX, std::size_t nFlagsY, - Vector3 &left, Vector3 &mid, Vector3 &right, - Vector2 &texLeft, Vector2 &texMid, Vector2 &texRight, - Vector4 &colLeft, Vector4 &colMid, Vector4 &colRight, - bool bTranspose) -{ - int newFlagsX, newFlagsY; - - Vector3 tmp; - Vector3 vertex_0_0, vertex_0_1, vertex_1_0, vertex_1_1, vertex_2_0, vertex_2_1; - Vector2 texTmp; - Vector2 texcoord_0_0, texcoord_0_1, texcoord_1_0, texcoord_1_1, texcoord_2_0, texcoord_2_1; - Vector4 colTmp, colour_0_0, colour_0_1, colour_1_0, colour_1_1, colour_2_0, colour_2_1; - - { - // texcoords - - BezierInterpolate2(texcoord_for_index(m_tess.m_vertices, offStartX + offStartY), - texcoord_0_0, - texcoord_for_index(m_tess.m_vertices, BX->index + offStartY), - texcoord_0_1, - texcoord_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate2(texcoord_for_index(m_tess.m_vertices, offStartX + offEndY), - texcoord_2_0, - texcoord_for_index(m_tess.m_vertices, BX->index + offEndY), - texcoord_2_1, - texcoord_for_index(m_tess.m_vertices, offEndX + offEndY)); - - texTmp = texMid; - - BezierInterpolate2(texLeft, - texcoord_1_0, - texTmp, - texcoord_1_1, - texRight); - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->index + BY->index) = texTmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - texcoord_for_index(m_tess.m_vertices, BX->left->index + offStartY) = texcoord_0_0; - texcoord_for_index(m_tess.m_vertices, BX->left->index + offEndY) = texcoord_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->left->index + BY->index) = texcoord_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - texcoord_for_index(m_tess.m_vertices, BX->right->index + offStartY) = texcoord_0_1; - texcoord_for_index(m_tess.m_vertices, BX->right->index + offEndY) = texcoord_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->right->index + BY->index) = texcoord_1_1; - } - } - - - // colours - - BezierInterpolate4(colour_for_index(m_tess.m_vertices, offStartX + offStartY), - colour_0_0, - colour_for_index(m_tess.m_vertices, BX->index + offStartY), - colour_0_1, - colour_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate4(colour_for_index(m_tess.m_vertices, offStartX + offEndY), - colour_2_0, - colour_for_index(m_tess.m_vertices, BX->index + offEndY), - colour_2_1, - colour_for_index(m_tess.m_vertices, offEndX + offEndY)); - - colTmp = colMid; - - BezierInterpolate4(colLeft, - colour_1_0, - colTmp, - colour_1_1, - colRight); - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->index + BY->index) = colTmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - colour_for_index(m_tess.m_vertices, BX->left->index + offStartY) = colour_0_0; - colour_for_index(m_tess.m_vertices, BX->left->index + offEndY) = colour_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->left->index + BY->index) = colour_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - colour_for_index(m_tess.m_vertices, BX->right->index + offStartY) = colour_0_1; - colour_for_index(m_tess.m_vertices, BX->right->index + offEndY) = colour_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->right->index + BY->index) = colour_1_1; - } - } - - - // verts - - BezierInterpolate3(vertex_for_index(m_tess.m_vertices, offStartX + offStartY), - vertex_0_0, - vertex_for_index(m_tess.m_vertices, BX->index + offStartY), - vertex_0_1, - vertex_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate3(vertex_for_index(m_tess.m_vertices, offStartX + offEndY), - vertex_2_0, - vertex_for_index(m_tess.m_vertices, BX->index + offEndY), - vertex_2_1, - vertex_for_index(m_tess.m_vertices, offEndX + offEndY)); - - - tmp = mid; - - BezierInterpolate3(left, - vertex_1_0, - tmp, - vertex_1_1, - right); - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->index + BY->index) = tmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - vertex_for_index(m_tess.m_vertices, BX->left->index + offStartY) = vertex_0_0; - vertex_for_index(m_tess.m_vertices, BX->left->index + offEndY) = vertex_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->left->index + BY->index) = vertex_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - vertex_for_index(m_tess.m_vertices, BX->right->index + offStartY) = vertex_0_1; - vertex_for_index(m_tess.m_vertices, BX->right->index + offEndY) = vertex_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->right->index + BY->index) = vertex_1_1; - } - } - - // normals - - if (nFlagsX & SPLIT) { - ArbitraryMeshVertex a, b, c; - Vector3 tangentU; - - if (!(nFlagsX & DEGEN_0a) || !(nFlagsX & DEGEN_0b)) { - tangentU = vector3_subtracted(vertex_0_1, vertex_0_0); - a.vertex = vertex3f_for_vector3(vertex_0_0); - a.texcoord = texcoord2f_for_vector2(texcoord_0_0); - c.vertex = vertex3f_for_vector3(vertex_0_1); - c.texcoord = texcoord2f_for_vector2(texcoord_0_1); - } else if (!(nFlagsX & DEGEN_1a) || !(nFlagsX & DEGEN_1b)) { - tangentU = vector3_subtracted(vertex_1_1, vertex_1_0); - a.vertex = vertex3f_for_vector3(vertex_1_0); - a.texcoord = texcoord2f_for_vector2(texcoord_1_0); - c.vertex = vertex3f_for_vector3(vertex_1_1); - c.texcoord = texcoord2f_for_vector2(texcoord_1_1); - } else { - tangentU = vector3_subtracted(vertex_2_1, vertex_2_0); - a.vertex = vertex3f_for_vector3(vertex_2_0); - a.texcoord = texcoord2f_for_vector2(texcoord_2_0); - c.vertex = vertex3f_for_vector3(vertex_2_1); - c.texcoord = texcoord2f_for_vector2(texcoord_2_1); - } - - Vector3 tangentV; - - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_1a) && (nFlagsY & DEGEN_2a)) { - tangentV = vector3_subtracted(vertex_for_index(m_tess.m_vertices, BX->index + offEndY), tmp); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offEndY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offEndY].texcoord; - } else { - tangentV = vector3_subtracted(tmp, vertex_for_index(m_tess.m_vertices, BX->index + offStartY)); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offStartY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offStartY].texcoord; - } - - - Vector3 normal, s, t; - ArbitraryMeshVertex &v = m_tess.m_vertices[offStartY + BX->index]; - Vector3 &p = normal3f_to_vector3(v.normal); - Vector3 &ps = normal3f_to_vector3(v.tangent); - Vector3 &pt = normal3f_to_vector3(v.bitangent); - - if (bTranspose) { - normal = vector3_cross(tangentV, tangentU); - } else { - normal = vector3_cross(tangentU, tangentV); - } - normalise_safe(normal); - - ArbitraryMeshTriangle_calcTangents(a, b, c, s, t); - normalise_safe(s); - normalise_safe(t); - - if (nFlagsX & AVERAGE) { - p = vector3_normalised(vector3_added(p, normal)); - ps = vector3_normalised(vector3_added(ps, s)); - pt = vector3_normalised(vector3_added(pt, t)); - } else { - p = normal; - ps = s; - pt = t; - } - } - - { - ArbitraryMeshVertex a, b, c; - Vector3 tangentU; - - if (!(nFlagsX & DEGEN_2a) || !(nFlagsX & DEGEN_2b)) { - tangentU = vector3_subtracted(vertex_2_1, vertex_2_0); - a.vertex = vertex3f_for_vector3(vertex_2_0); - a.texcoord = texcoord2f_for_vector2(texcoord_2_0); - c.vertex = vertex3f_for_vector3(vertex_2_1); - c.texcoord = texcoord2f_for_vector2(texcoord_2_1); - } else if (!(nFlagsX & DEGEN_1a) || !(nFlagsX & DEGEN_1b)) { - tangentU = vector3_subtracted(vertex_1_1, vertex_1_0); - a.vertex = vertex3f_for_vector3(vertex_1_0); - a.texcoord = texcoord2f_for_vector2(texcoord_1_0); - c.vertex = vertex3f_for_vector3(vertex_1_1); - c.texcoord = texcoord2f_for_vector2(texcoord_1_1); - } else { - tangentU = vector3_subtracted(vertex_0_1, vertex_0_0); - a.vertex = vertex3f_for_vector3(vertex_0_0); - a.texcoord = texcoord2f_for_vector2(texcoord_0_0); - c.vertex = vertex3f_for_vector3(vertex_0_1); - c.texcoord = texcoord2f_for_vector2(texcoord_0_1); - } - - Vector3 tangentV; - - if ((nFlagsY & DEGEN_0b) && (nFlagsY & DEGEN_1b) && (nFlagsY & DEGEN_2b)) { - tangentV = vector3_subtracted(tmp, vertex_for_index(m_tess.m_vertices, BX->index + offStartY)); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offStartY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offStartY].texcoord; - } else { - tangentV = vector3_subtracted(vertex_for_index(m_tess.m_vertices, BX->index + offEndY), tmp); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offEndY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offEndY].texcoord; - } - - ArbitraryMeshVertex &v = m_tess.m_vertices[offEndY + BX->index]; - Vector3 &p = normal3f_to_vector3(v.normal); - Vector3 &ps = normal3f_to_vector3(v.tangent); - Vector3 &pt = normal3f_to_vector3(v.bitangent); - - if (bTranspose) { - p = vector3_cross(tangentV, tangentU); - } else { - p = vector3_cross(tangentU, tangentV); - } - normalise_safe(p); - - ArbitraryMeshTriangle_calcTangents(a, b, c, ps, pt); - normalise_safe(ps); - normalise_safe(pt); - } - } - - - newFlagsX = newFlagsY = 0; - - if ((nFlagsX & DEGEN_0a) && (nFlagsX & DEGEN_0b)) { - newFlagsX |= DEGEN_0a; - newFlagsX |= DEGEN_0b; - } - if ((nFlagsX & DEGEN_1a) && (nFlagsX & DEGEN_1b)) { - newFlagsX |= DEGEN_1a; - newFlagsX |= DEGEN_1b; - } - if ((nFlagsX & DEGEN_2a) && (nFlagsX & DEGEN_2b)) { - newFlagsX |= DEGEN_2a; - newFlagsX |= DEGEN_2b; - } - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_1a) && (nFlagsY & DEGEN_2a)) { - newFlagsY |= DEGEN_0a; - newFlagsY |= DEGEN_1a; - newFlagsY |= DEGEN_2a; - } - if ((nFlagsY & DEGEN_0b) && (nFlagsY & DEGEN_1b) && (nFlagsY & DEGEN_2b)) { - newFlagsY |= DEGEN_0b; - newFlagsY |= DEGEN_1b; - newFlagsY |= DEGEN_2b; - } - - - //if((nFlagsX & DEGEN_0a) && (nFlagsX & DEGEN_1a) && (nFlagsX & DEGEN_2a)) { newFlagsX |= DEGEN_0a; newFlagsX |= DEGEN_1a; newFlagsX |= DEGEN_2a; } - //if((nFlagsX & DEGEN_0b) && (nFlagsX & DEGEN_1b) && (nFlagsX & DEGEN_2b)) { newFlagsX |= DEGEN_0b; newFlagsX |= DEGEN_1b; newFlagsX |= DEGEN_2b; } - - newFlagsX |= (nFlagsX & SPLIT); - newFlagsX |= (nFlagsX & AVERAGE); - - if (!BezierCurveTree_isLeaf(BY)) { - { - int nTemp = newFlagsY; - - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_0b)) { - newFlagsY |= DEGEN_0a; - newFlagsY |= DEGEN_0b; - } - newFlagsY |= (nFlagsY & SPLIT); - newFlagsY |= (nFlagsY & AVERAGE); - - Vector3 &p = vertex_for_index(m_tess.m_vertices, BX->index + BY->index); - Vector3 vTemp(p); - - Vector2 &p2 = texcoord_for_index(m_tess.m_vertices, BX->index + BY->index); - Vector2 stTemp(p2); - - TesselateSubMatrix(BY, BX->left, - offStartY, offStartX, - offEndY, BX->index, - newFlagsY, newFlagsX, - vertex_0_0, vertex_1_0, vertex_2_0, - texcoord_0_0, texcoord_1_0, texcoord_2_0, - colour_0_0, colour_1_0, colour_2_0, - !bTranspose); - - newFlagsY = nTemp; - p = vTemp; - p2 = stTemp; - } - - if ((nFlagsY & DEGEN_2a) && (nFlagsY & DEGEN_2b)) { - newFlagsY |= DEGEN_2a; - newFlagsY |= DEGEN_2b; - } - - TesselateSubMatrix(BY, BX->right, - offStartY, BX->index, - offEndY, offEndX, - newFlagsY, newFlagsX, - vertex_0_1, vertex_1_1, vertex_2_1, - texcoord_0_1, texcoord_1_1, texcoord_2_1, - colour_0_1, colour_1_1, colour_2_1, - !bTranspose); - } else { - if (!BezierCurveTree_isLeaf(BX->left)) { - TesselateSubMatrix(BX->left, BY, - offStartX, offStartY, - BX->index, offEndY, - newFlagsX, newFlagsY, - left, vertex_1_0, tmp, - texLeft, texcoord_1_0, texTmp, - colLeft, colour_1_0, colTmp, - bTranspose); - } - - if (!BezierCurveTree_isLeaf(BX->right)) { - TesselateSubMatrix(BX->right, BY, - BX->index, offStartY, - offEndX, offEndY, - newFlagsX, newFlagsY, - tmp, vertex_1_1, right, - texTmp, texcoord_1_1, texRight, - colTmp, colour_1_1, colRight, - bTranspose); - } - } - -} - -void Patch::BuildTesselationCurves(EMatrixMajor major) -{ - std::size_t nArrayStride, length, cross, strideU, strideV; - switch (major) { - case ROW: - nArrayStride = 1; - length = (m_width - 1) >> 1; - cross = m_height; - strideU = 1; - strideV = m_width; - - if (!m_patchDef3) { - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeU); - } - - break; - case COL: - nArrayStride = m_tess.m_nArrayWidth; - length = (m_height - 1) >> 1; - cross = m_width; - strideU = m_width; - strideV = 1; - - if (!m_patchDef3) { - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeV); - } - - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - Array arrayLength(length); - Array pCurveTree(length); - - std::size_t nArrayLength = 1; - - if (m_patchDef3) { - if (!m_subdivisions_x && !m_subdivisions_y) { - for (Array::iterator i = arrayLength.begin(); i != arrayLength.end(); ++i) { - *i = 2; - nArrayLength += *i; - } - } else { - for (Array::iterator i = arrayLength.begin(); i != arrayLength.end(); ++i) { - *i = Array::value_type((major == ROW) ? m_subdivisions_x : m_subdivisions_y); - nArrayLength += *i; - } - } - } else { - // create a list of the horizontal control curves in each column of sub-patches - // adaptively tesselate each horizontal control curve in the list - // create a binary tree representing the combined tesselation of the list - for (std::size_t i = 0; i != length; ++i) { - PatchControl *p1 = m_ctrlTransformed.data() + (i * 2 * strideU); - GSList *pCurveList = 0; - for (std::size_t j = 0; j < cross; j += 2) { - PatchControl *p2 = p1 + strideV; - PatchControl *p3 = p2 + strideV; - - // directly taken from one row of control points - { - BezierCurve *pCurve = new BezierCurve; - pCurve->crd = (p1 + strideU)->m_vertex; - pCurve->left = p1->m_vertex; - pCurve->right = (p1 + (strideU << 1))->m_vertex; - pCurveList = g_slist_prepend(pCurveList, pCurve); - } - - if (j + 2 >= cross) { - break; - } - - // interpolated from three columns of control points - { - BezierCurve *pCurve = new BezierCurve; - pCurve->crd = vector3_mid((p1 + strideU)->m_vertex, (p3 + strideU)->m_vertex); - pCurve->left = vector3_mid(p1->m_vertex, p3->m_vertex); - pCurve->right = vector3_mid((p1 + (strideU << 1))->m_vertex, (p3 + (strideU << 1))->m_vertex); - - pCurve->crd = vector3_mid(pCurve->crd, (p2 + strideU)->m_vertex); - pCurve->left = vector3_mid(pCurve->left, p2->m_vertex); - pCurve->right = vector3_mid(pCurve->right, (p2 + (strideU << 1))->m_vertex); - pCurveList = g_slist_prepend(pCurveList, pCurve); - } - - p1 = p3; - } - - pCurveTree[i] = new BezierCurveTree; - BezierCurveTree_FromCurveList(pCurveTree[i], pCurveList); - for (GSList *l = pCurveList; l != 0; l = g_slist_next(l)) { - delete static_cast((*l).data ); - } - g_slist_free(pCurveList); - - // set up array indices for binary tree - // accumulate subarray width - arrayLength[i] = Array::value_type( - BezierCurveTree_Setup(pCurveTree[i], nArrayLength, nArrayStride) - (nArrayLength - 1)); - // accumulate total array width - nArrayLength += arrayLength[i]; - } - } - - switch (major) { - case ROW: - m_tess.m_nArrayWidth = nArrayLength; - std::swap(m_tess.m_arrayWidth, arrayLength); - - if (!m_patchDef3) { - std::swap(m_tess.m_curveTreeU, pCurveTree); - } - break; - case COL: - m_tess.m_nArrayHeight = nArrayLength; - std::swap(m_tess.m_arrayHeight, arrayLength); - - if (!m_patchDef3) { - std::swap(m_tess.m_curveTreeV, pCurveTree); - } - break; - } -} - -inline void vertex_assign_ctrl(ArbitraryMeshVertex &vertex, const PatchControl &ctrl) -{ - vertex.vertex = vertex3f_for_vector3(ctrl.m_vertex); - vertex.texcoord = texcoord2f_for_vector2(ctrl.m_texcoord); -} - -inline void vertex_clear_normal(ArbitraryMeshVertex &vertex) -{ - vertex.normal = Normal3f(0, 0, 0); - vertex.tangent = Normal3f(0, 0, 0); - vertex.bitangent = Normal3f(0, 0, 0); -} - -inline void tangents_remove_degenerate(Vector3 tangents[6], Vector2 textureTangents[6], unsigned int flags) -{ - if (flags & DEGEN_0a) { - const std::size_t i = - (flags & DEGEN_0b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_2a) - ? 5 - : 4 - : 3 - : 2 - : 1; - tangents[0] = tangents[i]; - textureTangents[0] = textureTangents[i]; - } - if (flags & DEGEN_0b) { - const std::size_t i = - (flags & DEGEN_0a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_2b) - ? 4 - : 5 - : 2 - : 3 - : 0; - tangents[1] = tangents[i]; - textureTangents[1] = textureTangents[i]; - } - if (flags & DEGEN_2a) { - const std::size_t i = - (flags & DEGEN_2b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_0a) - ? 1 - : 0 - : 3 - : 2 - : 5; - tangents[4] = tangents[i]; - textureTangents[4] = textureTangents[i]; - } - if (flags & DEGEN_2b) { - const std::size_t i = - (flags & DEGEN_2a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_0b) - ? 0 - : 1 - : 2 - : 3 - : 4; - tangents[5] = tangents[i]; - textureTangents[5] = textureTangents[i]; - } -} - -void bestTangents00(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (!(degenerateFlags & DEGEN_1a)) { // if this tangent is degenerate we cannot use it - index0 = 2; - index1 = 0; - } else if (!(degenerateFlags & DEGEN_0b)) { - index0 = 0; - index1 = 1; - } else { - index0 = 1; - index1 = 0; - } - } else if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (degenerateFlags & DEGEN_0b) { - index0 = 0; - index1 = 1; - } else { - index0 = 1; - index1 = 0; - } - } -} - -void bestTangents01(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (!(degenerateFlags & DEGEN_1a)) { // if this tangent is degenerate we cannot use it - index0 = 2; - index1 = 1; - } else if (!(degenerateFlags & DEGEN_2b)) { - index0 = 4; - index1 = 0; - } else { - index0 = 5; - index1 = 1; - } - } else if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (degenerateFlags & DEGEN_2b) { - index0 = 4; - index1 = 0; - } else { - index0 = 5; - index1 = 1; - } - } -} - -void bestTangents10(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (!(degenerateFlags & DEGEN_1b)) { // if this tangent is degenerate we cannot use it - index0 = 3; - index1 = 4; - } else if (!(degenerateFlags & DEGEN_0a)) { - index0 = 1; - index1 = 5; - } else { - index0 = 0; - index1 = 4; - } - } else if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (degenerateFlags & DEGEN_0a) { - index0 = 1; - index1 = 5; - } else { - index0 = 0; - index1 = 4; - } - } -} - -void bestTangents11(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (!(degenerateFlags & DEGEN_1b)) { // if this tangent is degenerate we cannot use it - index0 = 3; - index1 = 5; - } else if (!(degenerateFlags & DEGEN_2a)) { - index0 = 5; - index1 = 4; - } else { - index0 = 4; - index1 = 5; - } - } else if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (degenerateFlags & DEGEN_2a) { - index0 = 5; - index1 = 4; - } else { - index0 = 4; - index1 = 5; - } - } -} - -void -Patch::accumulateVertexTangentSpace(std::size_t index, Vector3 tangentX[6], Vector3 tangentY[6], Vector2 tangentS[6], - Vector2 tangentT[6], std::size_t index0, std::size_t index1) -{ - { - Vector3 normal(vector3_cross(tangentX[index0], tangentY[index1])); - if (!vector3_equal(normal, g_vector3_identity)) { - vector3_add(normal_for_index(m_tess.m_vertices, index), vector3_normalised(normal)); - } - } - - { - ArbitraryMeshVertex a, b, c; - a.vertex = Vertex3f(0, 0, 0); - a.texcoord = TexCoord2f(0, 0); - b.vertex = vertex3f_for_vector3(tangentX[index0]); - b.texcoord = texcoord2f_for_vector2(tangentS[index0]); - c.vertex = vertex3f_for_vector3(tangentY[index1]); - c.texcoord = texcoord2f_for_vector2(tangentT[index1]); - - Vector3 s, t; - ArbitraryMeshTriangle_calcTangents(a, b, c, s, t); - if (!vector3_equal(s, g_vector3_identity)) { - vector3_add(tangent_for_index(m_tess.m_vertices, index), vector3_normalised(s)); - } - if (!vector3_equal(t, g_vector3_identity)) { - vector3_add(bitangent_for_index(m_tess.m_vertices, index), vector3_normalised(t)); - } - } -} - -const std::size_t PATCH_MAX_VERTEX_ARRAY = 1048576; - -void Patch::BuildVertexArray() -{ - const std::size_t strideU = 1; - const std::size_t strideV = m_width; - - const std::size_t numElems = - m_tess.m_nArrayWidth * m_tess.m_nArrayHeight; // total number of elements in vertex array - - const bool bWidthStrips = (m_tess.m_nArrayWidth >= - m_tess.m_nArrayHeight); // decide if horizontal strips are longer than vertical - - - // allocate vertex, normal, texcoord and primitive-index arrays - m_tess.m_vertices.resize(numElems); - m_tess.m_indices.resize(m_tess.m_nArrayWidth * 2 * (m_tess.m_nArrayHeight - 1)); - - // set up strip indices - if (bWidthStrips) { - m_tess.m_numStrips = m_tess.m_nArrayHeight - 1; - m_tess.m_lenStrips = m_tess.m_nArrayWidth * 2; - - for (std::size_t i = 0; i < m_tess.m_nArrayWidth; i++) { - for (std::size_t j = 0; j < m_tess.m_numStrips; j++) { - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2] = RenderIndex(j * m_tess.m_nArrayWidth + i); - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2 + 1] = RenderIndex( - (j + 1) * m_tess.m_nArrayWidth + i); - // reverse because radiant uses CULL_FRONT - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2+1] = RenderIndex(j*m_tess.m_nArrayWidth+i); - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2] = RenderIndex((j+1)*m_tess.m_nArrayWidth+i); - } - } - } else { - m_tess.m_numStrips = m_tess.m_nArrayWidth - 1; - m_tess.m_lenStrips = m_tess.m_nArrayHeight * 2; - - for (std::size_t i = 0; i < m_tess.m_nArrayHeight; i++) { - for (std::size_t j = 0; j < m_tess.m_numStrips; j++) { - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2] = RenderIndex( - ((m_tess.m_nArrayHeight - 1) - i) * m_tess.m_nArrayWidth + j); - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2 + 1] = RenderIndex( - ((m_tess.m_nArrayHeight - 1) - i) * m_tess.m_nArrayWidth + j + 1); - // reverse because radiant uses CULL_FRONT - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2+1] = RenderIndex(((m_tess.m_nArrayHeight-1)-i)*m_tess.m_nArrayWidth+j); - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2] = RenderIndex(((m_tess.m_nArrayHeight-1)-i)*m_tess.m_nArrayWidth+j+1); - - } - } - } - - if (m_patchDef3 && !m_subdivisions_x && !m_subdivisions_y) - { - for (std::size_t i = 0; i < m_width*m_height; i++) - { - ArbitraryMeshVertex &p = m_tess.m_vertices[i]; - PatchControl &cp = m_ctrlTransformed[i]; - p.vertex = vertex3f_for_vector3(cp.m_vertex); - p.texcoord = texcoord2f_for_vector2(cp.m_texcoord); - p.colour = colour4f_for_vector4(cp.m_color); - } - } - else - { - PatchControlIter pCtrl = m_ctrlTransformed.data(); - for (std::size_t j = 0, offStartY = 0; j + 1 < m_height; j += 2, pCtrl += (strideU + strideV)) { - // set up array offsets for this sub-patch - const bool leafY = (m_patchDef3) ? false : BezierCurveTree_isLeaf(m_tess.m_curveTreeV[j >> 1]); - const std::size_t offMidY = (m_patchDef3) ? 0 : m_tess.m_curveTreeV[j >> 1]->index; - const std::size_t widthY = m_tess.m_arrayHeight[j >> 1] * m_tess.m_nArrayWidth; - const std::size_t offEndY = offStartY + widthY; - - for (std::size_t i = 0, offStartX = 0; i + 1 < m_width; i += 2, pCtrl += (strideU << 1)) { - const bool leafX = (m_patchDef3) ? false : BezierCurveTree_isLeaf(m_tess.m_curveTreeU[i >> 1]); - const std::size_t offMidX = (m_patchDef3) ? 0 : m_tess.m_curveTreeU[i >> 1]->index; - const std::size_t widthX = m_tess.m_arrayWidth[i >> 1]; - const std::size_t offEndX = offStartX + widthX; - - PatchControl *subMatrix[3][3]; - subMatrix[0][0] = pCtrl; - subMatrix[0][1] = subMatrix[0][0] + strideU; - subMatrix[0][2] = subMatrix[0][1] + strideU; - subMatrix[1][0] = subMatrix[0][0] + strideV; - subMatrix[1][1] = subMatrix[1][0] + strideU; - subMatrix[1][2] = subMatrix[1][1] + strideU; - subMatrix[2][0] = subMatrix[1][0] + strideV; - subMatrix[2][1] = subMatrix[2][0] + strideU; - subMatrix[2][2] = subMatrix[2][1] + strideU; - - // assign on-patch control points to vertex array - if (i == 0 && j == 0) { - vertex_clear_normal(m_tess.m_vertices[offStartX + offStartY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offStartY], *subMatrix[0][0]); - if (j == 0) { - vertex_clear_normal(m_tess.m_vertices[offEndX + offStartY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offStartY], *subMatrix[0][2]); - if (i == 0) { - vertex_clear_normal(m_tess.m_vertices[offStartX + offEndY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offEndY], *subMatrix[2][0]); - - vertex_clear_normal(m_tess.m_vertices[offEndX + offEndY]); - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offEndY], *subMatrix[2][2]); - - if (!m_patchDef3) { - // assign remaining control points to vertex array - if (!leafX) { - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offStartY], *subMatrix[0][1]); - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offEndY], *subMatrix[2][1]); - } - if (!leafY) { - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offMidY], *subMatrix[1][0]); - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offMidY], *subMatrix[1][2]); - - if (!leafX) { - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offMidY], *subMatrix[1][1]); - } - } - } - - // test all 12 edges for degeneracy - unsigned int nFlagsX = subarray_get_degen(pCtrl, strideU, strideV); - unsigned int nFlagsY = subarray_get_degen(pCtrl, strideV, strideU); - Vector3 tangentX[6], tangentY[6]; - Vector2 tangentS[6], tangentT[6]; - - // set up tangents for each of the 12 edges if they were not degenerate - if (!(nFlagsX & DEGEN_0a)) { - tangentX[0] = vector3_subtracted(subMatrix[0][1]->m_vertex, subMatrix[0][0]->m_vertex); - tangentS[0] = vector2_subtracted(subMatrix[0][1]->m_texcoord, subMatrix[0][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_0b)) { - tangentX[1] = vector3_subtracted(subMatrix[0][2]->m_vertex, subMatrix[0][1]->m_vertex); - tangentS[1] = vector2_subtracted(subMatrix[0][2]->m_texcoord, subMatrix[0][1]->m_texcoord); - } - if (!(nFlagsX & DEGEN_1a)) { - tangentX[2] = vector3_subtracted(subMatrix[1][1]->m_vertex, subMatrix[1][0]->m_vertex); - tangentS[2] = vector2_subtracted(subMatrix[1][1]->m_texcoord, subMatrix[1][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_1b)) { - tangentX[3] = vector3_subtracted(subMatrix[1][2]->m_vertex, subMatrix[1][1]->m_vertex); - tangentS[3] = vector2_subtracted(subMatrix[1][2]->m_texcoord, subMatrix[1][1]->m_texcoord); - } - if (!(nFlagsX & DEGEN_2a)) { - tangentX[4] = vector3_subtracted(subMatrix[2][1]->m_vertex, subMatrix[2][0]->m_vertex); - tangentS[4] = vector2_subtracted(subMatrix[2][1]->m_texcoord, subMatrix[2][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_2b)) { - tangentX[5] = vector3_subtracted(subMatrix[2][2]->m_vertex, subMatrix[2][1]->m_vertex); - tangentS[5] = vector2_subtracted(subMatrix[2][2]->m_texcoord, subMatrix[2][1]->m_texcoord); - } - - if (!(nFlagsY & DEGEN_0a)) { - tangentY[0] = vector3_subtracted(subMatrix[1][0]->m_vertex, subMatrix[0][0]->m_vertex); - tangentT[0] = vector2_subtracted(subMatrix[1][0]->m_texcoord, subMatrix[0][0]->m_texcoord); - } - if (!(nFlagsY & DEGEN_0b)) { - tangentY[1] = vector3_subtracted(subMatrix[2][0]->m_vertex, subMatrix[1][0]->m_vertex); - tangentT[1] = vector2_subtracted(subMatrix[2][0]->m_texcoord, subMatrix[1][0]->m_texcoord); - } - if (!(nFlagsY & DEGEN_1a)) { - tangentY[2] = vector3_subtracted(subMatrix[1][1]->m_vertex, subMatrix[0][1]->m_vertex); - tangentT[2] = vector2_subtracted(subMatrix[1][1]->m_texcoord, subMatrix[0][1]->m_texcoord); - } - if (!(nFlagsY & DEGEN_1b)) { - tangentY[3] = vector3_subtracted(subMatrix[2][1]->m_vertex, subMatrix[1][1]->m_vertex); - tangentT[3] = vector2_subtracted(subMatrix[2][1]->m_texcoord, subMatrix[1][1]->m_texcoord); - } - if (!(nFlagsY & DEGEN_2a)) { - tangentY[4] = vector3_subtracted(subMatrix[1][2]->m_vertex, subMatrix[0][2]->m_vertex); - tangentT[4] = vector2_subtracted(subMatrix[1][2]->m_texcoord, subMatrix[0][2]->m_texcoord); - } - if (!(nFlagsY & DEGEN_2b)) { - tangentY[5] = vector3_subtracted(subMatrix[2][2]->m_vertex, subMatrix[1][2]->m_vertex); - tangentT[5] = vector2_subtracted(subMatrix[2][2]->m_texcoord, subMatrix[1][2]->m_texcoord); - } - - // set up remaining edge tangents by borrowing the tangent from the closest parallel non-degenerate edge - tangents_remove_degenerate(tangentX, tangentS, nFlagsX); - tangents_remove_degenerate(tangentY, tangentT, nFlagsY); - - { - // x=0, y=0 - std::size_t index = offStartX + offStartY; - std::size_t index0 = 0; - std::size_t index1 = 0; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents00(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=1, y=0 - std::size_t index = offEndX + offStartY; - std::size_t index0 = 1; - std::size_t index1 = 4; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents10(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=0, y=1 - std::size_t index = offStartX + offEndY; - std::size_t index0 = 4; - std::size_t index1 = 1; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index1]) * vector3_length(tangentY[index1]); - - bestTangents01(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=1, y=1 - std::size_t index = offEndX + offEndY; - std::size_t index0 = 5; - std::size_t index1 = 5; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents11(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - //normalise normals that won't be accumulated again - if (i != 0 || j != 0) { - normalise_safe(normal_for_index(m_tess.m_vertices, offStartX + offStartY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offStartX + offStartY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offStartX + offStartY)); - } - if (i + 3 == m_width) { - normalise_safe(normal_for_index(m_tess.m_vertices, offEndX + offStartY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offEndX + offStartY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offEndX + offStartY)); - } - if (j + 3 == m_height) { - normalise_safe(normal_for_index(m_tess.m_vertices, offStartX + offEndY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offStartX + offEndY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offStartX + offEndY)); - } - if (i + 3 == m_width && j + 3 == m_height) { - normalise_safe(normal_for_index(m_tess.m_vertices, offEndX + offEndY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offEndX + offEndY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offEndX + offEndY)); - } - - // set flags to average normals between shared edges - if (j != 0) { - nFlagsX |= AVERAGE; - } - if (i != 0) { - nFlagsY |= AVERAGE; - } - // set flags to save evaluating shared edges twice - nFlagsX |= SPLIT; - nFlagsY |= SPLIT; - - // if the patch is curved.. tesselate recursively - // use the relevant control curves for this sub-patch - if (m_patchDef3) { - TesselateSubMatrixFixed(m_tess.m_vertices.data() + offStartX + offStartY, 1, m_tess.m_nArrayWidth, - nFlagsX, nFlagsY, subMatrix); - } else { - if (!leafX) { - TesselateSubMatrix(m_tess.m_curveTreeU[i >> 1], m_tess.m_curveTreeV[j >> 1], - offStartX, offStartY, offEndX, offEndY, // array offsets - nFlagsX, nFlagsY, - subMatrix[1][0]->m_vertex, subMatrix[1][1]->m_vertex, - subMatrix[1][2]->m_vertex, - subMatrix[1][0]->m_texcoord, subMatrix[1][1]->m_texcoord, - subMatrix[1][2]->m_texcoord, - subMatrix[1][0]->m_color, subMatrix[1][1]->m_color, - subMatrix[1][2]->m_color, - false); - } else if (!leafY) { - TesselateSubMatrix(m_tess.m_curveTreeV[j >> 1], m_tess.m_curveTreeU[i >> 1], - offStartY, offStartX, offEndY, offEndX, // array offsets - nFlagsY, nFlagsX, - subMatrix[0][1]->m_vertex, subMatrix[1][1]->m_vertex, - subMatrix[2][1]->m_vertex, - subMatrix[0][1]->m_texcoord, subMatrix[1][1]->m_texcoord, - subMatrix[2][1]->m_texcoord, - subMatrix[0][1]->m_color, subMatrix[1][1]->m_color, - subMatrix[2][1]->m_color, - true); - } - } - - offStartX = offEndX; - } - offStartY = offEndY; - } - } -} - - -class PatchFilterWrapper : public Filter { -bool m_active; -bool m_invert; -PatchFilter &m_filter; -public: -PatchFilterWrapper(PatchFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Patch &patch) -{ - return m_invert ^ m_filter.filter(patch); -} -}; - - -typedef std::list PatchFilters; -PatchFilters g_patchFilters; - -void add_patch_filter(PatchFilter &filter, int mask, bool invert) -{ - g_patchFilters.push_back(PatchFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_patchFilters.back(), mask); -} - -bool patch_filtered(Patch &patch) -{ - for (PatchFilters::iterator i = g_patchFilters.begin(); i != g_patchFilters.end(); ++i) { - if ((*i).active() && (*i).filter(patch)) { - return true; - } - } - return false; -} diff --git a/src/patch.h b/src/patch.h deleted file mode 100644 index c0e74aa..0000000 --- a/src/patch.h +++ /dev/null @@ -1,2129 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PATCH_H ) -#define INCLUDED_PATCH_H - -/// \file -/// \brief The patch primitive. -/// -/// A 2-dimensional matrix of vertices that define a quadratic bezier surface. -/// The Boundary-Representation of this primitive is a triangle mesh. -/// The surface is recursively tesselated until the angle between each triangle -/// edge is smaller than a specified tolerance. - -#include "globaldefs.h" -#include "nameable.h" -#include "ifilter.h" -#include "imap.h" -#include "ipatch.h" -#include "cullable.h" -#include "renderable.h" -#include "editable.h" -#include "selectable.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "math/frustum.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "stream/textstream.h" -#include "xml/xmlelement.h" -#include "scenelib.h" -#include "transformlib.h" -#include "instancelib.h" -#include "selectionlib.h" -#include "traverselib.h" -#include "render.h" -#include "stringio.h" -#include "shaderlib.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "texturelib.h" -#include "xml/ixml.h" -#include "dragplanes.h" - -enum EPatchType { - ePatchTypeQuake3, - ePatchTypeDoom3, -}; - -extern int g_PatchSubdivideThreshold; - - -#define MIN_PATCH_WIDTH 3 -#define MIN_PATCH_HEIGHT 3 - -extern std::size_t MAX_PATCH_WIDTH; -extern std::size_t MAX_PATCH_HEIGHT; - -#define MAX_PATCH_ROWCTRL ( ( ( MAX_PATCH_WIDTH - 1 ) - 1 ) / 2 ) -#define MAX_PATCH_COLCTRL ( ( ( MAX_PATCH_HEIGHT - 1 ) - 1 ) / 2 ) - -enum EPatchCap { - eCapBevel, - eCapEndCap, - eCapIBevel, - eCapIEndCap, - eCapCylinder, -}; - -enum EPatchPrefab { - ePlane, - eBevel, - eEndCap, - eCylinder, - eDenseCylinder, - eVeryDenseCylinder, - eSqCylinder, - eCone, - eSphere, - eXactCylinder, - eXactSphere, - eXactCone, -}; - -enum EMatrixMajor { - ROW, COL, -}; - -struct BezierCurve { - Vector3 crd; - Vector3 left; - Vector3 right; -}; - -const std::size_t BEZIERCURVETREE_MAX_INDEX = std::size_t(1) << (std::numeric_limits::digits - 1); - -struct BezierCurveTree { - std::size_t index; - BezierCurveTree *left; - BezierCurveTree *right; -}; - -inline bool BezierCurveTree_isLeaf(const BezierCurveTree *node) -{ - return node->left == 0 && node->right == 0; -} - -void BezierCurveTree_Delete(BezierCurveTree *pCurve); - - -inline VertexPointer vertexpointer_arbitrarymeshvertex(const ArbitraryMeshVertex *array) -{ - return VertexPointer(VertexPointer::pointer(&array->vertex), sizeof(ArbitraryMeshVertex)); -} - -typedef PatchControl *PatchControlIter; -typedef const PatchControl *PatchControlConstIter; - -inline void copy_ctrl(PatchControlIter ctrl, PatchControlConstIter begin, PatchControlConstIter end) -{ - std::copy(begin, end, ctrl); -} - -const Colour4b colour_corner(0, 255, 0, 255); -const Colour4b colour_inside(255, 0, 255, 255); - -class Patch; - -class PatchFilter { -public: -virtual bool filter(const Patch &patch) const = 0; -}; - -bool patch_filtered(Patch &patch); - -void add_patch_filter(PatchFilter &filter, int mask, bool invert = false); - -void Patch_addTextureChangedCallback(const SignalHandler &handler); - -void Patch_textureChanged(); - -inline void BezierCurveTreeArray_deleteAll(Array &curveTrees) -{ - for (Array::iterator i = curveTrees.begin(); i != curveTrees.end(); ++i) { - BezierCurveTree_Delete(*i); - } -} - -inline void PatchControlArray_invert(Array &ctrl, std::size_t width, std::size_t height) -{ - Array tmp(width); - - PatchControlIter from = ctrl.data() + (width * (height - 1)); - PatchControlIter to = ctrl.data(); - for (std::size_t h = 0; h != ((height - 1) >> 1); ++h, to += width, from -= width) { - copy_ctrl(tmp.data(), to, to + width); - copy_ctrl(to, from, from + width); - copy_ctrl(from, tmp.data(), tmp.data() + width); - } -} - -class PatchTesselation { -public: -PatchTesselation() - : m_numStrips(0), m_lenStrips(0), m_nArrayWidth(0), m_nArrayHeight(0) -{ -} - -Array m_vertices; -Array m_indices; -std::size_t m_numStrips; -std::size_t m_lenStrips; - -Array m_arrayWidth; -std::size_t m_nArrayWidth; -Array m_arrayHeight; -std::size_t m_nArrayHeight; - -Array m_curveTreeU; -Array m_curveTreeV; -}; - -class RenderablePatchWireframe : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchWireframe(PatchTesselation &tess) : m_tess(tess) -{ -} - -void render(RenderStateFlags state) const -{ - { -#if NV_DRIVER_BUG - glVertexPointer(3, GL_FLOAT, 0, 0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 0); -#endif - - std::size_t n = 0; - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - for (std::size_t i = 0; i <= m_tess.m_curveTreeV.size(); ++i) { - glDrawArrays(GL_LINE_STRIP, GLint(n), GLsizei(m_tess.m_nArrayWidth)); - - if (i == m_tess.m_curveTreeV.size()) { - break; - } - - if (!BezierCurveTree_isLeaf(m_tess.m_curveTreeV[i])) { - glDrawArrays(GL_LINE_STRIP, GLint(m_tess.m_curveTreeV[i]->index), GLsizei(m_tess.m_nArrayWidth)); - } - - n += (m_tess.m_arrayHeight[i] * m_tess.m_nArrayWidth); - - } - } - - { - const ArbitraryMeshVertex *p = m_tess.m_vertices.data(); - std::size_t n = m_tess.m_nArrayWidth * sizeof(ArbitraryMeshVertex); - for (std::size_t i = 0; i <= m_tess.m_curveTreeU.size(); ++i) { - glVertexPointer(3, GL_FLOAT, GLsizei(n), &p->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_tess.m_nArrayHeight)); - - if (i == m_tess.m_curveTreeU.size()) { - break; - } - - if (!BezierCurveTree_isLeaf(m_tess.m_curveTreeU[i])) { - glVertexPointer(3, GL_FLOAT, GLsizei(n), - &(m_tess.m_vertices.data() + (m_tess.m_curveTreeU[i]->index))->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_tess.m_nArrayHeight)); - } - - p += m_tess.m_arrayWidth[i]; - } - } -} -}; - -class RenderablePatchFixedWireframe : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchFixedWireframe(PatchTesselation &tess) : m_tess(tess) -{ -} - -void render(RenderStateFlags state) const -{ - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } -} -}; - -class RenderablePatchFixedSolid : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchFixedSolid(PatchTesselation &tess) : m_tess(tess) -{ -} - -void RenderNormals() const; - -void render(RenderStateFlags state) const -{ - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->texcoord); - glShadeModel(GL_SMOOTH); - glColorPointer(4, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } - glShadeModel(GL_FLAT); - RenderNormals(); -} -}; - -class RenderablePatchSolid : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchSolid(PatchTesselation &tess) : m_tess(tess) -{ -} - -void RenderNormals() const; - -void render(RenderStateFlags state) const -{ - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->texcoord); - glShadeModel(GL_SMOOTH); - glColorPointer(4, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } - glShadeModel(GL_FLAT); -} -}; - -// parametric surface defined by quadratic bezier control curves -class Patch : - public XMLImporter, - public XMLExporter, - public TransformNode, - public Bounded, - public Cullable, - public Snappable, - public Undoable, - public Filterable, - public Nameable { -class xml_state_t { -public: -enum EState { - eDefault, - ePatch, - eMatrix, - eShader, -}; - -xml_state_t(EState state) - : m_state(state) -{ -} - -EState state() const -{ - return m_state; -} - -const char *content() const -{ - return m_content.c_str(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_content.write(buffer, length); -} - -private: -EState m_state; -StringOutputStream m_content; -}; - -std::vector m_xml_state; - -typedef Array PatchControlArray; - -class SavedState : public UndoMemento { -public: -SavedState( - std::size_t width, - std::size_t height, - const PatchControlArray &ctrl, - const char *shader, - bool patchDef3, - bool patchDefWS, - std::size_t subdivisions_x, - std::size_t subdivisions_y - ) : - m_width(width), - m_height(height), - m_shader(shader), - m_ctrl(ctrl), - m_patchDef3(patchDef3), - m_patchDefWS(patchDefWS), - m_subdivisions_x(subdivisions_x), - m_subdivisions_y(subdivisions_y) -{ -} - -void release() -{ - delete this; -} - -std::size_t m_width, m_height; -CopiedString m_shader; -PatchControlArray m_ctrl; -bool m_patchDef3; -bool m_patchDefWS; -std::size_t m_subdivisions_x; -std::size_t m_subdivisions_y; -}; - -public: -class Observer { -public: -virtual void allocate(std::size_t size) = 0; -}; - -private: -typedef UniqueSet Observers; -Observers m_observers; - -scene::Node *m_node; - -AABB m_aabb_local; // local bbox - -CopiedString m_shader; -Shader *m_state; - -std::size_t m_width; -std::size_t m_height; -public: -bool m_patchDef3; -bool m_patchDefWS; -std::size_t m_subdivisions_x; -std::size_t m_subdivisions_y; -PatchTesselation m_tess; -private: - -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// dynamically allocated array of control points, size is m_width*m_height -PatchControlArray m_ctrl; -PatchControlArray m_ctrlTransformed; - -RenderablePatchSolid m_render_solid; -RenderablePatchFixedSolid m_render_solid_fixed; -RenderablePatchWireframe m_render_wireframe; -RenderablePatchFixedWireframe m_render_wireframe_fixed; - -static Shader *m_state_ctrl; -static Shader *m_state_lattice; -VertexBuffer m_ctrl_vertices; -RenderableVertexBuffer m_render_ctrl; -IndexBuffer m_lattice_indices; -RenderableIndexBuffer m_render_lattice; - -bool m_bOverlay; - -bool m_transformChanged; -Callback m_evaluateTransform; -Callback m_boundsChanged; - -void construct() -{ - m_bOverlay = false; - m_width = m_height = 0; - - m_patchDef3 = false; - m_patchDefWS = false; - m_subdivisions_x = 0; - m_subdivisions_y = 0; - - check_shader(); - captureShader(); - - m_xml_state.push_back(xml_state_t::eDefault); -} - -public: -Callback m_lightsChanged; - -static int m_CycleCapIndex; // = 0; -static EPatchType m_type; - -STRING_CONSTANT(Name, "Patch"); - -Patch(scene::Node &node, const Callback &evaluateTransform, const Callback &boundsChanged) : - m_node(&node), - m_shader(texdef_name_default()), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged) -{ - construct(); -} - -Patch(const Patch &other, scene::Node &node, const Callback &evaluateTransform, - const Callback &boundsChanged) : - m_node(&node), - m_shader(texdef_name_default()), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged) -{ - construct(); - - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - setDims(other.m_width, other.m_height); - copy_ctrl(m_ctrl.data(), other.m_ctrl.data(), other.m_ctrl.data() + (m_width * m_height)); - SetShader(other.m_shader.c_str()); - controlPointsChanged(); -} - -Patch(const Patch &other) : - XMLImporter(other), - XMLExporter(other), - TransformNode(other), - Bounded(other), - Cullable(other), - Snappable(), - Undoable(other), - Filterable(other), - Nameable(other), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(other.m_evaluateTransform), - m_boundsChanged(other.m_boundsChanged) -{ - m_bOverlay = false; - - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - setDims(other.m_width, other.m_height); - copy_ctrl(m_ctrl.data(), other.m_ctrl.data(), other.m_ctrl.data() + (m_width * m_height)); - SetShader(other.m_shader.c_str()); - controlPointsChanged(); -} - -~Patch() -{ - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeU); - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeV); - - releaseShader(); - - ASSERT_MESSAGE(m_observers.empty(), "Patch::~Patch: observers still attached"); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_state->incrementUsed(); - m_map = path_find_mapfile(path.begin(), path.end()); - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); - } else { - ASSERT_MESSAGE(path_find_mapfile(path.begin(), path.end()) == m_map, - "node is instanced across more than one file"); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_map = 0; - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - GlobalFilterSystem().unregisterFilterable(*this); - m_state->decrementUsed(); - } -} - -const char *name() const -{ - return "patch"; -} - -void attach(const NameCallback &callback) -{ -} - -void detach(const NameCallback &callback) -{ -} - -void attach(Observer *observer) -{ - observer->allocate(m_width * m_height); - - m_observers.insert(observer); -} - -void detach(Observer *observer) -{ - m_observers.erase(observer); -} - -void updateFiltered() -{ - if (m_node != 0) { - if (patch_filtered(*this)) { - m_node->enable(scene::Node::eFiltered); - } else { - m_node->disable(scene::Node::eFiltered); - } - } -} - -void onAllocate(std::size_t size) -{ - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->allocate(size); - } -} - -const Matrix4 &localToParent() const -{ - return g_matrix4_identity; -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -void render_solid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - - if (m_patchDef3) { - renderer.addRenderable(m_render_solid_fixed, localToWorld); - } else { - renderer.addRenderable(m_render_solid, localToWorld); - } -} - -void render_wireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - if (m_patchDef3) { - renderer.addRenderable(m_render_wireframe_fixed, localToWorld); - } else { - renderer.addRenderable(m_render_wireframe, localToWorld); - } -} - -void render_component(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state_lattice, Renderer::eWireframeOnly); - renderer.SetState(m_state_lattice, Renderer::eFullMaterials); - renderer.addRenderable(m_render_lattice, localToWorld); - - renderer.SetState(m_state_ctrl, Renderer::eWireframeOnly); - renderer.SetState(m_state_ctrl, Renderer::eFullMaterials); - renderer.addRenderable(m_render_ctrl, localToWorld); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - IndexPointer::index_type *pIndex = m_tess.m_indices.data(); - for (std::size_t s = 0; s < m_tess.m_numStrips; s++) { - test.TestQuadStrip(vertexpointer_arbitrarymeshvertex(m_tess.m_vertices.data()), - IndexPointer(pIndex, m_tess.m_lenStrips), best); - pIndex += m_tess.m_lenStrips; - } - if (best.valid()) { - selector.addIntersection(best); - } -} - -void transform(const Matrix4 &matrix) -{ - for (PatchControlIter i = m_ctrlTransformed.data(); - i != m_ctrlTransformed.data() + m_ctrlTransformed.size(); ++i) { - matrix4_transform_point(matrix, (*i).m_vertex); - } - - if (matrix4_handedness(matrix) == MATRIX4_LEFTHANDED) { - PatchControlArray_invert(m_ctrlTransformed, m_width, m_height); - } - UpdateCachedData(); -} - -void transformChanged() -{ - m_transformChanged = true; - m_lightsChanged(); - SceneChangeNotify(); -} - -typedef MemberCaller TransformChangedCaller; - -void evaluateTransform() -{ - if (m_transformChanged) { - m_transformChanged = false; - revertTransform(); - m_evaluateTransform(); - } -} - -void revertTransform() -{ - m_ctrlTransformed = m_ctrl; -} - -void freezeTransform() -{ - undoSave(); - evaluateTransform(); - ASSERT_MESSAGE(m_ctrlTransformed.size() == m_ctrl.size(), "Patch::freeze: size mismatch"); - std::copy(m_ctrlTransformed.begin(), m_ctrlTransformed.end(), m_ctrl.begin()); -} - -void controlPointsChanged() -{ - transformChanged(); - evaluateTransform(); - UpdateCachedData(); -} - -bool isValid() const; - -void snapto(float snap) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - vector3_snap((*i).m_vertex, snap); - } - - controlPointsChanged(); -} - - -void RenderDebug(RenderStateFlags state) const; - -void RenderNormals(RenderStateFlags state) const; - -void pushElement(const XMLElement &element) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ASSERT_MESSAGE(string_equal(element.name(), "patch"), "parse error"); - m_xml_state.push_back(xml_state_t::ePatch); - break; - case xml_state_t::ePatch: - if (string_equal(element.name(), "matrix")) { - setDims(atoi(element.attribute("width")), atoi(element.attribute("height"))); - m_xml_state.push_back(xml_state_t::eMatrix); - } else if (string_equal(element.name(), "shader")) { - m_xml_state.push_back(xml_state_t::eShader); - } - break; - default: - ERROR_MESSAGE("parse error"); - } - -} - -void popElement(const char *name) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ERROR_MESSAGE("parse error"); - break; - case xml_state_t::ePatch: - break; - case xml_state_t::eMatrix: { - StringTokeniser content(m_xml_state.back().content()); - - for (PatchControlIter i = m_ctrl.data(), end = m_ctrl.data() + m_ctrl.size(); i != end; ++i) { - (*i).m_vertex[0] = string_read_float(content.getToken()); - (*i).m_vertex[1] = string_read_float(content.getToken()); - (*i).m_vertex[2] = string_read_float(content.getToken()); - (*i).m_texcoord[0] = string_read_float(content.getToken()); - (*i).m_texcoord[1] = string_read_float(content.getToken()); - } - controlPointsChanged(); - } - break; - case xml_state_t::eShader: { - SetShader(m_xml_state.back().content()); - } - break; - default: - ERROR_MESSAGE("parse error"); - } - - ASSERT_MESSAGE(!m_xml_state.empty(), "popping empty stack"); - m_xml_state.pop_back(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - break; - case xml_state_t::ePatch: - break; - case xml_state_t::eMatrix: - case xml_state_t::eShader: - return m_xml_state.back().write(buffer, length); - break; - default: - ERROR_MESSAGE("parse error"); - } - return length; -} - -void exportXML(XMLImporter &importer) -{ - StaticElement patchElement("patch"); - importer.pushElement(patchElement); - - { - const StaticElement element("shader"); - importer.pushElement(element); - importer.write(m_shader.c_str(), strlen(m_shader.c_str())); - importer.popElement(element.name()); - } - - { - char width[16], height[16]; - sprintf(width, "%u", Unsigned(m_width)); - sprintf(height, "%u", Unsigned(m_height)); - StaticElement element("matrix"); - element.insertAttribute("width", width); - element.insertAttribute("height", height); - - importer.pushElement(element); - { - for (PatchControlIter i = m_ctrl.data(), end = m_ctrl.data() + m_ctrl.size(); i != end; ++i) { - importer << (*i).m_vertex[0] - << ' ' << (*i).m_vertex[1] - << ' ' << (*i).m_vertex[2] - << ' ' << (*i).m_texcoord[0] - << ' ' << (*i).m_texcoord[1]; - } - } - importer.popElement(element.name()); - } - - importer.popElement(patchElement.name()); -} - -void UpdateCachedData(); - -const char *GetShader() const -{ - return m_shader.c_str(); -} - -void SetShader(const char *name) -{ - ASSERT_NOTNULL(name); - - if (shader_equal(m_shader.c_str(), name)) { - return; - } - - undoSave(); - - if (m_instanceCounter.m_count != 0) { - m_state->decrementUsed(); - } - releaseShader(); - m_shader = name; - captureShader(); - if (m_instanceCounter.m_count != 0) { - m_state->incrementUsed(); - } - - check_shader(); - Patch_textureChanged(); -} - -int getShaderFlags() const -{ - if (m_state != 0) { - return m_state->getFlags(); - } - return 0; -} - -typedef PatchControl *iterator; -typedef const PatchControl *const_iterator; - -iterator begin() -{ - return m_ctrl.data(); -} - -const_iterator begin() const -{ - return m_ctrl.data(); -} - -iterator end() -{ - return m_ctrl.data() + m_ctrl.size(); -} - -const_iterator end() const -{ - return m_ctrl.data() + m_ctrl.size(); -} - -PatchControlArray &getControlPoints() -{ - return m_ctrl; -} - -PatchControlArray &getControlPointsTransformed() -{ - return m_ctrlTransformed; -} - -void setDims(std::size_t w, std::size_t h); - -std::size_t getWidth() const -{ - return m_width; -} - -std::size_t getHeight() const -{ - return m_height; -} - -PatchControl &ctrlAt(std::size_t row, std::size_t col) -{ - return m_ctrl[row * m_width + col]; -} - -const PatchControl &ctrlAt(std::size_t row, std::size_t col) const -{ - return m_ctrl[row * m_width + col]; -} - -void ConstructPrefab(const AABB &aabb, EPatchPrefab eType, int axis, std::size_t width = 3, std::size_t height = 3); - -void constructPlane(const AABB &aabb, int axis, std::size_t width, std::size_t height); - -void InvertMatrix(); - -void TransposeMatrix(); - -void Redisperse(EMatrixMajor mt); - -void Smooth(EMatrixMajor mt); - -void InsertRemove(bool bInsert, bool bColumn, bool bFirst); - -Patch *MakeCap(Patch *patch, EPatchCap eType, EMatrixMajor mt, bool bFirst); - -void ConstructSeam(EPatchCap eType, Vector3 *p, std::size_t width); - -void FlipTexture(int nAxis); - -void TranslateTexture(float s, float t); - -void ScaleTexture(float s, float t); - -void RotateTexture(float angle); - -void SetTextureRepeat(float s, float t); // call with s=1 t=1 for FIT -void CapTexture(); - -void NaturalTexture(); - -void ProjectTexture(int nAxis); - -void IdentityColour(void); //sets all colours to 1,1,1,1 - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -UndoMemento *exportState() const -{ - return new SavedState(m_width, m_height, m_ctrl, m_shader.c_str(), m_patchDef3, m_patchDefWS, m_subdivisions_x, - m_subdivisions_y); -} - -void importState(const UndoMemento *state) -{ - undoSave(); - - const SavedState &other = *(static_cast( state )); - - // begin duplicate of SavedState copy constructor, needs refactoring - - // copy construct - { - m_width = other.m_width; - m_height = other.m_height; - SetShader(other.m_shader.c_str()); - m_ctrl = other.m_ctrl; - onAllocate(m_ctrl.size()); - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - } - - // end duplicate code - - Patch_textureChanged(); - - controlPointsChanged(); -} - -static void constructStatic(EPatchType type) -{ - Patch::m_type = type; - Patch::m_state_ctrl = GlobalShaderCache().capture("$POINT"); - Patch::m_state_lattice = GlobalShaderCache().capture("$LATTICE"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$LATTICE"); - GlobalShaderCache().release("$POINT"); -} - -private: -void captureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void releaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -void check_shader() -{ - if (!shader_valid(GetShader())) { - globalErrorStream() << "patch has invalid texture name: '" << GetShader() << "'\n"; - } -} - -void InsertPoints(EMatrixMajor mt, bool bFirst); - -void RemovePoints(EMatrixMajor mt, bool bFirst); - -void AccumulateBBox(); - -void TesselateSubMatrixFixed(ArbitraryMeshVertex *vertices, std::size_t strideX, std::size_t strideY, - unsigned int nFlagsX, unsigned int nFlagsY, PatchControl *subMatrix[3][3]); - -// uses binary trees representing bezier curves to recursively tesselate a bezier sub-patch -void TesselateSubMatrix(const BezierCurveTree *BX, const BezierCurveTree *BY, - std::size_t offStartX, std::size_t offStartY, - std::size_t offEndX, std::size_t offEndY, - std::size_t nFlagsX, std::size_t nFlagsY, - Vector3 &left, Vector3 &mid, Vector3 &right, - Vector2 &texLeft, Vector2 &texMid, Vector2 &texRight, - Vector4 &colLeft, Vector4 &colMid, Vector4 &colRight, - bool bTranspose); - -// tesselates the entire surface -void BuildTesselationCurves(EMatrixMajor major); - -void accumulateVertexTangentSpace(std::size_t index, Vector3 tangentX[6], Vector3 tangentY[6], Vector2 tangentS[6], - Vector2 tangentT[6], std::size_t index0, std::size_t index1); - -void BuildVertexArray(); -}; - -inline bool Patch_importHeader(Patch &patch, Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - return true; -} - -inline bool Patch_importShader(Patch &patch, Tokeniser &tokeniser) -{ - // parse shader name - tokeniser.nextLine(); - const char *texture = tokeniser.getToken(); - if (texture == 0) { - Tokeniser_unexpectedError(tokeniser, texture, "#texture-name"); - return false; - } - if (string_equal(texture, "NULL")) { - patch.SetShader(texdef_name_default()); - } else { - StringOutputStream shader(string_length(GlobalTexturePrefix_get()) + string_length(texture)); - shader << GlobalTexturePrefix_get() << texture; - patch.SetShader(shader.c_str()); - } - return true; -} - -inline bool PatchDoom3_importShader(Patch &patch, Tokeniser &tokeniser) -{ - // parse shader name - tokeniser.nextLine(); - const char *shader = tokeniser.getToken(); - if (shader == 0) { - Tokeniser_unexpectedError(tokeniser, shader, "#shader-name"); - return false; - } - if (string_equal(shader, "_emptyname")) { - shader = texdef_name_default(); - } - patch.SetShader(shader); - return true; -} - -inline bool Patch_importParams(Patch &patch, Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - - // parse matrix dimensions - { - std::size_t c, r; - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, c)); - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, r)); - - patch.setDims(c, r); - } - - if (patch.m_patchDef3) { - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, patch.m_subdivisions_x)); - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, patch.m_subdivisions_y)); - } - - // ignore contents/flags/value - int tmp; - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool Patch_importMatrix(Patch &patch, Tokeniser &tokeniser) -{ - // parse matrix - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - { - for (std::size_t c = 0; c < patch.getWidth(); c++) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - for (std::size_t r = 0; r < patch.getHeight(); r++) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[2])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_texcoord[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_texcoord[1])); - - patch.ctrlAt(r, c).m_color = Vector4(1,1,1,1); //assume opaque white. - - if (patch.m_patchDefWS) { - //Temp Hack, to handle weird format... - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - //End Temp Hack. - } - - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[0])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[1])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[2])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[3])); - - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - } - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool Patch_importFooter(Patch &patch, Tokeniser &tokeniser) -{ - patch.controlPointsChanged(); - - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - return true; -} - -class PatchTokenImporter : public MapImporter { -Patch &m_patch; -public: -PatchTokenImporter(Patch &patch) : m_patch(patch) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Patch_importHeader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importShader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importParams(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importMatrix(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importFooter(m_patch, tokeniser)); - - return true; -} -}; - -class PatchDoom3TokenImporter : public MapImporter { -Patch &m_patch; -public: -PatchDoom3TokenImporter(Patch &patch) : m_patch(patch) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Patch_importHeader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(PatchDoom3_importShader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importParams(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importMatrix(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importFooter(m_patch, tokeniser)); - - return true; -} -}; - -inline void Patch_exportHeader(const Patch &patch, TokenWriter &writer) -{ - writer.writeToken("{"); - writer.nextLine(); - - //if it has colours, use our postfix on the patchdef type (to prevent incompatible tools giving weird results - our parser doesn't really care for now...) - bool hascolours = false; - for (std::size_t c = 0; c < patch.getWidth() && !hascolours; c++) { - for (std::size_t r = 0; r < patch.getHeight(); r++) { - auto v = patch.ctrlAt(r, c); - if (v.m_color[0] != 1 || v.m_color[1] != 1 || v.m_color[2] != 1 || v.m_color[3] != 1) - { - hascolours = true; - break; - } - } - } - if (hascolours) { - writer.writeToken(patch.m_patchDef3 ? "patchDef3WS" : "patchDef2WS"); - } else { - writer.writeToken(patch.m_patchDef3 ? "patchDef3" : "patchDef2"); - } - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); -} - -inline void Patch_exportShader(const Patch &patch, TokenWriter &writer) -{ - // write shader name - if (*(shader_get_textureName(patch.GetShader())) == '\0') { - writer.writeToken("NULL"); - } else { - writer.writeToken(shader_get_textureName(patch.GetShader())); - } - writer.nextLine(); -} - -inline void PatchDoom3_exportShader(const Patch &patch, TokenWriter &writer) -{ - // write shader name - if (*(shader_get_textureName(patch.GetShader())) == '\0') { - writer.writeString("_emptyname"); - } else { - writer.writeString(patch.GetShader()); - } - writer.nextLine(); -} - -inline void Patch_exportParams(const Patch &patch, TokenWriter &writer) -{ - // write matrix dimensions - writer.writeToken("("); - writer.writeUnsigned(patch.getWidth()); - writer.writeUnsigned(patch.getHeight()); - if (patch.m_patchDef3) { - writer.writeUnsigned(patch.m_subdivisions_x); - writer.writeUnsigned(patch.m_subdivisions_y); - } - writer.writeInteger(0); - writer.writeInteger(0); - writer.writeInteger(0); - writer.writeToken(")"); - writer.nextLine(); -} - -inline void Patch_exportMatrix(const Patch &patch, TokenWriter &writer) -{ - // write matrix - writer.writeToken("("); - writer.nextLine(); - for (std::size_t c = 0; c < patch.getWidth(); c++) { - writer.writeToken("("); - for (std::size_t r = 0; r < patch.getHeight(); r++) { - writer.writeToken("("); - auto v = patch.ctrlAt(r, c); - - writer.writeFloat(v.m_vertex[0]); - writer.writeFloat(v.m_vertex[1]); - writer.writeFloat(v.m_vertex[2]); - writer.writeFloat(v.m_texcoord[0]); - writer.writeFloat(v.m_texcoord[1]); - - if (v.m_color[0] != 1 || v.m_color[1] != 1 || v.m_color[2] != 1 || v.m_color[3] != 1) { - writer.writeFloat(v.m_color[0]); - writer.writeFloat(v.m_color[1]); - writer.writeFloat(v.m_color[2]); - writer.writeFloat(v.m_color[3]); - } - - writer.writeToken(")"); - } - writer.writeToken(")"); - writer.nextLine(); - } - writer.writeToken(")"); - writer.nextLine(); -} - -inline void Patch_exportFooter(const Patch &patch, TokenWriter &writer) -{ - writer.writeToken("}"); - writer.nextLine(); - writer.writeToken("}"); - writer.nextLine(); -} - -class PatchTokenExporter : public MapExporter { -const Patch &m_patch; -public: -PatchTokenExporter(Patch &patch) : m_patch(patch) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - Patch_exportHeader(m_patch, writer); - Patch_exportShader(m_patch, writer); - Patch_exportParams(m_patch, writer); - Patch_exportMatrix(m_patch, writer); - Patch_exportFooter(m_patch, writer); -} -}; - -class PatchDoom3TokenExporter : public MapExporter { -const Patch &m_patch; -public: -PatchDoom3TokenExporter(Patch &patch) : m_patch(patch) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - Patch_exportHeader(m_patch, writer); - PatchDoom3_exportShader(m_patch, writer); - Patch_exportParams(m_patch, writer); - Patch_exportMatrix(m_patch, writer); - Patch_exportFooter(m_patch, writer); -} -}; - -class PatchControlInstance { -public: -PatchControl *m_ctrl; -ObservedSelectable m_selectable; - -PatchControlInstance(PatchControl *ctrl, const SelectionChangeCallback &observer) - : m_ctrl(ctrl), m_selectable(observer) -{ -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - test.TestPoint(m_ctrl->m_vertex, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } -} - -void snapto(float snap) -{ - vector3_snap(m_ctrl->m_vertex, snap); -} -}; - - -class PatchInstance : - public Patch::Observer, - public scene::Instance, - public Selectable, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable, - public PlaneSelectable, - public LightCullable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); - InstanceContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -Patch &m_patch; -typedef std::vector PatchControlInstances; -PatchControlInstances m_ctrl_instances; - -ObservedSelectable m_selectable; - -DragPlanes m_dragPlanes; - -mutable RenderablePointVector m_render_selected; -mutable AABB m_aabb_component; - -static Shader *m_state_selpoint; - -const LightList *m_lightList; - -TransformModifier m_transform; -public: - -typedef LazyStatic StaticTypeCasts; - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -STRING_CONSTANT(Name, "PatchInstance"); - -PatchInstance(const scene::Path &path, scene::Instance *parent, Patch &patch) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_patch(patch), - m_selectable(SelectedChangedCaller(*this)), - m_dragPlanes(SelectedChangedComponentCaller(*this)), - m_render_selected(GL_POINTS), - m_transform(Patch::TransformChangedCaller(m_patch), ApplyTransformCaller(*this)) -{ - m_patch.instanceAttach(Instance::path()); - m_patch.attach(this); - - m_lightList = &GlobalShaderCache().attach(*this); - m_patch.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); -} - -~PatchInstance() -{ - Instance::setTransformChangedCallback(Callback()); - - m_patch.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); - - m_patch.detach(this); - m_patch.instanceDetach(Instance::path()); -} - -void selectedChanged(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::ePrimitive)(selectable); - GlobalSelectionSystem().onSelectedChanged(*this, selectable); - - Instance::selectedChanged(); -} - -typedef MemberCaller SelectedChangedCaller; - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -Patch &getPatch() -{ - return m_patch; -} - -Bounded &get(NullType) -{ - return m_patch; -} - -Cullable &get(NullType) -{ - return m_patch; -} - -Transformable &get(NullType) -{ - return m_transform; -} - -static void constructStatic() -{ - m_state_selpoint = GlobalShaderCache().capture("$SELPOINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$SELPOINT"); -} - - -void allocate(std::size_t size) -{ - m_ctrl_instances.clear(); - m_ctrl_instances.reserve(size); - for (Patch::iterator i = m_patch.begin(); i != m_patch.end(); ++i) { - m_ctrl_instances.push_back(PatchControlInstance(&(*i), SelectedChangedComponentCaller(*this))); - } -} - -void setSelected(bool select) -{ - m_selectable.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - - -void update_selected() const -{ - m_render_selected.clear(); - Patch::iterator ctrl = m_patch.getControlPointsTransformed().begin(); - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); - i != m_ctrl_instances.end(); ++i, ++ctrl) { - if ((*i).m_selectable.isSelected()) { - const Colour4b colour_selected(0, 0, 255, 255); - m_render_selected.push_back( - PointVertex(reinterpret_cast((*ctrl).m_vertex ), colour_selected)); - } - } -} - -#if 0 -void render( Renderer& renderer, const VolumeTest& volume ) const { - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && m_selectable.isSelected() ) { - renderer.Highlight( Renderer::eFace, false ); - - m_patch.render( renderer, volume, localToWorld() ); - - if ( GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex ) { - renderer.Highlight( Renderer::ePrimitive, false ); - - m_patch.render_component( renderer, volume, localToWorld() ); - - renderComponentsSelected( renderer, volume ); - } - } - else{ - m_patch.render( renderer, volume, localToWorld() ); - } -} -#endif - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - renderer.setLights(*m_lightList); - m_patch.render_solid(renderer, volume, localToWorld()); - - renderComponentsSelected(renderer, volume); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - m_patch.render_wireframe(renderer, volume, localToWorld()); - - renderComponentsSelected(renderer, volume); -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - update_selected(); - if (!m_render_selected.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(m_state_selpoint, Renderer::eWireframeOnly); - renderer.SetState(m_state_selpoint, Renderer::eFullMaterials); - renderer.addRenderable(m_render_selected, localToWorld()); - } -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) { - m_patch.render_component(renderer, volume, localToWorld()); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld(), true); - m_patch.testSelect(selector, test); -} - -void selectCtrl(bool select) -{ - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - (*i).m_selectable.setSelected(select); - } -} - -bool isSelectedComponents() const -{ - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - return true; - } - } - return false; -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - selectCtrl(select); - } else if (mode == SelectionSystem::eFace) { - m_dragPlanes.setSelected(select); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - aabb_extend_by_point_safe(m_aabb_component, (*i).m_ctrl->m_vertex); - } - } - - return m_aabb_component; -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - test.BeginMesh(localToWorld()); - - switch (mode) { - case SelectionSystem::eVertex: { - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - default: - break; - } -} - -bool selectedVertices() -{ - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - return true; - } - } - return false; -} - -void transformComponents(const Matrix4 &matrix) -{ - if (selectedVertices()) { - PatchControlIter ctrl = m_patch.getControlPointsTransformed().begin(); - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); - i != m_ctrl_instances.end(); ++i, ++ctrl) { - if ((*i).m_selectable.isSelected()) { - matrix4_transform_point(matrix, (*ctrl).m_vertex); - } - } - m_patch.UpdateCachedData(); - } - - if (m_dragPlanes.isSelected()) { // this should only be true when the transform is a pure translation. - m_patch.transform(m_dragPlanes.evaluateTransform(vector4_to_vector3(matrix.t()))); - } -} - - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - - m_dragPlanes.selectPlanes(m_patch.localAABB(), selector, test, selectedPlaneCallback); -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - m_dragPlanes.selectReversedPlanes(m_patch.localAABB(), selector, selectedPlanes); -} - - -void snapComponents(float snap) -{ - if (selectedVertices()) { - m_patch.undoSave(); - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - (*i).snapto(snap); - } - } - m_patch.controlPointsChanged(); - } -} - -void evaluateTransform() -{ - Matrix4 matrix(m_transform.calculateTransform()); - - if (m_transform.getType() == TRANSFORM_PRIMITIVE) { - m_patch.transform(matrix); - } else { - transformComponents(matrix); - } -} - -void applyTransform() -{ - m_patch.revertTransform(); - evaluateTransform(); - m_patch.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} -}; - - -template -class PatchNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -typedef PatchNode Self; - -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Patch m_patch; -TokenImporter m_importMap; -TokenExporter m_exportMap; - -public: - -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_patch; -} - -TransformNode &get(NullType) -{ - return m_patch; -} - -Patch &get(NullType) -{ - return m_patch; -} - -XMLImporter &get(NullType) -{ - return m_patch; -} - -XMLExporter &get(NullType) -{ - return m_patch; -} - -MapImporter &get(NullType) -{ - return m_importMap; -} - -MapExporter &get(NullType) -{ - return m_exportMap; -} - -Nameable &get(NullType) -{ - return m_patch; -} - -PatchNode(bool patchDef3, bool patchWS) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_patch(m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_importMap(m_patch), - m_exportMap(m_patch) -{ - m_patch.m_patchDef3 = patchDef3; - m_patch.m_patchDefWS = patchWS; -} - -PatchNode(const PatchNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_patch(other.m_patch, m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_importMap(m_patch), - m_exportMap(m_patch) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -Patch &get() -{ - return m_patch; -} - -const Patch &get() const -{ - return m_patch; -} - -scene::Node &clone() const -{ - return (new PatchNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PatchInstance(path, parent, m_patch); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -typedef PatchNode PatchNodeQuake3; -typedef PatchNode PatchNodeDoom3; - -inline Patch *Node_getPatch(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline PatchInstance *Instance_getPatch(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -template -class PatchSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -PatchSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0) { - m_functor(*patch); - } -} -}; - -template -inline void Scene_forEachSelectedPatch(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(PatchSelectedVisitor(functor)); -} - - -template -class PatchVisibleSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -PatchVisibleSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0 - && instance.path().top().get().visible()) { - m_functor(*patch); - } -} -}; - -template -inline void Scene_forEachVisibleSelectedPatchInstance(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(PatchVisibleSelectedVisitor(functor)); -} - -template -class PatchForEachWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisiblePatch(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachWalker(functor)); -} - -template -class PatchForEachSelectedWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachSelectedWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0 - && Instance_getSelectable(instance)->isSelected()) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisibleSelectedPatch(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachSelectedWalker(functor)); -} - -template -class PatchForEachInstanceWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachInstanceWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisiblePatchInstance(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachInstanceWalker(functor)); -} - -#endif diff --git a/src/patchdialog.cpp b/src/patchdialog.cpp deleted file mode 100644 index 1362388..0000000 --- a/src/patchdialog.cpp +++ /dev/null @@ -1,1239 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Patch Dialog -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "patchdialog.h" - -#include - -#include "itexdef.h" - -#include "debugging/debugging.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/entry.h" -#include "gtkutil/button.h" -#include "gtkutil/nonmodal.h" -#include "dialog.h" -#include "gtkdlgs.h" -#include "mainframe.h" -#include "patchmanip.h" -#include "patch.h" -#include "commands.h" -#include "preferences.h" -#include "signal/isignal.h" - - -#include - -// the increment we are using for the patch inspector (this is saved in the prefs) -struct pi_globals_t { - float shift[2]; - float scale[2]; - float rotate; - - pi_globals_t() - { - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } -}; - -pi_globals_t g_pi_globals; - -class PatchFixedSubdivisions { -public: -PatchFixedSubdivisions() : m_enabled(false), m_x(0), m_y(0) -{ -} - -PatchFixedSubdivisions(bool enabled, std::size_t x, std::size_t y) : m_enabled(enabled), m_x(x), m_y(y) -{ -} - -bool m_enabled; -std::size_t m_x; -std::size_t m_y; -}; - -void Patch_getFixedSubdivisions(const Patch &patch, PatchFixedSubdivisions &subdivisions) -{ - subdivisions.m_enabled = patch.m_patchDef3; - subdivisions.m_x = patch.m_subdivisions_x; - subdivisions.m_y = patch.m_subdivisions_y; -} - -const std::size_t MAX_PATCH_SUBDIVISIONS = 32; - -void Patch_setFixedSubdivisions(Patch &patch, const PatchFixedSubdivisions &subdivisions) -{ - patch.undoSave(); - - patch.m_patchDef3 = subdivisions.m_enabled; - patch.m_subdivisions_x = subdivisions.m_x; - patch.m_subdivisions_y = subdivisions.m_y; - - if (patch.m_subdivisions_x || patch.m_subdivisions_y) - { - if (patch.m_subdivisions_x == 0) { - patch.m_subdivisions_x = 4; - } else if (patch.m_subdivisions_x > MAX_PATCH_SUBDIVISIONS) { - patch.m_subdivisions_x = MAX_PATCH_SUBDIVISIONS; - } - if (patch.m_subdivisions_y == 0) { - patch.m_subdivisions_y = 4; - } else if (patch.m_subdivisions_y > MAX_PATCH_SUBDIVISIONS) { - patch.m_subdivisions_y = MAX_PATCH_SUBDIVISIONS; - } - } - - SceneChangeNotify(); - Patch_textureChanged(); - patch.controlPointsChanged(); -} - -class PatchGetFixedSubdivisions { -PatchFixedSubdivisions &m_subdivisions; -public: -PatchGetFixedSubdivisions(PatchFixedSubdivisions &subdivisions) : m_subdivisions(subdivisions) -{ -} - -void operator()(Patch &patch) -{ - Patch_getFixedSubdivisions(patch, m_subdivisions); - SceneChangeNotify(); -} -}; - -void Scene_PatchGetFixedSubdivisions(PatchFixedSubdivisions &subdivisions) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - Patch *patch = Node_getPatch(GlobalSelectionSystem().ultimateSelected().path().top()); - if (patch != 0) { - Patch_getFixedSubdivisions(*patch, subdivisions); - } - } -#else - Scene_forEachVisibleSelectedPatch( PatchGetFixedSubdivisions( subdivisions ) ); -#endif -} - -void Scene_PatchSetFixedSubdivisions(const PatchFixedSubdivisions &subdivisions) -{ - UndoableCommand command("patchSetFixedSubdivisions"); - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - Patch_setFixedSubdivisions(patch, subdivisions); - }); -} - - -class Subdivisions { -public: -gulong m_changeevent; -ui::ComboBoxText m_type; -// ui::CheckButton m_enabled; -ui::Entry m_horizontal; -ui::Entry m_vertical; - -Subdivisions() : m_type(ui::null), m_horizontal(ui::null), m_vertical(ui::null) -{ -} - -void update() -{ - PatchFixedSubdivisions subdivisions; - Scene_PatchGetFixedSubdivisions(subdivisions); - int mode = 0; - if (subdivisions.m_enabled) - { - if (subdivisions.m_x || subdivisions.m_y) - mode = 1; - else - mode = 2; - } - auto combo = GTK_COMBO_BOX_TEXT(m_type); - g_signal_handler_block(combo, m_changeevent); - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), mode); - g_signal_handler_unblock(combo, m_changeevent); - - if (subdivisions.m_enabled && (subdivisions.m_x||subdivisions.m_y)) { - entry_set_int(m_horizontal, static_cast( subdivisions.m_x )); - entry_set_int(m_vertical, static_cast( subdivisions.m_y )); - gtk_widget_set_sensitive(m_horizontal, TRUE); - gtk_widget_set_sensitive(m_vertical, TRUE); - } else { - m_horizontal.text(""); - m_vertical.text(""); - gtk_widget_set_sensitive(m_horizontal, FALSE); - gtk_widget_set_sensitive(m_vertical, FALSE); - } -} - -void cancel() -{ - update(); -} - -typedef MemberCaller CancelCaller; - -void apply() -{ - auto patchtypetext = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(m_type)); - int patchtype; - if (!strcasecmp(patchtypetext, "Explicit")) - patchtype = 2; - else if (!strcasecmp(patchtypetext, "Fixed")) - patchtype = 1; - else - patchtype = 0; - auto horiz = static_cast( entry_get_int(m_horizontal)); - auto vert = static_cast( entry_get_int(m_vertical)); - if (patchtype == 2) - horiz = vert = 0; - else if (!horiz || !vert) - horiz = vert = 4; - - Scene_PatchSetFixedSubdivisions( - PatchFixedSubdivisions( - patchtype != 0, - horiz, - vert - ) - ); - - SceneChangeNotify(); -} - -typedef MemberCaller ApplyCaller; - -static void OnSelchangeComboPatchType(ui::ComboBoxText toggle, Subdivisions *self) -{ - self->apply(); -} -// static void applyGtk(ui::ToggleButton toggle, Subdivisions *self) -// { -// self->apply(); -// } -}; - -class PatchInspector : public Dialog { -ui::Window BuildDialog(); - -Subdivisions m_subdivisions; -NonModalEntry m_horizontalSubdivisionsEntry; -NonModalEntry m_verticalSubdivisionsEntry; -public: -IdleDraw m_idleDraw; -WindowPositionTracker m_position_tracker; - -Patch *m_Patch; - -CopiedString m_strName; -float m_fS; -float m_fT; -float m_fX; -float m_fY; -float m_fZ; -float m_fR; -float m_fG; -float m_fB; -float m_fA; -/* float m_fHScale; - float m_fHShift; - float m_fRotate; - float m_fVScale; - float m_fVShift; */ -int m_nCol; -int m_nRow; -ui::ComboBoxText m_pRowCombo{ui::null}; -ui::ComboBoxText m_pColCombo{ui::null}; -std::size_t m_countRows; -std::size_t m_countCols; - -// turn on/off processing of the "changed" "value_changed" messages -// (need to turn off when we are feeding data in) -// NOTE: much more simple than blocking signals -bool m_bListenChanged; - -PatchInspector() : - m_horizontalSubdivisionsEntry(Subdivisions::ApplyCaller(m_subdivisions), - Subdivisions::CancelCaller(m_subdivisions)), - m_verticalSubdivisionsEntry(Subdivisions::ApplyCaller(m_subdivisions), - Subdivisions::CancelCaller(m_subdivisions)), - m_idleDraw(MemberCaller(*this)) -{ - m_fS = 0.0f; - m_fT = 0.0f; - m_fX = 0.0f; - m_fY = 0.0f; - m_fZ = 0.0f; - m_fR = 1.f; - m_fG = 1.f; - m_fB = 1.f; - m_fA = 1.f; - m_nCol = 0; - m_nRow = 0; - m_countRows = 0; - m_countCols = 0; - m_Patch = 0; - m_bListenChanged = true; - - m_position_tracker.setPosition(c_default_window_pos); -} - -bool visible() -{ - return GetWidget().visible(); -} - -// void UpdateInfo(); -// void SetPatchInfo(); -void GetPatchInfo(); - -void UpdateSpinners(bool bUp, int nID); - -// read the current patch on map and initialize m_fX m_fY accordingly -void UpdateRowColInfo(); - -// sync the dialog our internal data structures -// depending on the flag it will read or write -// we use m_nCol m_nRow m_fX m_fY m_fZ m_fS m_fT m_strName -// (NOTE: this doesn't actually commit stuff to the map or read from it) -void importData(); - -void exportData(); -}; - -PatchInspector g_PatchInspector; - -bool PatchInspector_IsSelected(int x, int y) -{ - if (g_PatchInspector.m_nCol == x && g_PatchInspector.m_nRow == y) { - return true; - } - return false; -} - -void PatchInspector_constructWindow(ui::Window main_window) -{ - g_PatchInspector.m_parent = main_window; - g_PatchInspector.Create(); -} - -void PatchInspector_destroyWindow() -{ - g_PatchInspector.Destroy(); -} - -void PatchInspector_queueDraw() -{ - if (g_PatchInspector.visible()) { - g_PatchInspector.m_idleDraw.queueDraw(); - } -} - -void DoPatchInspector() -{ - g_PatchInspector.GetPatchInfo(); - if (!g_PatchInspector.visible()) { - g_PatchInspector.ShowDlg(); - } -} - -void PatchInspector_toggleShown() -{ - if (g_PatchInspector.visible()) { - g_PatchInspector.m_Patch = 0; - g_PatchInspector.HideDlg(); - } else { - DoPatchInspector(); - } -} - - -// ============================================================================= -// static functions - -// memorize the current state (that is don't try to undo our do before changing something else) -static void OnApply(ui::Widget widget, gpointer data) -{ - g_PatchInspector.exportData(); - if (g_PatchInspector.m_Patch != 0) { - UndoableCommand command("patchSetTexture"); - g_PatchInspector.m_Patch->undoSave(); - - if (!texdef_name_valid(g_PatchInspector.m_strName.c_str())) { - globalErrorStream() << "invalid texture name '" << g_PatchInspector.m_strName.c_str() << "'\n"; - g_PatchInspector.m_strName = texdef_name_default(); - } - g_PatchInspector.m_Patch->SetShader(g_PatchInspector.m_strName.c_str()); - - std::size_t r = g_PatchInspector.m_nRow; - std::size_t c = g_PatchInspector.m_nCol; - if (r < g_PatchInspector.m_Patch->getHeight() - && c < g_PatchInspector.m_Patch->getWidth()) { - PatchControl &p = g_PatchInspector.m_Patch->ctrlAt(r, c); - p.m_vertex[0] = g_PatchInspector.m_fX; - p.m_vertex[1] = g_PatchInspector.m_fY; - p.m_vertex[2] = g_PatchInspector.m_fZ; - p.m_texcoord[0] = g_PatchInspector.m_fS; - p.m_texcoord[1] = g_PatchInspector.m_fT; - p.m_color[0] = g_PatchInspector.m_fR; - p.m_color[1] = g_PatchInspector.m_fG; - p.m_color[2] = g_PatchInspector.m_fB; - p.m_color[3] = g_PatchInspector.m_fA; - g_PatchInspector.m_Patch->controlPointsChanged(); - } - } -} - -static void OnSelchangeComboColRow(ui::Widget widget, gpointer data) -{ - if (!g_PatchInspector.m_bListenChanged) { - return; - } - // retrieve the current m_nRow and m_nCol, other params are not relevant - g_PatchInspector.exportData(); - // read the changed values ourselves - g_PatchInspector.UpdateRowColInfo(); - // now reflect our changes - g_PatchInspector.importData(); - - if (g_PatchInspector.m_Patch) - g_PatchInspector.m_Patch->controlPointsChanged(); -} - -void Scene_PatchTileTexture_Selected(scene::Graph &graph, float s, float t) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.SetTextureRepeat(s, t); - }); - SceneChangeNotify(); -} - -static void OnBtnPatchdetails(ui::Widget widget, gpointer data) -{ - Patch_CapTexture(); -} - -static void OnBtnPatchfit(ui::Widget widget, gpointer data) -{ - Patch_FitTexture(); -} - -static void OnBtnPatchnatural(ui::Widget widget, gpointer data) -{ - Patch_NaturalTexture(); -} - -static void OnBtnPatchreset(ui::Widget widget, gpointer data) -{ - Patch_ResetTexture(); -} - -static void OnBtnPatchFlipX(ui::Widget widget, gpointer data) -{ - Patch_FlipTextureX(); -} - -static void OnBtnPatchFlipY(ui::Widget widget, gpointer data) -{ - Patch_FlipTextureY(); -} - -void Scene_PatchRotateTexture_Selected(scene::Graph &graph, float angle) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.RotateTexture(angle); - }); -} - -float Patch_convertScale(float scale) -{ - if (scale > 0) { - return scale; - } - if (scale < 0) { - return -1 / scale; - } - return 1; -} - -void Scene_PatchScaleTexture_Selected(scene::Graph &graph, float s, float t) -{ - s = Patch_convertScale(s); - t = Patch_convertScale(t); - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.ScaleTexture(s, t); - }); -} - -void Scene_PatchTranslateTexture_Selected(scene::Graph &graph, float s, float t) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.TranslateTexture(s, t); - }); -} - -static void OnBtnPatchAutoCap(ui::Widget widget, gpointer data) -{ - Patch_AutoCapTexture(); -} - -static void OnSpinChanged(ui::Adjustment adj, gpointer data) -{ - texdef_t td; - - td.rotate = 0; - td.scale[0] = td.scale[1] = 0; - td.shift[0] = td.shift[1] = 0; - - if (gtk_adjustment_get_value(adj) == 0) { - return; - } - - if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "hshift_adj")) { - g_pi_globals.shift[0] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.shift[0] = g_pi_globals.shift[0]; - } else { - td.shift[0] = -g_pi_globals.shift[0]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "vshift_adj")) { - g_pi_globals.shift[1] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.shift[1] = g_pi_globals.shift[1]; - } else { - td.shift[1] = -g_pi_globals.shift[1]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "hscale_adj")) { - g_pi_globals.scale[0] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - if (g_pi_globals.scale[0] == 0.0f) { - return; - } - if (gtk_adjustment_get_value(adj) > 0) { - td.scale[0] = g_pi_globals.scale[0]; - } else { - td.scale[0] = -g_pi_globals.scale[0]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "vscale_adj")) { - g_pi_globals.scale[1] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - if (g_pi_globals.scale[1] == 0.0f) { - return; - } - if (gtk_adjustment_get_value(adj) > 0) { - td.scale[1] = g_pi_globals.scale[1]; - } else { - td.scale[1] = -g_pi_globals.scale[1]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "rotate_adj")) { - g_pi_globals.rotate = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.rotate = g_pi_globals.rotate; - } else { - td.rotate = -g_pi_globals.rotate; - } - } - - gtk_adjustment_set_value(adj, 0); - - // will scale shift rotate the patch accordingly - if (td.shift[0] || td.shift[1]) { - UndoableCommand command("patchTranslateTexture"); - Scene_PatchTranslateTexture_Selected(GlobalSceneGraph(), td.shift[0], td.shift[1]); - } else if (td.scale[0] || td.scale[1]) { - UndoableCommand command("patchScaleTexture"); - Scene_PatchScaleTexture_Selected(GlobalSceneGraph(), td.scale[0], td.scale[1]); - } else if (td.rotate) { - UndoableCommand command("patchRotateTexture"); - Scene_PatchRotateTexture_Selected(GlobalSceneGraph(), td.rotate); - } else { - /* we don't want to do this on locked patches - eukara */ - // update the point-by-point view - OnSelchangeComboColRow(ui::root, 0); - } -} - -static gint OnDialogKey(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - if (event->keyval == GDK_KEY_Return) { - OnApply(ui::root, 0); - return TRUE; - } else if (event->keyval == GDK_KEY_Escape) { - g_PatchInspector.GetPatchInfo(); - return TRUE; - } - return FALSE; -} - -// ============================================================================= -// PatchInspector class - -ui::Window PatchInspector::BuildDialog() -{ - ui::Window window = ui::Window(create_floating_window("Patch Properties", m_parent)); - - m_position_tracker.connect(window); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - - { - auto vbox = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - vbox.show(); - window.add(vbox); - { - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, TRUE, TRUE, 0); - { - auto vbox2 = ui::VBox(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 0); - vbox2.show(); - hbox.pack_start(vbox2, TRUE, TRUE, 0); - { - auto frame = ui::Frame("Details"); - frame.show(); - vbox2.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 5); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("Row:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - } - { - auto label = ui::Label("Column:"); - label.show(); - table.attach(label, {1, 2, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - } - { - auto combo = ui::ComboBoxText(ui::New); - combo.connect("changed", G_CALLBACK(OnSelchangeComboColRow), this); - AddDialogData(combo, m_nRow); - - combo.show(); - table.attach(combo, {0, 1, 1, 2}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_pRowCombo = combo; - } - - { - auto combo = ui::ComboBoxText(ui::New); - combo.connect("changed", G_CALLBACK(OnSelchangeComboColRow), this); - AddDialogData(combo, m_nCol); - - combo.show(); - table.attach(combo, {1, 2, 1, 2}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_pColCombo = combo; - } - } - auto table = ui::Table(5, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("X:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("Y:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("Z:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("S:"); - label.show(); - table.attach(label, {0, 1, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("T:"); - label.show(); - table.attach(label, {0, 1, 4, 5}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("R:"); - label.show(); - table.attach(label, {0, 1, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("G:"); - label.show(); - table.attach(label, {0, 1, 6, 7}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("B:"); - label.show(); - table.attach(label, {0, 1, 7, 8}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("A:"); - label.show(); - table.attach(label, {0, 1, 8, 9}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fX); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fY); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fZ); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fS); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 4, 5}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fT); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fR); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 6, 7}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fG); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 7, 8}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fB); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 8, 9}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fA); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - } - } - { - auto frame = ui::Frame("Tesselation"); - frame.show(); - vbox2.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 5); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(3, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - { - auto label = ui::Label("Type"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = ui::ComboBoxText(ui::New); - gtk_combo_box_text_append_text(combo, "Auto"); - gtk_combo_box_text_append_text(combo, "Fixed"); //patchDef3 - gtk_combo_box_text_append_text(combo, "Explicit"); - m_subdivisions.m_changeevent = combo.connect("changed", G_CALLBACK(Subdivisions::OnSelchangeComboPatchType), &m_subdivisions); -// AddDialogData(combo, m_nRow); - - combo.show(); - table.attach(combo, {1, 2, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_subdivisions.m_type = combo; - } - - /* - { - auto label = ui::Label("Fixed"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto check = ui::CheckButton::from(gtk_check_button_new()); - check.show(); - table.attach(check, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_enabled = check; - guint handler_id = check.connect("toggled", G_CALLBACK(&Subdivisions::applyGtk), - &m_subdivisions); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - }*/ - { - auto label = ui::Label("Horizontal"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_horizontal = entry; - m_horizontalSubdivisionsEntry.connect(entry); - } - { - auto label = ui::Label("Vertical"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_vertical = entry; - m_verticalSubdivisionsEntry.connect(entry); - } - } - } - } - } - { - auto frame = ui::Frame("Texturing"); - frame.show(); - hbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - { - auto label = ui::Label("Name:"); - label.show(); - vbox2.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - // gtk_editable_set_editable (GTK_ENTRY (entry), false); - entry.show(); - vbox2.pack_start(entry, TRUE, TRUE, 0); - AddDialogData(entry, m_strName); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto table = ui::Table(5, 4, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("Horizontal Shift Step"); - label.show(); - table.attach(label, {2, 4, 0, 1}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Vertical Shift Step"); - label.show(); - table.attach(label, {2, 4, 1, 2}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Horizontal Stretch Step"); - label.show(); - table.attach(label, {2, 3, 2, 3}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto button = ui::Button("Flip"); - button.show(); - table.attach(button, {3, 4, 2, 3}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnPatchFlipX), 0); - button.dimensions(60, -1); - } - { - auto label = ui::Label("Vertical Stretch Step"); - label.show(); - table.attach(label, {2, 3, 3, 4}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto button = ui::Button("Flip"); - button.show(); - table.attach(button, {3, 4, 3, 4}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnPatchFlipY), 0); - button.dimensions(60, -1); - } - { - auto label = ui::Label("Rotate Step"); - label.show(); - table.attach(label, {2, 4, 4, 5}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 0, 1}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - g_object_set_data(G_OBJECT(window), "hshift_entry", (void *) entry); - // we fill in this data, if no patch is selected the widgets are unmodified when the inspector is raised - // so we need to have at least one initialisation somewhere - entry_set_float(entry, g_pi_globals.shift[0]); - - auto adj = ui::Adjustment(0, -8192, 8192, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), (gpointer) entry); - g_object_set_data(G_OBJECT(window), "hshift_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 1, 2}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.shift[1]); - - auto adj = ui::Adjustment(0, -8192, 8192, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "vshift_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 2, 3}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.scale[0]); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "hscale_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 3, 4}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.scale[1]); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "vscale_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 3, 4}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 4, 5}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.rotate); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, - 0); // NOTE: Arnout - this really should be 360 but can't change it anymore as it could break existing maps - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "rotate_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 4, 5}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - } - auto hbox2 = ui::HBox(TRUE, 5); - hbox2.show(); - vbox2.pack_start(hbox2, TRUE, FALSE, 0); - { - auto button = ui::Button("Auto Cap"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchAutoCap), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("CAP"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchdetails), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Set..."); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchreset), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Natural"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchnatural), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Fit"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchfit), 0); - button.dimensions(60, -1); - } - } - } - } - } - - /* make small */ - gtk_window_set_default_size(GTK_WINDOW(window), 8, 8); - return window; -} - -// sync the dialog our internal data structures -void PatchInspector::exportData() -{ - m_bListenChanged = false; - Dialog::exportData(); - m_bListenChanged = true; -} - -void PatchInspector::importData() -{ - m_bListenChanged = false; - Dialog::importData(); - m_bListenChanged = true; -} - -// read the map and feed in the stuff to the dialog box -void PatchInspector::GetPatchInfo() -{ - { - m_subdivisions.update(); - } - - if (GlobalSelectionSystem().countSelected() == 0) { - m_Patch = 0; - } else { - m_Patch = Node_getPatch(GlobalSelectionSystem().ultimateSelected().path().top()); - } - - if (m_Patch != 0) { - m_strName = m_Patch->GetShader(); - - // fill in the numbers for Row / Col selection - m_bListenChanged = false; - - { - gtk_combo_box_set_active(m_pRowCombo, 0); - - for (std::size_t i = 0; i < m_countRows; ++i) { - gtk_combo_box_text_remove(m_pRowCombo, gint(m_countRows - i - 1)); - } - - m_countRows = m_Patch->getHeight(); - for (std::size_t i = 0; i < m_countRows; ++i) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(i)); - gtk_combo_box_text_append_text(m_pRowCombo, buffer); - } - - gtk_combo_box_set_active(m_pRowCombo, 0); - } - - { - gtk_combo_box_set_active(m_pColCombo, 0); - - for (std::size_t i = 0; i < m_countCols; ++i) { - gtk_combo_box_text_remove(m_pColCombo, gint(m_countCols - i - 1)); - } - - m_countCols = m_Patch->getWidth(); - for (std::size_t i = 0; i < m_countCols; ++i) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(i)); - gtk_combo_box_text_append_text(m_pColCombo, buffer); - } - - gtk_combo_box_set_active(m_pColCombo, 0); - } - - m_bListenChanged = true; - - } else { - //globalOutputStream() << "WARNING: no patch\n"; - } - // fill in our internal structs - m_nRow = 0; - m_nCol = 0; - UpdateRowColInfo(); - // now update the dialog box - importData(); -} - -// read the current patch on map and initialize m_fX m_fY accordingly -// NOTE: don't call UpdateData in there, it's not meant for -void PatchInspector::UpdateRowColInfo() -{ - m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0; - m_fR = m_fG = m_fB = m_fA = 1; - - if (m_Patch != 0) { - // we rely on whatever active row/column has been set before we get called - std::size_t r = m_nRow; - std::size_t c = m_nCol; - if (r < m_Patch->getHeight() - && c < m_Patch->getWidth()) { - const PatchControl &p = m_Patch->ctrlAt(r, c); - m_fX = p.m_vertex[0]; - m_fY = p.m_vertex[1]; - m_fZ = p.m_vertex[2]; - m_fS = p.m_texcoord[0]; - m_fT = p.m_texcoord[1]; - m_fR = p.m_color[0]; - m_fG = p.m_color[1]; - m_fB = p.m_color[2]; - m_fA = p.m_color[3]; - } - } -} - - -void PatchInspector_SelectionChanged(const Selectable &selectable) -{ - PatchInspector_queueDraw(); -} - - -#include "preferencesystem.h" - - -void PatchInspector_Construct() -{ - GlobalCommands_insert("PatchInspector", makeCallbackF(PatchInspector_toggleShown), - Accelerator('S', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalPreferenceSystem().registerPreference("PatchWnd", make_property( - g_PatchInspector.m_position_tracker)); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Scale1", make_property_string(g_pi_globals.scale[0])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Scale2", make_property_string(g_pi_globals.scale[1])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Shift1", make_property_string(g_pi_globals.shift[0])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Shift2", make_property_string(g_pi_globals.shift[1])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Rotate", make_property_string(g_pi_globals.rotate)); - - typedef FreeCaller PatchInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(PatchInspectorSelectionChangedCaller()); - typedef FreeCaller PatchInspectorQueueDrawCaller; - Patch_addTextureChangedCallback(PatchInspectorQueueDrawCaller()); -} - -void PatchInspector_Destroy() -{ -} diff --git a/src/patchdialog.h b/src/patchdialog.h deleted file mode 100644 index 38f52eb..0000000 --- a/src/patchdialog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PATCHDIALOG_H ) -#define INCLUDED_PATCHDIALOG_H - -void PatchInspector_Construct(); - -void PatchInspector_Destroy(); - -void PatchInspector_constructWindow(ui::Window main_window); - -void PatchInspector_destroyWindow(); - -namespace scene { -class Graph; -} - -void Scene_PatchTranslateTexture_Selected(scene::Graph &graph, float s, float t); - -void Scene_PatchRotateTexture_Selected(scene::Graph &graph, float angle); - -void Scene_PatchScaleTexture_Selected(scene::Graph &graph, float s, float t); - - -#endif diff --git a/src/patchmanip.cpp b/src/patchmanip.cpp deleted file mode 100644 index 42c5e39..0000000 --- a/src/patchmanip.cpp +++ /dev/null @@ -1,1137 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "patchmanip.h" - -#include -#include - -#include "debugging/debugging.h" - - -#include "iselection.h" -#include "ipatch.h" - -#include "math/vector.h" -#include "math/aabb.h" -#include "generic/callback.h" - -#include "gtkutil/menu.h" -#include "gtkutil/image.h" -#include "map.h" -#include "mainframe.h" -#include "commands.h" -#include "gtkmisc.h" -#include "gtkdlgs.h" -#include "texwindow.h" -#include "xywindow.h" -#include "select.h" -#include "patch.h" -#include "grid.h" - -PatchCreator *g_patchCreator = 0; - -void Scene_PatchConstructPrefab(scene::Graph &graph, const AABB aabb, const char *shader, EPatchPrefab eType, int axis, - std::size_t width = 3, std::size_t height = 3, int patchtype=0) -{ - Select_Delete(); - GlobalSelectionSystem().setSelectedAll(false); - - NodeSmartReference node(g_patchCreator->createPatch(patchtype!=0, true)); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node); - - Patch *patch = Node_getPatch(node); - patch->SetShader(shader); - - if (patchtype==1) - { - patch->m_subdivisions_x = 4; - patch->m_subdivisions_y = 4; - } - - patch->ConstructPrefab(aabb, eType, axis, width, height); - patch->controlPointsChanged(); - - { - scene::Path patchpath(makeReference(GlobalSceneGraph().root())); - patchpath.push(makeReference(*Map_GetWorldspawn(g_map))); - patchpath.push(makeReference(node.get())); - Instance_getSelectable(*graph.find(patchpath))->setSelected(true); - } -} - -void PatchAutoCapTexture(Patch &patch) -{ - - AABB box = patch.localAABB(); - float x = box.extents.x(); - float y = box.extents.y(); - float z = box.extents.z(); - - int cap_direction = -1; - if (x < y && x < z) { - cap_direction = 0; - } else if (y < x && y < z) { - cap_direction = 1; - } else if (z < x && z < x) { - cap_direction = 2; - } - - if (cap_direction >= 0) { - patch.ProjectTexture(cap_direction); - } else { - patch.NaturalTexture(); - } -} - -void Patch_AutoCapTexture() -{ - UndoableCommand command("patchAutoCapTexture"); - Scene_forEachVisibleSelectedPatch(&PatchAutoCapTexture); - SceneChangeNotify(); -} - -void Patch_makeCaps(Patch &patch, scene::Instance &instance, EPatchCap type, const char *shader) -{ - if ((type == eCapEndCap || type == eCapIEndCap) - && patch.getWidth() != 5) { - globalErrorStream() << "cannot create end-cap - patch width != 5\n"; - return; - } - if ((type == eCapBevel || type == eCapIBevel) - && patch.getWidth() != 3 && patch.getWidth() != 5) { - globalErrorStream() << "cannot create bevel-cap - patch width != 3\n"; - return; - } - if (type == eCapCylinder - && patch.getWidth() != 9) { - globalErrorStream() << "cannot create cylinder-cap - patch width != 9\n"; - return; - } - - { - NodeSmartReference cap(g_patchCreator->createPatch(false, true)); - Node_getTraversable(instance.path().parent())->insert(cap); - - Patch *cap_patch = Node_getPatch(cap); - patch.MakeCap(cap_patch, type, ROW, true); - cap_patch->SetShader(shader); - PatchAutoCapTexture(*cap_patch); - - scene::Path path(instance.path()); - path.pop(); - path.push(makeReference(cap.get())); - selectPath(path, true); - } - - { - NodeSmartReference cap(g_patchCreator->createPatch(false, true)); - Node_getTraversable(instance.path().parent())->insert(cap); - - Patch *cap_patch = Node_getPatch(cap); - patch.MakeCap(cap_patch, type, ROW, false); - cap_patch->SetShader(shader); - PatchAutoCapTexture(*cap_patch); - - scene::Path path(instance.path()); - path.pop(); - path.push(makeReference(cap.get())); - selectPath(path, true); - } -} - -typedef std::vector InstanceVector; - -enum ECapDialog { - PATCHCAP_BEVEL = 0, - PATCHCAP_ENDCAP, - PATCHCAP_INVERTED_BEVEL, - PATCHCAP_INVERTED_ENDCAP, - PATCHCAP_CYLINDER -}; - -EMessageBoxReturn DoCapDlg(ECapDialog *type); - -void Scene_PatchDoCap_Selected(scene::Graph &graph, const char *shader) -{ - ECapDialog nType; - - if (DoCapDlg(&nType) == eIDOK) { - EPatchCap eType; - switch (nType) { - case PATCHCAP_INVERTED_BEVEL: - eType = eCapIBevel; - break; - case PATCHCAP_BEVEL: - eType = eCapBevel; - break; - case PATCHCAP_INVERTED_ENDCAP: - eType = eCapIEndCap; - break; - case PATCHCAP_ENDCAP: - eType = eCapEndCap; - break; - case PATCHCAP_CYLINDER: - eType = eCapCylinder; - break; - default: - ERROR_MESSAGE("invalid patch cap type"); - return; - } - - InstanceVector instances; - Scene_forEachVisibleSelectedPatchInstance([&](PatchInstance &patch) { - instances.push_back(&patch); - }); - for (InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i) { - Patch_makeCaps(*Node_getPatch((*i)->path().top()), *(*i), eType, shader); - } - } -} - -Patch *Scene_GetUltimateSelectedVisiblePatch() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Node &node = GlobalSelectionSystem().ultimateSelected().path().top(); - if (node.visible()) { - return Node_getPatch(node); - } - } - return 0; -} - - -void Scene_PatchCapTexture_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.ProjectTexture(Patch::m_CycleCapIndex); - }); - Patch::m_CycleCapIndex = (Patch::m_CycleCapIndex == 0) ? 1 : (Patch::m_CycleCapIndex == 1) ? 2 : 0; - SceneChangeNotify(); -} - -void Scene_PatchFlipTexture_Selected(scene::Graph &graph, int axis) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.FlipTexture(axis); - }); -} - -void Scene_PatchNaturalTexture_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.NaturalTexture(); - }); - SceneChangeNotify(); -} - - -void Scene_PatchInsertRemove_Selected(scene::Graph &graph, bool bInsert, bool bColumn, bool bFirst) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.InsertRemove(bInsert, bColumn, bFirst); - }); -} - -void Scene_PatchInvert_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.InvertMatrix(); - }); -} - -void Scene_PatchRedisperse_Selected(scene::Graph &graph, EMatrixMajor major) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.Redisperse(major); - }); -} - -void Scene_PatchSmooth_Selected(scene::Graph &graph, EMatrixMajor major) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.Smooth(major); - }); -} - -void Scene_PatchTranspose_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.TransposeMatrix(); - }); -} - -void Scene_PatchSetShader_Selected(scene::Graph &graph, const char *name) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_PatchGetShader_Selected(scene::Graph &graph, CopiedString &name) -{ - Patch *patch = Scene_GetUltimateSelectedVisiblePatch(); - if (patch != 0) { - name = patch->GetShader(); - } -} - -void Scene_PatchSelectByShader(scene::Graph &graph, const char *name) -{ - Scene_forEachVisiblePatchInstance([&](PatchInstance &patch) { - if (shader_equal(patch.getPatch().GetShader(), name)) { - patch.setSelected(true); - } - }); -} - - -void Scene_PatchFindReplaceShader(scene::Graph &graph, const char *find, const char *replace) -{ - Scene_forEachVisiblePatch([&](Patch &patch) { - if (shader_equal(patch.GetShader(), find)) { - patch.SetShader(replace); - } - }); -} - -void Scene_PatchFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - if (shader_equal(patch.GetShader(), find)) { - patch.SetShader(replace); - } - }); -} - - -AABB PatchCreator_getBounds() -{ - AABB aabb(aabb_for_minmax(Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max)); - - float gridSize = GetGridSize(); - - if (aabb.extents[0] == 0) { - aabb.extents[0] = gridSize; - } - if (aabb.extents[1] == 0) { - aabb.extents[1] = gridSize; - } - if (aabb.extents[2] == 0) { - aabb.extents[2] = gridSize; - } - - if (aabb_valid(aabb)) { - return aabb; - } - return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64)); -} - -void DoNewPatchDlg(EPatchPrefab prefab, int minrows, int mincols, int defrows, int defcols, int maxrows, int maxcols); - -void Patch_XactCylinder() -{ - UndoableCommand undo("patchCreateXactCylinder"); - - DoNewPatchDlg(eXactCylinder, 3, 7, 3, 13, 0, 0); -} - -void Patch_XactSphere() -{ - UndoableCommand undo("patchCreateXactSphere"); - - DoNewPatchDlg(eXactSphere, 5, 7, 7, 13, 0, 0); -} - -void Patch_XactCone() -{ - UndoableCommand undo("patchCreateXactCone"); - - DoNewPatchDlg(eXactCone, 3, 7, 3, 13, 0, 0); -} - -void Patch_Cylinder() -{ - UndoableCommand undo("patchCreateCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_DenseCylinder() -{ - UndoableCommand undo("patchCreateDenseCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eDenseCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_VeryDenseCylinder() -{ - UndoableCommand undo("patchCreateVeryDenseCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eVeryDenseCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_SquareCylinder() -{ - UndoableCommand undo("patchCreateSquareCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eSqCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Endcap() -{ - UndoableCommand undo("patchCreateCaps"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eEndCap, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Bevel() -{ - UndoableCommand undo("patchCreateBevel"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eBevel, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Sphere() -{ - UndoableCommand undo("patchCreateSphere"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eSphere, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_SquareBevel() -{ -} - -void Patch_SquareEndcap() -{ -} - -void Patch_Cone() -{ - UndoableCommand undo("patchCreateCone"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eCone, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Plane() -{ - UndoableCommand undo("patchCreatePlane"); - - DoNewPatchDlg(ePlane, 3, 3, 3, 3, 0, 0); -} - -void Patch_InsertInsertColumn() -{ - UndoableCommand undo("patchInsertColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, true, false); -} - -void Patch_InsertAddColumn() -{ - UndoableCommand undo("patchAddColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, true, true); -} - -void Patch_InsertInsertRow() -{ - UndoableCommand undo("patchInsertRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, false, false); -} - -void Patch_InsertAddRow() -{ - UndoableCommand undo("patchAddRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, false, true); -} - -void Patch_DeleteFirstColumn() -{ - UndoableCommand undo("patchDeleteFirstColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, true, true); -} - -void Patch_DeleteLastColumn() -{ - UndoableCommand undo("patchDeleteLastColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, true, false); -} - -void Patch_DeleteFirstRow() -{ - UndoableCommand undo("patchDeleteFirstRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, false, true); -} - -void Patch_DeleteLastRow() -{ - UndoableCommand undo("patchDeleteLastRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, false, false); -} - -void Patch_Invert() -{ - UndoableCommand undo("patchInvert"); - - Scene_PatchInvert_Selected(GlobalSceneGraph()); -} - -void Patch_RedisperseRows() -{ - UndoableCommand undo("patchRedisperseRows"); - - Scene_PatchRedisperse_Selected(GlobalSceneGraph(), ROW); -} - -void Patch_RedisperseCols() -{ - UndoableCommand undo("patchRedisperseColumns"); - - Scene_PatchRedisperse_Selected(GlobalSceneGraph(), COL); -} - -void Patch_SmoothRows() -{ - UndoableCommand undo("patchSmoothRows"); - - Scene_PatchSmooth_Selected(GlobalSceneGraph(), ROW); -} - -void Patch_SmoothCols() -{ - UndoableCommand undo("patchSmoothColumns"); - - Scene_PatchSmooth_Selected(GlobalSceneGraph(), COL); -} - -void Patch_Transpose() -{ - UndoableCommand undo("patchTranspose"); - - Scene_PatchTranspose_Selected(GlobalSceneGraph()); -} - -void Patch_Cap() -{ - // FIXME: add support for patch cap creation - // Patch_CapCurrent(); - UndoableCommand undo("patchCreateCaps"); - - Scene_PatchDoCap_Selected(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -void Patch_CycleProjection() -{ - UndoableCommand undo("patchCycleUVProjectionAxis"); - - Scene_PatchCapTexture_Selected(GlobalSceneGraph()); -} - -///\todo Unfinished. -void Patch_OverlayOn() -{ -} - -///\todo Unfinished. -void Patch_OverlayOff() -{ -} - -void Patch_FlipTextureX() -{ - UndoableCommand undo("patchFlipTextureU"); - - Scene_PatchFlipTexture_Selected(GlobalSceneGraph(), 0); -} - -void Patch_FlipTextureY() -{ - UndoableCommand undo("patchFlipTextureV"); - - Scene_PatchFlipTexture_Selected(GlobalSceneGraph(), 1); -} - -void Patch_NaturalTexture() -{ - UndoableCommand undo("patchNaturalTexture"); - - Scene_PatchNaturalTexture_Selected(GlobalSceneGraph()); -} - -void Patch_CapTexture() -{ - UndoableCommand command("patchCapTexture"); - - Scene_PatchCapTexture_Selected(GlobalSceneGraph()); -} - -void Patch_ResetTexture() -{ - float fx, fy; - if (DoTextureLayout(&fx, &fy) == eIDOK) { - UndoableCommand command("patchTileTexture"); - Scene_PatchTileTexture_Selected(GlobalSceneGraph(), fx, fy); - } -} - -void Patch_FitTexture() -{ - UndoableCommand command("patchFitTexture"); - - Scene_PatchTileTexture_Selected(GlobalSceneGraph(), 1, 1); -} - -#include "ifilter.h" - - -class filter_patch_all : public PatchFilter { -public: -bool filter(const Patch &patch) const -{ - return true; -} -}; - -class filter_patch_shader : public PatchFilter { -const char *m_shader; -public: -filter_patch_shader(const char *shader) : m_shader(shader) -{ -} - -bool filter(const Patch &patch) const -{ - return shader_equal(patch.GetShader(), m_shader); -} -}; - -class filter_patch_flags : public PatchFilter { -int m_flags; -public: -filter_patch_flags(int flags) : m_flags(flags) -{ -} - -bool filter(const Patch &patch) const -{ - return (patch.getShaderFlags() & m_flags) != 0; -} -}; - - -filter_patch_all g_filter_patch_all; -filter_patch_shader g_filter_patch_clip("textures/common/clip"); -filter_patch_shader g_filter_patch_weapclip("textures/common/weapclip"); -filter_patch_flags g_filter_patch_translucent(QER_TRANS); - -void PatchFilters_construct() -{ - add_patch_filter(g_filter_patch_all, EXCLUDE_CURVES); - add_patch_filter(g_filter_patch_clip, EXCLUDE_CLIP); - add_patch_filter(g_filter_patch_weapclip, EXCLUDE_CLIP); - add_patch_filter(g_filter_patch_translucent, EXCLUDE_TRANSLUCENT); -} - - -#include "preferences.h" - -void Patch_constructPreferences(PreferencesPage &page) -{ - page.appendEntry("Patch Subdivide Threshold", g_PatchSubdivideThreshold); -} - -void Patch_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Patches", "Patch Display Preferences")); - Patch_constructPreferences(page); -} - -void Patch_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Patch_constructPage)); -} - - -#include "preferencesystem.h" - -void PatchPreferences_construct() -{ - GlobalPreferenceSystem().registerPreference("Subdivisions", make_property_string(g_PatchSubdivideThreshold)); -} - - -#include "generic/callback.h" - -void Patch_registerCommands() -{ - GlobalCommands_insert("InvertCurveTextureX", makeCallbackF(Patch_FlipTextureX), - Accelerator('I', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("InvertCurveTextureY", makeCallbackF(Patch_FlipTextureY), - Accelerator('I', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("NaturalizePatch", makeCallbackF(Patch_NaturalTexture), - Accelerator('N', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchCylinder", makeCallbackF(Patch_Cylinder)); - GlobalCommands_insert("PatchDenseCylinder", makeCallbackF(Patch_DenseCylinder)); - GlobalCommands_insert("PatchVeryDenseCylinder", makeCallbackF(Patch_VeryDenseCylinder)); - GlobalCommands_insert("PatchSquareCylinder", makeCallbackF(Patch_SquareCylinder)); - GlobalCommands_insert("PatchXactCylinder", makeCallbackF(Patch_XactCylinder)); - GlobalCommands_insert("PatchXactSphere", makeCallbackF(Patch_XactSphere)); - GlobalCommands_insert("PatchXactCone", makeCallbackF(Patch_XactCone)); - GlobalCommands_insert("PatchEndCap", makeCallbackF(Patch_Endcap)); - GlobalCommands_insert("PatchBevel", makeCallbackF(Patch_Bevel)); - GlobalCommands_insert("PatchSquareBevel", makeCallbackF(Patch_SquareBevel)); - GlobalCommands_insert("PatchSquareEndcap", makeCallbackF(Patch_SquareEndcap)); - GlobalCommands_insert("PatchCone", makeCallbackF(Patch_Cone)); - GlobalCommands_insert("PatchSphere", makeCallbackF(Patch_Sphere)); - GlobalCommands_insert("SimplePatchMesh", makeCallbackF(Patch_Plane), - Accelerator('P', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("PatchInsertInsertColumn", makeCallbackF(Patch_InsertInsertColumn), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PatchInsertAddColumn", makeCallbackF(Patch_InsertAddColumn)); - GlobalCommands_insert("PatchInsertInsertRow", makeCallbackF(Patch_InsertInsertRow), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchInsertAddRow", makeCallbackF(Patch_InsertAddRow)); - GlobalCommands_insert("PatchDeleteFirstColumn", makeCallbackF(Patch_DeleteFirstColumn)); - GlobalCommands_insert("PatchDeleteLastColumn", makeCallbackF(Patch_DeleteLastColumn), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PatchDeleteFirstRow", makeCallbackF(Patch_DeleteFirstRow), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchDeleteLastRow", makeCallbackF(Patch_DeleteLastRow)); - GlobalCommands_insert("InvertCurve", makeCallbackF(Patch_Invert), - Accelerator('I', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("RedisperseRows", makeCallbackF(Patch_RedisperseRows), - Accelerator('E', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("RedisperseCols", makeCallbackF(Patch_RedisperseCols), - Accelerator('E', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("SmoothRows", makeCallbackF(Patch_SmoothRows), - Accelerator('W', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("SmoothCols", makeCallbackF(Patch_SmoothCols), - Accelerator('W', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("MatrixTranspose", makeCallbackF(Patch_Transpose), - Accelerator('M', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("CapCurrentCurve", makeCallbackF(Patch_Cap), - Accelerator('C', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CycleCapTexturePatch", makeCallbackF(Patch_CycleProjection), - Accelerator('N', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("MakeOverlayPatch", makeCallbackF(Patch_OverlayOn), Accelerator('Y')); - GlobalCommands_insert("ClearPatchOverlays", makeCallbackF(Patch_OverlayOff), - Accelerator('L', (GdkModifierType) GDK_CONTROL_MASK)); -} - -void Patch_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Put caps on the current patch", "cap_curve.xpm", "CapCurrentCurve"); -} - -void Patch_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Cylinder", "PatchCylinder"); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "More Cylinders"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Dense Cylinder", "PatchDenseCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Very Dense Cylinder", "PatchVeryDenseCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Square Cylinder", "PatchSquareCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Exact Cylinder...", "PatchXactCylinder"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "End cap", "PatchEndCap"); - create_menu_item_with_mnemonic(menu, "Bevel", "PatchBevel"); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "More End caps, Bevels"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Square Endcap", "PatchSquareBevel"); - create_menu_item_with_mnemonic(menu_in_menu, "Square Bevel", "PatchSquareEndcap"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Cone", "PatchCone"); - create_menu_item_with_mnemonic(menu, "Exact Cone...", "PatchXactCone"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Sphere", "PatchSphere"); - create_menu_item_with_mnemonic(menu, "Exact Sphere...", "PatchXactSphere"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Simple Patch Mesh...", "SimplePatchMesh"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Insert"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Insert (2) Columns", "PatchInsertInsertColumn"); - create_menu_item_with_mnemonic(menu_in_menu, "Add (2) Columns", "PatchInsertAddColumn"); - menu_separator(menu_in_menu); - create_menu_item_with_mnemonic(menu_in_menu, "Insert (2) Rows", "PatchInsertInsertRow"); - create_menu_item_with_mnemonic(menu_in_menu, "Add (2) Rows", "PatchInsertAddRow"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Delete"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "First (2) Columns", "PatchDeleteFirstColumn"); - create_menu_item_with_mnemonic(menu_in_menu, "Last (2) Columns", "PatchDeleteLastColumn"); - menu_separator(menu_in_menu); - create_menu_item_with_mnemonic(menu_in_menu, "First (2) Rows", "PatchDeleteFirstRow"); - create_menu_item_with_mnemonic(menu_in_menu, "Last (2) Rows", "PatchDeleteLastRow"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Matrix"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Invert", "InvertCurve"); - auto menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Re-disperse"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_3); - }*/ - create_menu_item_with_mnemonic(menu_3, "Rows", "RedisperseRows"); - create_menu_item_with_mnemonic(menu_3, "Columns", "RedisperseCols"); - auto menu_4 = create_sub_menu_with_mnemonic(menu_in_menu, "Smooth"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_4); - }*/ - create_menu_item_with_mnemonic(menu_4, "Rows", "SmoothRows"); - create_menu_item_with_mnemonic(menu_4, "Columns", "SmoothCols"); - create_menu_item_with_mnemonic(menu_in_menu, "Transpose", "MatrixTranspose"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Cap Selection", "CapCurrentCurve"); - create_menu_item_with_mnemonic(menu, "Cycle Cap Texture", "CycleCapTexturePatch"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Overlay"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Set", "MakeOverlayPatch"); - create_menu_item_with_mnemonic(menu_in_menu, "Clear", "ClearPatchOverlays"); - } -} - - -#include "gtkutil/dialog.h" -#include "gtkutil/widget.h" - -void DoNewPatchDlg(EPatchPrefab prefab, int minrows, int mincols, int defrows, int defcols, int maxrows, int maxcols) -{ - ModalDialog dialog; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Patch density", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - auto width = ui::ComboBoxText(ui::New); - auto height = ui::ComboBoxText(ui::New); - auto type = ui::ComboBoxText(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - auto label = ui::Label("Width:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Height:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Type:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - - { - auto combo = width; -#define D_ITEM(x) if ( x >= mincols && ( !maxcols || x <= maxcols ) ) gtk_combo_box_text_append_text( combo, #x ) - D_ITEM(3); - D_ITEM(5); - D_ITEM(7); - D_ITEM(9); - D_ITEM(11); - D_ITEM(13); - D_ITEM(15); - D_ITEM(17); - D_ITEM(19); - D_ITEM(21); - D_ITEM(23); - D_ITEM(25); - D_ITEM(27); - D_ITEM(29); - D_ITEM(31); // MAX_PATCH_SIZE is 32, so we should be able to do 31... -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = height; -#define D_ITEM(x) if ( x >= minrows && ( !maxrows || x <= maxrows ) ) gtk_combo_box_text_append_text( combo, #x ) - D_ITEM(3); - D_ITEM(5); - D_ITEM(7); - D_ITEM(9); - D_ITEM(11); - D_ITEM(13); - D_ITEM(15); - D_ITEM(17); - D_ITEM(19); - D_ITEM(21); - D_ITEM(23); - D_ITEM(25); - D_ITEM(27); - D_ITEM(29); - D_ITEM(31); // MAX_PATCH_SIZE is 32, so we should be able to do 31... -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = type; -#define D_ITEM(x) gtk_combo_box_text_append_text( combo, x ) - D_ITEM("Auto"); - D_ITEM("Fixed"); - D_ITEM("Explicit"); -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - } - - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_grab_focus(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize dialog - gtk_combo_box_set_active(width, (defcols - mincols) / 2); - gtk_combo_box_set_active(height, (defrows - minrows) / 2); - gtk_combo_box_set_active(type, 0); - - if (modal_dialog_show(window, dialog) == eIDOK) { - int w = gtk_combo_box_get_active(width) * 2 + mincols; - int h = gtk_combo_box_get_active(height) * 2 + minrows; - int t = gtk_combo_box_get_active(type); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), prefab, - GlobalXYWnd_getCurrentViewType(), w, h, t); - } - - window.destroy(); -} - - -EMessageBoxReturn DoCapDlg(ECapDialog *type) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ui::Widget bevel{ui::null}; - ui::Widget ibevel{ui::null}; - ui::Widget endcap{ui::null}; - ui::Widget iendcap{ui::null}; - ui::Widget cylinder{ui::null}; - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Cap", dialog); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - - { - // Gef: Added a vbox to contain the toggle buttons - auto radio_vbox = create_dialog_vbox(4); - hbox.add(radio_vbox); - - { - auto table = ui::Table(5, 2, FALSE); - table.show(); - radio_vbox.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - { - auto image = new_local_image("cap_bevel.xpm"); - image.show(); - table.attach(image, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_endcap.xpm"); - image.show(); - table.attach(image, {0, 1, 1, 2}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_ibevel.xpm"); - image.show(); - table.attach(image, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_iendcap.xpm"); - image.show(); - table.attach(image, {0, 1, 3, 4}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_cylinder.xpm"); - image.show(); - table.attach(image, {0, 1, 4, 5}, {GTK_FILL, 0}); - } - - GSList *group = 0; - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Bevel")); - button.show(); - table.attach(button, {1, 2, 0, 1}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - bevel = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Endcap")); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - endcap = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Inverted Bevel")); - button.show(); - table.attach(button, {1, 2, 2, 3}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - ibevel = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Inverted Endcap")); - button.show(); - table.attach(button, {1, 2, 3, 4}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - iendcap = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Cylinder")); - button.show(); - table.attach(button, {1, 2, 4, 5}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - cylinder = button; - } - } - } - - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - // Initialize dialog - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bevel), TRUE); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bevel))) { - *type = PATCHCAP_BEVEL; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(endcap))) { - *type = PATCHCAP_ENDCAP; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ibevel))) { - *type = PATCHCAP_INVERTED_BEVEL; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(iendcap))) { - *type = PATCHCAP_INVERTED_ENDCAP; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cylinder))) { - *type = PATCHCAP_CYLINDER; - } - } - - window.destroy(); - - return ret; -} diff --git a/src/patchmanip.h b/src/patchmanip.h deleted file mode 100644 index 151d59c..0000000 --- a/src/patchmanip.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_PATCHMANIP_H ) -#define INCLUDED_PATCHMANIP_H - -#include -#include "string/stringfwd.h" - -void Patch_registerCommands(); - -void Patch_constructToolbar(ui::Toolbar toolbar); - -void Patch_constructMenu(ui::Menu menu); - -namespace scene { -class Graph; -} - -void Scene_PatchSetShader_Selected(scene::Graph &graph, const char *name); - -void Scene_PatchGetShader_Selected(scene::Graph &graph, CopiedString &name); - -void Scene_PatchSelectByShader(scene::Graph &graph, const char *name); - -void Scene_PatchFindReplaceShader(scene::Graph &graph, const char *find, const char *replace); - -void Scene_PatchFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_PatchCapTexture_Selected(scene::Graph &graph); - -void Scene_PatchNaturalTexture_Selected(scene::Graph &graph); - -void Scene_PatchTileTexture_Selected(scene::Graph &graph, float s, float t); - -void PatchFilters_construct(); - -void PatchPreferences_construct(); - -void Patch_registerPreferencesPage(); - -void Patch_NaturalTexture(); - -void Patch_CapTexture(); - -void Patch_ResetTexture(); - -void Patch_FitTexture(); - -void Patch_FlipTextureX(); - -void Patch_FlipTextureY(); - -void Patch_AutoCapTexture(); - -class PatchCreator; - -extern PatchCreator *g_patchCreator; - -#endif diff --git a/src/patchmodule.cpp b/src/patchmodule.cpp deleted file mode 100644 index aa9b620..0000000 --- a/src/patchmodule.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "patchmodule.h" - -#include "qerplugin.h" -#include "ipatch.h" - -#include "patch.h" -#include "patchmanip.h" - -namespace { -std::size_t g_patchModuleCount = 0; -} - -void Patch_Construct(EPatchType type) -{ - if (++g_patchModuleCount != 1) { - return; - } - - PatchFilters_construct(); - - PatchPreferences_construct(); - - Patch_registerPreferencesPage(); - - Patch::constructStatic(type); - PatchInstance::constructStatic(); - - if (type == ePatchTypeDoom3) { - MAX_PATCH_WIDTH = MAX_PATCH_HEIGHT = 99; - } else { - MAX_PATCH_WIDTH = MAX_PATCH_HEIGHT = 31; // matching q3map2 - } -} - -void Patch_Destroy() -{ - if (--g_patchModuleCount != 0) { - return; - } - - Patch::destroyStatic(); - PatchInstance::destroyStatic(); -} - -class CommonPatchCreator : public PatchCreator { -public: -void Patch_undoSave(scene::Node &patch) const -{ - Node_getPatch(patch)->undoSave(); -} - -void Patch_resize(scene::Node &patch, std::size_t width, std::size_t height) const -{ - Node_getPatch(patch)->setDims(width, height); -} - -PatchControlMatrix Patch_getControlPoints(scene::Node &node) const -{ - Patch &patch = *Node_getPatch(node); - return PatchControlMatrix(patch.getHeight(), patch.getWidth(), patch.getControlPoints().data()); -} - -void Patch_controlPointsChanged(scene::Node &patch) const -{ - return Node_getPatch(patch)->controlPointsChanged(); -} - -const char *Patch_getShader(scene::Node &patch) const -{ - return Node_getPatch(patch)->GetShader(); -} - -void Patch_setShader(scene::Node &patch, const char *shader) const -{ - Node_getPatch(patch)->SetShader(shader); -} -}; - -class Quake3PatchCreator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ - return (new PatchNodeQuake3(def3, ws))->node(); -} -}; - -Quake3PatchCreator g_Quake3PatchCreator; - -PatchCreator &GetQuake3PatchCreator() -{ - return g_Quake3PatchCreator; -} - -class Doom3PatchCreator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ //these are ALWAYS def3... - return (new PatchNodeDoom3(true, ws))->node(); -} -}; - -Doom3PatchCreator g_Doom3PatchCreator; - -PatchCreator &GetDoom3PatchCreator() -{ - return g_Doom3PatchCreator; -} - -class Doom3PatchDef2Creator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ - return (new PatchNodeDoom3(def3, ws))->node(); -} -}; - -Doom3PatchDef2Creator g_Doom3PatchDef2Creator; - -PatchCreator &GetDoom3PatchDef2Creator() -{ - return g_Doom3PatchDef2Creator; -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class PatchDependencies : - public GlobalRadiantModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalFilterModuleRef { -}; - -class PatchQuake3API : public TypeSystemRef { -PatchCreator *m_patchquake3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -PatchQuake3API() -{ - Patch_Construct(ePatchTypeQuake3); - - m_patchquake3 = &GetQuake3PatchCreator(); - g_patchCreator = m_patchquake3; -} - -~PatchQuake3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchquake3; -} -}; - -typedef SingletonModule PatchQuake3Module; -typedef Static StaticPatchQuake3Module; -StaticRegisterModule staticRegisterPatchQuake3(StaticPatchQuake3Module::instance()); - - -class PatchDoom3API : public TypeSystemRef { -PatchCreator *m_patchdoom3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "doom3"); - -PatchDoom3API() -{ - Patch_Construct(ePatchTypeDoom3); - - m_patchdoom3 = &GetDoom3PatchCreator(); -} - -~PatchDoom3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchdoom3; -} -}; - -typedef SingletonModule PatchDoom3Module; -typedef Static StaticPatchDoom3Module; -StaticRegisterModule staticRegisterPatchDoom3(StaticPatchDoom3Module::instance()); - - -class PatchDef2Doom3API : public TypeSystemRef { -PatchCreator *m_patchdef2doom3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "def2doom3"); - -PatchDef2Doom3API() -{ - Patch_Construct(ePatchTypeDoom3); - - m_patchdef2doom3 = &GetDoom3PatchDef2Creator(); - g_patchCreator = m_patchdef2doom3; -} - -~PatchDef2Doom3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchdef2doom3; -} -}; - -typedef SingletonModule PatchDef2Doom3Module; -typedef Static StaticPatchDef2Doom3Module; -StaticRegisterModule staticRegisterPatchDef2Doom3(StaticPatchDef2Doom3Module::instance()); diff --git a/src/patchmodule.h b/src/patchmodule.h deleted file mode 100644 index c97cb7f..0000000 --- a/src/patchmodule.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PATCHMODULE_H ) -#define INCLUDED_PATCHMODULE_H - -#endif diff --git a/tools/vmap/path_init.c b/src/path_init.c similarity index 100% rename from tools/vmap/path_init.c rename to src/path_init.c diff --git a/src/plugin.cpp b/src/plugin.cpp deleted file mode 100644 index 8de23e7..0000000 --- a/src/plugin.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugin.h" - -#include "debugging/debugging.h" - -#include "qerplugin.h" -#include "ifilesystem.h" -#include "ishaders.h" -#include "ientity.h" -#include "ieclass.h" -#include "irender.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "ifilter.h" -#include "iscriplib.h" -#include "igl.h" -#include "iundo.h" -#include "itextures.h" -#include "ireference.h" -#include "ifiletypes.h" -#include "preferencesystem.h" -#include "ibrush.h" -#include "ipatch.h" -#include "iimage.h" -#include "itoolbar.h" -#include "iplugin.h" -#include "imap.h" -#include "namespace.h" - -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" -#include "maplib.h" - -#include "error.h" -#include "map.h" -#include "qe3.h" -#include "entityinspector.h" -#include "entitylist.h" -#include "points.h" -#include "gtkmisc.h" -#include "texwindow.h" -#include "mainframe.h" -#include "build.h" -#include "mru.h" -#include "multimon.h" -#include "surfacedialog.h" -#include "groupdialog.h" -#include "patchdialog.h" -#include "camwindow.h" -#include "watchbsp.h" -#include "xywindow.h" -#include "entity.h" -#include "select.h" -#include "preferences.h" -#include "autosave.h" -#include "plugintoolbar.h" -#include "findtexturedialog.h" -#include "nullmodel.h" -#include "grid.h" - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" - -#include "generic/callback.h" - -const char *GameDescription_getKeyValue(const char *key) -{ - return g_pGameDescription->getKeyValue(key); -} - -const char *GameDescription_getRequiredKeyValue(const char *key) -{ - return g_pGameDescription->getRequiredKeyValue(key); -} - -const char *getMapName() -{ - return Map_Name(g_map); -} - -scene::Node &getMapWorldEntity() -{ - return Map_FindOrInsertWorldspawn(g_map); -} - -VIEWTYPE XYWindow_getViewType() -{ - return g_pParentWnd->GetXYWnd()->GetViewType(); -} - -Vector3 XYWindow_windowToWorld(const WindowVector &position) -{ - Vector3 result(0, 0, 0); - g_pParentWnd->GetXYWnd()->XY_ToPoint(static_cast( position.x()), static_cast( position.y()), result); - return result; -} - -const char *TextureBrowser_getSelectedShader() -{ - return TextureBrowser_GetSelectedShader(GlobalTextureBrowser()); -} - -const char *getGameFile() -{ - return g_GamesDialog.m_sGameFile.c_str(); -} - -class RadiantCoreAPI { -_QERFuncTable_1 m_radiantcore; -public: -typedef _QERFuncTable_1 Type; - -STRING_CONSTANT(Name, "*"); - -RadiantCoreAPI() -{ - m_radiantcore.getEnginePath = &EnginePath_get; - m_radiantcore.getLocalRcPath = &LocalRcPath_get; - m_radiantcore.getAppPath = &AppPath_get; - m_radiantcore.getGameToolsPath = &GameToolsPath_get; - m_radiantcore.getSettingsPath = &SettingsPath_get; - m_radiantcore.getMapsPath = &getMapsPath; - - m_radiantcore.getGameFile = &getGameFile; - m_radiantcore.getGameName = &gamename_get; - m_radiantcore.getGameMode = &gamemode_get; - - m_radiantcore.getMapName = &getMapName; - m_radiantcore.getMapWorldEntity = getMapWorldEntity; - m_radiantcore.getGridSize = GetGridSize; - - m_radiantcore.getGameDescriptionKeyValue = &GameDescription_getKeyValue; - m_radiantcore.getRequiredGameDescriptionKeyValue = &GameDescription_getRequiredKeyValue; - - m_radiantcore.XYWindowDestroyed_connect = XYWindowDestroyed_connect; - m_radiantcore.XYWindowDestroyed_disconnect = XYWindowDestroyed_disconnect; - m_radiantcore.XYWindowMouseDown_connect = XYWindowMouseDown_connect; - m_radiantcore.XYWindowMouseDown_disconnect = XYWindowMouseDown_disconnect; - m_radiantcore.XYWindow_getViewType = XYWindow_getViewType; - m_radiantcore.XYWindow_windowToWorld = XYWindow_windowToWorld; - m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_getSelectedShader; - - m_radiantcore.m_pfnMessageBox = >k_MessageBox; - m_radiantcore.m_pfnFileDialog = &file_dialog; - m_radiantcore.m_pfnColorDialog = &color_dialog; - m_radiantcore.m_pfnDirDialog = &dir_dialog; - m_radiantcore.m_pfnNewImage = &new_plugin_image; -} - -_QERFuncTable_1 *getTable() -{ - return &m_radiantcore; -} -}; - -typedef SingletonModule RadiantCoreModule; -typedef Static StaticRadiantCoreModule; -StaticRegisterModule staticRegisterRadiantCore(StaticRadiantCoreModule::instance()); - - -class RadiantDependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalEntityModuleRef, - public GlobalShadersModuleRef, - public GlobalBrushModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalFiletypesModuleRef, - public GlobalSelectionModuleRef, - public GlobalReferenceModuleRef, - public GlobalOpenGLModuleRef, - public GlobalEntityClassManagerModuleRef, - public GlobalUndoModuleRef, - public GlobalScripLibModuleRef, - public GlobalNamespaceModuleRef { -ImageModulesRef m_image_modules; -MapModulesRef m_map_modules; -ToolbarModulesRef m_toolbar_modules; -PluginModulesRef m_plugin_modules; - -public: -RadiantDependencies() : - GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities")), - GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")), - GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")), - GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")), - m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")), - m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")), - m_toolbar_modules("*"), - m_plugin_modules("*") -{ -} - -ImageModules &getImageModules() -{ - return m_image_modules.get(); -} - -MapModules &getMapModules() -{ - return m_map_modules.get(); -} - -ToolbarModules &getToolbarModules() -{ - return m_toolbar_modules.get(); -} - -PluginModules &getPluginModules() -{ - return m_plugin_modules.get(); -} -}; - -class Radiant : public TypeSystemRef { -public: -Radiant() -{ - Preferences_Init(); - - GlobalFiletypes().addType("sound", "wav", filetype_t("PCM sound files", "*.wav")); - - Selection_construct(); - VFS_Construct(); - Grid_construct(); - MultiMon_Construct(); - MRU_Construct(); - Pointfile_Construct(); - GLWindow_Construct(); - BuildMenu_Construct(); - Map_Construct(); - EntityList_Construct(); - MainFrame_Construct(); - GroupDialog_Construct(); - SurfaceInspector_Construct(); - PatchInspector_Construct(); - CamWnd_Construct(); - XYWindow_Construct(); - BuildMonitor_Construct(); - TextureBrowser_Construct(); - Entity_Construct(); - Autosave_Construct(); - EntityInspector_construct(); - FindTextureDialog_Construct(); - NullModel_construct(); - MapRoot_construct(); - - EnginePath_verify(); - EnginePath_Realise(); -} - -~Radiant() -{ - EnginePath_Unrealise(); - - MapRoot_destroy(); - NullModel_destroy(); - FindTextureDialog_Destroy(); - EntityInspector_destroy(); - Autosave_Destroy(); - Entity_Destroy(); - TextureBrowser_Destroy(); - BuildMonitor_Destroy(); - XYWindow_Destroy(); - CamWnd_Destroy(); - PatchInspector_Destroy(); - SurfaceInspector_Destroy(); - GroupDialog_Destroy(); - MainFrame_Destroy(); - EntityList_Destroy(); - Map_Destroy(); - BuildMenu_Destroy(); - GLWindow_Destroy(); - Pointfile_Destroy(); - MRU_Destroy(); - MultiMon_Destroy(); - Grid_destroy(); - VFS_Destroy(); - Selection_destroy(); -} -}; - -namespace { -bool g_RadiantInitialised = false; -RadiantDependencies *g_RadiantDependencies; -Radiant *g_Radiant; -} - - -bool Radiant_Construct(ModuleServer &server) -{ - GlobalModuleServer::instance().set(server); - StaticModuleRegistryList().instance().registerModules(); - - g_RadiantDependencies = new RadiantDependencies(); - - g_RadiantInitialised = !server.getError(); - - if (g_RadiantInitialised) { - g_Radiant = new Radiant; - } - - return g_RadiantInitialised; -} - -void Radiant_Destroy() -{ - if (g_RadiantInitialised) { - delete g_Radiant; - } - - delete g_RadiantDependencies; -} - -ImageModules &Radiant_getImageModules() -{ - return g_RadiantDependencies->getImageModules(); -} - -MapModules &Radiant_getMapModules() -{ - return g_RadiantDependencies->getMapModules(); -} - -ToolbarModules &Radiant_getToolbarModules() -{ - return g_RadiantDependencies->getToolbarModules(); -} - -PluginModules &Radiant_getPluginModules() -{ - return g_RadiantDependencies->getPluginModules(); -} diff --git a/src/plugin.h b/src/plugin.h deleted file mode 100644 index 4b0992a..0000000 --- a/src/plugin.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGIN_H ) -#define INCLUDED_PLUGIN_H - -class ModuleServer; - -bool Radiant_Construct(ModuleServer &server); - -void Radiant_Destroy(); - - -template -class Modules; - -struct _QERPlugImageTable; -typedef Modules<_QERPlugImageTable> ImageModules; - -ImageModules &Radiant_getImageModules(); - -class MapFormat; - -typedef Modules MapModules; - -MapModules &Radiant_getMapModules(); - -struct _QERPlugToolbarTable; -typedef Modules<_QERPlugToolbarTable> ToolbarModules; - -ToolbarModules &Radiant_getToolbarModules(); - -struct _QERPluginTable; -typedef Modules<_QERPluginTable> PluginModules; - -PluginModules &Radiant_getPluginModules(); - - -#endif diff --git a/src/pluginapi.cpp b/src/pluginapi.cpp deleted file mode 100644 index aca5a06..0000000 --- a/src/pluginapi.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pluginapi.h" - -#include "modulesystem.h" -#include "qerplugin.h" - -#include "generic/callback.h" -#include "math/vector.h" - -#include "gtkmisc.h" - -#include "camwindow.h" - -#include "mainframe.h" - - -// camera API -void QERApp_GetCamera(Vector3 &origin, Vector3 &angles) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - origin = Camera_getOrigin(camwnd); - angles = Camera_getAngles(camwnd); -} - -void QERApp_SetCamera(const Vector3 &origin, const Vector3 &angles) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, origin); - Camera_setAngles(camwnd, angles); -} - -void QERApp_GetCamWindowExtents(int *x, int *y, int *width, int *height) -{ -#if 0 - CamWnd* camwnd = g_pParentWnd->GetCamWnd(); - - gtk_window_get_position( camwnd->m_window, x, y ); - - *width = camwnd->Camera()->width; - *height = camwnd->Camera()->height; -#endif -} - -#include "icamera.h" - -class CameraAPI { -_QERCameraTable m_camera; -public: -typedef _QERCameraTable Type; - -STRING_CONSTANT(Name, "*"); - -CameraAPI() -{ - m_camera.m_pfnGetCamera = &QERApp_GetCamera; - m_camera.m_pfnSetCamera = &QERApp_SetCamera; - m_camera.m_pfnGetCamWindowExtents = &QERApp_GetCamWindowExtents; -} - -_QERCameraTable *getTable() -{ - return &m_camera; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule CameraModule; -typedef Static StaticCameraModule; -StaticRegisterModule staticRegisterCamera(StaticCameraModule::instance()); diff --git a/src/pluginapi.h b/src/pluginapi.h deleted file mode 100644 index f145c09..0000000 --- a/src/pluginapi.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGINAPI_H ) -#define INCLUDED_PLUGINAPI_H - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -// camera API -void QERApp_GetCamera(Vector3 &origin, Vector3 &angles); - -void QERApp_SetCamera(const Vector3 &origin, const Vector3 &angles); - -void QERApp_GetCamWindowExtents(int *x, int *y, int *width, int *height); - -#endif diff --git a/src/pluginmanager.cpp b/src/pluginmanager.cpp deleted file mode 100644 index fe9e694..0000000 --- a/src/pluginmanager.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// PlugInManager.cpp: implementation of the CPlugInManager class. -// -////////////////////////////////////////////////////////////////////// - -#include "pluginmanager.h" - -#include "modulesystem.h" -#include "qerplugin.h" -#include "iplugin.h" - -#include "math/vector.h" -#include "string/string.h" - -#include "error.h" -#include "select.h" -#include "plugin.h" - -#include "modulesystem.h" - -#include - -/* plugin manager --------------------------------------- */ -class CPluginSlot : public IPlugIn { -CopiedString m_menu_name; -const _QERPluginTable *mpTable; -std::list m_CommandStrings; -std::list m_CommandTitleStrings; -std::list m_CommandIDs; - -public: -/*! - build directly from a SYN_PROVIDE interface - */ -CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table); - -/*! - dispatching a command by name to the plugin - */ -void Dispatch(const char *p); - -// IPlugIn ------------------------------------------------------------ -const char *getMenuName(); - -std::size_t getCommandCount(); - -const char *getCommand(std::size_t n); - -const char *getCommandTitle(std::size_t n); - -void addMenuID(std::size_t n); - -bool ownsCommandID(std::size_t n); - -}; - -CPluginSlot::CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) -{ - mpTable = &table; - m_menu_name = name; - - const char *commands = mpTable->m_pfnQERPlug_GetCommandList(); - const char *titles = mpTable->m_pfnQERPlug_GetCommandTitleList(); - - StringTokeniser commandTokeniser(commands, ",;"); - StringTokeniser titleTokeniser(titles, ",;"); - - const char *cmdToken = commandTokeniser.getToken(); - const char *titleToken = titleTokeniser.getToken(); - while (!string_empty(cmdToken)) { - if (string_empty(titleToken)) { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(cmdToken); - cmdToken = commandTokeniser.getToken(); - titleToken = ""; - } else { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(titleToken); - cmdToken = commandTokeniser.getToken(); - titleToken = titleTokeniser.getToken(); - } - } - mpTable->m_pfnQERPlug_Init(0, (void *) main_window); -} - -const char *CPluginSlot::getMenuName() -{ - return m_menu_name.c_str(); -} - -std::size_t CPluginSlot::getCommandCount() -{ - return m_CommandStrings.size(); -} - -const char *CPluginSlot::getCommand(std::size_t n) -{ - std::list::iterator i = m_CommandStrings.begin(); - while (n-- != 0) { - ++i; - } - return (*i).c_str(); -} - -const char *CPluginSlot::getCommandTitle(std::size_t n) -{ - std::list::iterator i = m_CommandTitleStrings.begin(); - while (n-- != 0) { - ++i; - } - return (*i).c_str(); -} - -void CPluginSlot::addMenuID(std::size_t n) -{ - m_CommandIDs.push_back(n); -} - -bool CPluginSlot::ownsCommandID(std::size_t n) -{ - for (std::list::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i) { - if (*i == n) { - return true; - } - } - return false; -} - -void CPluginSlot::Dispatch(const char *p) -{ - Vector3 vMin, vMax; - Select_GetBounds(vMin, vMax); - mpTable->m_pfnQERPlug_Dispatch(p, reinterpret_cast( &vMin ), reinterpret_cast( &vMax ), - true); //QE_SingleBrush(true)); -} - - -class CPluginSlots { -std::list mSlots; -public: -virtual ~CPluginSlots(); - -void AddPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) -{ - mSlots.push_back(new CPluginSlot(main_window, name, table)); -} - -void PopulateMenu(PluginsVisitor &menu); - -bool Dispatch(std::size_t n, const char *p); -}; - -CPluginSlots::~CPluginSlots() -{ - std::list::iterator iSlot; - for (iSlot = mSlots.begin(); iSlot != mSlots.end(); ++iSlot) { - delete *iSlot; - *iSlot = 0; - } -} - -void CPluginSlots::PopulateMenu(PluginsVisitor &menu) -{ - std::list::iterator iPlug; - for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { - menu.visit(*(*iPlug)); - } -} - -bool CPluginSlots::Dispatch(std::size_t n, const char *p) -{ - std::list::iterator iPlug; - for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { - CPluginSlot *pPlug = *iPlug; - if (pPlug->ownsCommandID(n)) { - pPlug->Dispatch(p); - return true; - } - } - return false; -} - -CPluginSlots g_plugin_slots; - - -void FillPluginSlots(CPluginSlots &slots, ui::Widget main_window) -{ - class AddPluginVisitor : public PluginModules::Visitor { - CPluginSlots &m_slots; - ui::Widget m_main_window; -public: - AddPluginVisitor(CPluginSlots &slots, ui::Widget main_window) - : m_slots(slots), m_main_window(main_window) - { - } - - void visit(const char *name, const _QERPluginTable &table) const - { - m_slots.AddPluginSlot(m_main_window, name, table); - } - } visitor(slots, main_window); - - Radiant_getPluginModules().foreachModule(visitor); -} - - -#include "pluginmanager.h" - -CPlugInManager g_PlugInMgr; - -CPlugInManager &GetPlugInMgr() -{ - return g_PlugInMgr; -} - -void CPlugInManager::Dispatch(std::size_t n, const char *p) -{ - g_plugin_slots.Dispatch(n, p); -} - -void CPlugInManager::Init(ui::Widget main_window) -{ - FillPluginSlots(g_plugin_slots, main_window); -} - -void CPlugInManager::constructMenu(PluginsVisitor &menu) -{ - g_plugin_slots.PopulateMenu(menu); -} - -void CPlugInManager::Shutdown() -{ -} diff --git a/src/pluginmanager.h b/src/pluginmanager.h deleted file mode 100644 index af8c096..0000000 --- a/src/pluginmanager.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGINMANAGER_H ) -#define INCLUDED_PLUGINMANAGER_H - -#include -#include - - -/*! - \class IPlugin - pure virtual interface for a plugin - temporary solution for migration from old plugin tech to synapse plugins - */ -class IPlugIn { -public: -IPlugIn() -{ -} - -virtual ~IPlugIn() -{ -} - -virtual const char *getMenuName() = 0; - -virtual std::size_t getCommandCount() = 0; - -virtual const char *getCommand(std::size_t) = 0; - -virtual const char *getCommandTitle(std::size_t) = 0; - -virtual void addMenuID(std::size_t) = 0; - -virtual bool ownsCommandID(std::size_t n) = 0; -}; - -class PluginsVisitor { -public: -virtual void visit(IPlugIn &plugin) = 0; -}; - -class CPlugInManager { -public: -void Dispatch(std::size_t n, const char *p); - -void Init(ui::Widget main_window); - -void constructMenu(PluginsVisitor &menu); - -void Shutdown(); -}; - -CPlugInManager &GetPlugInMgr(); - -#endif diff --git a/src/pluginmenu.cpp b/src/pluginmenu.cpp deleted file mode 100644 index 2db4bf1..0000000 --- a/src/pluginmenu.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pluginmenu.h" - -#include - -#include "stream/textstream.h" - -#include "gtkutil/pointer.h" -#include "gtkutil/menu.h" - -#include "pluginmanager.h" -#include "mainframe.h" -#include "preferences.h" - - -int m_nNextPlugInID = 0; - -void plugin_activated(ui::Widget widget, gpointer data) -{ - const char *str = (const char *) g_object_get_data(G_OBJECT(widget), "command"); - GetPlugInMgr().Dispatch(gpointer_to_int(data), str); -} - -#include - -void PlugInMenu_Add(ui::Menu plugin_menu, IPlugIn *pPlugIn) -{ - ui::Widget item{ui::null}, parent{ui::null}; - ui::Menu menu{ui::null}, subMenu{ui::null}; - const char *menuText, *menuCommand; - std::stack menuStack; - - parent = ui::MenuItem(pPlugIn->getMenuName()); - parent.show(); - plugin_menu.add(parent); - - std::size_t nCount = pPlugIn->getCommandCount(); - if (nCount > 0) { - menu = ui::Menu(ui::New); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - while (nCount > 0) { - menuText = pPlugIn->getCommandTitle(--nCount); - menuCommand = pPlugIn->getCommand(nCount); - - if (menuText != 0 && strlen(menuText) > 0) { - if (!strcmp(menuText, "-")) { - item = ui::Widget::from(gtk_menu_item_new()); - gtk_widget_set_sensitive(item, FALSE); - } else if (!strcmp(menuText, ">")) { - menuText = pPlugIn->getCommandTitle(--nCount); - menuCommand = pPlugIn->getCommand(nCount); - if (!strcmp(menuText, "-") || !strcmp(menuText, ">") || !strcmp(menuText, "<")) { - globalErrorStream() << pPlugIn->getMenuName() << " Invalid title (" << menuText - << ") for submenu.\n"; - continue; - } - - item = ui::MenuItem(menuText); - item.show(); - menu.add(item); - - subMenu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), subMenu); - menuStack.push(menu); - menu = subMenu; - continue; - } else if (!strcmp(menuText, "<")) { - if (!menuStack.empty()) { - menu = menuStack.top(); - menuStack.pop(); - } else { - globalErrorStream() << pPlugIn->getMenuName() - << ": Attempt to end non-existent submenu ignored.\n"; - } - continue; - } else { - item = ui::MenuItem(menuText); - g_object_set_data(G_OBJECT(item), "command", - const_cast( static_cast( menuCommand ))); - item.connect("activate", G_CALLBACK(plugin_activated), gint_to_pointer(m_nNextPlugInID)); - } - item.show(); - menu.add(item); - pPlugIn->addMenuID(m_nNextPlugInID++); - } - } - if (!menuStack.empty()) { - std::size_t size = menuStack.size(); - if (size != 0) { - globalErrorStream() << pPlugIn->getMenuName() << " mismatched > <. " << Unsigned(size) - << " submenu(s) not closed.\n"; - } - for (std::size_t i = 0; i < (size - 1); i++) { - menuStack.pop(); - } - menu = menuStack.top(); - menuStack.pop(); - } - gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), menu); - } -} - -ui::Menu g_plugins_menu{ui::null}; -ui::MenuItem g_plugins_menu_separator{ui::null}; - -void PluginsMenu_populate() -{ - class PluginsMenuConstructor : public PluginsVisitor { - ui::Menu m_menu; -public: - PluginsMenuConstructor(ui::Menu menu) : m_menu(menu) - { - } - - void visit(IPlugIn &plugin) - { - PlugInMenu_Add(m_menu, &plugin); - } - }; - - PluginsMenuConstructor constructor(g_plugins_menu); - GetPlugInMgr().constructMenu(constructor); -} - -void PluginsMenu_clear() -{ - m_nNextPlugInID = 0; - - GList *lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), - g_plugins_menu_separator._handle); - while (lst->next) { - g_plugins_menu.remove(ui::Widget::from(lst->next->data)); - lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), g_plugins_menu_separator._handle); - } -} - -ui::MenuItem create_plugins_menu() -{ - // Plugins menu - auto plugins_menu_item = new_sub_menu_item_with_mnemonic("_Plugins"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(plugins_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - g_plugins_menu = menu; - - //TODO: some modules/plugins do not yet support refresh -#if 0 - create_menu_item_with_mnemonic( menu, "Refresh", makeCallbackF(Restart) ); - - // NOTE: the seperator is used when doing a refresh of the list, everything past the seperator is removed - g_plugins_menu_separator = menu_separator( menu ); -#endif - - PluginsMenu_populate(); - - return plugins_menu_item; -} diff --git a/src/pluginmenu.h b/src/pluginmenu.h deleted file mode 100644 index 1d2f8b6..0000000 --- a/src/pluginmenu.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PLUGINMENU_H ) -#define INCLUDED_PLUGINMENU_H - -ui::MenuItem create_plugins_menu(); - -void PluginsMenu_populate(); - -void PluginsMenu_clear(); - -#endif diff --git a/src/plugintoolbar.cpp b/src/plugintoolbar.cpp deleted file mode 100644 index f0c5b49..0000000 --- a/src/plugintoolbar.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugintoolbar.h" - -#include - -#include "itoolbar.h" -#include "modulesystem.h" - -#include "stream/stringstream.h" -#include "gtkutil/image.h" -#include "gtkutil/container.h" - -#include "mainframe.h" -#include "plugin.h" - -ui::Image new_plugin_image(const char *filename) -{ - { - StringOutputStream fullpath(256); - fullpath << GameToolsPath_get() << g_pluginsDir << "bitmaps/" << filename; - if (auto image = image_new_from_file_with_mask(fullpath.c_str())) { return image; } - } - - { - StringOutputStream fullpath(256); - fullpath << AppPath_get() << g_pluginsDir << "bitmaps/" << filename; - if (auto image = image_new_from_file_with_mask(fullpath.c_str())) { return image; } - } - - return image_new_missing(); -} - -void -toolbar_insert(ui::Toolbar toolbar, const char *icon, const char *text, const char *tooltip, IToolbarButton::EType type, - GCallback handler, gpointer data) -{ - if (type == IToolbarButton::eSpace) { - auto it = ui::ToolItem::from(gtk_separator_tool_item_new()); - it.show(); - toolbar.add(it); - return; - } - if (type == IToolbarButton::eButton) { - auto button = ui::ToolButton::from(gtk_tool_button_new(new_plugin_image(icon), text)); - gtk_widget_set_tooltip_text(button, tooltip); - gtk_widget_show_all(button); - button.connect("clicked", G_CALLBACK(handler), data); - toolbar.add(button); - return; - } - if (type == IToolbarButton::eToggleButton) { - auto button = ui::ToolButton::from(gtk_toggle_tool_button_new()); - gtk_tool_button_set_icon_widget(button, new_plugin_image(icon)); - gtk_tool_button_set_label(button, text); - gtk_widget_set_tooltip_text(button, tooltip); - gtk_widget_show_all(button); - button.connect("toggled", G_CALLBACK(handler), data); - toolbar.add(button); - return; - } - ERROR_MESSAGE("invalid toolbar button type"); -} - -void ActivateToolbarButton(ui::ToolButton widget, gpointer data) -{ - (const_cast( reinterpret_cast( data )))->activate(); -} - -void PlugInToolbar_AddButton(ui::Toolbar toolbar, const IToolbarButton *button) -{ - toolbar_insert(toolbar, button->getImage(), button->getText(), button->getTooltip(), button->getType(), - G_CALLBACK(ActivateToolbarButton), - reinterpret_cast( const_cast( button ))); -} - -ui::Toolbar g_plugin_toolbar{ui::null}; - -void PluginToolbar_populate() -{ - class AddToolbarItemVisitor : public ToolbarModules::Visitor { - ui::Toolbar m_toolbar; -public: - AddToolbarItemVisitor(ui::Toolbar toolbar) - : m_toolbar(toolbar) - { - } - - void visit(const char *name, const _QERPlugToolbarTable &table) const - { - const std::size_t count = table.m_pfnToolbarButtonCount(); - for (std::size_t i = 0; i < count; ++i) { - PlugInToolbar_AddButton(m_toolbar, table.m_pfnGetToolbarButton(i)); - } - } - - } visitor(g_plugin_toolbar); - - Radiant_getToolbarModules().foreachModule(visitor); -} - -void PluginToolbar_clear() -{ - container_remove_all(g_plugin_toolbar); -} - -ui::Toolbar create_plugin_toolbar() -{ - - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - toolbar.show(); - - g_plugin_toolbar = toolbar; - - PluginToolbar_populate(); - - return toolbar; -} - -/* blerugh - eukara */ -void PluginToolbar_AddToMain(ui::Toolbar toolbar) -{ - - g_plugin_toolbar = toolbar; - - PluginToolbar_populate(); -} diff --git a/src/plugintoolbar.h b/src/plugintoolbar.h deleted file mode 100644 index 9445cdf..0000000 --- a/src/plugintoolbar.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PLUGINTOOLBAR_H ) -#define INCLUDED_PLUGINTOOLBAR_H - -ui::Toolbar create_plugin_toolbar(); - -void PluginToolbar_populate(); - -void PluginToolbar_clear(); - -ui::Image new_plugin_image(const char *filename); // filename is relative to plugin bitmaps path - -#endif diff --git a/src/points.cpp b/src/points.cpp deleted file mode 100644 index 650a1fc..0000000 --- a/src/points.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -#include "points.h" - -#include "debugging/debugging.h" - -#include "irender.h" -#include "igl.h" -#include "renderable.h" - -#include "stream/stringstream.h" -#include "os/path.h" -#include "os/file.h" -#include "cmdlib.h" - -#include "map.h" -#include "qe3.h" -#include "camwindow.h" -#include "xywindow.h" -#include "xmlstuff.h" -#include "mainframe.h" -#include "watchbsp.h" -#include "commands.h" - - -class CPointfile; - -void Pointfile_Parse(CPointfile &pointfile); - - -class CPointfile : public ISAXHandler, public Renderable, public OpenGLRenderable { -enum { - MAX_POINTFILE = 8192, -}; -Vector3 s_pointvecs[MAX_POINTFILE]; -std::size_t s_num_points; -int m_displaylist; -static Shader *m_renderstate; -StringOutputStream m_characters; -public: -CPointfile() -{ -} - -~CPointfile() -{ -} - -void Init(); - -void PushPoint(const Vector3 &v); - -void GenerateDisplayList(); - -// SAX interface -void Release() -{ - // blank because not heap-allocated -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -const char *getName(); - -typedef const Vector3 *const_iterator; - -const_iterator begin() const -{ - return &s_pointvecs[0]; -} - -const_iterator end() const -{ - return &s_pointvecs[s_num_points]; -} - -bool shown() const -{ - return m_displaylist != 0; -} - -void show(bool show) -{ - if (show && !shown()) { - Pointfile_Parse(*this); - GenerateDisplayList(); - SceneChangeNotify(); - } else if (!show && shown()) { - glDeleteLists(m_displaylist, 1); - m_displaylist = 0; - SceneChangeNotify(); - } -} - -void render(RenderStateFlags state) const -{ - glCallList(m_displaylist); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - if (shown()) { - renderer.SetState(m_renderstate, Renderer::eWireframeOnly); - renderer.SetState(m_renderstate, Renderer::eFullMaterials); - renderer.addRenderable(*this, g_matrix4_identity); - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -static void constructStatic() -{ - m_renderstate = GlobalShaderCache().capture("$POINTFILE"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$POINTFILE"); -} -}; - -Shader *CPointfile::m_renderstate = 0; - -namespace { -CPointfile s_pointfile; -} - -ISAXHandler &g_pointfile = s_pointfile; - -static CPointfile::const_iterator s_check_point; - -void CPointfile::Init() -{ - s_num_points = 0; - m_displaylist = 0; -} - -void CPointfile::PushPoint(const Vector3 &v) -{ - if (s_num_points < MAX_POINTFILE) { - s_pointvecs[s_num_points] = v; - ++s_num_points; - } -} - -// create the display list at the end -void CPointfile::GenerateDisplayList() -{ - m_displaylist = glGenLists(1); - - glNewList(m_displaylist, GL_COMPILE); - - glBegin(GL_LINE_STRIP); - for (std::size_t i = 0; i < s_num_points; i++) - glVertex3fv(vector3_to_array(s_pointvecs[i])); - glEnd(); - glLineWidth(1); - - glEndList(); -} - -// old (but still relevant) pointfile code ------------------------------------- - -void Pointfile_Delete(void) -{ - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".lin"; - file_remove(name.c_str()); -} - -// advance camera to next point -void Pointfile_Next(void) -{ - if (!s_pointfile.shown()) { - return; - } - - if (s_check_point + 2 == s_pointfile.end()) { - globalOutputStream() << "End of pointfile\n"; - return; - } - - CPointfile::const_iterator i = ++s_check_point; - - - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, *i); - g_pParentWnd->GetXYWnd()->SetOrigin(*i); - { - Vector3 dir(vector3_normalised(vector3_subtracted(*(++i), Camera_getOrigin(camwnd)))); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_YAW] = static_cast( radians_to_degrees(atan2(dir[1], dir[0]))); - angles[CAMERA_PITCH] = static_cast( radians_to_degrees(asin(dir[2]))); - Camera_setAngles(camwnd, angles); - } -} - -// advance camera to previous point -void Pointfile_Prev(void) -{ - if (!s_pointfile.shown()) { - return; - } - - if (s_check_point == s_pointfile.begin()) { - globalOutputStream() << "Start of pointfile\n"; - return; - } - - CPointfile::const_iterator i = --s_check_point; - - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, *i); - g_pParentWnd->GetXYWnd()->SetOrigin(*i); - { - Vector3 dir(vector3_normalised(vector3_subtracted(*(++i), Camera_getOrigin(camwnd)))); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_YAW] = static_cast( radians_to_degrees(atan2(dir[1], dir[0]))); - angles[CAMERA_PITCH] = static_cast( radians_to_degrees(asin(dir[2]))); - Camera_setAngles(camwnd, angles); - } -} - -int LoadFile(const char *filename, void **bufferptr) -{ - FILE *f; - long len; - - f = fopen(filename, "rb"); - if (f == 0) { - return -1; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - rewind(f); - - *bufferptr = malloc(len + 1); - if (*bufferptr == 0) { - return -1; - } - - fread(*bufferptr, 1, len, f); - fclose(f); - - // we need to end the buffer with a 0 - ((char *) (*bufferptr))[len] = 0; - - return len; -} - -void Pointfile_Parse(CPointfile &pointfile) -{ - int size; - char *data; - char *text; - int line = 1; - - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".lin"; - - size = LoadFile(name.c_str(), (void **) &data); - if (size == -1) { - globalErrorStream() << "Pointfile " << name.c_str() << " not found\n"; - return; - } - - // store a pointer - text = data; - - globalOutputStream() << "Reading pointfile " << name.c_str() << "\n"; - - pointfile.Init(); - - while (*data) { - Vector3 v; - if (sscanf(data, "%f %f %f", &v[0], &v[1], &v[2]) != 3) { - globalOutputStream() << "Corrupt point file, line " << line << "\n"; - break; - } - - while (*data && *data != '\n') { - if (*(data - 1) == ' ' && *(data) == '-' && *(data + 1) == ' ') { - break; - } - data++; - } - // deal with zhlt style point files. - if (*data == '-') { - if (sscanf(data, "- %f %f %f", &v[0], &v[1], &v[2]) != 3) { - globalOutputStream() << "Corrupt point file, line " << line << "\n"; - break; - } - - while (*data && *data != '\n') { - data++; - } - - } - while (*data == '\n') { - data++; // skip the \n - line++; - } - pointfile.PushPoint(v); - } - - g_free(text); -} - -void Pointfile_Clear() -{ - s_pointfile.show(false); -} - -void Pointfile_Toggle() -{ - s_pointfile.show(!s_pointfile.shown()); - - s_check_point = s_pointfile.begin(); -} - -void Pointfile_Construct() -{ - CPointfile::constructStatic(); - - GlobalShaderCache().attachRenderable(s_pointfile); - - GlobalCommands_insert("TogglePointfile", makeCallbackF(Pointfile_Toggle)); - GlobalCommands_insert("NextLeakSpot", makeCallbackF(Pointfile_Next), - Accelerator('K', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PrevLeakSpot", makeCallbackF(Pointfile_Prev), - Accelerator('L', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); -} - -void Pointfile_Destroy() -{ - GlobalShaderCache().detachRenderable(s_pointfile); - - CPointfile::destroyStatic(); -} - - -// CPointfile implementation for SAX-specific stuff ------------------------------- -void CPointfile::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "polyline")) { - Init(); - // there's a prefs setting to avoid stopping on leak - if (!g_WatchBSP_LeakStop) { - ctx->stop_depth = 0; - } - } -} - -void CPointfile::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "polyline")) { - // we are done - GenerateDisplayList(); - SceneChangeNotify(); - s_check_point = begin(); - } else if (string_equal(reinterpret_cast( name ), "point")) { - Vector3 v; - sscanf(m_characters.c_str(), "%f %f %f\n", &v[0], &v[1], &v[2]); - PushPoint(v); - m_characters.clear(); - } -} - -// only "point" is expected to have characters around here -void CPointfile::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - m_characters.write(reinterpret_cast( ch ), len); -} - -const char *CPointfile::getName() -{ - return "Map leaked"; -} diff --git a/src/points.h b/src/points.h deleted file mode 100644 index 449af54..0000000 --- a/src/points.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// header for Pointfile stuff (adding a C++ class to wrap the pointfile thing in the SAX parser) -// - -#if !defined( INCLUDED_POINTS_H ) -#define INCLUDED_POINTS_H - -void Pointfile_Clear(); - -void Pointfile_Delete(void); - -void Pointfile_Construct(); - -void Pointfile_Destroy(); - -class ISAXHandler; - -extern ISAXHandler &g_pointfile; - -#endif diff --git a/tools/vmap/portals.c b/src/portals.c similarity index 100% rename from tools/vmap/portals.c rename to src/portals.c diff --git a/src/preferencedictionary.cpp b/src/preferencedictionary.cpp deleted file mode 100644 index 08ca943..0000000 --- a/src/preferencedictionary.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "preferencedictionary.h" diff --git a/src/preferencedictionary.h b/src/preferencedictionary.h deleted file mode 100644 index be1f69f..0000000 --- a/src/preferencedictionary.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PREFERENCEDICTIONARY_H ) -#define INCLUDED_PREFERENCEDICTIONARY_H - -#include "preferencesystem.h" -#include "xml/ixml.h" -#include "stream/stringstream.h" -#include "generic/callback.h" -#include "versionlib.h" -#include - -class PreferenceDictionary : public PreferenceSystem { -class PreferenceEntry { -Property m_cb; -public: -PreferenceEntry(const Property &cb) - : m_cb(cb) -{ -} - -void importString(const char *string) -{ - m_cb.set(string); -} - -void exportString(const Callback &importer) -{ - m_cb.get(importer); -} -}; - -typedef std::map PreferenceEntries; -PreferenceEntries m_preferences; - -typedef std::map PreferenceCache; -PreferenceCache m_cache; - -public: -typedef PreferenceEntries::iterator iterator; - -iterator begin() -{ - return m_preferences.begin(); -} - -iterator end() -{ - return m_preferences.end(); -} - -iterator find(const char *name) -{ - return m_preferences.find(name); -} - -void registerPreference(const char *name, const Property &cb) -{ - m_preferences.insert(PreferenceEntries::value_type(name, PreferenceEntry(cb))); - PreferenceCache::iterator i = m_cache.find(name); - if (i != m_cache.end()) { - cb.set(i->second.c_str()); - m_cache.erase(i); - } -} - -void importPref(const char *name, const char *value) -{ - PreferenceEntries::iterator i = m_preferences.find(name); - if (i != m_preferences.end()) { - (*i).second.importString(value); - } else { - m_cache.erase(name); - m_cache.insert(PreferenceCache::value_type(name, value)); - } -} -}; - -inline void XMLPreference_importString(XMLImporter &importer, const char *value) -{ - importer.write(value, string_length(value)); -} - -typedef ReferenceCaller XMLPreferenceImportStringCaller; - -class XMLPreferenceDictionaryExporter : public XMLExporter { -class XMLQPrefElement : public XMLElement { -const char *m_version; -public: -XMLQPrefElement(const char *version) : m_version(version) -{ -} - -const char *name() const -{ - return "qpref"; -} - -const char *attribute(const char *name) const -{ - if (string_equal(name, "version")) { - return m_version; - } - return ""; -} - -void forEachAttribute(XMLAttrVisitor &visitor) const -{ - visitor.visit("version", m_version); -} -}; - -class XMLPreferenceElement : public XMLElement { -const char *m_name; -public: -XMLPreferenceElement(const char *name) - : m_name(name) -{ -} - -const char *name() const -{ - return "epair"; -} - -const char *attribute(const char *name) const -{ - if (string_equal(name, "name")) { - return m_name; - } - return ""; -} - -void forEachAttribute(XMLAttrVisitor &visitor) const -{ - visitor.visit("name", m_name); -} -}; - -typedef PreferenceDictionary PreferenceEntries; -PreferenceEntries &m_preferences; -const char *m_version; -public: -XMLPreferenceDictionaryExporter(PreferenceDictionary &preferences, const char *version) - : m_preferences(preferences), m_version(version) -{ -} - -void exportXML(XMLImporter &importer) -{ - importer.write("\n", 1); - - XMLQPrefElement qpref_element(m_version); - importer.pushElement(qpref_element); - importer.write("\n", 1); - - for (PreferenceEntries::iterator i = m_preferences.begin(); i != m_preferences.end(); ++i) { - XMLPreferenceElement epair_element((*i).first.c_str()); - - importer.pushElement(epair_element); - - (*i).second.exportString(XMLPreferenceImportStringCaller(importer)); - - importer.popElement(epair_element.name()); - importer.write("\n", 1); - } - - importer.popElement(qpref_element.name()); - importer.write("\n", 1); -} -}; - -class XMLPreferenceDictionaryImporter : public XMLImporter { -struct xml_state_t { - enum ETag { - tag_qpref, - tag_qpref_ignore, - tag_epair, - tag_epair_ignore - }; - - xml_state_t(ETag tag) - : m_tag(tag) - { - } - - ETag m_tag; - CopiedString m_name; - StringOutputStream m_ostream; -}; - -typedef std::vector xml_stack_t; -xml_stack_t m_xml_stack; - -typedef PreferenceDictionary PreferenceEntries; -PreferenceEntries &m_preferences; -Version m_version; -public: -XMLPreferenceDictionaryImporter(PreferenceDictionary &preferences, const char *version) - : m_preferences(preferences), m_version(version_parse(version)) -{ -} - -void pushElement(const XMLElement &element) -{ - if (m_xml_stack.empty()) { - if (string_equal(element.name(), "qpref")) { - Version dataVersion(version_parse(element.attribute("version"))); - if (!version_compatible(m_version, dataVersion)) { - globalOutputStream() << "qpref import: data version " << dataVersion - << " is not compatible with code version " << m_version << "\n"; - m_xml_stack.push_back(xml_state_t::tag_qpref_ignore); - } else { - globalOutputStream() << "qpref import: data version " << dataVersion - << " is compatible with code version " << m_version << "\n"; - m_xml_stack.push_back(xml_state_t::tag_qpref); - } - } else { - // not valid - } - } else { - switch (m_xml_stack.back().m_tag) { - case xml_state_t::tag_qpref: - if (string_equal(element.name(), "epair")) { - m_xml_stack.push_back(xml_state_t::tag_epair); - m_xml_stack.back().m_name = element.attribute("name"); - } else { - // not valid - } - break; - case xml_state_t::tag_qpref_ignore: - if (string_equal(element.name(), "epair")) { - m_xml_stack.push_back(xml_state_t::tag_epair_ignore); - } else { - // not valid - } - break; - case xml_state_t::tag_epair: - case xml_state_t::tag_epair_ignore: - // not valid - break; - } - } - -} - -void popElement(const char *name) -{ - if (m_xml_stack.back().m_tag == xml_state_t::tag_epair) { - m_preferences.importPref(m_xml_stack.back().m_name.c_str(), m_xml_stack.back().m_ostream.c_str()); - } - m_xml_stack.pop_back(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_xml_stack.back().m_ostream.write(buffer, length); -} -}; - -#endif diff --git a/src/preferences.cpp b/src/preferences.cpp deleted file mode 100644 index ee72aa5..0000000 --- a/src/preferences.cpp +++ /dev/null @@ -1,1011 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// User preferences -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "preferences.h" -#include "globaldefs.h" - -#include -#include "gtkutil/image.h" -#include "environment.h" - -#include "debugging/debugging.h" - -#include "generic/callback.h" -#include "math/vector.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "os/path.h" -#include "os/dir.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "cmdlib.h" - -#include "error.h" -#include "console.h" -#include "xywindow.h" -#include "mainframe.h" -#include "qe3.h" -#include "gtkdlgs.h" - -void Interface_constructPreferences(PreferencesPage &page) -{ -#if GDEF_OS_WINDOWS - page.appendCheckBox( "", "Default Text Editor", g_TextEditor_useWin32Editor ); -#else - { - ui::CheckButton use_custom = page.appendCheckBox("Text Editor", "Custom", g_TextEditor_useCustomEditor); - ui::Widget custom_editor = page.appendPathEntry("Text Editor Command", g_TextEditor_editorCommand, true); - Widget_connectToggleDependency(custom_editor, use_custom); - } -#endif -} - -void Mouse_constructPreferences(PreferencesPage &page) -{ - { - const char *buttons[] = {"2 button", "3 button",}; - page.appendRadio("Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE(buttons)); - } - page.appendCheckBox("Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick); -} - -void Mouse_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Mouse", "Mouse Preferences")); - Mouse_constructPreferences(page); -} - -void Mouse_registerPreferencesPage() -{ - PreferencesDialog_addInterfacePage(makeCallbackF(Mouse_constructPage)); -} - - -/*! - ========================================================= - Games selection dialog - ========================================================= - */ - -#include -#include - -inline const char *xmlAttr_getName(xmlAttrPtr attr) -{ - return reinterpret_cast( attr->name ); -} - -inline const char *xmlAttr_getValue(xmlAttrPtr attr) -{ - return reinterpret_cast( attr->children->content ); -} - -CGameDescription::CGameDescription(xmlDocPtr pDoc, const CopiedString &gameFile) -{ - // read the user-friendly game name - xmlNodePtr pNode = pDoc->children; - - while (strcmp((const char *) pNode->name, "game") && pNode != 0) { - pNode = pNode->next; - } - if (!pNode) { - Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL); - } - - for (xmlAttrPtr attr = pNode->properties; attr != 0; attr = attr->next) { - m_gameDescription.insert(GameDescription::value_type(xmlAttr_getName(attr), xmlAttr_getValue(attr))); - } - - { - StringOutputStream path(256); - path << AppPath_get() << gameFile.c_str() << "/"; - mGameToolsPath = path.c_str(); - } - - ASSERT_MESSAGE(file_exists(mGameToolsPath.c_str()), - "game directory not found: " << makeQuoted(mGameToolsPath.c_str())); - - mGameFile = gameFile; - - { - GameDescription::iterator i = m_gameDescription.find("type"); - if (i == m_gameDescription.end()) { - globalErrorStream() << "Warning, 'type' attribute not found in '" - << reinterpret_cast( pDoc->URL ) << "'\n"; - // default - mGameType = "q3"; - } else { - mGameType = (*i).second.c_str(); - } - } -} - -void CGameDescription::Dump() -{ - globalOutputStream() << "game description file: " << makeQuoted(mGameFile.c_str()) << "\n"; - for (GameDescription::iterator i = m_gameDescription.begin(); i != m_gameDescription.end(); ++i) { - globalOutputStream() << (*i).first.c_str() << " = " << makeQuoted((*i).second.c_str()) << "\n"; - } -} - -CGameDescription *g_pGameDescription; ///< shortcut to g_GamesDialog.m_pCurrentDescription - - -#include "warnings.h" -#include "stream/textfilestream.h" -#include "container/array.h" -#include "xml/ixml.h" -#include "xml/xmlparser.h" -#include "xml/xmlwriter.h" - -#include "preferencedictionary.h" -#include "stringio.h" - -const char *const PREFERENCES_VERSION = "1.0"; - -bool Preferences_Load(PreferenceDictionary &preferences, const char *filename, const char *cmdline_prefix) -{ - bool ret = false; - TextFileInputStream file(filename); - if (!file.failed()) { - XMLStreamParser parser(file); - XMLPreferenceDictionaryImporter importer(preferences, PREFERENCES_VERSION); - parser.exportXML(importer); - ret = true; - } - - int l = strlen(cmdline_prefix); - for (int i = 1; i < g_argc - 1; ++i) { - if (g_argv[i][0] == '-') { - if (!strncmp(g_argv[i] + 1, cmdline_prefix, l)) { - if (g_argv[i][l + 1] == '-') { - preferences.importPref(g_argv[i] + l + 2, g_argv[i + 1]); - } - } - ++i; - } - } - - return ret; -} - -bool Preferences_Save(PreferenceDictionary &preferences, const char *filename) -{ - TextFileOutputStream file(filename); - if (!file.failed()) { - XMLStreamWriter writer(file); - XMLPreferenceDictionaryExporter exporter(preferences, PREFERENCES_VERSION); - exporter.exportXML(writer); - return true; - } - return false; -} - -bool Preferences_Save_Safe(PreferenceDictionary &preferences, const char *filename) -{ - Array tmpName(filename, filename + strlen(filename) + 1 + 3); - *(tmpName.end() - 4) = 'T'; - *(tmpName.end() - 3) = 'M'; - *(tmpName.end() - 2) = 'P'; - *(tmpName.end() - 1) = '\0'; - - return Preferences_Save(preferences, tmpName.data()) - && (!file_exists(filename) || file_remove(filename)) - && file_move(tmpName.data(), filename); -} - -void RegisterGlobalPreferences(PreferenceSystem &preferences) -{ - preferences.registerPreference("gamefile", make_property_string(g_GamesDialog.m_sGameFile)); - preferences.registerPreference("gamePrompt", make_property_string(g_GamesDialog.m_bGamePrompt)); -} - - -PreferenceDictionary g_global_preferences; - -void GlobalPreferences_Init() -{ - RegisterGlobalPreferences(g_global_preferences); -} - -void CGameDialog::LoadPrefs() -{ - // load global .pref file - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - - globalOutputStream() << "loading global preferences from " << makeQuoted(strGlobalPref.c_str()) << "\n"; - - if (!Preferences_Load(g_global_preferences, strGlobalPref.c_str(), "global")) { - globalOutputStream() << "failed to load global preferences from " << strGlobalPref.c_str() << "\n"; - } -} - -void CGameDialog::SavePrefs() -{ - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - - globalOutputStream() << "saving global preferences to " << strGlobalPref.c_str() << "\n"; - - if (!Preferences_Save_Safe(g_global_preferences, strGlobalPref.c_str())) { - globalOutputStream() << "failed to save global preferences to " << strGlobalPref.c_str() << "\n"; - } -} - -void CGameDialog::DoGameDialog() -{ - // show the UI - DoModal(); - - // we save the prefs file - SavePrefs(); -} - -void CGameDialog::GameFileImport(int value) -{ - m_nComboSelect = value; - // use value to set m_sGameFile - std::list::iterator iGame = mGames.begin(); - int i; - for (i = 0; i < value; i++) { - ++iGame; - } - m_sGameFile = (*iGame)->mGameFile; -} - -void CGameDialog::GameFileExport(const Callback &importCallback) const -{ - // use m_sGameFile to set value - std::list::const_iterator iGame; - int i = 0; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - if ((*iGame)->mGameFile == m_sGameFile) { - m_nComboSelect = i; - break; - } - i++; - } - importCallback(m_nComboSelect); -} - -struct CGameDialog_GameFile { - static void Export(const CGameDialog &self, const Callback &returnz) - { - self.GameFileExport(returnz); - } - - static void Import(CGameDialog &self, int value) - { - self.GameFileImport(value); - } -}; - -void CGameDialog::CreateGlobalFrame(PreferencesPage &page) -{ - std::vector games; - games.reserve(mGames.size()); - for (std::list::iterator i = mGames.begin(); i != mGames.end(); ++i) { - games.push_back((*i)->getRequiredKeyValue("name")); - } - page.appendCombo( - "Select the game", - StringArrayRange(&(*games.begin()), &(*games.end())), - make_property(*this) - ); - page.appendCheckBox("Startup", "Show Global Preferences", m_bGamePrompt); -} - -ui::Window CGameDialog::BuildDialog() -{ - - auto frame = create_dialog_frame("Game settings", ui::Shadow::ETCHED_IN); - auto image = new_local_image("splash.xpm"); - image.show(); - auto vbox = ui::VBox(FALSE, 2); - auto vbox2 = create_dialog_vbox(0, 4); - vbox.show(); - vbox.pack_start(image, TRUE, TRUE, 0); - frame.add(vbox2); - vbox.pack_start(frame, FALSE, FALSE, 0); - - PreferencesPage preferencesPage(*this, vbox2); - CreateGlobalFrame(preferencesPage); - - return create_simple_modal_dialog_window("Global Preferences", m_modal, vbox); -} - -void CGameDialog::ScanForGames() -{ - StringOutputStream strGamesPath(256); - strGamesPath << AppPath_get() << "games/"; - const char *path = strGamesPath.c_str(); - - globalOutputStream() << "Scanning for game description files: " << path << '\n'; - - /*! - \todo FIXME LINUX: - do we put game description files below AppPath, or in ~/.radiant - i.e. read only or read/write? - my guess .. readonly cause it's an install - we will probably want to add ~/.radiant//games/ scanning on top of that for developers - (if that's really needed) - */ - - Directory_forEach(path, [&](const char *name) { - if (!extension_equal(path_get_extension(name), "game")) { - return; - } - StringOutputStream strPath(256); - strPath << path << name; - globalOutputStream() << strPath.c_str() << '\n'; - - xmlDocPtr pDoc = xmlParseFile(strPath.c_str()); - if (pDoc) { - mGames.push_front(new CGameDescription(pDoc, name)); - xmlFreeDoc(pDoc); - } else { - globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n"; - } - }); -} - -CGameDescription *CGameDialog::GameDescriptionForComboItem() -{ - std::list::iterator iGame; - int i = 0; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame, i++) { - if (i == m_nComboSelect) { - return (*iGame); - } - } - return 0; // not found -} - -void CGameDialog::InitGlobalPrefPath() -{ - g_Preferences.m_global_rc_path = g_string_new(SettingsPath_get()); -} - -void CGameDialog::Reset() -{ - if (!g_Preferences.m_global_rc_path) { - InitGlobalPrefPath(); - } - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - file_remove(strGlobalPref.c_str()); -} - -void CGameDialog::Init() -{ - InitGlobalPrefPath(); - LoadPrefs(); - ScanForGames(); - if (mGames.empty()) { - Error("Didn't find any valid game file descriptions, aborting\n"); - } else { - std::list::iterator iGame, iPrevGame; - for (iGame = mGames.begin(), iPrevGame = mGames.end(); iGame != mGames.end(); iPrevGame = iGame, ++iGame) { - if (iPrevGame != mGames.end()) { - if (strcmp((*iGame)->getRequiredKeyValue("name"), (*iPrevGame)->getRequiredKeyValue("name")) < 0) { - CGameDescription *h = *iGame; - *iGame = *iPrevGame; - *iPrevGame = h; - } - } - } - } - - CGameDescription *currentGameDescription = 0; - - if (!m_bGamePrompt) { - // search by .game name - std::list::iterator iGame; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - if ((*iGame)->mGameFile == m_sGameFile) { - currentGameDescription = (*iGame); - break; - } - } - } - if (m_bGamePrompt || !currentGameDescription) { - Create(); - DoGameDialog(); - // use m_nComboSelect to identify the game to run as and set the globals - currentGameDescription = GameDescriptionForComboItem(); - ASSERT_NOTNULL(currentGameDescription); - } - g_pGameDescription = currentGameDescription; - - g_pGameDescription->Dump(); -} - -CGameDialog::~CGameDialog() -{ - // free all the game descriptions - std::list::iterator iGame; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - delete (*iGame); - *iGame = 0; - } - if (GetWidget()) { - Destroy(); - } -} - -inline const char *GameDescription_getIdentifier(const CGameDescription &gameDescription) -{ - const char *identifier = gameDescription.getKeyValue("index"); - if (string_empty(identifier)) { - identifier = "1"; - } - return identifier; -} - - -CGameDialog g_GamesDialog; - - -// ============================================================================= -// Widget callbacks for PrefsDlg - -static void OnButtonClean(ui::Widget widget, gpointer data) -{ - // make sure this is what the user wants - if (ui::alert(g_Preferences.GetWidget(), "This will close Radiant and clean the corresponding registry entries.\n" - "Next time you start Radiant it will be good as new. Do you wish to continue?", - "Reset Registry", ui::alert_type::YESNO, ui::alert_icon::Asterisk) == ui::alert_response::YES) { - PrefsDlg *dlg = (PrefsDlg *) data; - dlg->EndModal(eIDCANCEL); - - g_preferences_globals.disable_ini = true; - Preferences_Reset(); - gtk_main_quit(); - } -} - -// ============================================================================= -// PrefsDlg class - -/* - ======== - - very first prefs init deals with selecting the game and the game tools path - then we can load .ini stuff - - using prefs / ini settings: - those are per-game - - look in ~/.radiant//gamename - ======== - */ - -const char *PREFS_LOCAL_FILENAME = "local.pref"; - -void PrefsDlg::Init() -{ - // m_global_rc_path has been set above - // m_rc_path is for game specific preferences - // takes the form: global-pref-path/gamename/prefs-file - - // this is common to win32 and Linux init now - m_rc_path = g_string_new(m_global_rc_path->str); - - // game sub-dir - g_string_append(m_rc_path, g_pGameDescription->mGameFile.c_str()); - g_string_append(m_rc_path, "/"); - Q_mkdir(m_rc_path->str); - - // then the ini file - m_inipath = g_string_new(m_rc_path->str); - g_string_append(m_inipath, PREFS_LOCAL_FILENAME); -} - -void notebook_set_page(ui::Widget notebook, ui::Widget page) -{ - int pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), page); - if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != pagenum) { - gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), pagenum); - } -} - -void PrefsDlg::showPrefPage(ui::Widget prefpage) -{ - notebook_set_page(m_notebook, prefpage); - return; -} - -static void treeSelection(ui::TreeSelection selection, gpointer data) -{ - PrefsDlg *dlg = (PrefsDlg *) data; - - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - ui::Widget prefpage{ui::null}; - gtk_tree_model_get(model, &selected, 1, (gpointer *) &prefpage, -1); - dlg->showPrefPage(prefpage); - } -} - -typedef std::list PreferenceGroupCallbacks; - -inline void PreferenceGroupCallbacks_constructGroup(const PreferenceGroupCallbacks &callbacks, PreferenceGroup &group) -{ - for (PreferenceGroupCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { - (*i)(group); - } -} - - -inline void -PreferenceGroupCallbacks_pushBack(PreferenceGroupCallbacks &callbacks, const PreferenceGroupCallback &callback) -{ - callbacks.push_back(callback); -} - -typedef std::list PreferencesPageCallbacks; - -inline void PreferencesPageCallbacks_constructPage(const PreferencesPageCallbacks &callbacks, PreferencesPage &page) -{ - for (PreferencesPageCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { - (*i)(page); - } -} - -inline void -PreferencesPageCallbacks_pushBack(PreferencesPageCallbacks &callbacks, const PreferencesPageCallback &callback) -{ - callbacks.push_back(callback); -} - -PreferencesPageCallbacks g_interfacePreferences; - -void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_interfacePreferences, callback); -} - -PreferenceGroupCallbacks g_interfaceCallbacks; - -void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_interfaceCallbacks, callback); -} - -PreferencesPageCallbacks g_displayPreferences; - -void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_displayPreferences, callback); -} - -PreferenceGroupCallbacks g_displayCallbacks; - -void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_displayCallbacks, callback); -} - -PreferencesPageCallbacks g_settingsPreferences; - -void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_settingsPreferences, callback); -} - -PreferenceGroupCallbacks g_settingsCallbacks; - -void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_settingsCallbacks, callback); -} - -void Widget_updateDependency(ui::Widget self, ui::Widget toggleButton) -{ - gtk_widget_set_sensitive(self, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggleButton)) && - gtk_widget_is_sensitive(toggleButton)); -} - -void ToggleButton_toggled_Widget_updateDependency(ui::Widget toggleButton, ui::Widget self) -{ - Widget_updateDependency(self, toggleButton); -} - -void ToggleButton_state_changed_Widget_updateDependency(ui::Widget toggleButton, GtkStateType state, ui::Widget self) -{ - if (state == GTK_STATE_INSENSITIVE) { - Widget_updateDependency(self, toggleButton); - } -} - -void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton) -{ - toggleButton.connect("state_changed", G_CALLBACK(ToggleButton_state_changed_Widget_updateDependency), self); - toggleButton.connect("toggled", G_CALLBACK(ToggleButton_toggled_Widget_updateDependency), self); - Widget_updateDependency(self, toggleButton); -} - - -inline ui::VBox getVBox(ui::Bin page) -{ - return ui::VBox::from(gtk_bin_get_child(page)); -} - -GtkTreeIter PreferenceTree_appendPage(ui::TreeStore store, GtkTreeIter *parent, const char *name, ui::Widget page) -{ - GtkTreeIter group; - gtk_tree_store_append(store, &group, parent); - gtk_tree_store_set(store, &group, 0, name, 1, page, -1); - return group; -} - -ui::Bin PreferencePages_addPage(ui::Widget notebook, const char *name) -{ - ui::Widget preflabel = ui::Label(name); - preflabel.show(); - - auto pageframe = ui::Frame(name); - gtk_container_set_border_width(GTK_CONTAINER(pageframe), 4); - pageframe.show(); - - ui::Widget vbox = ui::VBox(FALSE, 4); - vbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); - pageframe.add(vbox); - - // Add the page to the notebook - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel); - - return pageframe; -} - -class PreferenceTreeGroup : public PreferenceGroup { -Dialog &m_dialog; -ui::Widget m_notebook; -ui::TreeStore m_store; -GtkTreeIter m_group; -public: -PreferenceTreeGroup(Dialog &dialog, ui::Widget notebook, ui::TreeStore store, GtkTreeIter group) : - m_dialog(dialog), - m_notebook(notebook), - m_store(store), - m_group(group) -{ -} - -PreferencesPage createPage(const char *treeName, const char *frameName) -{ - auto page = PreferencePages_addPage(m_notebook, frameName); - PreferenceTree_appendPage(m_store, &m_group, treeName, page); - return PreferencesPage(m_dialog, getVBox(page)); -} -}; - -ui::Window PrefsDlg::BuildDialog() -{ - PreferencesDialog_addInterfacePreferences(makeCallbackF(Interface_constructPreferences)); - Mouse_registerPreferencesPage(); - - ui::Window dialog = ui::Window(create_floating_window("WorldSpawn Preferences", m_parent)); - - { - auto mainvbox = ui::VBox(FALSE, 5); - dialog.add(mainvbox); - gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5); - mainvbox.show(); - - { - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - mainvbox.pack_end(hbox, FALSE, TRUE, 0); - - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &m_modal); - hbox.pack_end(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &m_modal); - hbox.pack_end(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Clean", G_CALLBACK(OnButtonClean), this); - hbox.pack_end(button, FALSE, FALSE, 0); - } - } - - { - auto hbox = ui::HBox(FALSE, 5); - mainvbox.pack_start(hbox, TRUE, TRUE, 0); - hbox.show(); - - { - auto sc_win = ui::ScrolledWindow(ui::New); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - hbox.pack_start(sc_win, FALSE, FALSE, 0); - sc_win.show(); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN); - - // prefs pages notebook - m_notebook = ui::Widget::from(gtk_notebook_new()); - // hide the notebook tabs since its not supposed to look like a notebook - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_notebook), FALSE); - hbox.pack_start(m_notebook, TRUE, TRUE, 0); - m_notebook.show(); - - - { - auto store = ui::TreeStore::from(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Preferences", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(treeSelection), this); - } - - view.show(); - - sc_win.add(view); - - { - /********************************************************************/ - /* Add preference tree options */ - /********************************************************************/ - // Front page... - //GtkWidget* front = - PreferencePages_addPage(m_notebook, "Front Page"); - - { - auto global = PreferencePages_addPage(m_notebook, "Global Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(global)); - } - auto group = PreferenceTree_appendPage(store, 0, "Global", global); - { - auto game = PreferencePages_addPage(m_notebook, "Game"); - PreferencesPage preferencesPage(*this, getVBox(game)); - g_GamesDialog.CreateGlobalFrame(preferencesPage); - - PreferenceTree_appendPage(store, &group, "Game", game); - } - } - - { - auto interfacePage = PreferencePages_addPage(m_notebook, "Interface Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(interfacePage)); - PreferencesPageCallbacks_constructPage(g_interfacePreferences, preferencesPage); - } - - auto group = PreferenceTree_appendPage(store, 0, "Interface", interfacePage); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_interfaceCallbacks, preferenceGroup); - } - - { - auto display = PreferencePages_addPage(m_notebook, "Display Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(display)); - PreferencesPageCallbacks_constructPage(g_displayPreferences, preferencesPage); - } - auto group = PreferenceTree_appendPage(store, 0, "Display", display); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_displayCallbacks, preferenceGroup); - } - - { - auto settings = PreferencePages_addPage(m_notebook, "General Settings"); - { - PreferencesPage preferencesPage(*this, getVBox(settings)); - PreferencesPageCallbacks_constructPage(g_settingsPreferences, preferencesPage); - } - - auto group = PreferenceTree_appendPage(store, 0, "Settings", settings); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_settingsCallbacks, preferenceGroup); - } - } - - gtk_tree_view_expand_all(view); - - g_object_unref(G_OBJECT(store)); - } - } - } - } - - gtk_notebook_set_current_page(GTK_NOTEBOOK(m_notebook), 0); - - return dialog; -} - -preferences_globals_t g_preferences_globals; - -PrefsDlg g_Preferences; // global prefs instance - - -void PreferencesDialog_constructWindow(ui::Window main_window) -{ - g_Preferences.m_parent = main_window; - g_Preferences.Create(); -} - -void PreferencesDialog_destroyWindow() -{ - g_Preferences.Destroy(); -} - - -PreferenceDictionary g_preferences; - -PreferenceSystem &GetPreferenceSystem() -{ - return g_preferences; -} - -class PreferenceSystemAPI { -PreferenceSystem *m_preferencesystem; -public: -typedef PreferenceSystem Type; - -STRING_CONSTANT(Name, "*"); - -PreferenceSystemAPI() -{ - m_preferencesystem = &GetPreferenceSystem(); -} - -PreferenceSystem *getTable() -{ - return m_preferencesystem; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule PreferenceSystemModule; -typedef Static StaticPreferenceSystemModule; -StaticRegisterModule staticRegisterPreferenceSystem(StaticPreferenceSystemModule::instance()); - -void Preferences_Load() -{ - g_GamesDialog.LoadPrefs(); - - globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath->str << "\n"; - - if (!Preferences_Load(g_preferences, g_Preferences.m_inipath->str, g_GamesDialog.m_sGameFile.c_str())) { - globalOutputStream() << "failed to load local preferences from " << g_Preferences.m_inipath->str << "\n"; - } -} - -void Preferences_Save() -{ - if (g_preferences_globals.disable_ini) { - return; - } - - g_GamesDialog.SavePrefs(); - - globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; - - if (!Preferences_Save_Safe(g_preferences, g_Preferences.m_inipath->str)) { - globalOutputStream() << "failed to save local preferences to " << g_Preferences.m_inipath->str << "\n"; - } -} - -void Preferences_Reset() -{ - file_remove(g_Preferences.m_inipath->str); -} - - -void PrefsDlg::PostModal(EMessageBoxReturn code) -{ - if (code == eIDOK) { - Preferences_Save(); - UpdateAllWindows(); - } -} - -std::vector g_restart_required; - -void PreferencesDialog_restartRequired(const char *staticName) -{ - g_restart_required.push_back(staticName); -} - -void PreferencesDialog_showDialog() -{ - if (ConfirmModified("Edit Preferences") && g_Preferences.DoModal() == eIDOK) { - if (!g_restart_required.empty()) { - StringOutputStream message(256); - message << "Preference changes require a restart:\n"; - for (std::vector::iterator i = g_restart_required.begin(); - i != g_restart_required.end(); ++i) { - message << (*i) << '\n'; - } - ui::alert(MainFrame_getWindow(), message.c_str()); - g_restart_required.clear(); - } - } -} - -struct GameName { - static void Export(const Callback &returnz) - { - returnz(gamename_get()); - } - - static void Import(const char *value) - { - gamename_set(value); - } -}; - -struct GameMode { - static void Export(const Callback &returnz) - { - returnz(gamemode_get()); - } - - static void Import(const char *value) - { - gamemode_set(value); - } -}; - -void RegisterPreferences(PreferenceSystem &preferences) -{ -#if GDEF_OS_WINDOWS - preferences.registerPreference( "UseCustomShaderEditor", make_property_string( g_TextEditor_useWin32Editor ) ); -#else - preferences.registerPreference("UseCustomShaderEditor", make_property_string(g_TextEditor_useCustomEditor)); - preferences.registerPreference("CustomShaderEditorCommand", make_property_string(g_TextEditor_editorCommand)); -#endif - - preferences.registerPreference("GameName", make_property()); - preferences.registerPreference("GameMode", make_property()); -} - -void Preferences_Init() -{ - RegisterPreferences(GetPreferenceSystem()); -} diff --git a/src/preferences.h b/src/preferences.h deleted file mode 100644 index 7ea3ba3..0000000 --- a/src/preferences.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -#if !defined( INCLUDED_PREFERENCES_H ) -#define INCLUDED_PREFERENCES_H - -#include "libxml/parser.h" -#include "dialog.h" -#include -#include -#include "property.h" - -void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton); - -class PreferencesPage { -Dialog &m_dialog; -ui::VBox m_vbox; -public: -PreferencesPage(Dialog &dialog, ui::VBox vbox) : m_dialog(dialog), m_vbox(vbox) -{ -} - -ui::CheckButton appendCheckBox(const char *name, const char *flag, bool &data) -{ - return m_dialog.addCheckBox(m_vbox, name, flag, data); -} - -ui::CheckButton appendCheckBox(const char *name, const char *flag, Property const &cb) -{ - return m_dialog.addCheckBox(m_vbox, name, flag, cb); -} - -void appendCombo(const char *name, StringArrayRange values, Property const &cb) -{ - m_dialog.addCombo(m_vbox, name, values, cb); -} - -void appendCombo(const char *name, int &data, StringArrayRange values) -{ - m_dialog.addCombo(m_vbox, name, data, values); -} - -void appendSlider(const char *name, int &data, gboolean draw_value, const char *low, const char *high, double value, - double lower, double upper, double step_increment, double page_increment) -{ - m_dialog.addSlider(m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, - page_increment); -} - -void appendRadio(const char *name, StringArrayRange names, Property const &cb) -{ - m_dialog.addRadio(m_vbox, name, names, cb); -} - -void appendRadio(const char *name, int &data, StringArrayRange names) -{ - m_dialog.addRadio(m_vbox, name, data, names); -} - -void appendRadioIcons(const char *name, StringArrayRange icons, Property const &cb) -{ - m_dialog.addRadioIcons(m_vbox, name, icons, cb); -} - -void appendRadioIcons(const char *name, int &data, StringArrayRange icons) -{ - m_dialog.addRadioIcons(m_vbox, name, data, icons); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addIntEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, int &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addSizeEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, std::size_t &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addFloatEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, float &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendPathEntry(const char *name, bool browse_directory, Property const &cb) -{ - return m_dialog.addPathEntry(m_vbox, name, browse_directory, cb); -} - -ui::Widget appendPathEntry(const char *name, CopiedString &data, bool directory) -{ - return m_dialog.addPathEntry(m_vbox, name, data, directory); -} - -ui::SpinButton appendSpinner(const char *name, int &data, double value, double lower, double upper) -{ - return m_dialog.addSpinner(m_vbox, name, data, value, lower, upper); -} - -ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property const &cb) -{ - return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb); -} - -ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property const &cb) -{ - return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb); -} -}; - -typedef Callback PreferencesPageCallback; - -class PreferenceGroup { -public: -virtual PreferencesPage createPage(const char *treeName, const char *frameName) = 0; -}; - -typedef Callback PreferenceGroupCallback; - -void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_restartRequired(const char *staticName); - -template -class LatchedValue { -public: -Value m_value; -Value m_latched; -const char *m_description; - -LatchedValue(Value value, const char *description) : m_latched(value), m_description(description) -{ -} - -void useLatched() -{ - m_value = m_latched; -} -}; - -template -struct PropertyImpl, T> { - static void Export(const LatchedValue &self, const Callback &returnz) - { - returnz(self.m_latched); - } - - static void Import(LatchedValue &self, T value) - { - self.m_latched = value; - if (value != self.m_value) { - PreferencesDialog_restartRequired(self.m_description); - } - } -}; - -template -Property make_property(LatchedValue &self) -{ - return make_property, T>(self); -} - -/*! - holds information for a given game - I'm a bit unclear on that still - it holds game specific configuration stuff - such as base names, engine names, some game specific features to activate in the various modules - it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking - support for a new game) - - what we do now is fully generate the information for this during the setup. We might want to - generate a piece that just says "the game pack is there", but put the rest of the config somwhere - else (i.e. not generated, copied over during setup .. for instance in the game tools directory) - */ -class CGameDescription { -typedef std::map GameDescription; - -public: -CopiedString mGameFile; ///< the .game file that describes this game -GameDescription m_gameDescription; - -CopiedString mGameToolsPath; ///< the explicit path to the game-dependent modules -CopiedString mGameType; ///< the type of the engine - -const char *getKeyValue(const char *key) const -{ - GameDescription::const_iterator i = m_gameDescription.find(key); - if (i != m_gameDescription.end()) { - return (*i).second.c_str(); - } - return ""; -} - -const char *getRequiredKeyValue(const char *key) const -{ - GameDescription::const_iterator i = m_gameDescription.find(key); - if (i != m_gameDescription.end()) { - return (*i).second.c_str(); - } - ERROR_MESSAGE("game attribute " << makeQuoted(key) << " not found in " << makeQuoted(mGameFile.c_str())); - return ""; -} - -CGameDescription(xmlDocPtr pDoc, const CopiedString &GameFile); - -void Dump(); -}; - -extern CGameDescription *g_pGameDescription; - -class PrefsDlg; - -class PreferencesPage; - -class StringOutputStream; - -/*! - standalone dialog for games selection, and more generally global settings - */ -class CGameDialog : public Dialog { -protected: - -mutable int m_nComboSelect; ///< intermediate int value for combo in dialog box - -public: - -/*! - those settings are saved in the global prefs file - I'm too lazy to wrap behind protected access, not sure this needs to be public - NOTE: those are preference settings. if you change them it is likely that you would - have to restart the editor for them to take effect - */ -/*@{*/ -/*! - what game has been selected - this is the name of the .game file - */ -CopiedString m_sGameFile; -/*! - prompt which game to load on startup - */ -bool m_bGamePrompt; -/*@}*/ - -/*! - the list of game descriptions we scanned from the game/ dir - */ -std::list mGames; - -CGameDialog() : - m_sGameFile(""), - m_bGamePrompt(true) -{ -} - -virtual ~CGameDialog(); - -/*! - intialize the game dialog, called at CPrefsDlg::Init - will scan for games, load prefs, and do game selection dialog if needed - */ -void Init(); - -/*! - reset the global settings by removing the file - */ -void Reset(); - -/*! - run the dialog UI for the list of games - */ -void DoGameDialog(); - -/*! - Dialog API - this is only called when the dialog is built at startup for main engine select - */ -ui::Window BuildDialog(); - -void GameFileImport(int value); - -void GameFileExport(const Callback &importCallback) const; - -/*! - construction of the dialog frame - this is the part to be re-used in prefs dialog - for the standalone dialog, we include this in a modal box - for prefs, we hook the frame in the main notebook - build the frame on-demand (only once) - */ -void CreateGlobalFrame(PreferencesPage &page); - -/*! - global preferences subsystem - XML-based this time, hopefully this will generalize to other prefs - LoadPrefs has hardcoded defaults - NOTE: it may not be strictly 'CGameDialog' to put the global prefs here - could have named the class differently I guess - */ -/*@{*/ -void LoadPrefs(); ///< load from file into variables -void SavePrefs(); ///< save pref variables to file -/*@}*/ - -private: -/*! - scan for .game files, load them - */ -void ScanForGames(); - -/*! - inits g_Preferences.m_global_rc_path - */ -void InitGlobalPrefPath(); - -/*! - uses m_nComboItem to find the right mGames - */ -CGameDescription *GameDescriptionForComboItem(); -}; - -/*! - this holds global level preferences - */ -extern CGameDialog g_GamesDialog; - - -class texdef_t; - -class PrefsDlg : public Dialog { -public: -protected: -std::list mGames; - -public: - -ui::Widget m_notebook{ui::null}; - -virtual ~PrefsDlg() -{ - g_string_free(m_rc_path, true); - g_string_free(m_inipath, true); -} - -/*! - path for global settings - win32: AppPath - linux: ~/.radiant/[version]/ - */ -GString *m_global_rc_path; - -/*! - path to per-game settings - used for various game dependant storage - win32: GameToolsPath - linux: ~/.radiant/[version]/[gamename]/ - */ -GString *m_rc_path; - -/*! - holds per-game settings - m_rc_path+"local.pref" - \todo FIXME at some point this should become XML property bag code too - */ -GString *m_inipath; - -// initialize the above paths -void Init(); - -/*! Utility function for swapping notebook pages for tree list selections */ -void showPrefPage(ui::Widget prefpage); - -protected: - -/*! Dialog API */ -ui::Window BuildDialog(); - -void PostModal(EMessageBoxReturn code); -}; - -extern PrefsDlg g_Preferences; - -struct preferences_globals_t { - // disabled all INI / registry read write .. used when shutting down after registry cleanup - bool disable_ini; - - preferences_globals_t() : disable_ini(false) - { - } -}; - -extern preferences_globals_t g_preferences_globals; - -void PreferencesDialog_constructWindow(ui::Window main_window); - -void PreferencesDialog_destroyWindow(); - -void PreferencesDialog_showDialog(); - -void GlobalPreferences_Init(); - -void Preferences_Init(); - -void Preferences_Load(); - -void Preferences_Save(); - -void Preferences_Reset(); - - -#endif diff --git a/tools/vmap/prtfile.c b/src/prtfile.c similarity index 100% rename from tools/vmap/prtfile.c rename to src/prtfile.c diff --git a/src/qe3.cpp b/src/qe3.cpp deleted file mode 100644 index bca2c78..0000000 --- a/src/qe3.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -// -// Linux stuff -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "qe3.h" -#include "globaldefs.h" - -#include - -#include "debugging/debugging.h" - -#include "ifilesystem.h" -//#include "imap.h" - -#include - -#include - -#include "stream/textfilestream.h" -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "scenelib.h" - -#include "gtkutil/messagebox.h" -#include "error.h" -#include "map.h" -#include "build.h" -#include "points.h" -#include "camwindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "watchbsp.h" -#include "autosave.h" -#include "convert.h" - -QEGlobals_t g_qeglobals; - - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - - -void QE_InitVFS() -{ - // VFS initialization ----------------------- - // we will call GlobalFileSystem().initDirectory, giving the directories to look in (for files in pk3's and for standalone files) - // we need to call in order, the mod ones first, then the base ones .. they will be searched in this order - // *nix systems have a dual filesystem in ~/.q3a, which is searched first .. so we need to add that too - - const char *gamename = gamename_get(); - const char *basegame = basegame_get(); - const char *globalRoot = EnginePath_get(); - - // if we have a mod dir - if (!string_equal(gamename, basegame)) { - // / - StringOutputStream globalGamePath(256); - globalGamePath << globalRoot << gamename << '/'; - GlobalFileSystem().initDirectory(globalGamePath.c_str()); - } - - StringOutputStream globalBasePath(256); - globalBasePath << globalRoot << basegame << '/'; - GlobalFileSystem().initDirectory(globalBasePath.c_str()); -} - -int g_numbrushes = 0; -int g_numentities = 0; -int g_numhidden = 0; - -void QE_UpdateStatusBar() -{ - char buffer[128]; - sprintf(buffer, "Brushes: %d Entities: %d Hidden: %d", g_numbrushes, g_numentities, g_numhidden); - g_pParentWnd->SetStatusText(g_pParentWnd->m_brushcount_status, buffer); -} - -SimpleCounter g_brushCount; - -void QE_brushCountChanged() -{ - g_numbrushes = int(g_brushCount.get()); - QE_UpdateStatusBar(); -} - -SimpleCounter g_entityCount; - -void QE_entityCountChanged() -{ - g_numentities = int(g_entityCount.get()); - QE_UpdateStatusBar(); -} - -std::size_t Scene_countHiddenBrushes(scene::Graph &graph); -void QE_hiddenCountChanged() -{ - g_numhidden = int(Scene_countHiddenBrushes(GlobalSceneGraph())); - QE_UpdateStatusBar(); -} - -bool ConfirmModified(const char *title) -{ - if (!Map_Modified(g_map)) { - return true; - } - - auto result = ui::alert(MainFrame_getWindow(), - "The current map has changed since it was last saved.\nDo you want to save the current map before continuing?", - title, ui::alert_type::YESNOCANCEL, ui::alert_icon::Question); - if (result == ui::alert_response::CANCEL) { - return false; - } - if (result == ui::alert_response::YES) { - if (Map_Unnamed(g_map)) { - return Map_SaveAs(); - } else { - return Map_Save(); - } - } - return true; -} - -void bsp_init() -{ - build_set_variable("RadiantPath", AppPath_get()); - build_set_variable("EnginePath", EnginePath_get()); - build_set_variable("UserEnginePath", g_qeglobals.m_userEnginePath.c_str()); - build_set_variable("MonitorAddress", (g_WatchBSP_Enabled) ? "127.0.0.1:39000" : ""); - build_set_variable("GameName", gamename_get()); - - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".bsp"; - - build_set_variable("MapFile", mapname); - build_set_variable("BspFile", name.c_str()); -} - -void bsp_shutdown() -{ - build_clear_variables(); -} - -class ArrayCommandListener : public CommandListener { -GPtrArray *m_array; -public: -ArrayCommandListener() -{ - m_array = g_ptr_array_new(); -} - -~ArrayCommandListener() -{ - g_ptr_array_free(m_array, TRUE); -} - -void execute(const char *command) -{ - g_ptr_array_add(m_array, g_strdup(command)); -} - -GPtrArray *array() const -{ - return m_array; -} -}; - -class BatchCommandListener : public CommandListener { -TextOutputStream &m_file; -std::size_t m_commandCount; -const char *m_outputRedirect; -public: -BatchCommandListener(TextOutputStream &file, const char *outputRedirect) : m_file(file), m_commandCount(0), - m_outputRedirect(outputRedirect) -{ -} - -void execute(const char *command) -{ - m_file << command; - if (m_commandCount == 0) { - m_file << " > "; - } else { - m_file << " >> "; - } - m_file << "\"" << m_outputRedirect << "\""; - m_file << "\n"; - ++m_commandCount; -} -}; - -bool Region_cameraValid() -{ - Vector3 vOrig(vector3_snapped(Camera_getOrigin(*g_pParentWnd->GetCamWnd()))); - - for (int i = 0; i < 3; i++) { - if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i]) { - return false; - } - } - return true; -} - - -void RunBSP(const char *name) -{ - // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503 - // make sure we don't attempt to region compile a map with the camera outside the region - if (region_active && !Region_cameraValid()) { - globalErrorStream() << "The camera must be in the region to start a region compile.\n"; - return; - } - - SaveMap(); - - if (Map_Unnamed(g_map)) { - globalOutputStream() << "build cancelled\n"; - return; - } - - if (g_SnapShots_Enabled && !Map_Unnamed(g_map) && Map_Modified(g_map)) { - Map_Snapshot(); - } - - if (region_active) { - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".reg"; - Map_SaveRegion(name.c_str()); - } - - Pointfile_Delete(); - - bsp_init(); - - if (g_WatchBSP_Enabled) { - ArrayCommandListener listener; - build_run(name, listener); - // grab the file name for engine running - const char *fullname = Map_Name(g_map); - StringOutputStream bspname(64); - bspname << StringRange(path_get_filename_start(fullname), path_get_filename_base_end(fullname)); - BuildMonitor_Run(listener.array(), bspname.c_str()); - } else { - char junkpath[PATH_MAX]; - strcpy(junkpath, SettingsPath_get()); - strcat(junkpath, "junk.txt"); - - char batpath[PATH_MAX]; -#if GDEF_OS_POSIX - strcpy(batpath, SettingsPath_get()); - strcat(batpath, "qe3bsp.sh"); -#elif GDEF_OS_WINDOWS - strcpy( batpath, SettingsPath_get() ); - strcat( batpath, "qe3bsp.bat" ); -#else -#error "unsupported platform" -#endif - bool written = false; - { - TextFileOutputStream batchFile(batpath); - if (!batchFile.failed()) { -#if GDEF_OS_POSIX - batchFile << "#!/bin/sh \n\n"; -#endif - BatchCommandListener listener(batchFile, junkpath); - build_run(name, listener); - written = true; - } - } - if (written) { -#if GDEF_OS_POSIX - chmod(batpath, 0744); -#endif - globalOutputStream() << "Writing the compile script to '" << batpath << "'\n"; - globalOutputStream() << "The build output will be saved in '" << junkpath << "'\n"; - Q_Exec(batpath, NULL, NULL, true, false); - } - } - - bsp_shutdown(); -} - -// ============================================================================= -// Sys_ functions - -void Sys_SetTitle(const char *text, bool modified) -{ - StringOutputStream title; - title << "WorldSpawn - ["; - title << text; - title << "]"; - - if (modified) { - title << " *"; - } - - gtk_window_set_title(MainFrame_getWindow(), title.c_str()); -} - -bool g_bWaitCursor = false; - -void Sys_BeginWait(void) -{ - ScreenUpdates_Disable("Processing...", "Please Wait"); - GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); - gdk_window_set_cursor(gtk_widget_get_window(MainFrame_getWindow()), cursor); - gdk_cursor_unref(cursor); - g_bWaitCursor = true; -} - -void Sys_EndWait(void) -{ - ScreenUpdates_Enable(); - gdk_window_set_cursor(gtk_widget_get_window(MainFrame_getWindow()), 0); - g_bWaitCursor = false; -} - -void Sys_Beep(void) -{ - gdk_beep(); -} diff --git a/src/qe3.h b/src/qe3.h deleted file mode 100644 index fae88ed..0000000 --- a/src/qe3.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_QE3_H ) -#define INCLUDED_QE3_H - -#include "string/string.h" - -// -// system functions -// -void Sys_SetTitle(const char *text, bool modified); - - -void RunBSP(const char *name); - - -void QE_InitVFS(); - -void QE_brushCountChanged(); - -void QE_entityCountChanged(); - -bool ConfirmModified(const char *title); - - -// most of the QE globals are stored in this structure -typedef struct { - /*! - win32: engine full path. - unix: user home full path + engine dir. - */ - CopiedString m_userEnginePath; - /*! - cache for m_userEnginePath + mod subdirectory. - */ - CopiedString m_userGamePath; - -} QEGlobals_t; - -extern QEGlobals_t g_qeglobals; - -class SimpleCounter; - -extern SimpleCounter g_brushCount; -extern SimpleCounter g_entityCount; - - -#endif diff --git a/src/qgl.cpp b/src/qgl.cpp deleted file mode 100644 index d7dce85..0000000 --- a/src/qgl.cpp +++ /dev/null @@ -1,1515 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "qgl.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#if GDEF_OS_WINDOWS -#define WINGDIAPI __declspec( dllimport ) -#define APIENTRY __stdcall -#endif - -#if GDEF_OS_MACOS && !defined( XWINDOWS ) -#include -#else - -#include - -#endif - -#if GDEF_OS_WINDOWS -#undef WINGDIAPI -#undef APIENTRY -#endif - -#include "igl.h" - - -#if GDEF_OS_WINDOWS - -#include - -PROC ( WINAPI * qwglGetProcAddress )( LPCSTR ); - -#elif defined ( XWINDOWS ) - -#include -#include - -Bool ( *qglXQueryExtension )(Display *dpy, int *errorb, int *event); - -void *( *qglXGetProcAddressARB )(const GLubyte *procName); - -typedef void *( *glXGetProcAddressARBProc )(const GLubyte *procName); - -#elif GDEF_OS_MACOS -#include -#include -#include -#else -#error "unsupported platform" -#endif - - -void QGL_Shutdown(OpenGLBinding &table) -{ - globalOutputStream() << "Shutting down OpenGL module..."; - -#if GDEF_OS_WINDOWS - qwglGetProcAddress = 0; -#elif defined( XWINDOWS ) - qglXQueryExtension = glXQueryExtension; - qglXGetProcAddressARB = 0; -#elif GDEF_OS_MACOS -#else -#error "unsupported platform" -#endif - - globalOutputStream() << "Done.\n"; -} - - -typedef struct glu_error_struct { - GLenum errnum; - const char *errstr; -} GLU_ERROR_STRUCT; - -GLU_ERROR_STRUCT glu_errlist[] = { - {GL_NO_ERROR, "GL_NO_ERROR - no error"}, - {GL_INVALID_ENUM, "GL_INVALID_ENUM - An unacceptable value is specified for an enumerated argument."}, - {GL_INVALID_VALUE, "GL_INVALID_VALUE - A numeric argument is out of range."}, - {GL_INVALID_OPERATION, "GL_INVALID_OPERATION - The specified operation is not allowed in the current state."}, - {GL_STACK_OVERFLOW, "GL_STACK_OVERFLOW - Function would cause a stack overflow."}, - {GL_STACK_UNDERFLOW, "GL_STACK_UNDERFLOW - Function would cause a stack underflow."}, - {GL_OUT_OF_MEMORY, "GL_OUT_OF_MEMORY - There is not enough memory left to execute the function."}, - {0, 0} -}; - -const GLubyte *qgluErrorString(GLenum errCode) -{ - int search = 0; - for (search = 0; glu_errlist[search].errstr; search++) { - if (errCode == glu_errlist[search].errnum) { - return (const GLubyte *) glu_errlist[search].errstr; - } - } //end for - return (const GLubyte *) "Unknown error"; -} - - -void glInvalidFunction() -{ - ERROR_MESSAGE("calling an invalid OpenGL function"); -} - -#define EXTENSIONS_ENABLED 1 - -bool QGL_ExtensionSupported(const char *extension) -{ -#if EXTENSIONS_ENABLED - const GLubyte *extensions = 0; - const GLubyte *start; - GLubyte *where, *terminator; - - // Extension names should not have spaces. - where = (GLubyte *) strchr(extension, ' '); - if (where || *extension == '\0') { - return false; - } - - extensions = GlobalOpenGL().m_glGetString(GL_EXTENSIONS); -#if !GDEF_OS_MACOS - if (!extensions) { - return false; - } -#endif - - // It takes a bit of care to be fool-proof about parsing the - // OpenGL extensions string. Don't be fooled by sub-strings, etc. - for (start = extensions;;) { - where = (GLubyte *) strstr((const char *) start, extension); - if (!where) { - break; - } - - terminator = where + strlen(extension); - if (where == start || *(where - 1) == ' ') { - if (*terminator == ' ' || *terminator == '\0') { - return true; - } - } - - start = terminator; - } -#endif - - return false; -} - -typedef int ( QGL_DLLEXPORT *QGLFunctionPointer )(); - -QGLFunctionPointer QGL_getExtensionFunc(const char *symbol) -{ -#if GDEF_OS_WINDOWS - ASSERT_NOTNULL( qwglGetProcAddress ); - return (QGLFunctionPointer) qwglGetProcAddress( symbol ); -#elif defined( XWINDOWS ) - //ASSERT_NOTNULL(qglXGetProcAddressARB); - if (qglXGetProcAddressARB == 0) { - return reinterpret_cast( glInvalidFunction ); - } else { - return (QGLFunctionPointer) qglXGetProcAddressARB(reinterpret_cast( symbol )); - } -#elif GDEF_OS_MACOS - // Prepend a '_' for the Unix C symbol mangling convention - char *symbolName = (char *) malloc(strlen(symbol) + 2); - strcpy(symbolName + 1, symbol); - symbolName[0] = '_'; - NSSymbol nssymbol = NULL; - if (NSIsSymbolNameDefined(symbolName)) nssymbol = NSLookupAndBindSymbol(symbolName); - free(symbolName); - return nssymbol ? reinterpret_cast(NSAddressOfSymbol(nssymbol)) : reinterpret_cast(glInvalidFunction); -#error "unsupported platform" -#endif -} - - -template -bool QGL_constructExtensionFunc(Func &func, const char *symbol) -{ - func = reinterpret_cast( QGL_getExtensionFunc(symbol)); - return func != 0; -} - -template -void QGL_invalidateExtensionFunc(Func &func) -{ - func = reinterpret_cast( glInvalidFunction ); -} - -void QGL_clear(OpenGLBinding &table) -{ - QGL_invalidateExtensionFunc(table.m_glAccum); - QGL_invalidateExtensionFunc(table.m_glAlphaFunc); - QGL_invalidateExtensionFunc(table.m_glAreTexturesResident); - QGL_invalidateExtensionFunc(table.m_glArrayElement); - QGL_invalidateExtensionFunc(table.m_glBegin); - QGL_invalidateExtensionFunc(table.m_glBindTexture); - QGL_invalidateExtensionFunc(table.m_glBitmap); - QGL_invalidateExtensionFunc(table.m_glBlendFunc); - QGL_invalidateExtensionFunc(table.m_glCallList); - QGL_invalidateExtensionFunc(table.m_glCallLists); - QGL_invalidateExtensionFunc(table.m_glClear); - QGL_invalidateExtensionFunc(table.m_glClearAccum); - QGL_invalidateExtensionFunc(table.m_glClearColor); - QGL_invalidateExtensionFunc(table.m_glClearDepth); - QGL_invalidateExtensionFunc(table.m_glClearIndex); - QGL_invalidateExtensionFunc(table.m_glClearStencil); - QGL_invalidateExtensionFunc(table.m_glClipPlane); - QGL_invalidateExtensionFunc(table.m_glColor3b); - QGL_invalidateExtensionFunc(table.m_glColor3bv); - QGL_invalidateExtensionFunc(table.m_glColor3d); - QGL_invalidateExtensionFunc(table.m_glColor3dv); - QGL_invalidateExtensionFunc(table.m_glColor3f); - QGL_invalidateExtensionFunc(table.m_glColor3fv); - QGL_invalidateExtensionFunc(table.m_glColor3i); - QGL_invalidateExtensionFunc(table.m_glColor3iv); - QGL_invalidateExtensionFunc(table.m_glColor3s); - QGL_invalidateExtensionFunc(table.m_glColor3sv); - QGL_invalidateExtensionFunc(table.m_glColor3ub); - QGL_invalidateExtensionFunc(table.m_glColor3ubv); - QGL_invalidateExtensionFunc(table.m_glColor3ui); - QGL_invalidateExtensionFunc(table.m_glColor3uiv); - QGL_invalidateExtensionFunc(table.m_glColor3us); - QGL_invalidateExtensionFunc(table.m_glColor3usv); - QGL_invalidateExtensionFunc(table.m_glColor4b); - QGL_invalidateExtensionFunc(table.m_glColor4bv); - QGL_invalidateExtensionFunc(table.m_glColor4d); - QGL_invalidateExtensionFunc(table.m_glColor4dv); - QGL_invalidateExtensionFunc(table.m_glColor4f); - QGL_invalidateExtensionFunc(table.m_glColor4fv); - QGL_invalidateExtensionFunc(table.m_glColor4i); - QGL_invalidateExtensionFunc(table.m_glColor4iv); - QGL_invalidateExtensionFunc(table.m_glColor4s); - QGL_invalidateExtensionFunc(table.m_glColor4sv); - QGL_invalidateExtensionFunc(table.m_glColor4ub); - QGL_invalidateExtensionFunc(table.m_glColor4ubv); - QGL_invalidateExtensionFunc(table.m_glColor4ui); - QGL_invalidateExtensionFunc(table.m_glColor4uiv); - QGL_invalidateExtensionFunc(table.m_glColor4us); - QGL_invalidateExtensionFunc(table.m_glColor4usv); - QGL_invalidateExtensionFunc(table.m_glColorMask); - QGL_invalidateExtensionFunc(table.m_glColorMaterial); - QGL_invalidateExtensionFunc(table.m_glColorPointer); - QGL_invalidateExtensionFunc(table.m_glCopyPixels); - QGL_invalidateExtensionFunc(table.m_glCopyTexImage1D); - QGL_invalidateExtensionFunc(table.m_glCopyTexImage2D); - QGL_invalidateExtensionFunc(table.m_glCopyTexSubImage1D); - QGL_invalidateExtensionFunc(table.m_glCopyTexSubImage2D); - QGL_invalidateExtensionFunc(table.m_glCullFace); - QGL_invalidateExtensionFunc(table.m_glDeleteLists); - QGL_invalidateExtensionFunc(table.m_glDeleteTextures); - QGL_invalidateExtensionFunc(table.m_glDepthFunc); - QGL_invalidateExtensionFunc(table.m_glDepthMask); - QGL_invalidateExtensionFunc(table.m_glDepthRange); - QGL_invalidateExtensionFunc(table.m_glDisable); - QGL_invalidateExtensionFunc(table.m_glDisableClientState); - QGL_invalidateExtensionFunc(table.m_glDrawArrays); - QGL_invalidateExtensionFunc(table.m_glDrawBuffer); - QGL_invalidateExtensionFunc(table.m_glDrawElements); - QGL_invalidateExtensionFunc(table.m_glDrawPixels); - QGL_invalidateExtensionFunc(table.m_glEdgeFlag); - QGL_invalidateExtensionFunc(table.m_glEdgeFlagPointer); - QGL_invalidateExtensionFunc(table.m_glEdgeFlagv); - QGL_invalidateExtensionFunc(table.m_glEnable); - QGL_invalidateExtensionFunc(table.m_glEnableClientState); - QGL_invalidateExtensionFunc(table.m_glEnd); - QGL_invalidateExtensionFunc(table.m_glEndList); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1d); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1dv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1f); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1fv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2d); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2dv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2f); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2fv); - QGL_invalidateExtensionFunc(table.m_glEvalMesh1); - QGL_invalidateExtensionFunc(table.m_glEvalMesh2); - QGL_invalidateExtensionFunc(table.m_glEvalPoint1); - QGL_invalidateExtensionFunc(table.m_glEvalPoint2); - QGL_invalidateExtensionFunc(table.m_glFeedbackBuffer); - QGL_invalidateExtensionFunc(table.m_glFinish); - QGL_invalidateExtensionFunc(table.m_glFlush); - QGL_invalidateExtensionFunc(table.m_glFogf); - QGL_invalidateExtensionFunc(table.m_glFogfv); - QGL_invalidateExtensionFunc(table.m_glFogi); - QGL_invalidateExtensionFunc(table.m_glFogiv); - QGL_invalidateExtensionFunc(table.m_glFrontFace); - QGL_invalidateExtensionFunc(table.m_glFrustum); - QGL_invalidateExtensionFunc(table.m_glGenLists); - QGL_invalidateExtensionFunc(table.m_glGenTextures); - QGL_invalidateExtensionFunc(table.m_glGetBooleanv); - QGL_invalidateExtensionFunc(table.m_glGetClipPlane); - QGL_invalidateExtensionFunc(table.m_glGetDoublev); - QGL_invalidateExtensionFunc(table.m_glGetError); - QGL_invalidateExtensionFunc(table.m_glGetFloatv); - QGL_invalidateExtensionFunc(table.m_glGetIntegerv); - QGL_invalidateExtensionFunc(table.m_glGetLightfv); - QGL_invalidateExtensionFunc(table.m_glGetLightiv); - QGL_invalidateExtensionFunc(table.m_glGetMapdv); - QGL_invalidateExtensionFunc(table.m_glGetMapfv); - QGL_invalidateExtensionFunc(table.m_glGetMapiv); - QGL_invalidateExtensionFunc(table.m_glGetMaterialfv); - QGL_invalidateExtensionFunc(table.m_glGetMaterialiv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapfv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapuiv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapusv); - QGL_invalidateExtensionFunc(table.m_glGetPointerv); - QGL_invalidateExtensionFunc(table.m_glGetPolygonStipple); - table.m_glGetString = glGetString; - QGL_invalidateExtensionFunc(table.m_glGetTexEnvfv); - QGL_invalidateExtensionFunc(table.m_glGetTexEnviv); - QGL_invalidateExtensionFunc(table.m_glGetTexGendv); - QGL_invalidateExtensionFunc(table.m_glGetTexGenfv); - QGL_invalidateExtensionFunc(table.m_glGetTexGeniv); - QGL_invalidateExtensionFunc(table.m_glGetTexImage); - QGL_invalidateExtensionFunc(table.m_glGetTexLevelParameterfv); - QGL_invalidateExtensionFunc(table.m_glGetTexLevelParameteriv); - QGL_invalidateExtensionFunc(table.m_glGetTexParameterfv); - QGL_invalidateExtensionFunc(table.m_glGetTexParameteriv); - QGL_invalidateExtensionFunc(table.m_glHint); - QGL_invalidateExtensionFunc(table.m_glIndexMask); - QGL_invalidateExtensionFunc(table.m_glIndexPointer); - QGL_invalidateExtensionFunc(table.m_glIndexd); - QGL_invalidateExtensionFunc(table.m_glIndexdv); - QGL_invalidateExtensionFunc(table.m_glIndexf); - QGL_invalidateExtensionFunc(table.m_glIndexfv); - QGL_invalidateExtensionFunc(table.m_glIndexi); - QGL_invalidateExtensionFunc(table.m_glIndexiv); - QGL_invalidateExtensionFunc(table.m_glIndexs); - QGL_invalidateExtensionFunc(table.m_glIndexsv); - QGL_invalidateExtensionFunc(table.m_glIndexub); - QGL_invalidateExtensionFunc(table.m_glIndexubv); - QGL_invalidateExtensionFunc(table.m_glInitNames); - QGL_invalidateExtensionFunc(table.m_glInterleavedArrays); - QGL_invalidateExtensionFunc(table.m_glIsEnabled); - QGL_invalidateExtensionFunc(table.m_glIsList); - QGL_invalidateExtensionFunc(table.m_glIsTexture); - QGL_invalidateExtensionFunc(table.m_glLightModelf); - QGL_invalidateExtensionFunc(table.m_glLightModelfv); - QGL_invalidateExtensionFunc(table.m_glLightModeli); - QGL_invalidateExtensionFunc(table.m_glLightModeliv); - QGL_invalidateExtensionFunc(table.m_glLightf); - QGL_invalidateExtensionFunc(table.m_glLightfv); - QGL_invalidateExtensionFunc(table.m_glLighti); - QGL_invalidateExtensionFunc(table.m_glLightiv); - QGL_invalidateExtensionFunc(table.m_glLineStipple); - QGL_invalidateExtensionFunc(table.m_glLineWidth); - QGL_invalidateExtensionFunc(table.m_glListBase); - QGL_invalidateExtensionFunc(table.m_glLoadIdentity); - QGL_invalidateExtensionFunc(table.m_glLoadMatrixd); - QGL_invalidateExtensionFunc(table.m_glLoadMatrixf); - QGL_invalidateExtensionFunc(table.m_glLoadName); - QGL_invalidateExtensionFunc(table.m_glLogicOp); - QGL_invalidateExtensionFunc(table.m_glMap1d); - QGL_invalidateExtensionFunc(table.m_glMap1f); - QGL_invalidateExtensionFunc(table.m_glMap2d); - QGL_invalidateExtensionFunc(table.m_glMap2f); - QGL_invalidateExtensionFunc(table.m_glMapGrid1d); - QGL_invalidateExtensionFunc(table.m_glMapGrid1f); - QGL_invalidateExtensionFunc(table.m_glMapGrid2d); - QGL_invalidateExtensionFunc(table.m_glMapGrid2f); - QGL_invalidateExtensionFunc(table.m_glMaterialf); - QGL_invalidateExtensionFunc(table.m_glMaterialfv); - QGL_invalidateExtensionFunc(table.m_glMateriali); - QGL_invalidateExtensionFunc(table.m_glMaterialiv); - QGL_invalidateExtensionFunc(table.m_glMatrixMode); - QGL_invalidateExtensionFunc(table.m_glMultMatrixd); - QGL_invalidateExtensionFunc(table.m_glMultMatrixf); - QGL_invalidateExtensionFunc(table.m_glNewList); - QGL_invalidateExtensionFunc(table.m_glNormal3b); - QGL_invalidateExtensionFunc(table.m_glNormal3bv); - QGL_invalidateExtensionFunc(table.m_glNormal3d); - QGL_invalidateExtensionFunc(table.m_glNormal3dv); - QGL_invalidateExtensionFunc(table.m_glNormal3f); - QGL_invalidateExtensionFunc(table.m_glNormal3fv); - QGL_invalidateExtensionFunc(table.m_glNormal3i); - QGL_invalidateExtensionFunc(table.m_glNormal3iv); - QGL_invalidateExtensionFunc(table.m_glNormal3s); - QGL_invalidateExtensionFunc(table.m_glNormal3sv); - QGL_invalidateExtensionFunc(table.m_glNormalPointer); - QGL_invalidateExtensionFunc(table.m_glOrtho); - QGL_invalidateExtensionFunc(table.m_glPassThrough); - QGL_invalidateExtensionFunc(table.m_glPixelMapfv); - QGL_invalidateExtensionFunc(table.m_glPixelMapuiv); - QGL_invalidateExtensionFunc(table.m_glPixelMapusv); - QGL_invalidateExtensionFunc(table.m_glPixelStoref); - QGL_invalidateExtensionFunc(table.m_glPixelStorei); - QGL_invalidateExtensionFunc(table.m_glPixelTransferf); - QGL_invalidateExtensionFunc(table.m_glPixelTransferi); - QGL_invalidateExtensionFunc(table.m_glPixelZoom); - QGL_invalidateExtensionFunc(table.m_glPointSize); - QGL_invalidateExtensionFunc(table.m_glPolygonMode); - QGL_invalidateExtensionFunc(table.m_glPolygonOffset); - QGL_invalidateExtensionFunc(table.m_glPolygonStipple); - QGL_invalidateExtensionFunc(table.m_glPopAttrib); - QGL_invalidateExtensionFunc(table.m_glPopClientAttrib); - QGL_invalidateExtensionFunc(table.m_glPopMatrix); - QGL_invalidateExtensionFunc(table.m_glPopName); - QGL_invalidateExtensionFunc(table.m_glPrioritizeTextures); - QGL_invalidateExtensionFunc(table.m_glPushAttrib); - QGL_invalidateExtensionFunc(table.m_glPushClientAttrib); - QGL_invalidateExtensionFunc(table.m_glPushMatrix); - QGL_invalidateExtensionFunc(table.m_glPushName); - QGL_invalidateExtensionFunc(table.m_glRasterPos2d); - QGL_invalidateExtensionFunc(table.m_glRasterPos2dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2f); - QGL_invalidateExtensionFunc(table.m_glRasterPos2fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2i); - QGL_invalidateExtensionFunc(table.m_glRasterPos2iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2s); - QGL_invalidateExtensionFunc(table.m_glRasterPos2sv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3d); - QGL_invalidateExtensionFunc(table.m_glRasterPos3dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3f); - QGL_invalidateExtensionFunc(table.m_glRasterPos3fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3i); - QGL_invalidateExtensionFunc(table.m_glRasterPos3iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3s); - QGL_invalidateExtensionFunc(table.m_glRasterPos3sv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4d); - QGL_invalidateExtensionFunc(table.m_glRasterPos4dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4f); - QGL_invalidateExtensionFunc(table.m_glRasterPos4fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4i); - QGL_invalidateExtensionFunc(table.m_glRasterPos4iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4s); - QGL_invalidateExtensionFunc(table.m_glRasterPos4sv); - QGL_invalidateExtensionFunc(table.m_glReadBuffer); - QGL_invalidateExtensionFunc(table.m_glReadPixels); - QGL_invalidateExtensionFunc(table.m_glRectd); - QGL_invalidateExtensionFunc(table.m_glRectdv); - QGL_invalidateExtensionFunc(table.m_glRectf); - QGL_invalidateExtensionFunc(table.m_glRectfv); - QGL_invalidateExtensionFunc(table.m_glRecti); - QGL_invalidateExtensionFunc(table.m_glRectiv); - QGL_invalidateExtensionFunc(table.m_glRects); - QGL_invalidateExtensionFunc(table.m_glRectsv); - QGL_invalidateExtensionFunc(table.m_glRenderMode); - QGL_invalidateExtensionFunc(table.m_glRotated); - QGL_invalidateExtensionFunc(table.m_glRotatef); - QGL_invalidateExtensionFunc(table.m_glScaled); - QGL_invalidateExtensionFunc(table.m_glScalef); - QGL_invalidateExtensionFunc(table.m_glScissor); - QGL_invalidateExtensionFunc(table.m_glSelectBuffer); - QGL_invalidateExtensionFunc(table.m_glShadeModel); - QGL_invalidateExtensionFunc(table.m_glStencilFunc); - QGL_invalidateExtensionFunc(table.m_glStencilMask); - QGL_invalidateExtensionFunc(table.m_glStencilOp); - QGL_invalidateExtensionFunc(table.m_glTexCoord1d); - QGL_invalidateExtensionFunc(table.m_glTexCoord1dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1f); - QGL_invalidateExtensionFunc(table.m_glTexCoord1fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1i); - QGL_invalidateExtensionFunc(table.m_glTexCoord1iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1s); - QGL_invalidateExtensionFunc(table.m_glTexCoord1sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2d); - QGL_invalidateExtensionFunc(table.m_glTexCoord2dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2f); - QGL_invalidateExtensionFunc(table.m_glTexCoord2fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2i); - QGL_invalidateExtensionFunc(table.m_glTexCoord2iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2s); - QGL_invalidateExtensionFunc(table.m_glTexCoord2sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3d); - QGL_invalidateExtensionFunc(table.m_glTexCoord3dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3f); - QGL_invalidateExtensionFunc(table.m_glTexCoord3fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3i); - QGL_invalidateExtensionFunc(table.m_glTexCoord3iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3s); - QGL_invalidateExtensionFunc(table.m_glTexCoord3sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4d); - QGL_invalidateExtensionFunc(table.m_glTexCoord4dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4f); - QGL_invalidateExtensionFunc(table.m_glTexCoord4fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4i); - QGL_invalidateExtensionFunc(table.m_glTexCoord4iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4s); - QGL_invalidateExtensionFunc(table.m_glTexCoord4sv); - QGL_invalidateExtensionFunc(table.m_glTexCoordPointer); - QGL_invalidateExtensionFunc(table.m_glTexEnvf); - QGL_invalidateExtensionFunc(table.m_glTexEnvfv); - QGL_invalidateExtensionFunc(table.m_glTexEnvi); - QGL_invalidateExtensionFunc(table.m_glTexEnviv); - QGL_invalidateExtensionFunc(table.m_glTexGend); - QGL_invalidateExtensionFunc(table.m_glTexGendv); - QGL_invalidateExtensionFunc(table.m_glTexGenf); - QGL_invalidateExtensionFunc(table.m_glTexGenfv); - QGL_invalidateExtensionFunc(table.m_glTexGeni); - QGL_invalidateExtensionFunc(table.m_glTexGeniv); - QGL_invalidateExtensionFunc(table.m_glTexImage1D); - QGL_invalidateExtensionFunc(table.m_glTexImage2D); - QGL_invalidateExtensionFunc(table.m_glTexParameterf); - QGL_invalidateExtensionFunc(table.m_glTexParameterfv); - QGL_invalidateExtensionFunc(table.m_glTexParameteri); - QGL_invalidateExtensionFunc(table.m_glTexParameteriv); - QGL_invalidateExtensionFunc(table.m_glTexSubImage1D); - QGL_invalidateExtensionFunc(table.m_glTexSubImage2D); - QGL_invalidateExtensionFunc(table.m_glTranslated); - QGL_invalidateExtensionFunc(table.m_glTranslatef); - QGL_invalidateExtensionFunc(table.m_glVertex2d); - QGL_invalidateExtensionFunc(table.m_glVertex2dv); - QGL_invalidateExtensionFunc(table.m_glVertex2f); - QGL_invalidateExtensionFunc(table.m_glVertex2fv); - QGL_invalidateExtensionFunc(table.m_glVertex2i); - QGL_invalidateExtensionFunc(table.m_glVertex2iv); - QGL_invalidateExtensionFunc(table.m_glVertex2s); - QGL_invalidateExtensionFunc(table.m_glVertex2sv); - QGL_invalidateExtensionFunc(table.m_glVertex3d); - QGL_invalidateExtensionFunc(table.m_glVertex3dv); - QGL_invalidateExtensionFunc(table.m_glVertex3f); - QGL_invalidateExtensionFunc(table.m_glVertex3fv); - QGL_invalidateExtensionFunc(table.m_glVertex3i); - QGL_invalidateExtensionFunc(table.m_glVertex3iv); - QGL_invalidateExtensionFunc(table.m_glVertex3s); - QGL_invalidateExtensionFunc(table.m_glVertex3sv); - QGL_invalidateExtensionFunc(table.m_glVertex4d); - QGL_invalidateExtensionFunc(table.m_glVertex4dv); - QGL_invalidateExtensionFunc(table.m_glVertex4f); - QGL_invalidateExtensionFunc(table.m_glVertex4fv); - QGL_invalidateExtensionFunc(table.m_glVertex4i); - QGL_invalidateExtensionFunc(table.m_glVertex4iv); - QGL_invalidateExtensionFunc(table.m_glVertex4s); - QGL_invalidateExtensionFunc(table.m_glVertex4sv); - QGL_invalidateExtensionFunc(table.m_glVertexPointer); - QGL_invalidateExtensionFunc(table.m_glViewport); -} - -int QGL_Init(OpenGLBinding &table) -{ - QGL_clear(table); - -#if GDEF_OS_WINDOWS - qwglGetProcAddress = wglGetProcAddress; -#elif defined( XWINDOWS ) - qglXGetProcAddressARB = (glXGetProcAddressARBProc) dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); - if ((qglXQueryExtension == 0)) { - return 0; - } -#elif GDEF_OS_MACOS -#else -#error "unsupported platform" -#endif - - return 1; -} - -int g_qglMajorVersion = 0; -int g_qglMinorVersion = 0; - -// requires a valid gl context -void QGL_InitVersion() -{ -#if EXTENSIONS_ENABLED - const std::size_t versionSize = 256; - char version[versionSize]; - strncpy(version, reinterpret_cast( GlobalOpenGL().m_glGetString(GL_VERSION)), versionSize - 1); - version[versionSize - 1] = '\0'; - char *firstDot = strchr(version, '.'); - ASSERT_NOTNULL(firstDot); - *firstDot = '\0'; - g_qglMajorVersion = atoi(version); - char *secondDot = strchr(firstDot + 1, '.'); - if (secondDot != 0) { - *secondDot = '\0'; - } - g_qglMinorVersion = atoi(firstDot + 1); -#else - g_qglMajorVersion = 1; - g_qglMinorVersion = 1; -#endif -} - - -inline void extension_not_implemented(const char *extension) -{ - globalErrorStream() << "WARNING: OpenGL driver reports support for " << extension << " but does not implement it\n"; -} - -float g_maxTextureAnisotropy; - -float QGL_maxTextureAnisotropy() -{ - return g_maxTextureAnisotropy; -} - -void QGL_sharedContextCreated(OpenGLBinding &table) -{ - QGL_InitVersion(); - - table.major_version = g_qglMajorVersion; - table.minor_version = g_qglMinorVersion; - - table.m_glAccum = glAccum; - table.m_glAlphaFunc = glAlphaFunc; - table.m_glAreTexturesResident = glAreTexturesResident; - table.m_glArrayElement = glArrayElement; - table.m_glBegin = glBegin; - table.m_glBindTexture = glBindTexture; - table.m_glBitmap = glBitmap; - table.m_glBlendFunc = glBlendFunc; - table.m_glCallList = glCallList; - table.m_glCallLists = glCallLists; - table.m_glClear = glClear; - table.m_glClearAccum = glClearAccum; - table.m_glClearColor = glClearColor; - table.m_glClearDepth = glClearDepth; - table.m_glClearIndex = glClearIndex; - table.m_glClearStencil = glClearStencil; - table.m_glClipPlane = glClipPlane; - table.m_glColor3b = glColor3b; - table.m_glColor3bv = glColor3bv; - table.m_glColor3d = glColor3d; - table.m_glColor3dv = glColor3dv; - table.m_glColor3f = glColor3f; - table.m_glColor3fv = glColor3fv; - table.m_glColor3i = glColor3i; - table.m_glColor3iv = glColor3iv; - table.m_glColor3s = glColor3s; - table.m_glColor3sv = glColor3sv; - table.m_glColor3ub = glColor3ub; - table.m_glColor3ubv = glColor3ubv; - table.m_glColor3ui = glColor3ui; - table.m_glColor3uiv = glColor3uiv; - table.m_glColor3us = glColor3us; - table.m_glColor3usv = glColor3usv; - table.m_glColor4b = glColor4b; - table.m_glColor4bv = glColor4bv; - table.m_glColor4d = glColor4d; - table.m_glColor4dv = glColor4dv; - table.m_glColor4f = glColor4f; - table.m_glColor4fv = glColor4fv; - table.m_glColor4i = glColor4i; - table.m_glColor4iv = glColor4iv; - table.m_glColor4s = glColor4s; - table.m_glColor4sv = glColor4sv; - table.m_glColor4ub = glColor4ub; - table.m_glColor4ubv = glColor4ubv; - table.m_glColor4ui = glColor4ui; - table.m_glColor4uiv = glColor4uiv; - table.m_glColor4us = glColor4us; - table.m_glColor4usv = glColor4usv; - table.m_glColorMask = glColorMask; - table.m_glColorMaterial = glColorMaterial; - table.m_glColorPointer = glColorPointer; - table.m_glCopyPixels = glCopyPixels; - table.m_glCopyTexImage1D = glCopyTexImage1D; - table.m_glCopyTexImage2D = glCopyTexImage2D; - table.m_glCopyTexSubImage1D = glCopyTexSubImage1D; - table.m_glCopyTexSubImage2D = glCopyTexSubImage2D; - table.m_glCullFace = glCullFace; - table.m_glDeleteLists = glDeleteLists; - table.m_glDeleteTextures = glDeleteTextures; - table.m_glDepthFunc = glDepthFunc; - table.m_glDepthMask = glDepthMask; - table.m_glDepthRange = glDepthRange; - table.m_glDisable = glDisable; - table.m_glDisableClientState = glDisableClientState; - table.m_glDrawArrays = glDrawArrays; - table.m_glDrawBuffer = glDrawBuffer; - table.m_glDrawElements = glDrawElements; - table.m_glDrawPixels = glDrawPixels; - table.m_glEdgeFlag = glEdgeFlag; - table.m_glEdgeFlagPointer = glEdgeFlagPointer; - table.m_glEdgeFlagv = glEdgeFlagv; - table.m_glEnable = glEnable; - table.m_glEnableClientState = glEnableClientState; - table.m_glEnd = glEnd; - table.m_glEndList = glEndList; - table.m_glEvalCoord1d = glEvalCoord1d; - table.m_glEvalCoord1dv = glEvalCoord1dv; - table.m_glEvalCoord1f = glEvalCoord1f; - table.m_glEvalCoord1fv = glEvalCoord1fv; - table.m_glEvalCoord2d = glEvalCoord2d; - table.m_glEvalCoord2dv = glEvalCoord2dv; - table.m_glEvalCoord2f = glEvalCoord2f; - table.m_glEvalCoord2fv = glEvalCoord2fv; - table.m_glEvalMesh1 = glEvalMesh1; - table.m_glEvalMesh2 = glEvalMesh2; - table.m_glEvalPoint1 = glEvalPoint1; - table.m_glEvalPoint2 = glEvalPoint2; - table.m_glFeedbackBuffer = glFeedbackBuffer; - table.m_glFinish = glFinish; - table.m_glFlush = glFlush; - table.m_glFogf = glFogf; - table.m_glFogfv = glFogfv; - table.m_glFogi = glFogi; - table.m_glFogiv = glFogiv; - table.m_glFrontFace = glFrontFace; - table.m_glFrustum = glFrustum; - table.m_glGenLists = glGenLists; - table.m_glGenTextures = glGenTextures; - table.m_glGetBooleanv = glGetBooleanv; - table.m_glGetClipPlane = glGetClipPlane; - table.m_glGetDoublev = glGetDoublev; - table.m_glGetError = glGetError; - table.m_glGetFloatv = glGetFloatv; - table.m_glGetIntegerv = glGetIntegerv; - table.m_glGetLightfv = glGetLightfv; - table.m_glGetLightiv = glGetLightiv; - table.m_glGetMapdv = glGetMapdv; - table.m_glGetMapfv = glGetMapfv; - table.m_glGetMapiv = glGetMapiv; - table.m_glGetMaterialfv = glGetMaterialfv; - table.m_glGetMaterialiv = glGetMaterialiv; - table.m_glGetPixelMapfv = glGetPixelMapfv; - table.m_glGetPixelMapuiv = glGetPixelMapuiv; - table.m_glGetPixelMapusv = glGetPixelMapusv; - table.m_glGetPointerv = glGetPointerv; - table.m_glGetPolygonStipple = glGetPolygonStipple; - table.m_glGetString = glGetString; - table.m_glGetTexEnvfv = glGetTexEnvfv; - table.m_glGetTexEnviv = glGetTexEnviv; - table.m_glGetTexGendv = glGetTexGendv; - table.m_glGetTexGenfv = glGetTexGenfv; - table.m_glGetTexGeniv = glGetTexGeniv; - table.m_glGetTexImage = glGetTexImage; - table.m_glGetTexLevelParameterfv = glGetTexLevelParameterfv; - table.m_glGetTexLevelParameteriv = glGetTexLevelParameteriv; - table.m_glGetTexParameterfv = glGetTexParameterfv; - table.m_glGetTexParameteriv = glGetTexParameteriv; - table.m_glHint = glHint; - table.m_glIndexMask = glIndexMask; - table.m_glIndexPointer = glIndexPointer; - table.m_glIndexd = glIndexd; - table.m_glIndexdv = glIndexdv; - table.m_glIndexf = glIndexf; - table.m_glIndexfv = glIndexfv; - table.m_glIndexi = glIndexi; - table.m_glIndexiv = glIndexiv; - table.m_glIndexs = glIndexs; - table.m_glIndexsv = glIndexsv; - table.m_glIndexub = glIndexub; - table.m_glIndexubv = glIndexubv; - table.m_glInitNames = glInitNames; - table.m_glInterleavedArrays = glInterleavedArrays; - table.m_glIsEnabled = glIsEnabled; - table.m_glIsList = glIsList; - table.m_glIsTexture = glIsTexture; - table.m_glLightModelf = glLightModelf; - table.m_glLightModelfv = glLightModelfv; - table.m_glLightModeli = glLightModeli; - table.m_glLightModeliv = glLightModeliv; - table.m_glLightf = glLightf; - table.m_glLightfv = glLightfv; - table.m_glLighti = glLighti; - table.m_glLightiv = glLightiv; - table.m_glLineStipple = glLineStipple; - table.m_glLineWidth = glLineWidth; - table.m_glListBase = glListBase; - table.m_glLoadIdentity = glLoadIdentity; - table.m_glLoadMatrixd = glLoadMatrixd; - table.m_glLoadMatrixf = glLoadMatrixf; - table.m_glLoadName = glLoadName; - table.m_glLogicOp = glLogicOp; - table.m_glMap1d = glMap1d; - table.m_glMap1f = glMap1f; - table.m_glMap2d = glMap2d; - table.m_glMap2f = glMap2f; - table.m_glMapGrid1d = glMapGrid1d; - table.m_glMapGrid1f = glMapGrid1f; - table.m_glMapGrid2d = glMapGrid2d; - table.m_glMapGrid2f = glMapGrid2f; - table.m_glMaterialf = glMaterialf; - table.m_glMaterialfv = glMaterialfv; - table.m_glMateriali = glMateriali; - table.m_glMaterialiv = glMaterialiv; - table.m_glMatrixMode = glMatrixMode; - table.m_glMultMatrixd = glMultMatrixd; - table.m_glMultMatrixf = glMultMatrixf; - table.m_glNewList = glNewList; - table.m_glNormal3b = glNormal3b; - table.m_glNormal3bv = glNormal3bv; - table.m_glNormal3d = glNormal3d; - table.m_glNormal3dv = glNormal3dv; - table.m_glNormal3f = glNormal3f; - table.m_glNormal3fv = glNormal3fv; - table.m_glNormal3i = glNormal3i; - table.m_glNormal3iv = glNormal3iv; - table.m_glNormal3s = glNormal3s; - table.m_glNormal3sv = glNormal3sv; - table.m_glNormalPointer = glNormalPointer; - table.m_glOrtho = glOrtho; - table.m_glPassThrough = glPassThrough; - table.m_glPixelMapfv = glPixelMapfv; - table.m_glPixelMapuiv = glPixelMapuiv; - table.m_glPixelMapusv = glPixelMapusv; - table.m_glPixelStoref = glPixelStoref; - table.m_glPixelStorei = glPixelStorei; - table.m_glPixelTransferf = glPixelTransferf; - table.m_glPixelTransferi = glPixelTransferi; - table.m_glPixelZoom = glPixelZoom; - table.m_glPointSize = glPointSize; - table.m_glPolygonMode = glPolygonMode; - table.m_glPolygonOffset = glPolygonOffset; - table.m_glPolygonStipple = glPolygonStipple; - table.m_glPopAttrib = glPopAttrib; - table.m_glPopClientAttrib = glPopClientAttrib; - table.m_glPopMatrix = glPopMatrix; - table.m_glPopName = glPopName; - table.m_glPrioritizeTextures = glPrioritizeTextures; - table.m_glPushAttrib = glPushAttrib; - table.m_glPushClientAttrib = glPushClientAttrib; - table.m_glPushMatrix = glPushMatrix; - table.m_glPushName = glPushName; - table.m_glRasterPos2d = glRasterPos2d; - table.m_glRasterPos2dv = glRasterPos2dv; - table.m_glRasterPos2f = glRasterPos2f; - table.m_glRasterPos2fv = glRasterPos2fv; - table.m_glRasterPos2i = glRasterPos2i; - table.m_glRasterPos2iv = glRasterPos2iv; - table.m_glRasterPos2s = glRasterPos2s; - table.m_glRasterPos2sv = glRasterPos2sv; - table.m_glRasterPos3d = glRasterPos3d; - table.m_glRasterPos3dv = glRasterPos3dv; - table.m_glRasterPos3f = glRasterPos3f; - table.m_glRasterPos3fv = glRasterPos3fv; - table.m_glRasterPos3i = glRasterPos3i; - table.m_glRasterPos3iv = glRasterPos3iv; - table.m_glRasterPos3s = glRasterPos3s; - table.m_glRasterPos3sv = glRasterPos3sv; - table.m_glRasterPos4d = glRasterPos4d; - table.m_glRasterPos4dv = glRasterPos4dv; - table.m_glRasterPos4f = glRasterPos4f; - table.m_glRasterPos4fv = glRasterPos4fv; - table.m_glRasterPos4i = glRasterPos4i; - table.m_glRasterPos4iv = glRasterPos4iv; - table.m_glRasterPos4s = glRasterPos4s; - table.m_glRasterPos4sv = glRasterPos4sv; - table.m_glReadBuffer = glReadBuffer; - table.m_glReadPixels = glReadPixels; - table.m_glRectd = glRectd; - table.m_glRectdv = glRectdv; - table.m_glRectf = glRectf; - table.m_glRectfv = glRectfv; - table.m_glRecti = glRecti; - table.m_glRectiv = glRectiv; - table.m_glRects = glRects; - table.m_glRectsv = glRectsv; - table.m_glRenderMode = glRenderMode; - table.m_glRotated = glRotated; - table.m_glRotatef = glRotatef; - table.m_glScaled = glScaled; - table.m_glScalef = glScalef; - table.m_glScissor = glScissor; - table.m_glSelectBuffer = glSelectBuffer; - table.m_glShadeModel = glShadeModel; - table.m_glStencilFunc = glStencilFunc; - table.m_glStencilMask = glStencilMask; - table.m_glStencilOp = glStencilOp; - table.m_glTexCoord1d = glTexCoord1d; - table.m_glTexCoord1dv = glTexCoord1dv; - table.m_glTexCoord1f = glTexCoord1f; - table.m_glTexCoord1fv = glTexCoord1fv; - table.m_glTexCoord1i = glTexCoord1i; - table.m_glTexCoord1iv = glTexCoord1iv; - table.m_glTexCoord1s = glTexCoord1s; - table.m_glTexCoord1sv = glTexCoord1sv; - table.m_glTexCoord2d = glTexCoord2d; - table.m_glTexCoord2dv = glTexCoord2dv; - table.m_glTexCoord2f = glTexCoord2f; - table.m_glTexCoord2fv = glTexCoord2fv; - table.m_glTexCoord2i = glTexCoord2i; - table.m_glTexCoord2iv = glTexCoord2iv; - table.m_glTexCoord2s = glTexCoord2s; - table.m_glTexCoord2sv = glTexCoord2sv; - table.m_glTexCoord3d = glTexCoord3d; - table.m_glTexCoord3dv = glTexCoord3dv; - table.m_glTexCoord3f = glTexCoord3f; - table.m_glTexCoord3fv = glTexCoord3fv; - table.m_glTexCoord3i = glTexCoord3i; - table.m_glTexCoord3iv = glTexCoord3iv; - table.m_glTexCoord3s = glTexCoord3s; - table.m_glTexCoord3sv = glTexCoord3sv; - table.m_glTexCoord4d = glTexCoord4d; - table.m_glTexCoord4dv = glTexCoord4dv; - table.m_glTexCoord4f = glTexCoord4f; - table.m_glTexCoord4fv = glTexCoord4fv; - table.m_glTexCoord4i = glTexCoord4i; - table.m_glTexCoord4iv = glTexCoord4iv; - table.m_glTexCoord4s = glTexCoord4s; - table.m_glTexCoord4sv = glTexCoord4sv; - table.m_glTexCoordPointer = glTexCoordPointer; - table.m_glTexEnvf = glTexEnvf; - table.m_glTexEnvfv = glTexEnvfv; - table.m_glTexEnvi = glTexEnvi; - table.m_glTexEnviv = glTexEnviv; - table.m_glTexGend = glTexGend; - table.m_glTexGendv = glTexGendv; - table.m_glTexGenf = glTexGenf; - table.m_glTexGenfv = glTexGenfv; - table.m_glTexGeni = glTexGeni; - table.m_glTexGeniv = glTexGeniv; - table.m_glTexImage1D = glTexImage1D; - table.m_glTexImage2D = glTexImage2D; - table.m_glTexParameterf = glTexParameterf; - table.m_glTexParameterfv = glTexParameterfv; - table.m_glTexParameteri = glTexParameteri; - table.m_glTexParameteriv = glTexParameteriv; - table.m_glTexSubImage1D = glTexSubImage1D; - table.m_glTexSubImage2D = glTexSubImage2D; - table.m_glTranslated = glTranslated; - table.m_glTranslatef = glTranslatef; - table.m_glVertex2d = glVertex2d; - table.m_glVertex2dv = glVertex2dv; - table.m_glVertex2f = glVertex2f; - table.m_glVertex2fv = glVertex2fv; - table.m_glVertex2i = glVertex2i; - table.m_glVertex2iv = glVertex2iv; - table.m_glVertex2s = glVertex2s; - table.m_glVertex2sv = glVertex2sv; - table.m_glVertex3d = glVertex3d; - table.m_glVertex3dv = glVertex3dv; - table.m_glVertex3f = glVertex3f; - table.m_glVertex3fv = glVertex3fv; - table.m_glVertex3i = glVertex3i; - table.m_glVertex3iv = glVertex3iv; - table.m_glVertex3s = glVertex3s; - table.m_glVertex3sv = glVertex3sv; - table.m_glVertex4d = glVertex4d; - table.m_glVertex4dv = glVertex4dv; - table.m_glVertex4f = glVertex4f; - table.m_glVertex4fv = glVertex4fv; - table.m_glVertex4i = glVertex4i; - table.m_glVertex4iv = glVertex4iv; - table.m_glVertex4s = glVertex4s; - table.m_glVertex4sv = glVertex4sv; - table.m_glVertexPointer = glVertexPointer; - table.m_glViewport = glViewport; - - if (QGL_ExtensionSupported("GL_ARB_multitexture")) { - table.support_ARB_multitexture = - QGL_constructExtensionFunc(table.m_glActiveTextureARB, "glActiveTextureARB") - && QGL_constructExtensionFunc(table.m_glClientActiveTextureARB, "glClientActiveTextureARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dARB, "glMultiTexCoord1dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fARB, "glMultiTexCoord1fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1iARB, "glMultiTexCoord1iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1sARB, "glMultiTexCoord1sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1svARB, "glMultiTexCoord1svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dARB, "glMultiTexCoord2dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fARB, "glMultiTexCoord2fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2iARB, "glMultiTexCoord2iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2sARB, "glMultiTexCoord2sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2svARB, "glMultiTexCoord2svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dARB, "glMultiTexCoord3dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fARB, "glMultiTexCoord3fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3iARB, "glMultiTexCoord3iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3sARB, "glMultiTexCoord3sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3svARB, "glMultiTexCoord3svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dARB, "glMultiTexCoord4dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fARB, "glMultiTexCoord4fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4iARB, "glMultiTexCoord4iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4sARB, "glMultiTexCoord4sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4svARB, "glMultiTexCoord4svARB"); - - if (!table.support_ARB_multitexture) { - extension_not_implemented("GL_ARB_multitexture"); - } - } else { - table.support_ARB_multitexture = false; - } - - if (QGL_ExtensionSupported("GL_ARB_texture_compression")) { - table.support_ARB_texture_compression = - QGL_constructExtensionFunc(table.m_glCompressedTexImage3DARB, "glCompressedTexImage3DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage2DARB, "glCompressedTexImage2DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage1DARB, "glCompressedTexImage1DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage3DARB, "glCompressedTexSubImage3DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage2DARB, "glCompressedTexSubImage2DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage1DARB, "glCompressedTexSubImage1DARB") - && QGL_constructExtensionFunc(table.m_glGetCompressedTexImageARB, "glGetCompressedTexImageARB"); - - if (!table.support_ARB_texture_compression) { - extension_not_implemented("GL_ARB_texture_compression"); - } - } else { - table.support_ARB_texture_compression = false; - } - - table.support_EXT_texture_compression_s3tc = QGL_ExtensionSupported("GL_EXT_texture_compression_s3tc"); - - // GL 1.2 - if (table.major_version > 1 || table.minor_version >= 2) { - table.support_GL_1_2 = - QGL_constructExtensionFunc(table.m_glCopyTexSubImage3D, "glCopyTexSubImage3D") - && QGL_constructExtensionFunc(table.m_glDrawRangeElements, "glDrawRangeElements") - && QGL_constructExtensionFunc(table.m_glTexImage3D, "glTexImage3D") - && QGL_constructExtensionFunc(table.m_glTexSubImage3D, "glTexSubImage3D"); - - if (!table.support_GL_1_2) { - extension_not_implemented("GL_VERSION_1_2"); - } - } else { - table.support_GL_1_2 = false; - } - - // GL 1.3 - if (table.major_version > 1 || table.minor_version >= 3) { - table.support_GL_1_3 = - QGL_constructExtensionFunc(table.m_glActiveTexture, "glActiveTexture") - && QGL_constructExtensionFunc(table.m_glClientActiveTexture, "glClientActiveTexture") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage1D, "glCompressedTexImage1D") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage2D, "glCompressedTexImage2D") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage3D, "glCompressedTexImage3D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage1D, "glCompressedTexSubImage1D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage2D, "glCompressedTexSubImage2D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage3D, "glCompressedTexSubImage3D") - && QGL_constructExtensionFunc(table.m_glGetCompressedTexImage, "glGetCompressedTexImage") - && QGL_constructExtensionFunc(table.m_glLoadTransposeMatrixd, "glLoadTransposeMatrixd") - && QGL_constructExtensionFunc(table.m_glLoadTransposeMatrixf, "glLoadTransposeMatrixf") - && QGL_constructExtensionFunc(table.m_glMultTransposeMatrixd, "glMultTransposeMatrixd") - && QGL_constructExtensionFunc(table.m_glMultTransposeMatrixf, "glMultTransposeMatrixf") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1d, "glMultiTexCoord1d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dv, "glMultiTexCoord1dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1f, "glMultiTexCoord1f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fv, "glMultiTexCoord1fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1i, "glMultiTexCoord1i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1iv, "glMultiTexCoord1iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1s, "glMultiTexCoord1s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1sv, "glMultiTexCoord1sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2d, "glMultiTexCoord2d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dv, "glMultiTexCoord2dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2f, "glMultiTexCoord2f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fv, "glMultiTexCoord2fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2i, "glMultiTexCoord2i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2iv, "glMultiTexCoord2iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2s, "glMultiTexCoord2s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2sv, "glMultiTexCoord2sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3d, "glMultiTexCoord3d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dv, "glMultiTexCoord3dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3f, "glMultiTexCoord3f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fv, "glMultiTexCoord3fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3i, "glMultiTexCoord3i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3iv, "glMultiTexCoord3iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3s, "glMultiTexCoord3s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3sv, "glMultiTexCoord3sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4d, "glMultiTexCoord4d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dv, "glMultiTexCoord4dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4f, "glMultiTexCoord4f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fv, "glMultiTexCoord4fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4i, "glMultiTexCoord4i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4iv, "glMultiTexCoord4iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4s, "glMultiTexCoord4s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4sv, "glMultiTexCoord4sv") - && QGL_constructExtensionFunc(table.m_glSampleCoverage, "glSampleCoverage"); - - if (!table.support_GL_1_3) { - extension_not_implemented("GL_VERSION_1_3"); - } - } else { - table.support_GL_1_3 = false; - } - - // GL 1.4 - if (table.major_version > 1 || table.minor_version >= 4) { - table.support_GL_1_4 = - QGL_constructExtensionFunc(table.m_glBlendColor, "glBlendColor") - && QGL_constructExtensionFunc(table.m_glBlendEquation, "glBlendEquation") - && QGL_constructExtensionFunc(table.m_glBlendFuncSeparate, "glBlendFuncSeparate") - && QGL_constructExtensionFunc(table.m_glFogCoordPointer, "glFogCoordPointer") - && QGL_constructExtensionFunc(table.m_glFogCoordd, "glFogCoordd") - && QGL_constructExtensionFunc(table.m_glFogCoorddv, "glFogCoorddv") - && QGL_constructExtensionFunc(table.m_glFogCoordf, "glFogCoordf") - && QGL_constructExtensionFunc(table.m_glFogCoordfv, "glFogCoordfv") - && QGL_constructExtensionFunc(table.m_glMultiDrawArrays, "glMultiDrawArrays") - && QGL_constructExtensionFunc(table.m_glMultiDrawElements, "glMultiDrawElements") - && QGL_constructExtensionFunc(table.m_glPointParameterf, "glPointParameterf") - && QGL_constructExtensionFunc(table.m_glPointParameterfv, "glPointParameterfv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3b, "glSecondaryColor3b") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3bv, "glSecondaryColor3bv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3d, "glSecondaryColor3d") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3dv, "glSecondaryColor3dv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3f, "glSecondaryColor3f") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3fv, "glSecondaryColor3fv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3i, "glSecondaryColor3i") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3iv, "glSecondaryColor3iv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3s, "glSecondaryColor3s") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3sv, "glSecondaryColor3sv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ub, "glSecondaryColor3ub") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ubv, "glSecondaryColor3ubv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ui, "glSecondaryColor3ui") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3uiv, "glSecondaryColor3uiv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3us, "glSecondaryColor3us") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3usv, "glSecondaryColor3usv") - && QGL_constructExtensionFunc(table.m_glSecondaryColorPointer, "glSecondaryColorPointer") - && QGL_constructExtensionFunc(table.m_glWindowPos2d, "glWindowPos2d") - && QGL_constructExtensionFunc(table.m_glWindowPos2dv, "glWindowPos2dv") - && QGL_constructExtensionFunc(table.m_glWindowPos2f, "glWindowPos2f") - && QGL_constructExtensionFunc(table.m_glWindowPos2fv, "glWindowPos2fv") - && QGL_constructExtensionFunc(table.m_glWindowPos2i, "glWindowPos2i") - && QGL_constructExtensionFunc(table.m_glWindowPos2iv, "glWindowPos2iv") - && QGL_constructExtensionFunc(table.m_glWindowPos2s, "glWindowPos2s") - && QGL_constructExtensionFunc(table.m_glWindowPos2sv, "glWindowPos2sv") - && QGL_constructExtensionFunc(table.m_glWindowPos3d, "glWindowPos3d") - && QGL_constructExtensionFunc(table.m_glWindowPos3dv, "glWindowPos3dv") - && QGL_constructExtensionFunc(table.m_glWindowPos3f, "glWindowPos3f") - && QGL_constructExtensionFunc(table.m_glWindowPos3fv, "glWindowPos3fv") - && QGL_constructExtensionFunc(table.m_glWindowPos3i, "glWindowPos3i") - && QGL_constructExtensionFunc(table.m_glWindowPos3iv, "glWindowPos3iv") - && QGL_constructExtensionFunc(table.m_glWindowPos3s, "glWindowPos3s") - && QGL_constructExtensionFunc(table.m_glWindowPos3sv, "glWindowPos3sv"); - - if (!table.support_GL_1_4) { - extension_not_implemented("GL_VERSION_1_4"); - } - } else { - table.support_GL_1_4 = false; - } - - // GL 1.5 - if (table.major_version > 1 || table.minor_version >= 5) { - table.support_GL_1_5 = - QGL_constructExtensionFunc(table.m_glBeginQuery, "glBeginQuery") - && QGL_constructExtensionFunc(table.m_glBindBuffer, "glBindBuffer") - && QGL_constructExtensionFunc(table.m_glBufferData, "glBufferData") - && QGL_constructExtensionFunc(table.m_glBufferSubData, "glBufferSubData") - && QGL_constructExtensionFunc(table.m_glDeleteBuffers, "glDeleteBuffers") - && QGL_constructExtensionFunc(table.m_glDeleteQueries, "glDeleteQueries") - && QGL_constructExtensionFunc(table.m_glEndQuery, "glEndQuery") - && QGL_constructExtensionFunc(table.m_glGenBuffers, "glGenBuffers") - && QGL_constructExtensionFunc(table.m_glGenQueries, "glGenQueries") - && QGL_constructExtensionFunc(table.m_glGetBufferParameteriv, "glGetBufferParameteriv") - && QGL_constructExtensionFunc(table.m_glGetBufferPointerv, "glGetBufferPointerv") - && QGL_constructExtensionFunc(table.m_glGetBufferSubData, "glGetBufferSubData") - && QGL_constructExtensionFunc(table.m_glGetQueryObjectiv, "glGetQueryObjectiv") - && QGL_constructExtensionFunc(table.m_glGetQueryObjectuiv, "glGetQueryObjectuiv") - && QGL_constructExtensionFunc(table.m_glGetQueryiv, "glGetQueryiv") - && QGL_constructExtensionFunc(table.m_glIsBuffer, "glIsBuffer") - && QGL_constructExtensionFunc(table.m_glIsQuery, "glIsQuery") - && QGL_constructExtensionFunc(table.m_glMapBuffer, "glMapBuffer") - && QGL_constructExtensionFunc(table.m_glUnmapBuffer, "glUnmapBuffer"); - - if (!table.support_GL_1_5) { - extension_not_implemented("GL_VERSION_1_5"); - } - } else { - table.support_GL_1_5 = false; - } - - - if (QGL_ExtensionSupported("GL_ARB_vertex_program")) { - table.support_ARB_vertex_program = - QGL_constructExtensionFunc(table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB") - && QGL_constructExtensionFunc(table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glProgramStringARB, "glProgramStringARB") - && QGL_constructExtensionFunc(table.m_glBindProgramARB, "glBindProgramARB") - && QGL_constructExtensionFunc(table.m_glDeleteProgramsARB, "glDeleteProgramsARB") - && QGL_constructExtensionFunc(table.m_glGenProgramsARB, "glGenProgramsARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4dARB, "glProgramEnvParameter4dARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4dvARB, "glProgramEnvParameter4dvARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4fARB, "glProgramEnvParameter4fARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4fvARB, "glProgramEnvParameter4fvARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4dARB, "glProgramLocalParameter4dARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4dvARB, "glProgramLocalParameter4dvARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4fARB, "glProgramLocalParameter4fARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4fvARB, "glProgramLocalParameter4fvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramEnvParameterdvARB, "glGetProgramEnvParameterdvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramEnvParameterfvARB, "glGetProgramEnvParameterfvARB") - && - QGL_constructExtensionFunc(table.m_glGetProgramLocalParameterdvARB, "glGetProgramLocalParameterdvARB") - && - QGL_constructExtensionFunc(table.m_glGetProgramLocalParameterfvARB, "glGetProgramLocalParameterfvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramivARB, "glGetProgramivARB") - && QGL_constructExtensionFunc(table.m_glGetProgramStringARB, "glGetProgramStringARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB") - && QGL_constructExtensionFunc(table.m_glIsProgramARB, "glIsProgramARB"); - - if (!table.support_ARB_vertex_program) { - extension_not_implemented("GL_ARB_vertex_program"); - } - } else { - table.support_ARB_vertex_program = false; - } - - - table.support_ARB_fragment_program = QGL_ExtensionSupported("GL_ARB_fragment_program"); - - if (QGL_ExtensionSupported("GL_ARB_shader_objects")) { - table.support_ARB_shader_objects = - QGL_constructExtensionFunc(table.m_glDeleteObjectARB, "glDeleteObjectARB") - && QGL_constructExtensionFunc(table.m_glGetHandleARB, "glGetHandleARB") - && QGL_constructExtensionFunc(table.m_glDetachObjectARB, "glDetachObjectARB") - && QGL_constructExtensionFunc(table.m_glCreateShaderObjectARB, "glCreateShaderObjectARB") - && QGL_constructExtensionFunc(table.m_glShaderSourceARB, "glShaderSourceARB") - && QGL_constructExtensionFunc(table.m_glCompileShaderARB, "glCompileShaderARB") - && QGL_constructExtensionFunc(table.m_glCreateProgramObjectARB, "glCreateProgramObjectARB") - && QGL_constructExtensionFunc(table.m_glAttachObjectARB, "glAttachObjectARB") - && QGL_constructExtensionFunc(table.m_glLinkProgramARB, "glLinkProgramARB") - && QGL_constructExtensionFunc(table.m_glUseProgramObjectARB, "glUseProgramObjectARB") - && QGL_constructExtensionFunc(table.m_glValidateProgramARB, "glValidateProgramARB") - && QGL_constructExtensionFunc(table.m_glUniform1fARB, "glUniform1fARB") - && QGL_constructExtensionFunc(table.m_glUniform2fARB, "glUniform2fARB") - && QGL_constructExtensionFunc(table.m_glUniform3fARB, "glUniform3fARB") - && QGL_constructExtensionFunc(table.m_glUniform4fARB, "glUniform4fARB") - && QGL_constructExtensionFunc(table.m_glUniform1iARB, "glUniform1iARB") - && QGL_constructExtensionFunc(table.m_glUniform2iARB, "glUniform2iARB") - && QGL_constructExtensionFunc(table.m_glUniform3iARB, "glUniform3iARB") - && QGL_constructExtensionFunc(table.m_glUniform4iARB, "glUniform4iARB") - && QGL_constructExtensionFunc(table.m_glUniform1fvARB, "glUniform1fvARB") - && QGL_constructExtensionFunc(table.m_glUniform2fvARB, "glUniform2fvARB") - && QGL_constructExtensionFunc(table.m_glUniform3fvARB, "glUniform3fvARB") - && QGL_constructExtensionFunc(table.m_glUniform4fvARB, "glUniform4fvARB") - && QGL_constructExtensionFunc(table.m_glUniform1ivARB, "glUniform1ivARB") - && QGL_constructExtensionFunc(table.m_glUniform2ivARB, "glUniform2ivARB") - && QGL_constructExtensionFunc(table.m_glUniform3ivARB, "glUniform3ivARB") - && QGL_constructExtensionFunc(table.m_glUniform4ivARB, "glUniform4ivARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix2fvARB, "glUniformMatrix2fvARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix3fvARB, "glUniformMatrix3fvARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix4fvARB, "glUniformMatrix4fvARB") - && QGL_constructExtensionFunc(table.m_glGetObjectParameterfvARB, "glGetObjectParameterfvARB") - && QGL_constructExtensionFunc(table.m_glGetObjectParameterivARB, "glGetObjectParameterivARB") - && QGL_constructExtensionFunc(table.m_glGetInfoLogARB, "glGetInfoLogARB") - && QGL_constructExtensionFunc(table.m_glGetAttachedObjectsARB, "glGetAttachedObjectsARB") - && QGL_constructExtensionFunc(table.m_glGetUniformLocationARB, "glGetUniformLocationARB") - && QGL_constructExtensionFunc(table.m_glGetActiveUniformARB, "glGetActiveUniformARB") - && QGL_constructExtensionFunc(table.m_glGetUniformfvARB, "glGetUniformfvARB") - && QGL_constructExtensionFunc(table.m_glGetUniformivARB, "glGetUniformivARB") - && QGL_constructExtensionFunc(table.m_glGetShaderSourceARB, "glGetShaderSourceARB"); - - if (!table.support_ARB_shader_objects) { - extension_not_implemented("GL_ARB_shader_objects"); - } - } else { - table.support_ARB_shader_objects = false; - } - - if (QGL_ExtensionSupported("GL_ARB_vertex_shader")) { - table.support_ARB_vertex_shader = - QGL_constructExtensionFunc(table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB") - && QGL_constructExtensionFunc(table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB") - && QGL_constructExtensionFunc(table.m_glBindAttribLocationARB, "glBindAttribLocationARB") - && QGL_constructExtensionFunc(table.m_glGetActiveAttribARB, "glGetActiveAttribARB") - && QGL_constructExtensionFunc(table.m_glGetAttribLocationARB, "glGetAttribLocationARB"); - - if (!table.support_ARB_vertex_shader) { - extension_not_implemented("GL_ARB_vertex_shader"); - } - } else { - table.support_ARB_vertex_shader = false; - } - - if (QGL_ExtensionSupported("GL_NV_vertex_program2")) { - table.support_NV_vertex_program2 = - QGL_constructExtensionFunc(table.m_glAreProgramsResidentNV, "glAreProgramsResidentNV") - && QGL_constructExtensionFunc(table.m_glBindProgramNV, "glBindProgramNV") - && QGL_constructExtensionFunc(table.m_glDeleteProgramsNV, "glDeleteProgramsNV") - && QGL_constructExtensionFunc(table.m_glExecuteProgramNV, "glExecuteProgramNV") - && QGL_constructExtensionFunc(table.m_glGenProgramsNV, "glGenProgramsNV") - && QGL_constructExtensionFunc(table.m_glGetProgramParameterdvNV, "glGetProgramParameterdvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramParameterfvNV, "glGetProgramParameterfvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramivNV, "glGetProgramivNV") - && QGL_constructExtensionFunc(table.m_glGetProgramStringNV, "glGetProgramStringNV") - && QGL_constructExtensionFunc(table.m_glGetTrackMatrixivNV, "glGetTrackMatrixivNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvNV, "glGetVertexAttribdvNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvNV, "glGetVertexAttribfvNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivNV, "glGetVertexAttribivNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervNV, "glGetVertexAttribPointervNV") - && QGL_constructExtensionFunc(table.m_glIsProgramNV, "glIsProgramNV") - && QGL_constructExtensionFunc(table.m_glLoadProgramNV, "glLoadProgramNV") - && QGL_constructExtensionFunc(table.m_glProgramParameter4fNV, "glProgramParameter4fNV") - && QGL_constructExtensionFunc(table.m_glProgramParameter4fvNV, "glProgramParameter4fvNV") - && QGL_constructExtensionFunc(table.m_glProgramParameters4fvNV, "glProgramParameters4fvNV") - && QGL_constructExtensionFunc(table.m_glRequestResidentProgramsNV, "glRequestResidentProgramsNV") - && QGL_constructExtensionFunc(table.m_glTrackMatrixNV, "glTrackMatrixNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerNV, "glVertexAttribPointerNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fNV, "glVertexAttrib1fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvNV, "glVertexAttrib1fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fNV, "glVertexAttrib2fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvNV, "glVertexAttrib2fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fNV, "glVertexAttrib3fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvNV, "glVertexAttrib3fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fNV, "glVertexAttrib4fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvNV, "glVertexAttrib4fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs1fvNV, "glVertexAttribs1fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs2fvNV, "glVertexAttribs2fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs3fvNV, "glVertexAttribs3fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs4fvNV, "glVertexAttribs4fvNV"); - - if (!table.support_NV_vertex_program2) { - extension_not_implemented("GL_NV_vertex_program2"); - } - } else { - table.support_NV_vertex_program2 = false; - QGL_invalidateExtensionFunc(table.m_glAreProgramsResidentNV); - QGL_invalidateExtensionFunc(table.m_glBindProgramNV); - QGL_invalidateExtensionFunc(table.m_glDeleteProgramsNV); - QGL_invalidateExtensionFunc(table.m_glExecuteProgramNV); - QGL_invalidateExtensionFunc(table.m_glGenProgramsNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramParameterdvNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramParameterfvNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramivNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramStringNV); - QGL_invalidateExtensionFunc(table.m_glGetTrackMatrixivNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribdvNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribfvNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribivNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribPointervNV); - QGL_invalidateExtensionFunc(table.m_glIsProgramNV); - QGL_invalidateExtensionFunc(table.m_glLoadProgramNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameter4fNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameter4fvNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameters4fvNV); - QGL_invalidateExtensionFunc(table.m_glRequestResidentProgramsNV); - QGL_invalidateExtensionFunc(table.m_glTrackMatrixNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribPointerNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib1fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib1fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib2fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib2fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib3fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib3fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib4fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib4fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs1fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs2fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs3fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs4fvNV); - } - - if (QGL_ExtensionSupported("GL_NV_fragment_program")) { - table.support_NV_fragment_program = - QGL_constructExtensionFunc(table.m_glProgramNamedParameter4fNV, "glProgramNamedParameter4fNV") - && QGL_constructExtensionFunc(table.m_glProgramNamedParameter4fvNV, "glProgramNamedParameter4fvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramNamedParameterfvNV, "glGetProgramNamedParameterfvNV"); - - if (!table.support_NV_fragment_program) { - extension_not_implemented("GL_NV_fragment_program"); - } - } else { - table.support_NV_fragment_program = false; - } - - table.support_ARB_fragment_shader = QGL_ExtensionSupported("GL_ARB_fragment_shader"); - table.support_ARB_shading_language_100 = QGL_ExtensionSupported("GL_ARB_shading_language_100"); - - if (QGL_ExtensionSupported("GL_EXT_texture_filter_anisotropic")) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &g_maxTextureAnisotropy); - globalOutputStream() << "Anisotropic filtering possible (max " << g_maxTextureAnisotropy << "x)\n"; - } else { - globalOutputStream() << "No Anisotropic filtering available\n"; - g_maxTextureAnisotropy = 0; - } -} - -void QGL_sharedContextDestroyed(OpenGLBinding &table) -{ - QGL_clear(table); -} - - -void QGL_assertNoErrors(const char *file, int line) -{ - GLenum error = GlobalOpenGL().m_glGetError(); - while (error != GL_NO_ERROR) { - const char *errorString = reinterpret_cast( qgluErrorString(error)); - if (error == GL_OUT_OF_MEMORY) { - ERROR_MESSAGE("OpenGL out of memory error at " << file << ":" << line << ": " << errorString); - } else { - ERROR_MESSAGE("OpenGL error at " << file << ":" << line << ": " << errorString); - } - error = GlobalOpenGL().m_glGetError(); - } -} - - -class QglAPI { -OpenGLBinding m_qgl; -public: -typedef OpenGLBinding Type; - -STRING_CONSTANT(Name, "*"); - -QglAPI() -{ - QGL_Init(m_qgl); - - m_qgl.assertNoErrors = &QGL_assertNoErrors; -} - -~QglAPI() -{ - QGL_Shutdown(m_qgl); -} - -OpenGLBinding *getTable() -{ - return &m_qgl; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule QglModule; -typedef Static StaticQglModule; -StaticRegisterModule staticRegisterQgl(StaticQglModule::instance()); diff --git a/src/qgl.h b/src/qgl.h deleted file mode 100644 index 9d80852..0000000 --- a/src/qgl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_QGL_H ) -#define INCLUDED_QGL_H - -struct OpenGLBinding; - -void QGL_sharedContextCreated(OpenGLBinding &table); - -void QGL_sharedContextDestroyed(OpenGLBinding &table); - -bool QGL_ExtensionSupported(const char *extension); - -float QGL_maxTextureAnisotropy(); - -#endif diff --git a/src/referencecache.cpp b/src/referencecache.cpp deleted file mode 100644 index d053e70..0000000 --- a/src/referencecache.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "referencecache.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "iselection.h" -#include "iundo.h" -#include "imap.h" - -MapModules &ReferenceAPI_getMapModules(); - -#include "imodel.h" - -ModelModules &ReferenceAPI_getModelModules(); - -#include "ifilesystem.h" -#include "iarchive.h" -#include "ifiletypes.h" -#include "ireference.h" -#include "ientity.h" -#include "qerplugin.h" - -#include - -#include "container/cache.h" -#include "container/hashfunc.h" -#include "os/path.h" -#include "stream/textfilestream.h" -#include "nullmodel.h" -#include "maplib.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "moduleobserver.h" -#include "moduleobservers.h" - -#include "mainframe.h" -#include "map.h" -#include "filetypes.h" - - -bool References_Saved(); - -void MapChanged() -{ - Map_SetModified(g_map, !References_Saved()); -} - - -EntityCreator *g_entityCreator = 0; - -bool MapResource_loadFile(const MapFormat &format, scene::Node &root, const char *filename) -{ - globalOutputStream() << "Open file " << filename << " for read..."; - TextFileInputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "success\n"; - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(filename), "Loading Map"); - ASSERT_NOTNULL(g_entityCreator); - format.readGraph(root, file, *g_entityCreator); - return true; - } else { - globalErrorStream() << "failure\n"; - return false; - } -} - -NodeSmartReference MapResource_load(const MapFormat &format, const char *path, const char *name) -{ - NodeSmartReference root(NewMapRoot(name)); - - StringOutputStream fullpath(256); - fullpath << path << name; - - if (path_is_absolute(fullpath.c_str())) { - MapResource_loadFile(format, root, fullpath.c_str()); - } else { - globalErrorStream() << "map path is not fully qualified: " << makeQuoted(fullpath.c_str()) << "\n"; - } - - return root; -} - -bool MapResource_saveFile(const MapFormat &format, scene::Node &root, GraphTraversalFunc traverse, const char *filename) -{ - //ASSERT_MESSAGE(path_is_absolute(filename), "MapResource_saveFile: path is not absolute: " << makeQuoted(filename)); - globalOutputStream() << "Open file " << filename << " for write..."; - TextFileOutputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "success\n"; - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(filename), "Saving Map"); - format.writeGraph(root, traverse, file); - return true; - } - - globalErrorStream() << "failure\n"; - return false; -} - -bool file_saveBackup(const char *path) -{ - if (file_writeable(path)) { - StringOutputStream backup(256); - backup << StringRange(path, path_get_extension(path)) << "bak"; - - return (!file_exists(backup.c_str()) || file_remove(backup.c_str())) // remove backup - && file_move(path, backup.c_str()); // rename current to backup - } - - globalErrorStream() << "map path is not writeable: " << makeQuoted(path) << "\n"; - return false; -} - -bool MapResource_save(const MapFormat &format, scene::Node &root, const char *path, const char *name) -{ - StringOutputStream fullpath(256); - fullpath << path << name; - - if (path_is_absolute(fullpath.c_str())) { - if (!file_exists(fullpath.c_str()) || file_saveBackup(fullpath.c_str())) { - return MapResource_saveFile(format, root, Map_Traverse, fullpath.c_str()); - } - - globalErrorStream() << "failed to save a backup map file: " << makeQuoted(fullpath.c_str()) << "\n"; - return false; - } - - globalErrorStream() << "map path is not fully qualified: " << makeQuoted(fullpath.c_str()) << "\n"; - return false; -} - -namespace { -NodeSmartReference g_nullNode(NewNullNode()); -NodeSmartReference g_nullModel(g_nullNode); -} - -class NullModelLoader : public ModelLoader { -public: -scene::Node &loadModel(ArchiveFile &file) -{ - return g_nullModel; -} -}; - -namespace { -NullModelLoader g_NullModelLoader; -} - - -/// \brief Returns the model loader for the model \p type or 0 if the model \p type has no loader module -ModelLoader *ModelLoader_forType(const char *type) -{ - const char *moduleName = findModuleName(&GlobalFiletypes(), ModelLoader::Name(), type); - if (string_not_empty(moduleName)) { - ModelLoader *table = ReferenceAPI_getModelModules().findModule(moduleName); - if (table != 0) { - return table; - } else { - globalErrorStream() << "ERROR: Model type incorrectly registered: \"" << moduleName << "\"\n"; - return &g_NullModelLoader; - } - } - return 0; -} - -NodeSmartReference ModelResource_load(ModelLoader *loader, const char *name) -{ - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(name), "Loading Model"); - - NodeSmartReference model(g_nullModel); - - - ArchiveFile *file = GlobalFileSystem().openFile(name); - - if (file != 0) { - // Only output failures, we don't need to spam the console with successes - //globalOutputStream() << "Loaded Model: \"" << name << "\"\n"; - model = loader->loadModel(*file); - file->release(); - } else { - globalErrorStream() << "Model load failed: \"" << name << "\"\n"; - } - - model.get().m_isRoot = true; - return model; -} - - -inline hash_t path_hash(const char *path, hash_t previous = 0) -{ -#if GDEF_OS_WINDOWS - return string_hash_nocase( path, previous ); -#else // UNIX - return string_hash(path, previous); -#endif -} - -struct PathEqual { - bool operator()(const CopiedString &path, const CopiedString &other) const - { - return path_equal(path.c_str(), other.c_str()); - } -}; - -struct PathHash { - typedef hash_t hash_type; - - hash_type operator()(const CopiedString &path) const - { - return path_hash(path.c_str()); - } -}; - -typedef std::pair ModelKey; - -struct ModelKeyEqual { - bool operator()(const ModelKey &key, const ModelKey &other) const - { - return path_equal(key.first.c_str(), other.first.c_str()) && - path_equal(key.second.c_str(), other.second.c_str()); - } -}; - -struct ModelKeyHash { - typedef hash_t hash_type; - - hash_type operator()(const ModelKey &key) const - { - return hash_combine(path_hash(key.first.c_str()), path_hash(key.second.c_str())); - } -}; - -typedef HashTable ModelCache; -ModelCache g_modelCache; -bool g_modelCache_enabled = true; - -ModelCache::iterator ModelCache_find(const char *path, const char *name) -{ - if (g_modelCache_enabled) { - return g_modelCache.find(ModelKey(path, name)); - } - return g_modelCache.end(); -} - -ModelCache::iterator ModelCache_insert(const char *path, const char *name, scene::Node &node) -{ - if (g_modelCache_enabled) { - return g_modelCache.insert(ModelKey(path, name), NodeSmartReference(node)); - } - return g_modelCache.insert(ModelKey("", ""), g_nullModel); -} - -void ModelCache_flush(const char *path, const char *name) -{ - ModelCache::iterator i = g_modelCache.find(ModelKey(path, name)); - if (i != g_modelCache.end()) { - //ASSERT_MESSAGE((*i).value.getCount() == 0, "resource flushed while still in use: " << (*i).key.first.c_str() << (*i).key.second.c_str()); - g_modelCache.erase(i); - } -} - -void ModelCache_clear() -{ - g_modelCache_enabled = false; - g_modelCache.clear(); - g_modelCache_enabled = true; -} - -NodeSmartReference Model_load(ModelLoader *loader, const char *path, const char *name, const char *type) -{ - if (loader != 0) { - return ModelResource_load(loader, name); - } else { - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), type); - if (string_not_empty(moduleName)) { - const MapFormat *format = ReferenceAPI_getMapModules().findModule(moduleName); - if (format != 0) { - return MapResource_load(*format, path, name); - } else { - globalErrorStream() << "ERROR: Map type incorrectly registered: \"" << moduleName << "\"\n"; - return g_nullModel; - } - } else { - if (string_not_empty(type)) { - globalErrorStream() << "Model type not supported: \"" << name << "\"\n"; - } - return g_nullModel; - } - } -} - -namespace { -bool g_realised = false; - -// name may be absolute or relative -const char *rootPath(const char *name) -{ - return GlobalFileSystem().findRoot( - path_is_absolute(name) - ? name - : GlobalFileSystem().findFile(name) - ); -} -} - -struct ModelResource : public Resource { - NodeSmartReference m_model; - const CopiedString m_originalName; - CopiedString m_path; - CopiedString m_name; - CopiedString m_type; - ModelLoader *m_loader; - ModuleObservers m_observers; - std::time_t m_modified; - std::size_t m_unrealised; - - ModelResource(const CopiedString &name) : - m_model(g_nullModel), - m_originalName(name), - m_type(path_get_extension(name.c_str())), - m_loader(0), - m_modified(0), - m_unrealised(1) - { - m_loader = ModelLoader_forType(m_type.c_str()); - - if (g_realised) { - realise(); - } - } - - ~ModelResource() - { - if (realised()) { - unrealise(); - } - ASSERT_MESSAGE(!realised(), "ModelResource::~ModelResource: resource reference still realised: " - << makeQuoted(m_name.c_str())); - } - - // NOT COPYABLE - ModelResource(const ModelResource &); - - // NOT ASSIGNABLE - ModelResource &operator=(const ModelResource &); - - void setModel(const NodeSmartReference &model) - { - m_model = model; - } - - void clearModel() - { - m_model = g_nullModel; - } - - void loadCached() - { - if (g_modelCache_enabled) { - // cache lookup - ModelCache::iterator i = ModelCache_find(m_path.c_str(), m_name.c_str()); - if (i == g_modelCache.end()) { - i = ModelCache_insert( - m_path.c_str(), - m_name.c_str(), - Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str()) - ); - } - - setModel((*i).value); - } else { - setModel(Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str())); - } - } - - void loadModel() - { - loadCached(); - connectMap(); - mapSave(); - } - - bool load() - { - ASSERT_MESSAGE(realised(), "resource not realised"); - if (m_model == g_nullModel) { - loadModel(); - } - - return m_model != g_nullModel; - } - - bool save() - { - if (!mapSaved()) { - const char *moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), m_type.c_str()); - if (string_not_empty(moduleName)) { - const MapFormat *format = ReferenceAPI_getMapModules().findModule(moduleName); - if (format != 0 && MapResource_save(*format, m_model.get(), m_path.c_str(), m_name.c_str())) { - mapSave(); - return true; - } - } - } - return false; - } - - void flush() - { - if (realised()) { - ModelCache_flush(m_path.c_str(), m_name.c_str()); - } - } - - scene::Node *getNode() - { - //if(m_model != g_nullModel) - { - return m_model.get_pointer(); - } - //return 0; - } - - void setNode(scene::Node *node) - { - ModelCache::iterator i = ModelCache_find(m_path.c_str(), m_name.c_str()); - if (i != g_modelCache.end()) { - (*i).value = NodeSmartReference(*node); - } - setModel(NodeSmartReference(*node)); - - connectMap(); - } - - void attach(ModuleObserver &observer) - { - if (realised()) { - observer.realise(); - } - m_observers.attach(observer); - } - - void detach(ModuleObserver &observer) - { - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); - } - - bool realised() - { - return m_unrealised == 0; - } - - void realise() - { - ASSERT_MESSAGE(m_unrealised != 0, "ModelResource::realise: already realised"); - if (--m_unrealised == 0) { - m_path = rootPath(m_originalName.c_str()); - m_name = path_make_relative(m_originalName.c_str(), m_path.c_str()); - - //globalOutputStream() << "ModelResource::realise: " << m_path.c_str() << m_name.c_str() << "\n"; - - m_observers.realise(); - } - } - - void unrealise() - { - if (++m_unrealised == 1) { - m_observers.unrealise(); - - //globalOutputStream() << "ModelResource::unrealise: " << m_path.c_str() << m_name.c_str() << "\n"; - clearModel(); - } - } - - bool isMap() const - { - return Node_getMapFile(m_model) != 0; - } - - void connectMap() - { - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - map->setChangedCallback(makeCallbackF(MapChanged)); - } - } - - std::time_t modified() const - { - StringOutputStream fullpath(256); - fullpath << m_path.c_str() << m_name.c_str(); - return file_modified(fullpath.c_str()); - } - - void mapSave() - { - m_modified = modified(); - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - map->save(); - } - } - - bool mapSaved() const - { - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - return m_modified == modified() && map->saved(); - } - return true; - } - - bool isModified() const - { - return ((!string_empty(m_path.c_str()) // had or has an absolute path - && m_modified != modified()) // AND disk timestamp changed - || !path_equal(rootPath(m_originalName.c_str()), m_path.c_str())); // OR absolute vfs-root changed - } - - void refresh() - { - if (isModified()) { - flush(); - unrealise(); - realise(); - } - } -}; - -class HashtableReferenceCache : public ReferenceCache, public ModuleObserver { -typedef HashedCache ModelReferences; -ModelReferences m_references; -std::size_t m_unrealised; - -class ModelReferencesSnapshot { -ModelReferences &m_references; -typedef std::list Iterators; -Iterators m_iterators; -public: -typedef Iterators::iterator iterator; - -ModelReferencesSnapshot(ModelReferences &references) : m_references(references) -{ - for (ModelReferences::iterator i = m_references.begin(); i != m_references.end(); ++i) { - m_references.capture(i); - m_iterators.push_back(i); - } -} - -~ModelReferencesSnapshot() -{ - for (Iterators::iterator i = m_iterators.begin(); i != m_iterators.end(); ++i) { - m_references.release(*i); - } -} - -iterator begin() -{ - return m_iterators.begin(); -} - -iterator end() -{ - return m_iterators.end(); -} -}; - -public: - -typedef ModelReferences::iterator iterator; - -HashtableReferenceCache() : m_unrealised(1) -{ -} - -iterator begin() -{ - return m_references.begin(); -} - -iterator end() -{ - return m_references.end(); -} - -void clear() -{ - m_references.clear(); -} - -Resource *capture(const char *path) -{ - //globalOutputStream() << "capture: \"" << path << "\"\n"; - return m_references.capture(CopiedString(path)).get(); -} - -void release(const char *path) -{ - m_references.release(CopiedString(path)); - //globalOutputStream() << "release: \"" << path << "\"\n"; -} - -void setEntityCreator(EntityCreator &entityCreator) -{ - g_entityCreator = &entityCreator; -} - -bool realised() const -{ - return m_unrealised == 0; -} - -void realise() -{ - ASSERT_MESSAGE(m_unrealised != 0, "HashtableReferenceCache::realise: already realised"); - if (--m_unrealised == 0) { - g_realised = true; - - { - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelReferences::value_type &value = *(*i); - if (value.value.count() != 1) { - value.value.get()->realise(); - } - } - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - g_realised = false; - - { - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelReferences::value_type &value = *(*i); - if (value.value.count() != 1) { - value.value.get()->unrealise(); - } - } - } - - ModelCache_clear(); - } -} - -void refresh() -{ - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelResource *resource = (*(*i)).value.get(); - if (!resource->isMap()) { - resource->refresh(); - } - } -} -}; - -namespace { -HashtableReferenceCache g_referenceCache; -} - -void SaveReferences() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - for (HashtableReferenceCache::iterator i = g_referenceCache.begin(); i != g_referenceCache.end(); ++i) { - (*i).value->save(); - } - MapChanged(); -} - -bool References_Saved() -{ - for (HashtableReferenceCache::iterator i = g_referenceCache.begin(); i != g_referenceCache.end(); ++i) { - scene::Node *node = (*i).value->getNode(); - if (node != 0) { - MapFile *map = Node_getMapFile(*node); - if (map != 0 && !map->saved()) { - return false; - } - } - } - return true; -} - -void RefreshReferences() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Refreshing Models"); - g_referenceCache.refresh(); -} - - -void FlushReferences() -{ - ModelCache_clear(); - - g_referenceCache.clear(); -} - -ReferenceCache &GetReferenceCache() -{ - return g_referenceCache; -} - - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class ReferenceDependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalFiletypesModuleRef { -ModelModulesRef m_model_modules; -MapModulesRef m_map_modules; -public: -ReferenceDependencies() : - m_model_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("modeltypes")), - m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")) -{ -} - -ModelModules &getModelModules() -{ - return m_model_modules.get(); -} - -MapModules &getMapModules() -{ - return m_map_modules.get(); -} -}; - -class ReferenceAPI : public TypeSystemRef { -ReferenceCache *m_reference; -public: -typedef ReferenceCache Type; - -STRING_CONSTANT(Name, "*"); - -ReferenceAPI() -{ - g_nullModel = NewNullModel(); - - GlobalFileSystem().attach(g_referenceCache); - - m_reference = &GetReferenceCache(); -} - -~ReferenceAPI() -{ - GlobalFileSystem().detach(g_referenceCache); - - g_nullModel = g_nullNode; -} - -ReferenceCache *getTable() -{ - return m_reference; -} -}; - -typedef SingletonModule ReferenceModule; -typedef Static StaticReferenceModule; -StaticRegisterModule staticRegisterReference(StaticReferenceModule::instance()); - -ModelModules &ReferenceAPI_getModelModules() -{ - return StaticReferenceModule::instance().getDependencies().getModelModules(); -} - -MapModules &ReferenceAPI_getMapModules() -{ - return StaticReferenceModule::instance().getDependencies().getMapModules(); -} diff --git a/src/referencecache.h b/src/referencecache.h deleted file mode 100644 index 1431e3e..0000000 --- a/src/referencecache.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_REFERENCECACHE_H ) -#define INCLUDED_REFERENCECACHE_H - -/// \brief Saves all open resource references if they differ from the version on disk. -void SaveReferences(); - -/// \brief Flushes the cache of resource references. All resource references must be released before calling this. -void FlushReferences(); - -/// \brief Reloads all resource references that differ from the version on disk. -void RefreshReferences(); - -#include "iscenegraph.h" - -namespace scene { -class Node; -} -class MapFormat; - -typedef void ( *GraphTraversalFunc )(scene::Node &root, const scene::Traversable::Walker &walker); - -bool -MapResource_saveFile(const MapFormat &format, scene::Node &root, GraphTraversalFunc traverse, const char *filename); - -#endif diff --git a/src/renderer.cpp b/src/renderer.cpp deleted file mode 100644 index 76e80f4..0000000 --- a/src/renderer.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "renderer.h" diff --git a/src/renderer.h b/src/renderer.h deleted file mode 100644 index 3de3b1b..0000000 --- a/src/renderer.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDERER_H ) -#define INCLUDED_RENDERER_H - -#include "irender.h" -#include "renderable.h" -#include "iselection.h" -#include "cullable.h" -#include "scenelib.h" -#include "math/frustum.h" -#include - -inline Cullable *Instance_getCullable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -inline Renderable *Instance_getRenderable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -inline VolumeIntersectionValue -Cullable_testVisible(scene::Instance &instance, const VolumeTest &volume, VolumeIntersectionValue parentVisible) -{ - if (parentVisible == c_volumePartial) { - Cullable *cullable = Instance_getCullable(instance); - if (cullable != 0) { - return cullable->intersectVolume(volume, instance.localToWorld()); - } - } - return parentVisible; -} - -template -class CullingWalker { -const VolumeTest &m_volume; -const _Walker &m_walker; -public: -CullingWalker(const VolumeTest &volume, const _Walker &walker) - : m_volume(volume), m_walker(walker) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - VolumeIntersectionValue visible = Cullable_testVisible(instance, m_volume, parentVisible); - if (visible != c_volumeOutside) { - return m_walker.pre(path, instance); - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - return m_walker.post(path, instance); -} -}; - -template -class ForEachVisible : public scene::Graph::Walker { -const VolumeTest &m_volume; -const Walker_ &m_walker; -mutable std::vector m_state; -public: -ForEachVisible(const VolumeTest &volume, const Walker_ &walker) - : m_volume(volume), m_walker(walker) -{ - m_state.push_back(c_volumePartial); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - VolumeIntersectionValue visible = (path.top().get().visible()) ? m_state.back() : c_volumeOutside; - - if (visible == c_volumePartial) { - visible = m_volume.TestAABB(instance.worldAABB()); - } - - m_state.push_back(visible); - - if (visible == c_volumeOutside) { - return false; - } else { - return m_walker.pre(path, instance, m_state.back()); - } -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (m_state.back() != c_volumeOutside) { - m_walker.post(path, instance, m_state.back()); - } - - m_state.pop_back(); -} -}; - -template -inline void Scene_forEachVisible(scene::Graph &graph, const VolumeTest &volume, const Functor &functor) -{ - graph.traverse(ForEachVisible >(volume, CullingWalker(volume, functor))); -} - -class RenderHighlighted { -Renderer &m_renderer; -const VolumeTest &m_volume; -public: -RenderHighlighted(Renderer &renderer, const VolumeTest &volume) - : m_renderer(renderer), m_volume(volume) -{ -} - -void render(const Renderable &renderable) const -{ - switch (m_renderer.getStyle()) { - case Renderer::eFullMaterials: - renderable.renderSolid(m_renderer, m_volume); - break; - case Renderer::eWireframeOnly: - renderable.renderWireframe(m_renderer, m_volume); - break; - } -} - -typedef ConstMemberCaller RenderCaller; - -bool pre(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - m_renderer.PushState(); - - if (Cullable_testVisible(instance, m_volume, parentVisible) != c_volumeOutside) { - Renderable *renderable = Instance_getRenderable(instance); - if (renderable) { - renderable->viewChanged(); - } - - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - m_renderer.Highlight(Renderer::eFace); - } else if (renderable) { - renderable->renderComponents(m_renderer, m_volume); - } - m_renderer.Highlight(Renderer::ePrimitive); - } - - if (renderable) { - render(*renderable); - } - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - m_renderer.PopState(); -} -}; - -inline void Scene_Render(Renderer &renderer, const VolumeTest &volume) -{ - GlobalSceneGraph().traverse(ForEachVisible(volume, RenderHighlighted(renderer, volume))); - GlobalShaderCache().forEachRenderable(RenderHighlighted::RenderCaller(RenderHighlighted(renderer, volume))); -} - -#endif diff --git a/src/renderstate.cpp b/src/renderstate.cpp deleted file mode 100644 index fde54cb..0000000 --- a/src/renderstate.cpp +++ /dev/null @@ -1,2522 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "renderstate.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "ishaders.h" -#include "irender.h" -#include "itextures.h" -#include "igl.h" -#include "iglrender.h" -#include "renderable.h" -#include "qerplugin.h" - -#include -#include -#include -#include - -#include "math/matrix.h" -#include "math/aabb.h" -#include "generic/callback.h" -#include "texturelib.h" -#include "string/string.h" -#include "container/hashfunc.h" -#include "container/cache.h" -#include "generic/reference.h" -#include "moduleobservers.h" -#include "stream/filestream.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "preferences.h" - -#include "xywindow.h" - - -#define DEBUG_RENDER 0 - -inline void debug_string(const char *string) -{ -#if (DEBUG_RENDER) - globalOutputStream() << string << "\n"; -#endif -} - -inline void debug_int(const char *comment, int i) -{ -#if (DEBUG_RENDER) - globalOutputStream() << comment << " " << i << "\n"; -#endif -} - -inline void debug_colour(const char *comment) -{ -#if (DEBUG_RENDER) - Vector4 v; - glGetFloatv( GL_CURRENT_COLOR, reinterpret_cast( &v ) ); - globalOutputStream() << comment << " colour: " - << v[0] << " " - << v[1] << " " - << v[2] << " " - << v[3]; - if ( glIsEnabled( GL_COLOR_ARRAY ) ) { - globalOutputStream() << " ARRAY"; - } - if ( glIsEnabled( GL_COLOR_MATERIAL ) ) { - globalOutputStream() << " MATERIAL"; - } - globalOutputStream() << "\n"; -#endif -} - -#include "timer.h" - -StringOutputStream g_renderer_stats; -std::size_t g_count_prims; -std::size_t g_count_states; -std::size_t g_count_transforms; -Timer g_timer; - -inline void count_prim() -{ - ++g_count_prims; -} - -inline void count_state() -{ - ++g_count_states; -} - -inline void count_transform() -{ - ++g_count_transforms; -} - -void Renderer_ResetStats() -{ - g_count_prims = 0; - g_count_states = 0; - g_count_transforms = 0; - g_timer.start(); -} - -const char *Renderer_GetStats() -{ - g_renderer_stats.clear(); - g_renderer_stats << "prims: " << Unsigned(g_count_prims) - << " | states: " << Unsigned(g_count_states) - << " | transforms: " << Unsigned(g_count_transforms) - << " | msec: " << g_timer.elapsed_msec(); - return g_renderer_stats.c_str(); -} - - -void printShaderLog(GLhandleARB object) -{ - GLint log_length = 0; - glGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_length); - - Array log(log_length); - glGetInfoLogARB(object, log_length, &log_length, log.data()); - - globalErrorStream() << StringRange(log.begin(), log.begin() + log_length) << "\n"; -} - -void createShader(GLhandleARB program, const char *filename, GLenum type) -{ - GLhandleARB shader = glCreateShaderObjectARB(type); - GlobalOpenGL_debugAssertNoErrors(); - - // load shader - { - std::size_t size = file_size(filename); - FileInputStream file(filename); - ASSERT_MESSAGE(!file.failed(), "failed to open " << makeQuoted(filename)); - Array buffer(size); - size = file.read(reinterpret_cast( buffer.data()), size); - - const GLcharARB *string = buffer.data(); - GLint length = GLint(size); - glShaderSourceARB(shader, 1, &string, &length); - } - - // compile shader - { - glCompileShaderARB(shader); - - GLint compiled = 0; - glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); - - if (!compiled) { - printShaderLog(shader); - } - - ASSERT_MESSAGE(compiled, "shader compile failed: " << makeQuoted(filename)); - } - - // attach shader - glAttachObjectARB(program, shader); - - glDeleteObjectARB(shader); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void GLSLProgram_link(GLhandleARB program) -{ - glLinkProgramARB(program); - - GLint linked = false; - glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked); - - if (!linked) { - printShaderLog(program); - } - - ASSERT_MESSAGE(linked, "program link failed"); -} - -void GLSLProgram_validate(GLhandleARB program) -{ - glValidateProgramARB(program); - - GLint validated = false; - glGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated); - - if (!validated) { - printShaderLog(program); - } - - ASSERT_MESSAGE(validated, "program validation failed"); -} - -bool g_bumpGLSLPass_enabled = false; -bool g_depthfillPass_enabled = false; - -class GLSLBumpProgram : public GLProgram { -public: -GLhandleARB m_program; -qtexture_t *m_light_attenuation_xy; -qtexture_t *m_light_attenuation_z; -GLint u_view_origin; -GLint u_light_origin; -GLint u_light_color; -GLint u_bump_scale; -GLint u_specular_exponent; - -GLSLBumpProgram() : m_program(0), m_light_attenuation_xy(0), m_light_attenuation_z(0) -{ -} - -void create() -{ - // create program - m_program = glCreateProgramObjectARB(); - - // create shader - { - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glsl"; - createShader(m_program, filename.c_str(), GL_VERTEX_SHADER_ARB); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glsl"; - createShader(m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB); - } - - GLSLProgram_link(m_program); - GLSLProgram_validate(m_program); - - glUseProgramObjectARB(m_program); - - glBindAttribLocationARB(m_program, c_attr_TexCoord0, "attr_TexCoord0"); - glBindAttribLocationARB(m_program, c_attr_Tangent, "attr_Tangent"); - glBindAttribLocationARB(m_program, c_attr_Binormal, "attr_Binormal"); - - glUniform1iARB(glGetUniformLocationARB(m_program, "u_diffusemap"), 0); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_bumpmap"), 1); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_specularmap"), 2); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_attenuationmap_xy"), 3); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_attenuationmap_z"), 4); - - u_view_origin = glGetUniformLocationARB(m_program, "u_view_origin"); - u_light_origin = glGetUniformLocationARB(m_program, "u_light_origin"); - u_light_color = glGetUniformLocationARB(m_program, "u_light_color"); - u_bump_scale = glGetUniformLocationARB(m_program, "u_bump_scale"); - u_specular_exponent = glGetUniformLocationARB(m_program, "u_specular_exponent"); - - glUseProgramObjectARB(0); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteObjectARB(m_program); - m_program = 0; -} - -void enable() -{ - glUseProgramObjectARB(m_program); - - glEnableVertexAttribArrayARB(c_attr_TexCoord0); - glEnableVertexAttribArrayARB(c_attr_Tangent); - glEnableVertexAttribArrayARB(c_attr_Binormal); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("enable bump"); - g_bumpGLSLPass_enabled = true; -} - -void disable() -{ - glUseProgramObjectARB(0); - - glDisableVertexAttribArrayARB(c_attr_TexCoord0); - glDisableVertexAttribArrayARB(c_attr_Tangent); - glDisableVertexAttribArrayARB(c_attr_Binormal); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("disable bump"); - g_bumpGLSLPass_enabled = false; -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ - Matrix4 world2local(localToWorld); - matrix4_affine_invert(world2local); - - Vector3 localLight(origin); - matrix4_transform_point(world2local, localLight); - - Vector3 localViewer(viewer); - matrix4_transform_point(world2local, localViewer); - - Matrix4 local2light(world2light); - matrix4_multiply_by_matrix4(local2light, localToWorld); // local->world->light - - glUniform3fARB(u_view_origin, localViewer.x(), localViewer.y(), localViewer.z()); - glUniform3fARB(u_light_origin, localLight.x(), localLight.y(), localLight.z()); - glUniform3fARB(u_light_color, colour.x(), colour.y(), colour.z()); - glUniform1fARB(u_bump_scale, 1.0); - glUniform1fARB(u_specular_exponent, 32.0); - - glActiveTexture(GL_TEXTURE3); - glClientActiveTexture(GL_TEXTURE3); - - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(reinterpret_cast( &local2light )); - glMatrixMode(GL_MODELVIEW); - - GlobalOpenGL_debugAssertNoErrors(); -} -}; - -GLSLBumpProgram g_bumpGLSL; - - -class GLSLDepthFillProgram : public GLProgram { -public: -GLhandleARB m_program; - -void create() -{ - // create program - m_program = glCreateProgramObjectARB(); - - // create shader - { - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glsl"; - createShader(m_program, filename.c_str(), GL_VERTEX_SHADER_ARB); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glsl"; - createShader(m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB); - } - - GLSLProgram_link(m_program); - GLSLProgram_validate(m_program); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteObjectARB(m_program); - m_program = 0; -} - -void enable() -{ - glUseProgramObjectARB(m_program); - GlobalOpenGL_debugAssertNoErrors(); - debug_string("enable depthfill"); - g_depthfillPass_enabled = true; -} - -void disable() -{ - glUseProgramObjectARB(0); - GlobalOpenGL_debugAssertNoErrors(); - debug_string("disable depthfill"); - g_depthfillPass_enabled = false; -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ -} -}; - -GLSLDepthFillProgram g_depthFillGLSL; - - -// ARB path - -void createProgram(const char *filename, GLenum type) -{ - std::size_t size = file_size(filename); - FileInputStream file(filename); - ASSERT_MESSAGE(!file.failed(), "failed to open " << makeQuoted(filename)); - Array buffer(size); - size = file.read(reinterpret_cast( buffer.data()), size); - - glProgramStringARB(type, GL_PROGRAM_FORMAT_ASCII_ARB, GLsizei(size), buffer.data()); - - if (GL_INVALID_OPERATION == glGetError()) { - GLint errPos; - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - const GLubyte *errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); - - globalErrorStream() << reinterpret_cast( filename ) << ":" << errPos << "\n" - << reinterpret_cast( errString ); - - ERROR_MESSAGE("error in gl program"); - } -} - -class ARBBumpProgram : public GLProgram { -public: -GLuint m_vertex_program; -GLuint m_fragment_program; - -void create() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - - { - glGenProgramsARB(1, &m_vertex_program); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glp"; - createProgram(filename.c_str(), GL_VERTEX_PROGRAM_ARB); - - glGenProgramsARB(1, &m_fragment_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glp"; - createProgram(filename.c_str(), GL_FRAGMENT_PROGRAM_ARB); - } - - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteProgramsARB(1, &m_vertex_program); - glDeleteProgramsARB(1, &m_fragment_program); - GlobalOpenGL_debugAssertNoErrors(); -} - -void enable() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - - glEnableVertexAttribArrayARB(8); - glEnableVertexAttribArrayARB(9); - glEnableVertexAttribArrayARB(10); - glEnableVertexAttribArrayARB(11); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void disable() -{ - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - glDisableVertexAttribArrayARB(8); - glDisableVertexAttribArrayARB(9); - glDisableVertexAttribArrayARB(10); - glDisableVertexAttribArrayARB(11); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ - Matrix4 world2local(localToWorld); - matrix4_affine_invert(world2local); - - Vector3 localLight(origin); - matrix4_transform_point(world2local, localLight); - - Vector3 localViewer(viewer); - matrix4_transform_point(world2local, localViewer); - - Matrix4 local2light(world2light); - matrix4_multiply_by_matrix4(local2light, localToWorld); // local->world->light - - // view origin - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 4, localViewer.x(), localViewer.y(), localViewer.z(), 0); - - // light origin - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, localLight.x(), localLight.y(), localLight.z(), 1); - - // light colour - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 3, colour.x(), colour.y(), colour.z(), 0); - - // bump scale - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1, 0, 0, 0); - - // specular exponent - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 5, 32, 0, 0, 0); - - - glActiveTexture(GL_TEXTURE3); - glClientActiveTexture(GL_TEXTURE3); - - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(reinterpret_cast( &local2light )); - glMatrixMode(GL_MODELVIEW); - - GlobalOpenGL_debugAssertNoErrors(); -} -}; - -class ARBDepthFillProgram : public GLProgram { -public: -GLuint m_vertex_program; -GLuint m_fragment_program; - -void create() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - - { - glGenProgramsARB(1, &m_vertex_program); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glp"; - createProgram(filename.c_str(), GL_VERTEX_PROGRAM_ARB); - - glGenProgramsARB(1, &m_fragment_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glp"; - createProgram(filename.c_str(), GL_FRAGMENT_PROGRAM_ARB); - } - - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteProgramsARB(1, &m_vertex_program); - glDeleteProgramsARB(1, &m_fragment_program); - GlobalOpenGL_debugAssertNoErrors(); -} - -void enable() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void disable() -{ - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ -} -}; - -ARBBumpProgram g_bumpARB; -ARBDepthFillProgram g_depthFillARB; - - -#if 0 -// NV20 path (unfinished) - -void createProgram( GLint program, const char* filename, GLenum type ){ - std::size_t size = file_size( filename ); - FileInputStream file( filename ); - ASSERT_MESSAGE( !file.failed(), "failed to open " << makeQuoted( filename ) ); - Array buffer( size ); - size = file.read( reinterpret_cast( buffer.data() ), size ); - - glLoadProgramNV( type, program, GLsizei( size ), buffer.data() ); - - if ( GL_INVALID_OPERATION == glGetError() ) { - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); - const GLubyte* errString = glGetString( GL_PROGRAM_ERROR_STRING_NV ); - - globalErrorStream() << filename << ":" << errPos << "\n" << errString; - - ERROR_MESSAGE( "error in gl program" ); - } -} - -GLuint m_vertex_program; -GLuint m_fragment_program; -qtexture_t* g_cube = 0; -qtexture_t* g_specular_lookup = 0; -qtexture_t* g_attenuation_xy = 0; -qtexture_t* g_attenuation_z = 0; - -void createVertexProgram(){ - { - glGenProgramsNV( 1, &m_vertex_program ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.nv30"; - createProgram( m_vertex_program, filename.c_str(), GL_VERTEX_PROGRAM_NV ); - - glGenProgramsNV( 1, &m_fragment_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.nv30"; - createProgram( m_fragment_program, filename.c_str(), GL_FRAGMENT_PROGRAM_NV ); - } - - g_cube = GlobalTexturesCache().capture( "generated/cube" ); - g_specular_lookup = GlobalTexturesCache().capture( "generated/specular" ); - - g_attenuation_xy = GlobalTexturesCache().capture( "lights/squarelight1" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_xy->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); - - g_attenuation_z = GlobalTexturesCache().capture( "lights/squarelight1a" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_z->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroyVertexProgram(){ - glDeleteProgramsNV( 1, &m_vertex_program ); - glDeleteProgramsNV( 1, &m_fragment_program ); - GlobalOpenGL_debugAssertNoErrors(); - - GlobalTexturesCache().release( g_cube ); - GlobalTexturesCache().release( g_specular_lookup ); - GlobalTexturesCache().release( g_attenuation_xy ); - GlobalTexturesCache().release( g_attenuation_z ); -} - -bool g_vertexProgram_enabled = false; - -void enableVertexProgram(){ - //set up the register combiners - //two general combiners - glCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 ); - - //combiner 0 does tex0+tex1 -> spare0 - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, - GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); - - //combiner 1 does tex2 dot tex3 -> spare1 - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE2_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE3_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV, - GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); - - - - //final combiner outputs (1-spare0)*constant color 0*spare1 - //do constant color 0*spare1 in the EF multiplier - glFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - //now do (1-spare0)*EF - glFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - glEnable( GL_VERTEX_PROGRAM_NV ); - glEnable( GL_REGISTER_COMBINERS_NV ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - - glActiveTexture( GL_TEXTURE0 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glEnable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glEnable( GL_TEXTURE_2D ); - - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = true; -} - -void disableVertexProgram(){ - glDisable( GL_VERTEX_PROGRAM_NV ); - glDisable( GL_REGISTER_COMBINERS_NV ); - - glActiveTexture( GL_TEXTURE0 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glDisable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glDisable( GL_TEXTURE_2D ); - - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = false; -} - -class GLstringNV -{ -public: -const GLubyte* m_string; -const GLint m_length; -GLstringNV( const char* string ) : m_string( reinterpret_cast( string ) ), m_length( GLint( string_length( string ) ) ){ -} -}; - -GLstringNV g_light_origin( "light_origin" ); -GLstringNV g_view_origin( "view_origin" ); -GLstringNV g_light_color( "light_color" ); -GLstringNV g_bumpGLSL_scale( "bump_scale" ); -GLstringNV g_specular_exponent( "specular_exponent" ); - -void setVertexProgramEnvironment( const Vector3& localViewer ){ - Matrix4 local2light( g_matrix4_identity ); - matrix4_translate_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 1.0 / 512.0, 1.0 / 512.0, 1.0 / 512.0 ) ); - matrix4_translate_by_vec3( local2light, vector3_negated( localViewer ) ); - - glActiveTexture( GL_TEXTURE3 ); - glClientActiveTexture( GL_TEXTURE3 ); - - glMatrixMode( GL_TEXTURE ); - glLoadMatrixf( reinterpret_cast( &local2light ) ); - glMatrixMode( GL_MODELVIEW ); - - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV ); - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE0_ARB, GL_IDENTITY_NV ); - - // view origin - //qglProgramNamedParameter4fNV(m_fragment_program, g_view_origin.m_length, g_view_origin.m_string, localViewer.x(), localViewer.y(), localViewer.z(), 0); - - // light origin - glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 8, localViewer.x(), localViewer.y(), localViewer.z(), 1.0f ); - - // light colour - glCombinerParameterfNV( GL_CONSTANT_COLOR0_NV, 1, 1, 1, 1 ) - - // bump scale - //qglProgramNamedParameter4fNV(m_fragment_program, g_bumpGLSL_scale.m_length, g_bumpGLSL_scale.m_string, 1, 0, 0, 0); - - // specular exponent - //qglProgramNamedParameter4fNV(m_fragment_program, g_specular_exponent.m_length, g_specular_exponent.m_string, 32, 0, 0, 0); - - GlobalOpenGL_debugAssertNoErrors(); -} - -#endif - - -bool g_vertexArray_enabled = false; -bool g_normalArray_enabled = false; -bool g_texcoordArray_enabled = false; -bool g_colorArray_enabled = false; - -inline bool OpenGLState_less(const OpenGLState &self, const OpenGLState &other) -{ - //! Sort by sort-order override. - if (self.m_sort != other.m_sort) { - return self.m_sort < other.m_sort; - } - //! Sort by texture handle. - if (self.m_texture != other.m_texture) { - return self.m_texture < other.m_texture; - } - if (self.m_texture1 != other.m_texture1) { - return self.m_texture1 < other.m_texture1; - } - if (self.m_texture2 != other.m_texture2) { - return self.m_texture2 < other.m_texture2; - } - if (self.m_texture3 != other.m_texture3) { - return self.m_texture3 < other.m_texture3; - } - if (self.m_texture4 != other.m_texture4) { - return self.m_texture4 < other.m_texture4; - } - if (self.m_texture5 != other.m_texture5) { - return self.m_texture5 < other.m_texture5; - } - if (self.m_texture6 != other.m_texture6) { - return self.m_texture6 < other.m_texture6; - } - if (self.m_texture7 != other.m_texture7) { - return self.m_texture7 < other.m_texture7; - } - //! Sort by state bit-vector. - if (self.m_state != other.m_state) { - return self.m_state < other.m_state; - } - //! Comparing address makes sure states are never equal. - return &self < &other; -} - -void OpenGLState_constructDefault(OpenGLState &state) -{ - state.m_state = RENDER_DEFAULT; - - state.m_texture = 0; - state.m_texture1 = 0; - state.m_texture2 = 0; - state.m_texture3 = 0; - state.m_texture4 = 0; - state.m_texture5 = 0; - state.m_texture6 = 0; - state.m_texture7 = 0; - - state.m_colour[0] = 1; - state.m_colour[1] = 1; - state.m_colour[2] = 1; - state.m_colour[3] = 1; - - state.m_depthfunc = GL_LESS; - - state.m_blend_src = GL_SRC_ALPHA; - state.m_blend_dst = GL_ONE_MINUS_SRC_ALPHA; - - state.m_alphafunc = GL_ALWAYS; - state.m_alpharef = 0; - - state.m_linewidth = 1; - state.m_pointsize = 1; - - state.m_linestipple_factor = 1; - state.m_linestipple_pattern = 0xaaaa; - - state.m_fog = OpenGLFogState(); -} - - -/// \brief A container of Renderable references. -/// May contain the same Renderable multiple times, with different transforms. -class OpenGLStateBucket { -public: -struct RenderTransform { - const Matrix4 *m_transform; - const OpenGLRenderable *m_renderable; - const RendererLight *m_light; - - RenderTransform(const OpenGLRenderable &renderable, const Matrix4 &transform, const RendererLight *light) - : m_transform(&transform), m_renderable(&renderable), m_light(light) - { - } -}; - -typedef std::vector Renderables; - -private: - -OpenGLState m_state; -Renderables m_renderables; - -public: -OpenGLStateBucket() -{ -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &modelview, const RendererLight *light = 0) -{ - m_renderables.push_back(RenderTransform(renderable, modelview, light)); -} - -OpenGLState &state() -{ - return m_state; -} - -void render(OpenGLState ¤t, unsigned int globalstate, const Vector3 &viewer); -}; - -#define LIGHT_SHADER_DEBUG 0 - -#if LIGHT_SHADER_DEBUG -typedef std::vector LightDebugShaders; -LightDebugShaders g_lightDebugShaders; -#endif - -class OpenGLStateLess { -public: -bool operator()(const OpenGLState &self, const OpenGLState &other) const -{ - return OpenGLState_less(self, other); -} -}; - -typedef ConstReference OpenGLStateReference; -typedef std::map OpenGLStates; -OpenGLStates g_state_sorted; - -class OpenGLStateBucketAdd { -OpenGLStateBucket &m_bucket; -const OpenGLRenderable &m_renderable; -const Matrix4 &m_modelview; -public: -using func = void (const RendererLight &); - -OpenGLStateBucketAdd(OpenGLStateBucket &bucket, const OpenGLRenderable &renderable, const Matrix4 &modelview) : - m_bucket(bucket), m_renderable(renderable), m_modelview(modelview) -{ -} - -void operator()(const RendererLight &light) -{ - m_bucket.addRenderable(m_renderable, m_modelview, &light); -} -}; - -class CountLights { -std::size_t m_count; -public: -using func = void (RendererLight &); - -CountLights() : m_count(0) -{ -} - -void operator()(const RendererLight &light) -{ - ++m_count; -} - -std::size_t count() const -{ - return m_count; -} -}; - -class OpenGLShader : public Shader { -typedef std::list Passes; -Passes m_passes; -IShader *m_shader; -std::size_t m_used; -ModuleObservers m_observers; -public: -OpenGLShader() : m_shader(0), m_used(0) -{ -} - -~OpenGLShader() -{ -} - -void construct(const char *name); - -void destroy() -{ - if (m_shader) { - m_shader->DecRef(); - } - m_shader = 0; - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - delete *i; - } - m_passes.clear(); -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &modelview, const LightList *lights) -{ - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { -#if LIGHT_SHADER_DEBUG - if ( ( ( *i )->state().m_state & RENDER_BUMP ) != 0 ) { - if ( lights != 0 ) { - CountLights counter; - lights->forEachLight( makeCallback1( counter ) ); - globalOutputStream() << "count = " << counter.count() << "\n"; - for ( std::size_t i = 0; i < counter.count(); ++i ) - { - g_lightDebugShaders[counter.count()]->addRenderable( renderable, modelview ); - } - } - } - else -#else - if (((*i)->state().m_state & RENDER_BUMP) != 0) { - if (lights != 0) { - OpenGLStateBucketAdd add(*(*i), renderable, modelview); - lights->forEachLight(makeCallback(add)); - } - } else -#endif - { - (*i)->addRenderable(renderable, modelview); - } - } -} - -void incrementUsed() -{ - if (++m_used == 1 && m_shader != 0) { - m_shader->SetInUse(true); - } -} - -void decrementUsed() -{ - if (--m_used == 0 && m_shader != 0) { - m_shader->SetInUse(false); - } -} - -bool realised() const -{ - return m_shader != 0; -} - -void attach(ModuleObserver &observer) -{ - if (realised()) { - observer.realise(); - } - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); -} - -void realise(const CopiedString &name) -{ - construct(name.c_str()); - - if (m_used != 0 && m_shader != 0) { - m_shader->SetInUse(true); - } - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - g_state_sorted.insert(OpenGLStates::value_type(OpenGLStateReference((*i)->state()), *i)); - } - - m_observers.realise(); -} - -void unrealise() -{ - m_observers.unrealise(); - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - g_state_sorted.erase(OpenGLStateReference((*i)->state())); - } - - destroy(); -} - -qtexture_t &getTexture() const -{ - ASSERT_NOTNULL(m_shader); - return *m_shader->getTexture(); -} - -unsigned int getFlags() const -{ - ASSERT_NOTNULL(m_shader); - return m_shader->getFlags(); -} - -IShader &getShader() const -{ - ASSERT_NOTNULL(m_shader); - return *m_shader; -} - -OpenGLState &appendDefaultPass() -{ - m_passes.push_back(new OpenGLStateBucket); - OpenGLState &state = m_passes.back()->state(); - OpenGLState_constructDefault(state); - return state; -} -}; - - -inline bool lightEnabled(const RendererLight &light, const LightCullable &cullable) -{ - return cullable.testLight(light); -} - -typedef std::set RendererLights; - -#define DEBUG_LIGHT_SYNC 0 - -class LinearLightList : public LightList { -LightCullable &m_cullable; -RendererLights &m_allLights; -Callback m_evaluateChanged; - -typedef std::list Lights; -mutable Lights m_lights; -mutable bool m_lightsChanged; -public: -LinearLightList(LightCullable &cullable, RendererLights &lights, const Callback &evaluateChanged) : - m_cullable(cullable), m_allLights(lights), m_evaluateChanged(evaluateChanged) -{ - m_lightsChanged = true; -} - -void evaluateLights() const -{ - m_evaluateChanged(); - if (m_lightsChanged) { - m_lightsChanged = false; - - m_lights.clear(); - m_cullable.clearLights(); - for (RendererLights::const_iterator i = m_allLights.begin(); i != m_allLights.end(); ++i) { - if (lightEnabled(*(*i), m_cullable)) { - m_lights.push_back(*i); - m_cullable.insertLight(*(*i)); - } - } - } -#if (DEBUG_LIGHT_SYNC) - else - { - Lights lights; - for ( RendererLights::const_iterator i = m_allLights.begin(); i != m_allLights.end(); ++i ) - { - if ( lightEnabled( *( *i ), m_cullable ) ) { - lights.push_back( *i ); - } - } - ASSERT_MESSAGE( - !std::lexicographical_compare( lights.begin(), lights.end(), m_lights.begin(), m_lights.end() ) - && !std::lexicographical_compare( m_lights.begin(), m_lights.end(), lights.begin(), lights.end() ), - "lights out of sync" - ); - } -#endif -} - -void forEachLight(const RendererLightCallback &callback) const -{ - evaluateLights(); - - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} - -void lightsChanged() const -{ - m_lightsChanged = true; -} -}; - -inline void setFogState(const OpenGLFogState &state) -{ - glFogi(GL_FOG_MODE, state.mode); - glFogf(GL_FOG_DENSITY, state.density); - glFogf(GL_FOG_START, state.start); - glFogf(GL_FOG_END, state.end); - glFogi(GL_FOG_INDEX, state.index); - glFogfv(GL_FOG_COLOR, vector4_to_array(state.colour)); -} - -#define DEBUG_SHADERS 0 - -class OpenGLShaderCache : public ShaderCache, public TexturesCacheObserver, public ModuleObserver { -class CreateOpenGLShader { -OpenGLShaderCache *m_cache; -public: -explicit CreateOpenGLShader(OpenGLShaderCache *cache = 0) - : m_cache(cache) -{ -} - -OpenGLShader *construct(const CopiedString &name) -{ - OpenGLShader *shader = new OpenGLShader; - if (m_cache->realised()) { - shader->realise(name); - } - return shader; -} - -void destroy(OpenGLShader *shader) -{ - if (m_cache->realised()) { - shader->unrealise(); - } - delete shader; -} -}; - -typedef HashedCache, CreateOpenGLShader> Shaders; -Shaders m_shaders; -std::size_t m_unrealised; - -bool m_lightingEnabled; -bool m_lightingSupported; -bool m_useShaderLanguage; - -public: -OpenGLShaderCache() - : m_shaders(CreateOpenGLShader(this)), - m_unrealised( - 3), // wait until shaders, gl-context and textures are realised before creating any render-states - m_lightingEnabled(true), - m_lightingSupported(false), - m_useShaderLanguage(false), - m_lightsChanged(true), - m_traverseRenderablesMutex(false) -{ -} - -~OpenGLShaderCache() -{ - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - globalOutputStream() << "leaked shader: " << makeQuoted((*i).key.c_str()) << "\n"; - } -} - -Shader *capture(const char *name) -{ - ASSERT_MESSAGE(name[0] == '$' - || *name == '[' - || *name == '<' - || *name == '(' - || strchr(name, '\\') == 0, "shader name contains invalid characters: \"" << name << "\""); -#if DEBUG_SHADERS - globalOutputStream() << "shaders capture: " << makeQuoted( name ) << '\n'; -#endif - return m_shaders.capture(name).get(); -} - -void release(const char *name) -{ -#if DEBUG_SHADERS - globalOutputStream() << "shaders release: " << makeQuoted( name ) << '\n'; -#endif - m_shaders.release(name); -} - -void -render(RenderStateFlags globalstate, const Matrix4 &modelview, const Matrix4 &projection, const Vector3 &viewer) -{ - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &projection )); -#if 0 - //qglGetFloatv(GL_PROJECTION_MATRIX, reinterpret_cast(&projection)); -#endif - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(reinterpret_cast( &modelview )); -#if 0 - //qglGetFloatv(GL_MODELVIEW_MATRIX, reinterpret_cast(&modelview)); -#endif - - ASSERT_MESSAGE(realised(), "render states are not realised"); - - // global settings that are not set in renderstates - glFrontFace(GL_CW); - glCullFace(GL_BACK); - glPolygonOffset(-1, 1); - { - const GLubyte pattern[132] = { - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55 - }; - glPolygonStipple(pattern); - } - glEnableClientState(GL_VERTEX_ARRAY); - g_vertexArray_enabled = true; - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - if (GlobalOpenGL().ARB_shader_objects()) { - glUseProgramObjectARB(0); - glDisableVertexAttribArrayARB(c_attr_TexCoord0); - glDisableVertexAttribArrayARB(c_attr_Tangent); - glDisableVertexAttribArrayARB(c_attr_Binormal); - } - - if (globalstate & RENDER_TEXTURE) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - - OpenGLState current; - OpenGLState_constructDefault(current); - current.m_sort = OpenGLState::eSortFirst; - - // default renderstate settings - glLineStipple(current.m_linestipple_factor, current.m_linestipple_pattern); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - g_texcoordArray_enabled = false; - glDisableClientState(GL_COLOR_ARRAY); - g_colorArray_enabled = false; - glDisableClientState(GL_NORMAL_ARRAY); - g_normalArray_enabled = false; - glDisable(GL_BLEND); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glShadeModel(GL_FLAT); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_ALPHA_TEST); - glDisable(GL_LINE_STIPPLE); - glDisable(GL_POLYGON_STIPPLE); - glDisable(GL_POLYGON_OFFSET_LINE); - - glBindTexture(GL_TEXTURE_2D, 0); - glColor4f(1, 1, 1, 1); - glDepthFunc(GL_LESS); - glAlphaFunc(GL_ALWAYS, 0); - glLineWidth(1); - glPointSize(1); - - glHint(GL_FOG_HINT, GL_NICEST); - glDisable(GL_FOG); - setFogState(OpenGLFogState()); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("begin rendering"); - for (OpenGLStates::iterator i = g_state_sorted.begin(); i != g_state_sorted.end(); ++i) { - (*i).second->render(current, globalstate, viewer); - } - debug_string("end rendering"); -} - -void realise() -{ - if (--m_unrealised == 0) { - if (lightingSupported() && lightingEnabled()) { - if (useShaderLanguage()) { - g_bumpGLSL.create(); - g_depthFillGLSL.create(); - } else { - g_bumpARB.create(); - g_depthFillARB.create(); - } - } - - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - if (!(*i).value.empty()) { - (*i).value->realise(i->key); - } - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - if (!(*i).value.empty()) { - (*i).value->unrealise(); - } - } - if (GlobalOpenGL().contextValid && lightingSupported() && lightingEnabled()) { - if (useShaderLanguage()) { - g_bumpGLSL.destroy(); - g_depthFillGLSL.destroy(); - } else { - g_bumpARB.destroy(); - g_depthFillARB.destroy(); - } - } - } -} - -bool realised() -{ - return m_unrealised == 0; -} - - -bool lightingEnabled() const -{ - return m_lightingEnabled; -} - -bool lightingSupported() const -{ - return m_lightingSupported; -} - -bool useShaderLanguage() const -{ - return m_useShaderLanguage; -} - -void setLighting(bool supported, bool enabled) -{ - bool refresh = (m_lightingSupported && m_lightingEnabled) != (supported && enabled); - - if (refresh) { - unrealise(); - GlobalShaderSystem().setLightingEnabled(supported && enabled); - } - - m_lightingSupported = supported; - m_lightingEnabled = enabled; - - if (refresh) { - realise(); - } -} - -void extensionsInitialised() -{ - setLighting(GlobalOpenGL().GL_1_3() - && GlobalOpenGL().ARB_vertex_program() - && GlobalOpenGL().ARB_fragment_program() - && GlobalOpenGL().ARB_shader_objects() - && GlobalOpenGL().ARB_vertex_shader() - && GlobalOpenGL().ARB_fragment_shader() - && GlobalOpenGL().ARB_shading_language_100(), - m_lightingEnabled - ); - - if (!lightingSupported()) { - globalOutputStream() << "Lighting mode requires OpenGL features not supported by your graphics drivers:\n"; - if (!GlobalOpenGL().GL_1_3()) { - globalOutputStream() << " GL version 1.3 or better\n"; - } - if (!GlobalOpenGL().ARB_vertex_program()) { - globalOutputStream() << " GL_ARB_vertex_program\n"; - } - if (!GlobalOpenGL().ARB_fragment_program()) { - globalOutputStream() << " GL_ARB_fragment_program\n"; - } - if (!GlobalOpenGL().ARB_shader_objects()) { - globalOutputStream() << " GL_ARB_shader_objects\n"; - } - if (!GlobalOpenGL().ARB_vertex_shader()) { - globalOutputStream() << " GL_ARB_vertex_shader\n"; - } - if (!GlobalOpenGL().ARB_fragment_shader()) { - globalOutputStream() << " GL_ARB_fragment_shader\n"; - } - if (!GlobalOpenGL().ARB_shading_language_100()) { - globalOutputStream() << " GL_ARB_shading_language_100\n"; - } - } -} - -void setLightingEnabled(bool enabled) -{ - setLighting(m_lightingSupported, enabled); -} - -// light culling - -RendererLights m_lights; -bool m_lightsChanged; -typedef std::map LightLists; -LightLists m_lightLists; - -const LightList &attach(LightCullable &cullable) -{ - return (*m_lightLists.insert(LightLists::value_type(&cullable, LinearLightList(cullable, m_lights, - EvaluateChangedCaller( - *this)))).first).second; -} - -void detach(LightCullable &cullable) -{ - m_lightLists.erase(&cullable); -} - -void changed(LightCullable &cullable) -{ - LightLists::iterator i = m_lightLists.find(&cullable); - ASSERT_MESSAGE(i != m_lightLists.end(), "cullable not attached"); - (*i).second.lightsChanged(); -} - -void attach(RendererLight &light) -{ - ASSERT_MESSAGE(m_lights.find(&light) == m_lights.end(), "light could not be attached"); - m_lights.insert(&light); - changed(light); -} - -void detach(RendererLight &light) -{ - ASSERT_MESSAGE(m_lights.find(&light) != m_lights.end(), "light could not be detached"); - m_lights.erase(&light); - changed(light); -} - -void changed(RendererLight &light) -{ - m_lightsChanged = true; -} - -void evaluateChanged() -{ - if (m_lightsChanged) { - m_lightsChanged = false; - for (LightLists::iterator i = m_lightLists.begin(); i != m_lightLists.end(); ++i) { - (*i).second.lightsChanged(); - } - } -} - -typedef MemberCaller EvaluateChangedCaller; - -typedef std::set Renderables; -Renderables m_renderables; -mutable bool m_traverseRenderablesMutex; - -// renderables -void attachRenderable(const Renderable &renderable) -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "attaching renderable during traversal"); - ASSERT_MESSAGE(m_renderables.find(&renderable) == m_renderables.end(), "renderable could not be attached"); - m_renderables.insert(&renderable); -} - -void detachRenderable(const Renderable &renderable) -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "detaching renderable during traversal"); - ASSERT_MESSAGE(m_renderables.find(&renderable) != m_renderables.end(), "renderable could not be detached"); - m_renderables.erase(&renderable); -} - -void forEachRenderable(const RenderableCallback &callback) const -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "for-each during traversal"); - m_traverseRenderablesMutex = true; - for (Renderables::const_iterator i = m_renderables.begin(); i != m_renderables.end(); ++i) { - callback(*(*i)); - } - m_traverseRenderablesMutex = false; -} -}; - -static OpenGLShaderCache *g_ShaderCache; - -void ShaderCache_extensionsInitialised() -{ - g_ShaderCache->extensionsInitialised(); -} - -void ShaderCache_setBumpEnabled(bool enabled) -{ - g_ShaderCache->setLightingEnabled(enabled); -} - - -Vector3 g_DebugShaderColours[256]; -Shader *g_defaultPointLight = 0; - -void ShaderCache_Construct() -{ - g_ShaderCache = new OpenGLShaderCache; - GlobalTexturesCache().attach(*g_ShaderCache); - GlobalShaderSystem().attach(*g_ShaderCache); -} - -void ShaderCache_Destroy() -{ - GlobalShaderSystem().detach(*g_ShaderCache); - GlobalTexturesCache().detach(*g_ShaderCache); - delete g_ShaderCache; -} - -ShaderCache *GetShaderCache() -{ - return g_ShaderCache; -} - -inline void setTextureState(GLint ¤t, const GLint &texture, GLenum textureUnit) -{ - if (texture != current) { - glActiveTexture(textureUnit); - glClientActiveTexture(textureUnit); - glBindTexture(GL_TEXTURE_2D, texture); - GlobalOpenGL_debugAssertNoErrors(); - current = texture; - } -} - -inline void setTextureState(GLint ¤t, const GLint &texture) -{ - if (texture != current) { - glBindTexture(GL_TEXTURE_2D, texture); - GlobalOpenGL_debugAssertNoErrors(); - current = texture; - } -} - -inline void setState(unsigned int state, unsigned int delta, unsigned int flag, GLenum glflag) -{ - if (delta & state & flag) { - glEnable(glflag); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & flag) { - glDisable(glflag); - GlobalOpenGL_debugAssertNoErrors(); - } -} - -void OpenGLState_apply(const OpenGLState &self, OpenGLState ¤t, unsigned int globalstate) -{ - debug_int("sort", int(self.m_sort)); - debug_int("texture", self.m_texture); - debug_int("state", self.m_state); - debug_int("address", int(std::size_t(&self))); - - count_state(); - - if (self.m_state & RENDER_OVERRIDE) { - globalstate |= RENDER_FILL | RENDER_DEPTHWRITE; - } - - const unsigned int state = self.m_state & globalstate; - const unsigned int delta = state ^current.m_state; - - GlobalOpenGL_debugAssertNoErrors(); - - GLProgram *program = (state & RENDER_PROGRAM) != 0 ? self.m_program : 0; - - if (program != current.m_program) { - if (current.m_program != 0) { - current.m_program->disable(); - glColor4fv(vector4_to_array(current.m_colour)); - debug_colour("cleaning program"); - } - - current.m_program = program; - - if (current.m_program != 0) { - current.m_program->enable(); - } - } - - if (delta & state & RENDER_FILL) { - //qglPolygonMode (GL_BACK, GL_LINE); - //qglPolygonMode (GL_FRONT, GL_FILL); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_FILL) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_OFFSETLINE, GL_POLYGON_OFFSET_LINE); - - if (delta & state & RENDER_LIGHTING) { - glEnable(GL_LIGHTING); - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_RESCALE_NORMAL); - glEnableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_normalArray_enabled = true; - } else if (delta & ~state & RENDER_LIGHTING) { - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_RESCALE_NORMAL); - glDisableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_normalArray_enabled = false; - } - - if (delta & state & RENDER_TEXTURE) { - GlobalOpenGL_debugAssertNoErrors(); - - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - glEnable(GL_TEXTURE_2D); - - glColor4f(1, 1, 1, self.m_colour[3]); - debug_colour("setting texture"); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_texcoordArray_enabled = true; - } else if (delta & ~state & RENDER_TEXTURE) { - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_texcoordArray_enabled = false; - } - - if (delta & state & RENDER_BLEND) { - // FIXME: some .TGA are buggy, have a completely empty alpha channel - // if such brushes are rendered in this loop they would be totally transparent with GL_MODULATE - // so I decided using GL_DECAL instead - // if an empty-alpha-channel or nearly-empty texture is used. It will be blank-transparent. - // this could get better if you can get glTexEnviv (GL_TEXTURE_ENV, to work .. patches are welcome - glEnable(GL_BLEND); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - } - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_BLEND) { - glDisable(GL_BLEND); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - } - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_CULLFACE, GL_CULL_FACE); - - if (delta & state & RENDER_SMOOTH) { - glShadeModel(GL_SMOOTH); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_SMOOTH) { - glShadeModel(GL_FLAT); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_SCALED, GL_RESCALE_NORMAL); // not GL_RESCALE_NORMAL - setState(state, delta, RENDER_DEPTHTEST, GL_DEPTH_TEST); - - if (delta & state & RENDER_DEPTHWRITE) { - glDepthMask(GL_TRUE); - - #if DEBUG_RENDER - GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); - ASSERT_MESSAGE( depthEnabled, "failed to set depth buffer mask bit" ); - #endif - debug_string("enabled depth-buffer writing"); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_DEPTHWRITE) { - glDepthMask(GL_FALSE); - - #if DEBUG_RENDER - GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); - ASSERT_MESSAGE( !depthEnabled, "failed to set depth buffer mask bit" ); - #endif - debug_string("disabled depth-buffer writing"); - - GlobalOpenGL_debugAssertNoErrors(); - } - - if (delta & state & RENDER_COLOURWRITE) { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_COLOURWRITE) { - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_ALPHATEST, GL_ALPHA_TEST); - - if (delta & state & RENDER_COLOURARRAY) { - glEnableClientState(GL_COLOR_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - debug_colour("enabling color_array"); - g_colorArray_enabled = true; - } else if (delta & ~state & RENDER_COLOURARRAY) { - glDisableClientState(GL_COLOR_ARRAY); - glColor4fv(vector4_to_array(self.m_colour)); - debug_colour("cleaning color_array"); - GlobalOpenGL_debugAssertNoErrors(); - g_colorArray_enabled = false; - } - - if (delta & ~state & RENDER_COLOURCHANGE) { - glColor4fv(vector4_to_array(self.m_colour)); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_LINESTIPPLE, GL_LINE_STIPPLE); - setState(state, delta, RENDER_LINESMOOTH, GL_LINE_SMOOTH); - setState(state, delta, RENDER_POLYGONSTIPPLE, GL_POLYGON_STIPPLE); - setState(state, delta, RENDER_POLYGONSMOOTH, GL_POLYGON_SMOOTH); - setState(state, delta, RENDER_FOG, GL_FOG); - - if ((state & RENDER_FOG) != 0) { - setFogState(self.m_fog); - GlobalOpenGL_debugAssertNoErrors(); - current.m_fog = self.m_fog; - } - - if (state & RENDER_DEPTHTEST && self.m_depthfunc != current.m_depthfunc) { - glDepthFunc(self.m_depthfunc); - GlobalOpenGL_debugAssertNoErrors(); - current.m_depthfunc = self.m_depthfunc; - } - - if (state & RENDER_POLYOFS) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-0.05, -25 * self.m_polygonoffset); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); - } - - if (state & RENDER_LINESTIPPLE - && (self.m_linestipple_factor != current.m_linestipple_factor - || self.m_linestipple_pattern != current.m_linestipple_pattern)) { - glLineStipple(self.m_linestipple_factor, self.m_linestipple_pattern); - GlobalOpenGL_debugAssertNoErrors(); - current.m_linestipple_factor = self.m_linestipple_factor; - current.m_linestipple_pattern = self.m_linestipple_pattern; - } - - if (state & RENDER_ALPHATEST - && (self.m_alphafunc != current.m_alphafunc - || self.m_alpharef != current.m_alpharef)) { - glAlphaFunc(self.m_alphafunc, self.m_alpharef); - GlobalOpenGL_debugAssertNoErrors(); - current.m_alphafunc = self.m_alphafunc; - current.m_alpharef = self.m_alpharef; - } - - GLint texture0 = 0; - GLint texture1 = 0; - GLint texture2 = 0; - GLint texture3 = 0; - GLint texture4 = 0; - GLint texture5 = 0; - GLint texture6 = 0; - GLint texture7 = 0; - - texture0 = self.m_texture; - texture1 = self.m_texture1; - texture2 = self.m_texture2; - texture3 = self.m_texture3; - texture4 = self.m_texture4; - texture5 = self.m_texture5; - texture6 = self.m_texture6; - texture7 = self.m_texture7; - - if (GlobalOpenGL().GL_1_3()) { - setTextureState(current.m_texture, texture0, GL_TEXTURE0); - setTextureState(current.m_texture1, texture1, GL_TEXTURE1); - setTextureState(current.m_texture2, texture2, GL_TEXTURE2); - setTextureState(current.m_texture3, texture3, GL_TEXTURE3); - setTextureState(current.m_texture4, texture4, GL_TEXTURE4); - setTextureState(current.m_texture5, texture5, GL_TEXTURE5); - setTextureState(current.m_texture6, texture6, GL_TEXTURE6); - setTextureState(current.m_texture7, texture7, GL_TEXTURE7); - } else { - setTextureState(current.m_texture, texture0); - } - - if (state & RENDER_TEXTURE && self.m_colour[3] != current.m_colour[3]) { - debug_colour("setting alpha"); - glColor4f(1, 1, 1, self.m_colour[3]); - GlobalOpenGL_debugAssertNoErrors(); - } - - if (!(state & RENDER_TEXTURE) - && (self.m_colour[0] != current.m_colour[0] - || self.m_colour[1] != current.m_colour[1] - || self.m_colour[2] != current.m_colour[2] - || self.m_colour[3] != current.m_colour[3])) { - glColor4fv(vector4_to_array(self.m_colour)); - debug_colour("setting non-texture"); - GlobalOpenGL_debugAssertNoErrors(); - } - current.m_colour = self.m_colour; - - if (state & RENDER_BLEND - && (self.m_blend_src != current.m_blend_src || self.m_blend_dst != current.m_blend_dst)) { - glBlendFunc(self.m_blend_src, self.m_blend_dst); - GlobalOpenGL_debugAssertNoErrors(); - current.m_blend_src = self.m_blend_src; - current.m_blend_dst = self.m_blend_dst; - } - - if (!(state & RENDER_FILL) - && self.m_linewidth != current.m_linewidth) { - glLineWidth(self.m_linewidth); - GlobalOpenGL_debugAssertNoErrors(); - current.m_linewidth = self.m_linewidth; - } - - if (!(state & RENDER_FILL) - && self.m_pointsize != current.m_pointsize) { - glPointSize(self.m_pointsize); - GlobalOpenGL_debugAssertNoErrors(); - current.m_pointsize = self.m_pointsize; - } - - current.m_state = state; - - GlobalOpenGL_debugAssertNoErrors(); -} - -void Renderables_flush(OpenGLStateBucket::Renderables &renderables, OpenGLState ¤t, unsigned int globalstate, - const Vector3 &viewer) -{ - const Matrix4 *transform = 0; - glPushMatrix(); - for (OpenGLStateBucket::Renderables::const_iterator i = renderables.begin(); i != renderables.end(); ++i) { - //qglLoadMatrixf(i->m_transform); - if (!transform || (transform != (*i).m_transform && !matrix4_affine_equal(*transform, *(*i).m_transform))) { - count_transform(); - transform = (*i).m_transform; - glPopMatrix(); - glPushMatrix(); - glMultMatrixf(reinterpret_cast( transform )); - glFrontFace( - ((current.m_state & RENDER_CULLFACE) != 0 && matrix4_handedness(*transform) == MATRIX4_RIGHTHANDED) - ? GL_CW : GL_CCW); - } - - count_prim(); - - if (current.m_program != 0 && (*i).m_light != 0) { - const IShader &lightShader = static_cast((*i).m_light->getShader())->getShader(); - if (lightShader.firstLayer() != 0) { - GLuint attenuation_xy = lightShader.firstLayer()->texture()->texture_number; - GLuint attenuation_z = lightShader.lightFalloffImage() != 0 - ? lightShader.lightFalloffImage()->texture_number - : static_cast( g_defaultPointLight )->getShader().lightFalloffImage()->texture_number; - - setTextureState(current.m_texture3, attenuation_xy, GL_TEXTURE3); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, attenuation_xy); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - setTextureState(current.m_texture4, attenuation_z, GL_TEXTURE4); - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, attenuation_z); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - - AABB lightBounds((*i).m_light->aabb()); - - Matrix4 world2light(g_matrix4_identity); - - if ((*i).m_light->isProjected()) { - world2light = (*i).m_light->projection(); - matrix4_multiply_by_matrix4(world2light, matrix4_transposed((*i).m_light->rotation())); - matrix4_translate_by_vec3(world2light, vector3_negated(lightBounds.origin)); // world->lightBounds - } - if (!(*i).m_light->isProjected()) { - matrix4_translate_by_vec3(world2light, Vector3(0.5f, 0.5f, 0.5f)); - matrix4_scale_by_vec3(world2light, Vector3(0.5f, 0.5f, 0.5f)); - matrix4_scale_by_vec3(world2light, - Vector3(1.0f / lightBounds.extents.x(), 1.0f / lightBounds.extents.y(), - 1.0f / lightBounds.extents.z())); - matrix4_multiply_by_matrix4(world2light, matrix4_transposed((*i).m_light->rotation())); - matrix4_translate_by_vec3(world2light, vector3_negated(lightBounds.origin)); // world->lightBounds - } - - current.m_program->setParameters(viewer, *(*i).m_transform, lightBounds.origin + (*i).m_light->offset(), - (*i).m_light->colour(), world2light); - debug_string("set lightBounds parameters"); - } - } - - (*i).m_renderable->render(current.m_state); - } - glPopMatrix(); - renderables.clear(); -} - -void OpenGLStateBucket::render(OpenGLState ¤t, unsigned int globalstate, const Vector3 &viewer) -{ - if ((globalstate & m_state.m_state & RENDER_SCREEN) != 0) { - OpenGLState_apply(m_state, current, globalstate); - debug_colour("screen fill"); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(reinterpret_cast( &g_matrix4_identity )); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(reinterpret_cast( &g_matrix4_identity )); - - glBegin(GL_QUADS); - glVertex3f(-1, -1, 0); - glVertex3f(1, -1, 0); - glVertex3f(1, 1, 0); - glVertex3f(-1, 1, 0); - glEnd(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } else if (!m_renderables.empty()) { - OpenGLState_apply(m_state, current, globalstate); - Renderables_flush(m_renderables, current, globalstate, viewer); - } -} - - -class OpenGLStateMap : public OpenGLStateLibrary { -typedef std::map States; -States m_states; -public: -~OpenGLStateMap() -{ - ASSERT_MESSAGE(m_states.empty(), "OpenGLStateMap::~OpenGLStateMap: not empty"); -} - -typedef States::iterator iterator; - -iterator begin() -{ - return m_states.begin(); -} - -iterator end() -{ - return m_states.end(); -} - -void getDefaultState(OpenGLState &state) const -{ - OpenGLState_constructDefault(state); -} - -void insert(const char *name, const OpenGLState &state) -{ - bool inserted = m_states.insert(States::value_type(name, state)).second; - ASSERT_MESSAGE(inserted, "OpenGLStateMap::insert: " << name << " already exists"); -} - -void erase(const char *name) -{ - std::size_t count = m_states.erase(name); - ASSERT_MESSAGE(count == 1, "OpenGLStateMap::erase: " << name << " does not exist"); -} - -iterator find(const char *name) -{ - return m_states.find(name); -} -}; - -OpenGLStateMap *g_openglStates = 0; - -inline GLenum convertBlendFactor(BlendFactor factor) -{ - switch (factor) { - case BLEND_ZERO: - return GL_ZERO; - case BLEND_ONE: - return GL_ONE; - case BLEND_SRC_COLOUR: - return GL_SRC_COLOR; - case BLEND_ONE_MINUS_SRC_COLOUR: - return GL_ONE_MINUS_SRC_COLOR; - case BLEND_SRC_ALPHA: - return GL_SRC_ALPHA; - case BLEND_ONE_MINUS_SRC_ALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - case BLEND_DST_COLOUR: - return GL_DST_COLOR; - case BLEND_ONE_MINUS_DST_COLOUR: - return GL_ONE_MINUS_DST_COLOR; - case BLEND_DST_ALPHA: - return GL_DST_ALPHA; - case BLEND_ONE_MINUS_DST_ALPHA: - return GL_ONE_MINUS_DST_ALPHA; - case BLEND_SRC_ALPHA_SATURATE: - return GL_SRC_ALPHA_SATURATE; - } - return GL_ZERO; -} - -/// \todo Define special-case shaders in a data file. -void OpenGLShader::construct(const char *name) -{ - OpenGLState &state = appendDefaultPass(); - switch (name[0]) { - case '(': - sscanf(name, "(%g %g %g)", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 1.0f; - state.m_state = RENDER_FILL | RENDER_LIGHTING | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - break; - - case '[': - sscanf(name, "[%g %g %g]", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 0.5f; - state.m_state = RENDER_FILL | RENDER_LIGHTING | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE | RENDER_BLEND; - state.m_sort = OpenGLState::eSortTranslucent; - break; - - case '<': - sscanf(name, "<%g %g %g>", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 1; - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - state.m_depthfunc = GL_LESS; - state.m_linewidth = 1; - state.m_pointsize = 1; - break; - - case '$': { - OpenGLStateMap::iterator i = g_openglStates->find(name); - if (i != g_openglStates->end()) { - state = (*i).second; - break; - } - } - if (string_equal(name + 1, "POINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - state.m_pointsize = 4; - } else if (string_equal(name + 1, "SELPOINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst + 1; - state.m_pointsize = 4; - } else if (string_equal(name + 1, "BIGPOINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - state.m_pointsize = 6; - } else if (string_equal(name + 1, "PIVOT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHTEST | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_linewidth = 2; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHTEST | RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_linewidth = 2; - hiddenLine.m_depthfunc = GL_GREATER; - } else if (string_equal(name + 1, "LATTICE")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0.5; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - } else if (string_equal(name + 1, "WIREFRAME")) { - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - } else if (string_equal(name + 1, "CAM_HIGHLIGHT")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 0.5f; - state.m_state = RENDER_FILL | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_BLEND | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortHighlight; - state.m_depthfunc = GL_LEQUAL; - } else if (string_equal(name + 1, "CAM_OVERLAY")) { -#if 0 - state.m_state = RENDER_CULLFACE | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; -#else - state.m_state = - RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_OFFSETLINE; - state.m_sort = OpenGLState::eSortOverlayFirst + 1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_colour[0] = 0.75; - hiddenLine.m_colour[1] = 0.75; - hiddenLine.m_colour[2] = 0.75; - hiddenLine.m_colour[3] = 1; - hiddenLine.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_OFFSETLINE | - RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortOverlayFirst; - hiddenLine.m_depthfunc = GL_GREATER; - hiddenLine.m_linestipple_factor = 2; -#endif - } else if (string_equal(name + 1, "XY_OVERLAY")) { - state.m_colour[0] = g_xywindow_globals.color_selbrushes[0]; - state.m_colour[1] = g_xywindow_globals.color_selbrushes[1]; - state.m_colour[2] = g_xywindow_globals.color_selbrushes[2]; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_LINESTIPPLE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = 2; - state.m_linestipple_factor = 3; - } else if (string_equal(name + 1, "DEBUG_CLIPPED")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortLast; - } else if (string_equal(name + 1, "POINTFILE")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - state.m_linewidth = 4; - } else if (string_equal(name + 1, "LIGHT_SPHERE")) { - state.m_colour[0] = .15f * .95f; - state.m_colour[1] = .15f * .95f; - state.m_colour[2] = .15f * .95f; - state.m_colour[3] = 1; - state.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_BLEND | RENDER_FILL | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_blend_src = GL_ONE; - state.m_blend_dst = GL_ONE; - state.m_sort = OpenGLState::eSortTranslucent; - } else if (string_equal(name + 1, "Q3MAP2_LIGHT_SPHERE")) { - state.m_colour[0] = .05f; - state.m_colour[1] = .05f; - state.m_colour[2] = .05f; - state.m_colour[3] = 1; - state.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_BLEND | RENDER_FILL; - state.m_blend_src = GL_ONE; - state.m_blend_dst = GL_ONE; - state.m_sort = OpenGLState::eSortTranslucent; - } else if (string_equal(name + 1, "WIRE_OVERLAY")) { -#if 0 - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortOverlayFirst; -#else - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE | RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_depthfunc = GL_GREATER; -#endif - } else if (string_equal(name + 1, "FLATSHADE_OVERLAY")) { - state.m_state = RENDER_CULLFACE | RENDER_LIGHTING | RENDER_SMOOTH | RENDER_SCALED | RENDER_COLOURARRAY | - RENDER_FILL | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = - RENDER_CULLFACE | RENDER_LIGHTING | RENDER_SMOOTH | RENDER_SCALED | RENDER_COLOURARRAY | - RENDER_FILL | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_OVERRIDE | - RENDER_POLYGONSTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_depthfunc = GL_GREATER; - } else if (string_equal(name + 1, "CLIPPER_OVERLAY")) { - state.m_colour[0] = g_xywindow_globals.color_clipper[0]; - state.m_colour[1] = g_xywindow_globals.color_clipper[1]; - state.m_colour[2] = g_xywindow_globals.color_clipper[2]; - state.m_colour[3] = 1; - state.m_state = - RENDER_CULLFACE | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_FILL | RENDER_POLYGONSTIPPLE; - state.m_sort = OpenGLState::eSortOverlayFirst; - } else if (string_equal(name + 1, "OVERBRIGHT")) { - const float lightScale = 2; - state.m_colour[0] = lightScale * 0.5f; - state.m_colour[1] = lightScale * 0.5f; - state.m_colour[2] = lightScale * 0.5f; - state.m_colour[3] = 0.5; - state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_SCREEN; - state.m_sort = OpenGLState::eSortOverbrighten; - state.m_blend_src = GL_DST_COLOR; - state.m_blend_dst = GL_SRC_COLOR; - } else { - // default to something recognisable.. =) - ERROR_MESSAGE("hardcoded renderstate not found"); - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 1; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFirst; - } - break; - default: - // construction from IShader - m_shader = QERApp_Shader_ForName(name); - - if (g_ShaderCache->lightingSupported() && g_ShaderCache->lightingEnabled() && m_shader->getBump() != 0 && - m_shader->getBump()->texture_number != 0) { // is a bump shader - state.m_state = RENDER_FILL | RENDER_CULLFACE | RENDER_TEXTURE | RENDER_DEPTHTEST | RENDER_DEPTHWRITE | - RENDER_COLOURWRITE | RENDER_PROGRAM; - state.m_colour[0] = 0; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_sort = OpenGLState::eSortOpaque; - - if (g_ShaderCache->useShaderLanguage()) { - state.m_program = &g_depthFillGLSL; - } else { - state.m_program = &g_depthFillARB; - } - - OpenGLState &bumpPass = appendDefaultPass(); - bumpPass.m_texture = m_shader->getDiffuse()->texture_number; - bumpPass.m_texture1 = m_shader->getBump()->texture_number; - bumpPass.m_texture2 = m_shader->getSpecular()->texture_number; - - bumpPass.m_state = - RENDER_BLEND | RENDER_FILL | RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | - RENDER_SMOOTH | RENDER_BUMP | RENDER_PROGRAM; - - if (g_ShaderCache->useShaderLanguage()) { - bumpPass.m_state |= RENDER_LIGHTING; - bumpPass.m_program = &g_bumpGLSL; - } else { - bumpPass.m_program = &g_bumpARB; - } - - bumpPass.m_depthfunc = GL_LEQUAL; - bumpPass.m_sort = OpenGLState::eSortMultiFirst; - bumpPass.m_blend_src = GL_ONE; - bumpPass.m_blend_dst = GL_ONE; - } else { - state.m_texture = m_shader->getTexture()->texture_number; - - state.m_state = RENDER_FILL | RENDER_TEXTURE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_LIGHTING | - RENDER_SMOOTH; - if ((m_shader->getFlags() & QER_CULL) != 0) { - if (m_shader->getCull() == IShader::eCullBack) { - state.m_state |= RENDER_CULLFACE; - } - } else { - state.m_state |= RENDER_CULLFACE; - } - - if ((m_shader->getFlags() & QER_POLYOFS) != 0) { - state.m_polygonoffset = m_shader->getPolygonOffset(); - state.m_state |= RENDER_POLYOFS; - } - - if ((m_shader->getFlags() & QER_ALPHATEST) != 0) { - state.m_state |= RENDER_ALPHATEST; - IShader::EAlphaFunc alphafunc; - m_shader->getAlphaFunc(&alphafunc, &state.m_alpharef); - switch (alphafunc) { - case IShader::eAlways: - state.m_alphafunc = GL_ALWAYS; - break; - case IShader::eEqual: - state.m_alphafunc = GL_EQUAL; - break; - case IShader::eLess: - state.m_alphafunc = GL_LESS; - break; - case IShader::eGreater: - state.m_alphafunc = GL_GREATER; - break; - case IShader::eLEqual: - state.m_alphafunc = GL_LEQUAL; - break; - case IShader::eGEqual: - state.m_alphafunc = GL_GEQUAL; - break; - } - } - reinterpret_cast( state.m_colour ) = m_shader->getTexture()->color; - state.m_colour[3] = 1.0f; - - if ((m_shader->getFlags() & QER_TRANS) != 0) { - state.m_state |= RENDER_BLEND; - state.m_colour[3] = m_shader->getTrans(); - state.m_sort = OpenGLState::eSortTranslucent; - BlendFunc blendFunc = m_shader->getBlendFunc(); - state.m_blend_src = convertBlendFactor(blendFunc.m_src); - state.m_blend_dst = convertBlendFactor(blendFunc.m_dst); - if (state.m_blend_src == GL_SRC_ALPHA || state.m_blend_dst == GL_SRC_ALPHA) { - state.m_state |= RENDER_DEPTHWRITE; - } - } else { - state.m_state |= RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - } - } - } -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class OpenGLStateLibraryAPI { -OpenGLStateMap m_stateMap; -public: -typedef OpenGLStateLibrary Type; - -STRING_CONSTANT(Name, "*"); - -OpenGLStateLibraryAPI() -{ - g_openglStates = &m_stateMap; -} - -~OpenGLStateLibraryAPI() -{ - g_openglStates = 0; -} - -OpenGLStateLibrary *getTable() -{ - return &m_stateMap; -} -}; - -typedef SingletonModule OpenGLStateLibraryModule; -typedef Static StaticOpenGLStateLibraryModule; -StaticRegisterModule staticRegisterOpenGLStateLibrary(StaticOpenGLStateLibraryModule::instance()); - -class ShaderCacheDependencies - : public GlobalShadersModuleRef, public GlobalTexturesModuleRef, public GlobalOpenGLStateLibraryModuleRef { -public: -ShaderCacheDependencies() : - GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")) -{ -} -}; - -class ShaderCacheAPI { -ShaderCache *m_shaderCache; -public: -typedef ShaderCache Type; - -STRING_CONSTANT(Name, "*"); - -ShaderCacheAPI() -{ - ShaderCache_Construct(); - - m_shaderCache = GetShaderCache(); -} - -~ShaderCacheAPI() -{ - ShaderCache_Destroy(); -} - -ShaderCache *getTable() -{ - return m_shaderCache; -} -}; - -typedef SingletonModule ShaderCacheModule; -typedef Static StaticShaderCacheModule; -StaticRegisterModule staticRegisterShaderCache(StaticShaderCacheModule::instance()); diff --git a/src/renderstate.h b/src/renderstate.h deleted file mode 100644 index f4ba496..0000000 --- a/src/renderstate.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDERSTATE_H ) -#define INCLUDED_RENDERSTATE_H - -void ShaderCache_setBumpEnabled(bool enabled); - -void ShaderCache_extensionsInitialised(); - -#endif diff --git a/src/resource.h b/src/resource.h deleted file mode 100644 index 506ba8a..0000000 --- a/src/resource.h +++ /dev/null @@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by worldspawn.rc -// -#define IDI_WORLDSPAWN 101 -#define IDR_MENU1 102 -#define IDD_DIALOG1 103 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/scenegraph.cpp b/src/scenegraph.cpp deleted file mode 100644 index 851f091..0000000 --- a/src/scenegraph.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "scenegraph.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "string/string.h" -#include "signal/signal.h" -#include "scenelib.h" -#include "instancelib.h" -#include "treemodel.h" - -template -class TypeIdMap { -typedef const char *TypeName; -typedef TypeName TypeNames[SIZE]; -TypeNames m_typeNames; -TypeName *m_typeNamesEnd; - -public: -TypeIdMap() : m_typeNamesEnd(m_typeNames) -{ -} - -TypeId getTypeId(const char *name) -{ - TypeName *i = std::find_if(m_typeNames, m_typeNamesEnd, [&](const char *other) { - return string_equal(name, other); - }); - if (i == m_typeNamesEnd) { - ASSERT_MESSAGE(m_typeNamesEnd != m_typeNames + SIZE, - "reached maximum number of type names supported (" << Unsigned(SIZE) << ")"); - *m_typeNamesEnd++ = name; - } - return i - m_typeNames; -} -}; - -class CompiledGraph : public scene::Graph, public scene::Instantiable::Observer { -typedef std::map InstanceMap; - -InstanceMap m_instances; -scene::Instantiable::Observer *m_observer; -Signal0 m_boundsChanged; -scene::Path m_rootpath; -Signal0 m_sceneChangedCallbacks; - -TypeIdMap m_nodeTypeIds; -TypeIdMap m_instanceTypeIds; - -public: - -CompiledGraph(scene::Instantiable::Observer *observer) - : m_observer(observer) -{ -} - -void addSceneChangedCallback(const SignalHandler &handler) -{ - m_sceneChangedCallbacks.connectLast(handler); -} - -void sceneChanged() -{ - m_sceneChangedCallbacks(); -} - -scene::Node &root() -{ - ASSERT_MESSAGE(!m_rootpath.empty(), "scenegraph root does not exist"); - return m_rootpath.top(); -} - -void insert_root(scene::Node &root) -{ - //globalOutputStream() << "insert_root\n"; - - ASSERT_MESSAGE(m_rootpath.empty(), "scenegraph root already exists"); - - root.IncRef(); - - Node_traverseSubgraph(root, InstanceSubgraphWalker(this, scene::Path(), 0)); - - m_rootpath.push(makeReference(root)); -} - -void erase_root() -{ - //globalOutputStream() << "erase_root\n"; - - ASSERT_MESSAGE(!m_rootpath.empty(), "scenegraph root does not exist"); - - scene::Node &root = m_rootpath.top(); - - m_rootpath.pop(); - - Node_traverseSubgraph(root, UninstanceSubgraphWalker(this, scene::Path())); - - root.DecRef(); -} - -void boundsChanged() -{ - m_boundsChanged(); -} - -void traverse(const Walker &walker) -{ - traverse_subgraph(walker, m_instances.begin()); -} - -void traverse_subgraph(const Walker &walker, const scene::Path &start) -{ - if (!m_instances.empty()) { - traverse_subgraph(walker, m_instances.find(PathConstReference(start))); - } -} - -scene::Instance *find(const scene::Path &path) -{ - InstanceMap::iterator i = m_instances.find(PathConstReference(path)); - if (i == m_instances.end()) { - return 0; - } - return (*i).second; -} - -void insert(scene::Instance *instance) -{ - m_instances.insert(InstanceMap::value_type(PathConstReference(instance->path()), instance)); - - m_observer->insert(instance); -} - -void erase(scene::Instance *instance) -{ - m_observer->erase(instance); - - m_instances.erase(PathConstReference(instance->path())); -} - -SignalHandlerId addBoundsChangedCallback(const SignalHandler &boundsChanged) -{ - return m_boundsChanged.connectLast(boundsChanged); -} - -void removeBoundsChangedCallback(SignalHandlerId id) -{ - m_boundsChanged.disconnect(id); -} - -TypeId getNodeTypeId(const char *name) -{ - return m_nodeTypeIds.getTypeId(name); -} - -TypeId getInstanceTypeId(const char *name) -{ - return m_instanceTypeIds.getTypeId(name); -} - -private: - -bool pre(const Walker &walker, const InstanceMap::iterator &i) -{ - return walker.pre(i->first, *i->second); -} - -void post(const Walker &walker, const InstanceMap::iterator &i) -{ - walker.post(i->first, *i->second); -} - -void traverse_subgraph(const Walker &walker, InstanceMap::iterator i) -{ - Stack stack; - if (i != m_instances.end()) { - const std::size_t startSize = (*i).first.get().size(); - do { - if (i != m_instances.end() - && stack.size() < ((*i).first.get().size() - startSize + 1)) { - stack.push(i); - ++i; - if (!pre(walker, stack.top())) { - // skip subgraph - while (i != m_instances.end() - && stack.size() < ((*i).first.get().size() - startSize + 1)) { - ++i; - } - } - } else { - post(walker, stack.top()); - stack.pop(); - } - } while (!stack.empty()); - } -} -}; - -namespace { -CompiledGraph *g_sceneGraph; -GraphTreeModel *g_tree_model; -} - -GraphTreeModel *scene_graph_get_tree_model() -{ - return g_tree_model; -} - - -class SceneGraphObserver : public scene::Instantiable::Observer { -public: -void insert(scene::Instance *instance) -{ - g_sceneGraph->sceneChanged(); - graph_tree_model_insert(g_tree_model, *instance); -} - -void erase(scene::Instance *instance) -{ - g_sceneGraph->sceneChanged(); - graph_tree_model_erase(g_tree_model, *instance); -} -}; - -SceneGraphObserver g_SceneGraphObserver; - -void SceneGraph_Construct() -{ - g_tree_model = graph_tree_model_new(); - - g_sceneGraph = new CompiledGraph(&g_SceneGraphObserver); -} - -void SceneGraph_Destroy() -{ - delete g_sceneGraph; - - graph_tree_model_delete(g_tree_model); -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class SceneGraphAPI { -scene::Graph *m_scenegraph; -public: -typedef scene::Graph Type; - -STRING_CONSTANT(Name, "*"); - -SceneGraphAPI() -{ - SceneGraph_Construct(); - - m_scenegraph = g_sceneGraph; -} - -~SceneGraphAPI() -{ - SceneGraph_Destroy(); -} - -scene::Graph *getTable() -{ - return m_scenegraph; -} -}; - -typedef SingletonModule SceneGraphModule; -typedef Static StaticSceneGraphModule; -StaticRegisterModule staticRegisterSceneGraph(StaticSceneGraphModule::instance()); diff --git a/src/scenegraph.h b/src/scenegraph.h deleted file mode 100644 index 48fb08b..0000000 --- a/src/scenegraph.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDEDE_SCENEGRAPH_H ) -#define INCLUDED_SCENEGRAPH_H - -#endif diff --git a/src/select.cpp b/src/select.cpp deleted file mode 100644 index ddeb791..0000000 --- a/src/select.cpp +++ /dev/null @@ -1,1421 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "select.h" - -#include - -#include "debugging/debugging.h" - -#include "ientity.h" -#include "eclasslib.h" -#include "iselection.h" -#include "iundo.h" - -#include - -#include "stream/stringstream.h" -#include "signal/isignal.h" -#include "shaderlib.h" -#include "scenelib.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/dialog.h" -#include "gtkutil/widget.h" -#include "brushmanip.h" -#include "brush.h" -#include "patchmanip.h" -#include "patchdialog.h" -#include "selection.h" -#include "texwindow.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "grid.h" -#include "map.h" -#include "entityinspector.h" - - -select_workzone_t g_select_workzone; - - -/** - Loops over all selected brushes and stores their - world AABBs in the specified array. - */ -class CollectSelectedBrushesBounds : public SelectionSystem::Visitor { -AABB *m_bounds; // array of AABBs -Unsigned m_max; // max AABB-elements in array -Unsigned &m_count; // count of valid AABBs stored in array - -public: -CollectSelectedBrushesBounds(AABB *bounds, Unsigned max, Unsigned &count) - : m_bounds(bounds), - m_max(max), - m_count(count) -{ - m_count = 0; -} - -void visit(scene::Instance &instance) const -{ - ASSERT_MESSAGE(m_count <= m_max, "Invalid m_count in CollectSelectedBrushesBounds"); - - // stop if the array is already full - if (m_count == m_max) { - return; - } - - Selectable *selectable = Instance_getSelectable(instance); - if ((selectable != 0) - && instance.isSelected()) { - // brushes only - if (Instance_getBrush(instance) != 0) { - m_bounds[m_count] = instance.worldAABB(); - ++m_count; - } - } -} -}; - -/** - Selects all objects that intersect one of the bounding AABBs. - The exact intersection-method is specified through TSelectionPolicy - */ -template -class SelectByBounds : public scene::Graph::Walker { -AABB *m_aabbs; // selection aabbs -Unsigned m_count; // number of aabbs in m_aabbs -TSelectionPolicy policy; // type that contains a custom intersection method aabb<->aabb - -public: -SelectByBounds(AABB *aabbs, Unsigned count) - : m_aabbs(aabbs), - m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - - // ignore worldspawn - Entity *entity = Node_getEntity(path.top()); - if (entity) { - if (string_equal(entity->getKeyValue("classname"), "worldspawn")) { - return true; - } - } - - if ((path.size() > 1) && - (!path.top().get().isRoot()) && - (selectable != 0) - ) { - for (Unsigned i = 0; i < m_count; ++i) { - if (policy.Evaluate(m_aabbs[i], instance)) { - selectable->setSelected(true); - } - } - } - - return true; -} - -/** - Performs selection operation on the global scenegraph. - If delete_bounds_src is true, then the objects which were - used as source for the selection aabbs will be deleted. - */ -static void DoSelection(bool delete_bounds_src = true) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - // we may not need all AABBs since not all selected objects have to be brushes - const Unsigned max = (Unsigned) GlobalSelectionSystem().countSelected(); - AABB *aabbs = new AABB[max]; - - Unsigned count; - CollectSelectedBrushesBounds collector(aabbs, max, count); - GlobalSelectionSystem().foreachSelected(collector); - - // nothing usable in selection - if (!count) { - delete[] aabbs; - return; - } - - // delete selected objects - if (delete_bounds_src) { // see deleteSelection - UndoableCommand undo("deleteSelected"); - Select_Delete(); - } - - // select objects with bounds - GlobalSceneGraph().traverse(SelectByBounds(aabbs, count)); - - SceneChangeNotify(); - delete[] aabbs; - } -} -}; - -/** - SelectionPolicy for SelectByBounds - Returns true if box and the AABB of instance intersect - */ -class SelectionPolicy_Touching { -public: -bool Evaluate(const AABB &box, scene::Instance &instance) const -{ - const AABB &other(instance.worldAABB()); - for (Unsigned i = 0; i < 3; ++i) { - if (fabsf(box.origin[i] - other.origin[i]) > (box.extents[i] + other.extents[i])) { - return false; - } - } - return true; -} -}; - -/** - SelectionPolicy for SelectByBounds - Returns true if the AABB of instance is inside box - */ -class SelectionPolicy_Inside { -public: -bool Evaluate(const AABB &box, scene::Instance &instance) const -{ - const AABB &other(instance.worldAABB()); - for (Unsigned i = 0; i < 3; ++i) { - if (fabsf(box.origin[i] - other.origin[i]) > (box.extents[i] - other.extents[i])) { - return false; - } - } - return true; -} -}; - -class DeleteSelected : public scene::Graph::Walker { -mutable bool m_remove; -mutable bool m_removedChild; -public: -DeleteSelected() - : m_remove(false), m_removedChild(false) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - m_removedChild = false; - - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1 - && !path.top().get().isRoot()) { - m_remove = true; - - return false; // dont traverse into child elements - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - - if (m_removedChild) { - m_removedChild = false; - - // delete empty entities - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && path.top().get_pointer() != Map_FindWorldspawn(g_map) - && Node_getTraversable(path.top())->empty()) { - Path_deleteTop(path); - } - } - - // node should be removed - if (m_remove) { - if (Node_isEntity(path.parent()) != 0) { - m_removedChild = true; - } - - m_remove = false; - Path_deleteTop(path); - } -} -}; - - - -class DeleteEmpty : public scene::Graph::Walker { -mutable bool m_remove; -public: -DeleteEmpty() - : m_remove(false) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - /* skip point ents, crash otherwise */ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 && entity->getEntityClass().fixedsize) { - return; - } - - // delete empty entities - if (entity != 0 - && path.top().get_pointer() != Map_FindWorldspawn(g_map) - && Node_getTraversable(path.top())->empty()) - { - Path_deleteTop(path); - } - /*}*/ - - /*// node should be removed - if (m_remove) { - if (Node_isEntity(path.parent()) != 0) { - m_removedChild = true; - } - - m_remove = false; - Path_deleteTop(path); - }*/ -} -}; - - -void Scene_DeleteEmpty() -{ - GlobalSceneGraph().traverse(DeleteEmpty()); - SceneChangeNotify(); -} - -void Scene_DeleteSelected(scene::Graph &graph) -{ - graph.traverse(DeleteSelected()); - SceneChangeNotify(); -} - -void Select_Delete(void) -{ - Scene_DeleteSelected(GlobalSceneGraph()); -} - -class InvertSelectionWalker : public scene::Graph::Walker { -SelectionSystem::EMode m_mode; -mutable Selectable *m_selectable; -public: -InvertSelectionWalker(SelectionSystem::EMode mode) - : m_mode(mode), m_selectable(0) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable) { - switch (m_mode) { - case SelectionSystem::eEntity: - if (Node_isEntity(path.top()) != 0) { - m_selectable = path.top().get().visible() ? selectable : 0; - } - break; - case SelectionSystem::ePrimitive: - m_selectable = path.top().get().visible() ? selectable : 0; - break; - case SelectionSystem::eComponent: - break; - } - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (m_selectable != 0) { - m_selectable->setSelected(!m_selectable->isSelected()); - m_selectable = 0; - } -} -}; - -void Scene_Invert_Selection(scene::Graph &graph) -{ - graph.traverse(InvertSelectionWalker(GlobalSelectionSystem().Mode())); -} - -void Select_Invert() -{ - Scene_Invert_Selection(GlobalSceneGraph()); -} - -class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker { -mutable std::size_t m_depth; -NodeSmartReference worldspawn; -public: -ExpandSelectionToEntitiesWalker() : m_depth(0), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ++m_depth; - - // ignore worldspawn - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return false; - } - - if (m_depth == 2) { // entity depth - // traverse and select children if any one is selected - if (instance.childSelected()) { - Instance_setSelected(instance, true); - } - return Node_getEntity(path.top())->isContainer() && instance.isSelected(); - } else if (m_depth == 3) { // primitive depth - Instance_setSelected(instance, true); - return false; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -void Scene_ExpandSelectionToEntities() -{ - GlobalSceneGraph().traverse(ExpandSelectionToEntitiesWalker()); -} - - -namespace { -void Selection_UpdateWorkzone() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - Select_GetBounds(g_select_workzone.d_work_min, g_select_workzone.d_work_max); - } -} - -typedef FreeCaller SelectionUpdateWorkzoneCaller; - -IdleDraw g_idleWorkzone = IdleDraw(SelectionUpdateWorkzoneCaller()); -} - -const select_workzone_t &Select_getWorkZone() -{ - g_idleWorkzone.flush(); - return g_select_workzone; -} - -void UpdateWorkzone_ForSelection() -{ - g_idleWorkzone.queueDraw(); -} - -// update the workzone to the current selection -void UpdateWorkzone_ForSelectionChanged(const Selectable &selectable) -{ - if (selectable.isSelected()) { - UpdateWorkzone_ForSelection(); - } -} - -void Select_SetShader(const char *shader) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetShader_Selected(GlobalSceneGraph(), shader); - Scene_PatchSetShader_Selected(GlobalSceneGraph(), shader); - } - Scene_BrushSetShader_Component_Selected(GlobalSceneGraph(), shader); -} - -void Select_SetTexdef(const TextureProjection &projection, bool ignorebasis) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetTexdef_Selected(GlobalSceneGraph(), projection, ignorebasis); - } - Scene_BrushSetTexdef_Component_Selected(GlobalSceneGraph(), projection, ignorebasis); -} - -void Select_SetFlags(const ContentsFlagsValue &flags) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetFlags_Selected(GlobalSceneGraph(), flags); - } - Scene_BrushSetFlags_Component_Selected(GlobalSceneGraph(), flags); -} - -void Select_GetBounds(Vector3 &mins, Vector3 &maxs) -{ - AABB bounds; - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - maxs = vector3_added(bounds.origin, bounds.extents); - mins = vector3_subtracted(bounds.origin, bounds.extents); -} - -void Select_GetMid(Vector3 &mid) -{ - AABB bounds; - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - mid = vector3_snapped(bounds.origin); -} - - -void Select_FlipAxis(int axis) -{ - Vector3 flip(1, 1, 1); - flip[axis] = -1; - GlobalSelectionSystem().scaleSelected(flip); -} - - -void Select_Scale(float x, float y, float z) -{ - GlobalSelectionSystem().scaleSelected(Vector3(x, y, z)); -} - -enum axis_t { - eAxisX = 0, - eAxisY = 1, - eAxisZ = 2, -}; - -enum sign_t { - eSignPositive = 1, - eSignNegative = -1, -}; - -inline Matrix4 matrix4_rotation_for_axis90(axis_t axis, sign_t sign) -{ - switch (axis) { - case eAxisX: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_x(1, 0); - } else { - return matrix4_rotation_for_sincos_x(-1, 0); - } - case eAxisY: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_y(1, 0); - } else { - return matrix4_rotation_for_sincos_y(-1, 0); - } - default: //case eAxisZ: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_z(1, 0); - } else { - return matrix4_rotation_for_sincos_z(-1, 0); - } - } -} - -inline void matrix4_rotate_by_axis90(Matrix4 &matrix, axis_t axis, sign_t sign) -{ - matrix4_multiply_by_matrix4(matrix, matrix4_rotation_for_axis90(axis, sign)); -} - -inline void matrix4_pivoted_rotate_by_axis90(Matrix4 &matrix, axis_t axis, sign_t sign, const Vector3 &pivotpoint) -{ - matrix4_translate_by_vec3(matrix, pivotpoint); - matrix4_rotate_by_axis90(matrix, axis, sign); - matrix4_translate_by_vec3(matrix, vector3_negated(pivotpoint)); -} - -inline Quaternion quaternion_for_axis90(axis_t axis, sign_t sign) -{ -#if 1 - switch (axis) { - case eAxisX: - if (sign == eSignPositive) { - return Quaternion(c_half_sqrt2f, 0, 0, c_half_sqrt2f); - } else { - return Quaternion(-c_half_sqrt2f, 0, 0, -c_half_sqrt2f); - } - case eAxisY: - if (sign == eSignPositive) { - return Quaternion(0, c_half_sqrt2f, 0, c_half_sqrt2f); - } else { - return Quaternion(0, -c_half_sqrt2f, 0, -c_half_sqrt2f); - } - default: //case eAxisZ: - if (sign == eSignPositive) { - return Quaternion(0, 0, c_half_sqrt2f, c_half_sqrt2f); - } else { - return Quaternion(0, 0, -c_half_sqrt2f, -c_half_sqrt2f); - } - } -#else - quaternion_for_matrix4_rotation( matrix4_rotation_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ) ); -#endif -} - -void Select_RotateAxis(int axis, float deg) -{ - if (fabs(deg) == 90.f) { - GlobalSelectionSystem().rotateSelected( - quaternion_for_axis90((axis_t) axis, (deg > 0) ? eSignPositive : eSignNegative)); - } else { - switch (axis) { - case 0: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_x_degrees(deg))); - break; - case 1: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_y_degrees(deg))); - break; - case 2: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_z_degrees(deg))); - break; - } - } -} - - -void Select_ShiftTexture(float x, float y) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushShiftTexdef_Selected(GlobalSceneGraph(), x, y); - Scene_PatchTranslateTexture_Selected(GlobalSceneGraph(), x, y); - } - //globalOutputStream() << "shift selected face textures: s=" << x << " t=" << y << '\n'; - Scene_BrushShiftTexdef_Component_Selected(GlobalSceneGraph(), x, y); -} - -void Select_ScaleTexture(float x, float y) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushScaleTexdef_Selected(GlobalSceneGraph(), x, y); - Scene_PatchScaleTexture_Selected(GlobalSceneGraph(), x, y); - } - Scene_BrushScaleTexdef_Component_Selected(GlobalSceneGraph(), x, y); -} - -void Select_RotateTexture(float amt) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushRotateTexdef_Selected(GlobalSceneGraph(), amt); - Scene_PatchRotateTexture_Selected(GlobalSceneGraph(), amt); - } - Scene_BrushRotateTexdef_Component_Selected(GlobalSceneGraph(), amt); -} - -// TTimo modified to handle shader architecture: -// expects shader names at input, comparison relies on shader names .. texture names no longer relevant -void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected) -{ - if (!texdef_name_valid(pFind)) { - globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pFind << "', aborted\n"; - return; - } - if (!texdef_name_valid(pReplace)) { - globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pReplace << "', aborted\n"; - return; - } - - StringOutputStream command; - command << "textureFindReplace -find " << pFind << " -replace " << pReplace; - UndoableCommand undo(command.c_str()); - - if (bSelected) { - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushFindReplaceShader_Selected(GlobalSceneGraph(), pFind, pReplace); - Scene_PatchFindReplaceShader_Selected(GlobalSceneGraph(), pFind, pReplace); - } - Scene_BrushFindReplaceShader_Component_Selected(GlobalSceneGraph(), pFind, pReplace); - } else { - Scene_BrushFindReplaceShader(GlobalSceneGraph(), pFind, pReplace); - Scene_PatchFindReplaceShader(GlobalSceneGraph(), pFind, pReplace); - } -} - -typedef std::vector PropertyValues; - -bool propertyvalues_contain(const PropertyValues &propertyvalues, const char *str) -{ - for (PropertyValues::const_iterator i = propertyvalues.begin(); i != propertyvalues.end(); ++i) { - if (string_equal(str, *i)) { - return true; - } - } - return false; -} - -class EntityFindByPropertyValueWalker : public scene::Graph::Walker { -const PropertyValues &m_propertyvalues; -const char *m_prop; -public: -EntityFindByPropertyValueWalker(const char *prop, const PropertyValues &propertyvalues) - : m_propertyvalues(propertyvalues), m_prop(prop) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) { - Instance_getSelectable(instance)->setSelected(true); - } - return true; -} -}; - -void Scene_EntitySelectByPropertyValues(scene::Graph &graph, const char *prop, const PropertyValues &propertyvalues) -{ - graph.traverse(EntityFindByPropertyValueWalker(prop, propertyvalues)); -} - -class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker { -PropertyValues &m_propertyvalues; -const char *m_prop; -public: -EntityGetSelectedPropertyValuesWalker(const char *prop, PropertyValues &propertyvalues) - : m_propertyvalues(propertyvalues), m_prop(prop) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - Entity *entity = Node_getEntity(path.top()); - if (entity != 0) { - if (!propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) { - m_propertyvalues.push_back(entity->getKeyValue(m_prop)); - } - } - } - return true; -} -}; - -void Scene_EntityGetPropertyValues(scene::Graph &graph, const char *prop, PropertyValues &propertyvalues) -{ - graph.traverse(EntityGetSelectedPropertyValuesWalker(prop, propertyvalues)); -} - -void Select_AllOfType() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - GlobalSelectionSystem().setSelectedAllComponents(false); - Scene_BrushSelectByShader_Component(GlobalSceneGraph(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } else { - PropertyValues propertyvalues; - const char *prop = EntityInspector_getCurrentKey(); - if (!prop || !*prop) { - prop = "classname"; - } - Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - GlobalSelectionSystem().setSelectedAll(false); - if (!propertyvalues.empty()) { - Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - } else { - Scene_BrushSelectByShader(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - Scene_PatchSelectByShader(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } -} - -void Select_AllOfModel() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - GlobalSelectionSystem().setSelectedAllComponents(false); - Scene_BrushSelectByShader_Component(GlobalSceneGraph(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } else { - PropertyValues propertyvalues; - const char *prop = EntityInspector_getCurrentKey(); - if (!prop || !*prop) { - prop = "model"; - } - Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - GlobalSelectionSystem().setSelectedAll(false); - if (!propertyvalues.empty()) { - Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - } - } -} - -void Select_Inside(void) -{ - SelectByBounds::DoSelection(); -} - -void Select_Touching(void) -{ - SelectByBounds::DoSelection(false); -} - -void Select_FitTexture(float horizontal, float vertical) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushFitTexture_Selected(GlobalSceneGraph(), horizontal, vertical); - } - Scene_BrushFitTexture_Component_Selected(GlobalSceneGraph(), horizontal, vertical); - - SceneChangeNotify(); -} - - -void Select_AlignTexture(int alignment) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushAlignTexture_Selected(GlobalSceneGraph(), alignment); - } - Scene_BrushAlignTexture_Component_Selected(GlobalSceneGraph(), alignment); - - SceneChangeNotify(); -} - -inline void hide_node(scene::Node &node, bool hide) -{ - hide - ? node.enable(scene::Node::eHidden) - : node.disable(scene::Node::eHidden); -} - -class HideSelectedWalker : public scene::Graph::Walker { -bool m_hide; -public: -HideSelectedWalker(bool hide) - : m_hide(hide) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - hide_node(path.top(), m_hide); - } - return true; -} -}; - -void Scene_Hide_Selected(bool hide) -{ - GlobalSceneGraph().traverse(HideSelectedWalker(hide)); -} - -void Select_Hide() -{ - Scene_Hide_Selected(true); - SceneChangeNotify(); -} - -void QE_hiddenCountChanged(); -void HideSelected() -{ - Select_Hide(); - GlobalSelectionSystem().setSelectedAll(false); - QE_hiddenCountChanged(); -} - -void HideUnselected() -{ - Select_Invert(); - Select_Hide(); - GlobalSelectionSystem().setSelectedAll(false); - QE_hiddenCountChanged(); -} - - -class HideAllWalker : public scene::Graph::Walker { -bool m_hide; -public: -HideAllWalker(bool hide) - : m_hide(hide) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - hide_node(path.top(), m_hide); - return true; -} -}; - -void Scene_Hide_All(bool hide) -{ - GlobalSceneGraph().traverse(HideAllWalker(hide)); -} - -void Select_ShowAllHidden() -{ - Scene_Hide_All(false); - SceneChangeNotify(); - QE_hiddenCountChanged(); -} - - -void Selection_Flipx() -{ - UndoableCommand undo("mirrorSelected -axis x"); - Select_FlipAxis(0); -} - -void Selection_Flipy() -{ - UndoableCommand undo("mirrorSelected -axis y"); - Select_FlipAxis(1); -} - -void Selection_Flipz() -{ - UndoableCommand undo("mirrorSelected -axis z"); - Select_FlipAxis(2); -} - -void Selection_Rotatex() -{ - UndoableCommand undo("rotateSelected -axis x -angle -90"); - Select_RotateAxis(0, -90); -} - -void Selection_Rotatey() -{ - UndoableCommand undo("rotateSelected -axis y -angle 90"); - Select_RotateAxis(1, 90); -} - -void Selection_Rotatez() -{ - UndoableCommand undo("rotateSelected -axis z -angle -90"); - Select_RotateAxis(2, -90); -} - - -void Nudge(int nDim, float fNudge) -{ - Vector3 translate(0, 0, 0); - translate[nDim] = fNudge; - - GlobalSelectionSystem().translateSelected(translate); -} - -void Selection_NudgeZ(float amount) -{ - StringOutputStream command; - command << "nudgeSelected -axis z -amount " << amount; - UndoableCommand undo(command.c_str()); - - Nudge(2, amount); -} - -void Selection_MoveDown() -{ - Selection_NudgeZ(-GetGridSize()); -} - -void Selection_MoveUp() -{ - Selection_NudgeZ(GetGridSize()); -} - -void SceneSelectionChange(const Selectable &selectable) -{ - SceneChangeNotify(); -} - -SignalHandlerId Selection_boundsChanged; - -void Selection_construct() -{ - typedef FreeCaller SceneSelectionChangeCaller; - GlobalSelectionSystem().addSelectionChangeCallback(SceneSelectionChangeCaller()); - typedef FreeCaller UpdateWorkzoneForSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(UpdateWorkzoneForSelectionChangedCaller()); - typedef FreeCaller UpdateWorkzoneForSelectionCaller; - Selection_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback(UpdateWorkzoneForSelectionCaller()); -} - -void Selection_destroy() -{ - GlobalSceneGraph().removeBoundsChangedCallback(Selection_boundsChanged); -} - - -#include "gtkdlgs.h" -#include - - -inline Quaternion quaternion_for_euler_xyz_degrees(const Vector3 &eulerXYZ) -{ -#if 0 - return quaternion_for_matrix4_rotation( matrix4_rotation_for_euler_xyz_degrees( eulerXYZ ) ); -#elif 0 - return quaternion_multiplied_by_quaternion( - quaternion_multiplied_by_quaternion( - quaternion_for_z( degrees_to_radians( eulerXYZ[2] ) ), - quaternion_for_y( degrees_to_radians( eulerXYZ[1] ) ) - ), - quaternion_for_x( degrees_to_radians( eulerXYZ[0] ) ) - ); -#elif 1 - double cx = cos(degrees_to_radians(eulerXYZ[0] * 0.5)); - double sx = sin(degrees_to_radians(eulerXYZ[0] * 0.5)); - double cy = cos(degrees_to_radians(eulerXYZ[1] * 0.5)); - double sy = sin(degrees_to_radians(eulerXYZ[1] * 0.5)); - double cz = cos(degrees_to_radians(eulerXYZ[2] * 0.5)); - double sz = sin(degrees_to_radians(eulerXYZ[2] * 0.5)); - - return Quaternion( - cz * cy * sx - sz * sy * cx, - cz * sy * cx + sz * cy * sx, - sz * cy * cx - cz * sy * sx, - cz * cy * cx + sz * sy * sx - ); -#endif -} - -struct RotateDialog { - ui::SpinButton x{ui::null}; - ui::SpinButton y{ui::null}; - ui::SpinButton z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean rotatedlg_apply(ui::Widget widget, RotateDialog *rotateDialog) -{ - Vector3 eulerXYZ; - - eulerXYZ[0] = static_cast( gtk_spin_button_get_value(rotateDialog->x)); - eulerXYZ[1] = static_cast( gtk_spin_button_get_value(rotateDialog->y)); - eulerXYZ[2] = static_cast( gtk_spin_button_get_value(rotateDialog->z)); - - StringOutputStream command; - command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2]; - UndoableCommand undo(command.c_str()); - - GlobalSelectionSystem().rotateSelected(quaternion_for_euler_xyz_degrees(eulerXYZ)); - return TRUE; -} - -static gboolean rotatedlg_cancel(ui::Widget widget, RotateDialog *rotateDialog) -{ - rotateDialog->window.hide(); - - gtk_spin_button_set_value(rotateDialog->x, 0.0f); // reset to 0 on close - gtk_spin_button_set_value(rotateDialog->y, 0.0f); - gtk_spin_button_set_value(rotateDialog->z, 0.0f); - - return TRUE; -} - -static gboolean rotatedlg_ok(ui::Widget widget, RotateDialog *rotateDialog) -{ - rotatedlg_apply(widget, rotateDialog); - rotateDialog->window.hide(); - return TRUE; -} - -static gboolean rotatedlg_delete(ui::Widget widget, GdkEventAny *event, RotateDialog *rotateDialog) -{ - rotatedlg_cancel(widget, rotateDialog); - return TRUE; -} - -RotateDialog g_rotate_dialog; - -void DoRotateDlg() -{ - if (!g_rotate_dialog.window) { - g_rotate_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary rotation", - G_CALLBACK(rotatedlg_delete), - &g_rotate_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_rotate_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_rotate_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - gtk_widget_grab_focus(spin); - - g_rotate_dialog.x = spin; - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - g_rotate_dialog.y = spin; - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - g_rotate_dialog.z = spin; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(rotatedlg_ok), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(rotatedlg_cancel), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(rotatedlg_apply), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_rotate_dialog.window.show(); -} - - -struct ScaleDialog { - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - ui::Entry z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean scaledlg_apply(ui::Widget widget, ScaleDialog *scaleDialog) -{ - float sx, sy, sz; - - sx = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->x)))); - sy = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->y)))); - sz = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->z)))); - - StringOutputStream command; - command << "scaleSelected -x " << sx << " -y " << sy << " -z " << sz; - UndoableCommand undo(command.c_str()); - - Select_Scale(sx, sy, sz); - - return TRUE; -} - -static gboolean scaledlg_cancel(ui::Widget widget, ScaleDialog *scaleDialog) -{ - scaleDialog->window.hide(); - - scaleDialog->x.text("1.0"); - scaleDialog->y.text("1.0"); - scaleDialog->z.text("1.0"); - - return TRUE; -} - -static gboolean scaledlg_ok(ui::Widget widget, ScaleDialog *scaleDialog) -{ - scaledlg_apply(widget, scaleDialog); - scaleDialog->window.hide(); - return TRUE; -} - -static gboolean scaledlg_delete(ui::Widget widget, GdkEventAny *event, ScaleDialog *scaleDialog) -{ - scaledlg_cancel(widget, scaleDialog); - return TRUE; -} - -ScaleDialog g_scale_dialog; - -void DoScaleDlg() -{ - if (!g_scale_dialog.window) { - g_scale_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", - G_CALLBACK(scaledlg_delete), - &g_scale_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_scale_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_scale_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.y = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.z = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(scaledlg_ok), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(scaledlg_cancel), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(scaledlg_apply), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_scale_dialog.window.show(); -} - -/* NEW: Artbirary Move */ - -struct MoveDialog { - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - ui::Entry z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean movedlg_apply(ui::Widget widget, MoveDialog *moveDialog) -{ - float sx, sy, sz; - - sx = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->x)))); - sy = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->y)))); - sz = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->z)))); - - StringOutputStream command; - command << "nudgeSelected -axis x " << sx; - command << "nudgeSelected -axis y " << sy; - command << "nudgeSelected -axis z " << sz; - UndoableCommand undo(command.c_str()); - - Nudge(0, sx); - Nudge(1, sy); - Nudge(2, sz); - return TRUE; -} - -static gboolean movedlg_cancel(ui::Widget widget, MoveDialog *moveDialog) -{ - moveDialog->window.hide(); - - moveDialog->x.text("0.0"); - moveDialog->y.text("0.0"); - moveDialog->z.text("0.0"); - - return TRUE; -} - -static gboolean movedlg_ok(ui::Widget widget, MoveDialog *moveDialog) -{ - movedlg_apply(widget, moveDialog); - moveDialog->window.hide(); - return TRUE; -} - -static gboolean movedlg_delete(ui::Widget widget, GdkEventAny *event, MoveDialog *moveDialog) -{ - movedlg_cancel(widget, moveDialog); - return TRUE; -} - -MoveDialog g_move_dialog; - -void DoMoveDlg() -{ - if (!g_move_dialog.window) { - g_move_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", - G_CALLBACK(movedlg_delete), - &g_move_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_move_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_move_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.y = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.z = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(movedlg_ok), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(movedlg_cancel), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(movedlg_apply), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_move_dialog.window.show(); -} - diff --git a/src/select.h b/src/select.h deleted file mode 100644 index 6a4e3f2..0000000 --- a/src/select.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SELECT_H ) -#define INCLUDED_SELECT_H - -#include "math/vector.h" - -void Select_GetBounds(Vector3 &mins, Vector3 &maxs); - -void Select_GetMid(Vector3 &mid); - -void Select_Delete(); - -void Select_Invert(); - -void Select_Inside(); - -void Select_Touching(); - -void Scene_ExpandSelectionToEntities(); - -void Selection_Flipx(); - -void Selection_Flipy(); - -void Selection_Flipz(); - -void Selection_Rotatex(); - -void Selection_Rotatey(); - -void Selection_Rotatez(); - - -void Selection_MoveDown(); - -void Selection_MoveUp(); - -void Select_AllOfType(); - -void Select_AllOfModel(); - -void DoRotateDlg(); - -void DoScaleDlg(); - -void DoMoveDlg(); - -void Select_SetShader(const char *shader); - -class TextureProjection; - -void Select_SetTexdef(const TextureProjection &projection, bool ignorebasis); - -class ContentsFlagsValue; - -void Select_SetFlags(const ContentsFlagsValue &flags); - -void Select_RotateTexture(float amt); - -void Select_ScaleTexture(float x, float y); - -void Select_ShiftTexture(float x, float y); - -void Select_FitTexture(float horizontal = 1, float vertical = 1); - -void Select_AlignTexture(int alignment); - -void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected); - -void HideSelected(); -void HideUnselected(); - -void Select_ShowAllHidden(); - -// updating workzone to a given brush (depends on current view) - -void Selection_construct(); - -void Selection_destroy(); - - -struct select_workzone_t { - // defines the boundaries of the current work area - // is used to guess brushes and drop points third coordinate when creating from 2D view - Vector3 d_work_min, d_work_max; - - select_workzone_t() : - d_work_min(-64.0f, -64.0f, -64.0f), - d_work_max(64.0f, 64.0f, 64.0f) - { - } -}; - -const select_workzone_t &Select_getWorkZone(); - -#endif diff --git a/src/selection.cpp b/src/selection.cpp deleted file mode 100644 index eeaca18..0000000 --- a/src/selection.cpp +++ /dev/null @@ -1,4098 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "selection.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "windowobserver.h" -#include "iundo.h" -#include "ientity.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "signal/signal.h" -#include "generic/object.h" -#include "selectionlib.h" -#include "render.h" -#include "view.h" -#include "renderer.h" -#include "stream/stringstream.h" -#include "eclasslib.h" -#include "generic/bitfield.h" -#include "generic/static.h" -#include "pivot.h" -#include "stringio.h" -#include "container/container.h" - -#include "grid.h" - -void Selection_Deselect(void); - -TextOutputStream &ostream_write(TextOutputStream &t, const Vector4 &v) -{ - return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]"; -} - -TextOutputStream &ostream_write(TextOutputStream &t, const Matrix4 &m) -{ - return t << "[ " << m.x() << " " << m.y() << " " << m.z() << " " << m.t() << " ]"; -} - -struct Pivot2World { - Matrix4 m_worldSpace; - Matrix4 m_viewpointSpace; - Matrix4 m_viewplaneSpace; - Vector3 m_axis_screen; - - void - update(const Matrix4 &pivot2world, const Matrix4 &modelview, const Matrix4 &projection, const Matrix4 &viewport) - { - Pivot2World_worldSpace(m_worldSpace, pivot2world, modelview, projection, viewport); - Pivot2World_viewpointSpace(m_viewpointSpace, m_axis_screen, pivot2world, modelview, projection, viewport); - Pivot2World_viewplaneSpace(m_viewplaneSpace, pivot2world, modelview, projection, viewport); - } -}; - - -void point_for_device_point(Vector3 &point, const Matrix4 &device2object, const float x, const float y, const float z) -{ - // transform from normalised device coords to object coords - point = vector4_projected(matrix4_transformed_vector4(device2object, Vector4(x, y, z, 1))); -} - -void ray_for_device_point(Ray &ray, const Matrix4 &device2object, const float x, const float y) -{ - // point at x, y, zNear - point_for_device_point(ray.origin, device2object, x, y, -1); - - // point at x, y, zFar - point_for_device_point(ray.direction, device2object, x, y, 1); - - // construct ray - vector3_subtract(ray.direction, ray.origin); - vector3_normalise(ray.direction); -} - -bool sphere_intersect_ray(const Vector3 &origin, float radius, const Ray &ray, Vector3 &intersection) -{ - intersection = vector3_subtracted(origin, ray.origin); - const double a = vector3_dot(intersection, ray.direction); - const double d = radius * radius - (vector3_dot(intersection, intersection) - a * a); - - if (d > 0) { - intersection = vector3_added(ray.origin, vector3_scaled(ray.direction, a - sqrt(d))); - return true; - } else { - intersection = vector3_added(ray.origin, vector3_scaled(ray.direction, a)); - return false; - } -} - -void ray_intersect_ray(const Ray &ray, const Ray &other, Vector3 &intersection) -{ - intersection = vector3_subtracted(ray.origin, other.origin); - //float a = 1;//vector3_dot(ray.direction, ray.direction); // always >= 0 - double dot = vector3_dot(ray.direction, other.direction); - //float c = 1;//vector3_dot(other.direction, other.direction); // always >= 0 - double d = vector3_dot(ray.direction, intersection); - double e = vector3_dot(other.direction, intersection); - double D = 1 - dot * dot; //a*c - dot*dot; // always >= 0 - - if (D < 0.000001) { - // the lines are almost parallel - intersection = vector3_added(other.origin, vector3_scaled(other.direction, e)); - } else { - intersection = vector3_added(other.origin, vector3_scaled(other.direction, (e - dot * d) / D)); - } -} - -const Vector3 g_origin(0, 0, 0); -const float g_radius = 64; - -void point_on_sphere(Vector3 &point, const Matrix4 &device2object, const float x, const float y) -{ - Ray ray; - ray_for_device_point(ray, device2object, x, y); - sphere_intersect_ray(g_origin, g_radius, ray, point); -} - -void point_on_axis(Vector3 &point, const Vector3 &axis, const Matrix4 &device2object, const float x, const float y) -{ - Ray ray; - ray_for_device_point(ray, device2object, x, y); - ray_intersect_ray(ray, Ray(Vector3(0, 0, 0), axis), point); -} - -void point_on_plane(Vector3 &point, const Matrix4 &device2object, const float x, const float y) -{ - Matrix4 object2device(matrix4_full_inverse(device2object)); - point = vector4_projected( - matrix4_transformed_vector4(device2object, Vector4(x, y, object2device[14] / object2device[15], 1))); -} - -//! a and b are unit vectors .. returns angle in radians -inline float angle_between(const Vector3 &a, const Vector3 &b) -{ - return static_cast( 2.0 * atan2( - vector3_length(vector3_subtracted(a, b)), - vector3_length(vector3_added(a, b)) - )); -} - - -#if GDEF_DEBUG - -class test_quat { -public: -test_quat(const Vector3 &from, const Vector3 &to) -{ - Vector4 quaternion(quaternion_for_unit_vectors(from, to)); - Matrix4 matrix(matrix4_rotation_for_quaternion( - quaternion_multiplied_by_quaternion(quaternion, c_quaternion_identity))); -} - -private: -}; - -static test_quat bleh(g_vector3_axis_x, g_vector3_axis_y); -#endif - -//! axis is a unit vector -inline void constrain_to_axis(Vector3 &vec, const Vector3 &axis) -{ - vec = vector3_normalised(vector3_added(vec, vector3_scaled(axis, -vector3_dot(vec, axis)))); -} - -//! a and b are unit vectors .. a and b must be orthogonal to axis .. returns angle in radians -float angle_for_axis(const Vector3 &a, const Vector3 &b, const Vector3 &axis) -{ - if (vector3_dot(axis, vector3_cross(a, b)) > 0.0) { - return angle_between(a, b); - } else { - return -angle_between(a, b); - } -} - -float distance_for_axis(const Vector3 &a, const Vector3 &b, const Vector3 &axis) -{ - return static_cast( vector3_dot(b, axis) - vector3_dot(a, axis)); -} - -class Manipulatable { -public: -virtual void Construct(const Matrix4 &device2manip, const float x, const float y) = 0; - -virtual void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) = 0; -}; - -void transform_local2object(Matrix4 &object, const Matrix4 &local, const Matrix4 &local2object) -{ - object = matrix4_multiplied_by_matrix4( - matrix4_multiplied_by_matrix4(local2object, local), - matrix4_full_inverse(local2object) - ); -} - -class Rotatable { -public: -virtual ~Rotatable() = default; - -virtual void rotate(const Quaternion &rotation) = 0; -}; - -class RotateFree : public Manipulatable { -Vector3 m_start; -Rotatable &m_rotatable; -public: -RotateFree(Rotatable &rotatable) - : m_rotatable(rotatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_sphere(m_start, device2manip, x, y); - vector3_normalise(m_start); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - - point_on_sphere(current, device2manip, x, y); - vector3_normalise(current); - - m_rotatable.rotate(quaternion_for_unit_vectors(m_start, current)); -} -}; - -class RotateAxis : public Manipulatable { -Vector3 m_axis; -Vector3 m_start; -Rotatable &m_rotatable; -public: -RotateAxis(Rotatable &rotatable) - : m_rotatable(rotatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_sphere(m_start, device2manip, x, y); - constrain_to_axis(m_start, m_axis); -} - -/// \brief Converts current position to a normalised vector orthogonal to axis. -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_sphere(current, device2manip, x, y); - constrain_to_axis(current, m_axis); - - m_rotatable.rotate(quaternion_for_axisangle(m_axis, angle_for_axis(m_start, current, m_axis))); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -void translation_local2object(Vector3 &object, const Vector3 &local, const Matrix4 &local2object) -{ - object = matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3(local2object, local), - matrix4_full_inverse(local2object) - ) - ); -} - -class Translatable { -public: -virtual ~Translatable() = default; - -virtual void translate(const Vector3 &translation) = 0; -}; - -class TranslateAxis : public Manipulatable { -Vector3 m_start; -Vector3 m_axis; -Translatable &m_translatable; -public: -TranslateAxis(Translatable &translatable) - : m_translatable(translatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_axis(m_start, m_axis, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_axis(current, m_axis, device2manip, x, y); - current = vector3_scaled(m_axis, distance_for_axis(m_start, current, m_axis)); - - translation_local2object(current, current, manip2object); - vector3_snap(current, GetSnapGridSize()); - - m_translatable.translate(current); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -class TranslateFree : public Manipulatable { -private: -Vector3 m_start; -Translatable &m_translatable; -public: -TranslateFree(Translatable &translatable) - : m_translatable(translatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_plane(m_start, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_plane(current, device2manip, x, y); - current = vector3_subtracted(current, m_start); - - translation_local2object(current, current, manip2object); - vector3_snap(current, GetSnapGridSize()); - - m_translatable.translate(current); -} -}; - - -class Scalable { -public: -virtual ~Scalable() = default; - -virtual void scale(const Vector3 &scaling) = 0; -}; - - -class ScaleAxis : public Manipulatable { -private: -Vector3 m_start; -Vector3 m_axis; -Scalable &m_scalable; -public: -ScaleAxis(Scalable &scalable) - : m_scalable(scalable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_axis(m_start, m_axis, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_axis(current, m_axis, device2manip, x, y); - Vector3 delta = vector3_subtracted(current, m_start); - - translation_local2object(delta, delta, manip2object); - vector3_snap(delta, GetSnapGridSize()); - - Vector3 start(vector3_snapped(m_start, GetSnapGridSize())); - Vector3 scale( - start[0] == 0 ? 1 : 1 + delta[0] / start[0], - start[1] == 0 ? 1 : 1 + delta[1] / start[1], - start[2] == 0 ? 1 : 1 + delta[2] / start[2] - ); - m_scalable.scale(scale); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -class ScaleFree : public Manipulatable { -private: -Vector3 m_start; -Scalable &m_scalable; -public: -ScaleFree(Scalable &scalable) - : m_scalable(scalable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_plane(m_start, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_plane(current, device2manip, x, y); - Vector3 delta = vector3_subtracted(current, m_start); - - translation_local2object(delta, delta, manip2object); - vector3_snap(delta, GetSnapGridSize()); - - Vector3 start(vector3_snapped(m_start, GetSnapGridSize())); - Vector3 scale( - start[0] == 0 ? 1 : 1 + delta[0] / start[0], - start[1] == 0 ? 1 : 1 + delta[1] / start[1], - start[2] == 0 ? 1 : 1 + delta[2] / start[2] - ); - m_scalable.scale(scale); -} -}; - - -class RenderableClippedPrimitive : public OpenGLRenderable { -struct primitive_t { - PointVertex m_points[9]; - std::size_t m_count; -}; -Matrix4 m_inverse; -std::vector m_primitives; -public: -Matrix4 m_world; - -void render(RenderStateFlags state) const -{ - for (std::size_t i = 0; i < m_primitives.size(); ++i) { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_primitives[i].m_points[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_primitives[i].m_points[0].vertex); - switch (m_primitives[i].m_count) { - case 1: - break; - case 2: - glDrawArrays(GL_LINES, 0, GLsizei(m_primitives[i].m_count)); - break; - default: - glDrawArrays(GL_POLYGON, 0, GLsizei(m_primitives[i].m_count)); - break; - } - } -} - -void construct(const Matrix4 &world2device) -{ - m_inverse = matrix4_full_inverse(world2device); - m_world = g_matrix4_identity; -} - -void insert(const Vector4 clipped[9], std::size_t count) -{ - add_one(); - - m_primitives.back().m_count = count; - for (std::size_t i = 0; i < count; ++i) { - Vector3 world_point(vector4_projected(matrix4_transformed_vector4(m_inverse, clipped[i]))); - m_primitives.back().m_points[i].vertex = vertex3f_for_vector3(world_point); - } -} - -void destroy() -{ - m_primitives.clear(); -} - -private: -void add_one() -{ - m_primitives.push_back(primitive_t()); - - const Colour4b colour_clipped(255, 127, 0, 255); - - for (std::size_t i = 0; i < 9; ++i) { - m_primitives.back().m_points[i].colour = colour_clipped; - } -} -}; - -#if GDEF_DEBUG -//#define DEBUG_SELECTION -#endif - -#if defined( DEBUG_SELECTION ) -Shader *g_state_clipped; -RenderableClippedPrimitive g_render_clipped; -#endif - - -#if 0 -// dist_Point_to_Line(): get the distance of a point to a line. -// Input: a Point P and a Line L (in any dimension) -// Return: the shortest distance from P to L -float -dist_Point_to_Line( Point P, Line L ){ - Vector v = L.P1 - L.P0; - Vector w = P - L.P0; - - double c1 = dot( w,v ); - double c2 = dot( v,v ); - double b = c1 / c2; - - Point Pb = L.P0 + b * v; - return d( P, Pb ); -} -#endif - -class Segment3D { -typedef Vector3 point_type; -public: -Segment3D(const point_type &_p0, const point_type &_p1) - : p0(_p0), p1(_p1) -{ -} - -point_type p0, p1; -}; - -typedef Vector3 Point3D; - -inline double vector3_distance_squared(const Point3D &a, const Point3D &b) -{ - return vector3_length_squared(b - a); -} - -// get the distance of a point to a segment. -Point3D segment_closest_point_to_point(const Segment3D &segment, const Point3D &point) -{ - Vector3 v = segment.p1 - segment.p0; - Vector3 w = point - segment.p0; - - double c1 = vector3_dot(w, v); - if (c1 <= 0) { - return segment.p0; - } - - double c2 = vector3_dot(v, v); - if (c2 <= c1) { - return segment.p1; - } - - return Point3D(segment.p0 + v * (c1 / c2)); -} - -double segment_dist_to_point_3d(const Segment3D &segment, const Point3D &point) -{ - return vector3_distance_squared(point, segment_closest_point_to_point(segment, point)); -} - -typedef Vector3 point_t; -typedef const Vector3 *point_iterator_t; - -// crossing number test for a point in a polygon -// This code is patterned after [Franklin, 2000] -bool point_test_polygon_2d(const point_t &P, point_iterator_t start, point_iterator_t finish) -{ - std::size_t crossings = 0; - - // loop through all edges of the polygon - for (point_iterator_t prev = finish - 1, cur = start; - cur != finish; prev = cur, ++cur) { // edge from (*prev) to (*cur) - if ((((*prev)[1] <= P[1]) && ((*cur)[1] > P[1])) // an upward crossing - || (((*prev)[1] > P[1]) && ((*cur)[1] <= P[1]))) { // a downward crossing - // compute the actual edge-ray intersect x-coordinate - float vt = (float) (P[1] - (*prev)[1]) / ((*cur)[1] - (*prev)[1]); - if (P[0] < (*prev)[0] + vt * ((*cur)[0] - (*prev)[0])) { // P[0] < intersect - ++crossings; // a valid crossing of y=P[1] right of P[0] - } - } - } - return (crossings & 0x1) != 0; // 0 if even (out), and 1 if odd (in) -} - -inline double triangle_signed_area_XY(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) -{ - return ((p1[0] - p0[0]) * (p2[1] - p0[1])) - ((p2[0] - p0[0]) * (p1[1] - p0[1])); -} - -enum clipcull_t { - eClipCullNone, - eClipCullCW, - eClipCullCCW, -}; - - -inline SelectionIntersection select_point_from_clipped(Vector4 &clipped) -{ - return SelectionIntersection(clipped[2] / clipped[3], static_cast( vector3_length_squared( - Vector3(clipped[0] / clipped[3], clipped[1] / clipped[3], 0)))); -} - -void BestPoint(std::size_t count, Vector4 clipped[9], SelectionIntersection &best, clipcull_t cull) -{ - Vector3 normalised[9]; - - { - for (std::size_t i = 0; i < count; ++i) { - normalised[i][0] = clipped[i][0] / clipped[i][3]; - normalised[i][1] = clipped[i][1] / clipped[i][3]; - normalised[i][2] = clipped[i][2] / clipped[i][3]; - } - } - - if (cull != eClipCullNone && count > 2) { - double signed_area = triangle_signed_area_XY(normalised[0], normalised[1], normalised[2]); - - if ((cull == eClipCullCW && signed_area > 0) - || (cull == eClipCullCCW && signed_area < 0)) { - return; - } - } - - if (count == 2) { - Segment3D segment(normalised[0], normalised[1]); - Point3D point = segment_closest_point_to_point(segment, Vector3(0, 0, 0)); - assign_if_closer(best, SelectionIntersection(point.z(), 0)); - } else if (count > 2 && !point_test_polygon_2d(Vector3(0, 0, 0), normalised, normalised + count)) { - point_iterator_t end = normalised + count; - for (point_iterator_t previous = end - 1, current = normalised; current != end; previous = current, ++current) { - Segment3D segment(*previous, *current); - Point3D point = segment_closest_point_to_point(segment, Vector3(0, 0, 0)); - float depth = point.z(); - point.z() = 0; - float distance = static_cast( vector3_length_squared(point)); - - assign_if_closer(best, SelectionIntersection(depth, distance)); - } - } else if (count > 2) { - assign_if_closer( - best, - SelectionIntersection( - static_cast( ray_distance_to_plane( - Ray(Vector3(0, 0, 0), Vector3(0, 0, 1)), - plane3_for_points(normalised[0], normalised[1], normalised[2]) - )), - 0 - ) - ); - } - -#if defined( DEBUG_SELECTION ) - if (count >= 2) { - g_render_clipped.insert(clipped, count); - } -#endif -} - -void LineStrip_BestPoint(const Matrix4 &local2view, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[2]; - for (std::size_t i = 0; (i + 1) < size; ++i) { - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[i + 1].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); - } -} - -void LineLoop_BestPoint(const Matrix4 &local2view, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[2]; - for (std::size_t i = 0; i < size; ++i) { - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[(i + 1) % size].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); - } -} - -void Line_BestPoint(const Matrix4 &local2view, const PointVertex vertices[2], SelectionIntersection &best) -{ - Vector4 clipped[2]; - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[0].vertex), - vertex3f_to_vector3(vertices[1].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); -} - -void Circle_BestPoint(const Matrix4 &local2view, clipcull_t cull, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (std::size_t i = 0; i < size; ++i) { - const std::size_t count = matrix4_clip_triangle(local2view, g_vector3_identity, - vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[(i + 1) % size].vertex), clipped); - BestPoint(count, clipped, best, cull); - } -} - -void -Quad_BestPoint(const Matrix4 &local2view, clipcull_t cull, const PointVertex *vertices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - { - const std::size_t count = matrix4_clip_triangle(local2view, vertex3f_to_vector3(vertices[0].vertex), - vertex3f_to_vector3(vertices[1].vertex), - vertex3f_to_vector3(vertices[3].vertex), clipped); - BestPoint(count, clipped, best, cull); - } - { - const std::size_t count = matrix4_clip_triangle(local2view, vertex3f_to_vector3(vertices[1].vertex), - vertex3f_to_vector3(vertices[2].vertex), - vertex3f_to_vector3(vertices[3].vertex), clipped); - BestPoint(count, clipped, best, cull); - } -} - -struct FlatShadedVertex { - Vertex3f vertex; - Colour4b colour; - Normal3f normal; - - FlatShadedVertex() - { - } -}; - - -typedef FlatShadedVertex *FlatShadedVertexIterator; - -void Triangles_BestPoint(const Matrix4 &local2view, clipcull_t cull, FlatShadedVertexIterator first, - FlatShadedVertexIterator last, SelectionIntersection &best) -{ - for (FlatShadedVertexIterator x(first), y(first + 1), z(first + 2); x != last; x += 3, y += 3, z += 3) { - Vector4 clipped[9]; - BestPoint( - matrix4_clip_triangle( - local2view, - reinterpret_cast((*x).vertex ), - reinterpret_cast((*y).vertex ), - reinterpret_cast((*z).vertex ), - clipped - ), - clipped, - best, - cull - ); - } -} - - -typedef std::multimap SelectableSortedSet; - -class SelectionPool : public Selector { -SelectableSortedSet m_pool; -SelectionIntersection m_intersection; -Selectable *m_selectable; - -public: -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - addSelectable(m_intersection, m_selectable); - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - assign_if_closer(m_intersection, intersection); -} - -void addSelectable(const SelectionIntersection &intersection, Selectable *selectable) -{ - if (intersection.valid()) { - m_pool.insert(SelectableSortedSet::value_type(intersection, selectable)); - } -} - -typedef SelectableSortedSet::iterator iterator; - -iterator begin() -{ - return m_pool.begin(); -} - -iterator end() -{ - return m_pool.end(); -} - -bool failed() -{ - return m_pool.empty(); -} -}; - - -const Colour4b g_colour_sphere(0, 0, 0, 255); -const Colour4b g_colour_screen(0, 255, 255, 255); -const Colour4b g_colour_selected(255, 255, 0, 255); - -inline const Colour4b &colourSelected(const Colour4b &colour, bool selected) -{ - return (selected) ? g_colour_selected : colour; -} - -template -inline void draw_semicircle(const std::size_t segments, const float radius, PointVertex *vertices, remap_policy remap) -{ - const double increment = c_pi / double(segments << 2); - - std::size_t count = 0; - float x = radius; - float y = 0; - remap_policy::set(vertices[segments << 2].vertex, -radius, 0, 0); - while (count < segments) { - PointVertex *i = vertices + count; - PointVertex *j = vertices + ((segments << 1) - (count + 1)); - - PointVertex *k = i + (segments << 1); - PointVertex *l = j + (segments << 1); - -#if 0 - PointVertex* m = i + ( segments << 2 ); - PointVertex* n = j + ( segments << 2 ); - PointVertex* o = k + ( segments << 2 ); - PointVertex* p = l + ( segments << 2 ); -#endif - - remap_policy::set(i->vertex, x, -y, 0); - remap_policy::set(k->vertex, -y, -x, 0); -#if 0 - remap_policy::set( m->vertex,-x, y, 0 ); - remap_policy::set( o->vertex, y, x, 0 ); -#endif - - ++count; - - { - const double theta = increment * count; - x = static_cast( radius * cos(theta)); - y = static_cast( radius * sin(theta)); - } - - remap_policy::set(j->vertex, y, -x, 0); - remap_policy::set(l->vertex, -x, -y, 0); -#if 0 - remap_policy::set( n->vertex,-y, x, 0 ); - remap_policy::set( p->vertex, x, y, 0 ); -#endif - } -} - -class Manipulator { -public: -virtual Manipulatable *GetManipulatable() = 0; - -virtual void testSelect(const View &view, const Matrix4 &pivot2world) -{ -} - -virtual void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ -} - -virtual void setSelected(bool select) = 0; - -virtual bool isSelected() const = 0; -}; - - -inline Vector3 normalised_safe(const Vector3 &self) -{ - if (vector3_equal(self, g_vector3_identity)) { - return g_vector3_identity; - } - return vector3_normalised(self); -} - - -class RotateManipulator : public Manipulator { -struct RenderableCircle : public OpenGLRenderable { - Array m_vertices; - - RenderableCircle(std::size_t size) : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex); - glDrawArrays(GL_LINE_LOOP, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -struct RenderableSemiCircle : public OpenGLRenderable { - Array m_vertices; - - RenderableSemiCircle(std::size_t size) : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -RotateFree m_free; -RotateAxis m_axis; -Vector3 m_axis_screen; -RenderableSemiCircle m_circle_x; -RenderableSemiCircle m_circle_y; -RenderableSemiCircle m_circle_z; -RenderableCircle m_circle_screen; -RenderableCircle m_circle_sphere; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -SelectableBool m_selectable_sphere; -Pivot2World m_pivot; -Matrix4 m_local2world_x; -Matrix4 m_local2world_y; -Matrix4 m_local2world_z; -bool m_circle_x_visible; -bool m_circle_y_visible; -bool m_circle_z_visible; -public: -static Shader *m_state_outer; - -RotateManipulator(Rotatable &rotatable, std::size_t segments, float radius) : - m_free(rotatable), - m_axis(rotatable), - m_circle_x((segments << 2) + 1), - m_circle_y((segments << 2) + 1), - m_circle_z((segments << 2) + 1), - m_circle_screen(segments << 3), - m_circle_sphere(segments << 3) -{ - draw_semicircle(segments, radius, m_circle_x.m_vertices.data(), RemapYZX()); - draw_semicircle(segments, radius, m_circle_y.m_vertices.data(), RemapZXY()); - draw_semicircle(segments, radius, m_circle_z.m_vertices.data(), RemapXYZ()); - - draw_circle(segments, radius * 1.15f, m_circle_screen.m_vertices.data(), RemapXYZ()); - draw_circle(segments, radius, m_circle_sphere.m_vertices.data(), RemapXYZ()); -} - - -void UpdateColours() -{ - m_circle_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_circle_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_circle_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_circle_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); - m_circle_sphere.setColour(colourSelected(g_colour_sphere, false)); -} - -void updateCircleTransforms() -{ - Vector3 localViewpoint(matrix4_transformed_direction(matrix4_transposed(m_pivot.m_worldSpace), - vector4_to_vector3(m_pivot.m_viewpointSpace.z()))); - - m_circle_x_visible = !vector3_equal_epsilon(g_vector3_axis_x, localViewpoint, 1e-6f); - if (m_circle_x_visible) { - m_local2world_x = g_matrix4_identity; - vector4_to_vector3(m_local2world_x.y()) = normalised_safe( - vector3_cross(g_vector3_axis_x, localViewpoint) - ); - vector4_to_vector3(m_local2world_x.z()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_x.x()), vector4_to_vector3(m_local2world_x.y())) - ); - matrix4_premultiply_by_matrix4(m_local2world_x, m_pivot.m_worldSpace); - } - - m_circle_y_visible = !vector3_equal_epsilon(g_vector3_axis_y, localViewpoint, 1e-6f); - if (m_circle_y_visible) { - m_local2world_y = g_matrix4_identity; - vector4_to_vector3(m_local2world_y.z()) = normalised_safe( - vector3_cross(g_vector3_axis_y, localViewpoint) - ); - vector4_to_vector3(m_local2world_y.x()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_y.y()), vector4_to_vector3(m_local2world_y.z())) - ); - matrix4_premultiply_by_matrix4(m_local2world_y, m_pivot.m_worldSpace); - } - - m_circle_z_visible = !vector3_equal_epsilon(g_vector3_axis_z, localViewpoint, 1e-6f); - if (m_circle_z_visible) { - m_local2world_z = g_matrix4_identity; - vector4_to_vector3(m_local2world_z.x()) = normalised_safe( - vector3_cross(g_vector3_axis_z, localViewpoint) - ); - vector4_to_vector3(m_local2world_z.y()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_z.z()), vector4_to_vector3(m_local2world_z.x())) - ); - matrix4_premultiply_by_matrix4(m_local2world_z, m_pivot.m_worldSpace); - } -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - updateCircleTransforms(); - - // temp hack - UpdateColours(); - - renderer.SetState(m_state_outer, Renderer::eWireframeOnly); - renderer.SetState(m_state_outer, Renderer::eFullMaterials); - - renderer.addRenderable(m_circle_screen, m_pivot.m_viewpointSpace); - renderer.addRenderable(m_circle_sphere, m_pivot.m_viewpointSpace); - - if (m_circle_x_visible) { - renderer.addRenderable(m_circle_x, m_local2world_x); - } - if (m_circle_y_visible) { - renderer.addRenderable(m_circle_y, m_local2world_y); - } - if (m_circle_z_visible) { - renderer.addRenderable(m_circle_z, m_local2world_z); - } -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - updateCircleTransforms(); - - SelectionPool selector; - - { - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_x)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_x.m_vertices.data(), m_circle_x.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_x); - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_y)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_y.m_vertices.data(), m_circle_y.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_y); - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_z)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_z.m_vertices.data(), m_circle_z.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_z); - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - LineLoop_BestPoint(local2view, m_circle_screen.m_vertices.data(), m_circle_screen.m_vertices.size(), - best); - selector.addSelectable(best, &m_selectable_screen); - } - - { - SelectionIntersection best; - Circle_BestPoint(local2view, eClipCullCW, m_circle_sphere.m_vertices.data(), - m_circle_sphere.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_sphere); - } - } - - m_axis_screen = m_pivot.m_axis_screen; - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else if (m_selectable_screen.isSelected()) { - m_axis.SetAxis(m_axis_screen); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected() - | m_selectable_sphere.isSelected(); -} -}; - -Shader *RotateManipulator::m_state_outer; - - -const float arrowhead_length = 16; -const float arrowhead_radius = 4; - -inline void draw_arrowline(const float length, PointVertex *line, const std::size_t axis) -{ - (*line++).vertex = vertex3f_identity; - (*line).vertex = vertex3f_identity; - vertex3f_to_array((*line).vertex)[axis] = length - arrowhead_length; -} - -template -inline void -draw_arrowhead(const std::size_t segments, const float length, FlatShadedVertex *vertices, VertexRemap, NormalRemap) -{ - std::size_t head_tris = (segments << 3); - const double head_segment = c_2pi / head_tris; - for (std::size_t i = 0; i < head_tris; ++i) { - { - FlatShadedVertex &point = vertices[i * 6 + 0]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos(i * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin(i * head_segment)); - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos(i * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin(i * head_segment)); - } - { - FlatShadedVertex &point = vertices[i * 6 + 1]; - VertexRemap::x(point.vertex) = length; - VertexRemap::y(point.vertex) = 0; - VertexRemap::z(point.vertex) = 0; - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos((i + 0.5) * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin((i + 0.5) * head_segment)); - } - { - FlatShadedVertex &point = vertices[i * 6 + 2]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos((i + 1) * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin((i + 1) * head_segment)); - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos((i + 1) * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin((i + 1) * head_segment)); - } - - { - FlatShadedVertex &point = vertices[i * 6 + 3]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = 0; - VertexRemap::z(point.vertex) = 0; - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - { - FlatShadedVertex &point = vertices[i * 6 + 4]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos(i * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin(i * head_segment)); - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - { - FlatShadedVertex &point = vertices[i * 6 + 5]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos((i + 1) * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin((i + 1) * head_segment)); - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - } -} - -template -class TripleRemapXYZ { -public: -static float &x(Triple &triple) -{ - return triple.x(); -} - -static float &y(Triple &triple) -{ - return triple.y(); -} - -static float &z(Triple &triple) -{ - return triple.z(); -} -}; - -template -class TripleRemapYZX { -public: -static float &x(Triple &triple) -{ - return triple.y(); -} - -static float &y(Triple &triple) -{ - return triple.z(); -} - -static float &z(Triple &triple) -{ - return triple.x(); -} -}; - -template -class TripleRemapZXY { -public: -static float &x(Triple &triple) -{ - return triple.z(); -} - -static float &y(Triple &triple) -{ - return triple.x(); -} - -static float &z(Triple &triple) -{ - return triple.y(); -} -}; - -void vector3_print(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )"; -} - -class TranslateManipulator : public Manipulator { -struct RenderableArrowLine : public OpenGLRenderable { - PointVertex m_line[2]; - - RenderableArrowLine() - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_line[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_line[0].vertex); - glDrawArrays(GL_LINES, 0, 2); - } - - void setColour(const Colour4b &colour) - { - m_line[0].colour = colour; - m_line[1].colour = colour; - } -}; - -struct RenderableArrowHead : public OpenGLRenderable { - Array m_vertices; - - RenderableArrowHead(std::size_t size) - : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FlatShadedVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(FlatShadedVertex), &m_vertices.data()->vertex); - glNormalPointer(GL_FLOAT, sizeof(FlatShadedVertex), &m_vertices.data()->normal); - glDrawArrays(GL_TRIANGLES, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -struct RenderableQuad : public OpenGLRenderable { - PointVertex m_quad[4]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_quad[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_quad[0].vertex); - glDrawArrays(GL_LINE_LOOP, 0, 4); - } - - void setColour(const Colour4b &colour) - { - m_quad[0].colour = colour; - m_quad[1].colour = colour; - m_quad[2].colour = colour; - m_quad[3].colour = colour; - } -}; - -TranslateFree m_free; -TranslateAxis m_axis; -RenderableArrowLine m_arrow_x; -RenderableArrowLine m_arrow_y; -RenderableArrowLine m_arrow_z; -RenderableArrowHead m_arrow_head_x; -RenderableArrowHead m_arrow_head_y; -RenderableArrowHead m_arrow_head_z; -RenderableQuad m_quad_screen; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -Pivot2World m_pivot; -public: -static Shader *m_state_wire; -static Shader *m_state_fill; - -TranslateManipulator(Translatable &translatable, std::size_t segments, float length) : - m_free(translatable), - m_axis(translatable), - m_arrow_head_x(3 * 2 * (segments << 3)), - m_arrow_head_y(3 * 2 * (segments << 3)), - m_arrow_head_z(3 * 2 * (segments << 3)) -{ - draw_arrowline(length, m_arrow_x.m_line, 0); - draw_arrowhead(segments, length, m_arrow_head_x.m_vertices.data(), TripleRemapXYZ(), - TripleRemapXYZ()); - draw_arrowline(length, m_arrow_y.m_line, 1); - draw_arrowhead(segments, length, m_arrow_head_y.m_vertices.data(), TripleRemapYZX(), - TripleRemapYZX()); - draw_arrowline(length, m_arrow_z.m_line, 2); - draw_arrowhead(segments, length, m_arrow_head_z.m_vertices.data(), TripleRemapZXY(), - TripleRemapZXY()); - - draw_quad(16, m_quad_screen.m_quad); -} - -void UpdateColours() -{ - m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_head_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_head_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_arrow_head_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); -} - -bool manipulator_show_axis(const Pivot2World &pivot, const Vector3 &axis) -{ - return fabs(vector3_dot(pivot.m_axis_screen, axis)) < 0.95; -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - - // temp hack - UpdateColours(); - - Vector3 x = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.x())); - bool show_x = manipulator_show_axis(m_pivot, x); - - Vector3 y = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.y())); - bool show_y = manipulator_show_axis(m_pivot, y); - - Vector3 z = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.z())); - bool show_z = manipulator_show_axis(m_pivot, z); - - renderer.SetState(m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_state_wire, Renderer::eFullMaterials); - - if (show_x) { - renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace); - } - if (show_y) { - renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace); - } - if (show_z) { - renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace); - } - - renderer.addRenderable(m_quad_screen, m_pivot.m_viewplaneSpace); - - renderer.SetState(m_state_fill, Renderer::eWireframeOnly); - renderer.SetState(m_state_fill, Renderer::eFullMaterials); - - if (show_x) { - renderer.addRenderable(m_arrow_head_x, m_pivot.m_worldSpace); - } - if (show_y) { - renderer.addRenderable(m_arrow_head_y, m_pivot.m_worldSpace); - } - if (show_z) { - renderer.addRenderable(m_arrow_head_z, m_pivot.m_worldSpace); - } -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - - SelectionPool selector; - - Vector3 x = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.x())); - bool show_x = manipulator_show_axis(m_pivot, x); - - Vector3 y = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.y())); - bool show_y = manipulator_show_axis(m_pivot, y); - - Vector3 z = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.z())); - bool show_z = manipulator_show_axis(m_pivot, z); - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best); - if (best.valid()) { - best = SelectionIntersection(0, 0); - selector.addSelectable(best, &m_selectable_screen); - } - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - if (show_x) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_x.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_x.m_vertices.begin(), - m_arrow_head_x.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_x); - } - - if (show_y) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_y.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_y.m_vertices.begin(), - m_arrow_head_y.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_y); - } - - if (show_z) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_z.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_z.m_vertices.begin(), - m_arrow_head_z.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_z); - } - } - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected(); -} -}; - -Shader *TranslateManipulator::m_state_wire; -Shader *TranslateManipulator::m_state_fill; - -class ScaleManipulator : public Manipulator { -struct RenderableArrow : public OpenGLRenderable { - PointVertex m_line[2]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_line[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_line[0].vertex); - glDrawArrays(GL_LINES, 0, 2); - } - - void setColour(const Colour4b &colour) - { - m_line[0].colour = colour; - m_line[1].colour = colour; - } -}; - -struct RenderableQuad : public OpenGLRenderable { - PointVertex m_quad[4]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_quad[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_quad[0].vertex); - glDrawArrays(GL_QUADS, 0, 4); - } - - void setColour(const Colour4b &colour) - { - m_quad[0].colour = colour; - m_quad[1].colour = colour; - m_quad[2].colour = colour; - m_quad[3].colour = colour; - } -}; - -ScaleFree m_free; -ScaleAxis m_axis; -RenderableArrow m_arrow_x; -RenderableArrow m_arrow_y; -RenderableArrow m_arrow_z; -RenderableQuad m_quad_screen; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -Pivot2World m_pivot; -public: -ScaleManipulator(Scalable &scalable, std::size_t segments, float length) : - m_free(scalable), - m_axis(scalable) -{ - draw_arrowline(length, m_arrow_x.m_line, 0); - draw_arrowline(length, m_arrow_y.m_line, 1); - draw_arrowline(length, m_arrow_z.m_line, 2); - - draw_quad(16, m_quad_screen.m_quad); -} - -Pivot2World &getPivot() -{ - return m_pivot; -} - -void UpdateColours() -{ - m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - - // temp hack - UpdateColours(); - - renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace); - renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace); - renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace); - - renderer.addRenderable(m_quad_screen, m_pivot.m_viewpointSpace); -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - - SelectionPool selector; - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_x.m_line, best); - selector.addSelectable(best, &m_selectable_x); - } - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_y.m_line, best); - selector.addSelectable(best, &m_selectable_y); - } - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_z.m_line, best); - selector.addSelectable(best, &m_selectable_z); - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best); - selector.addSelectable(best, &m_selectable_screen); - } - } - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected(); -} -}; - - -inline PlaneSelectable *Instance_getPlaneSelectable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -class PlaneSelectableSelectPlanes : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -PlaneCallback m_selectedPlaneCallback; -public: -PlaneSelectableSelectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) - : m_selector(selector), m_test(test), m_selectedPlaneCallback(selectedPlaneCallback) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - PlaneSelectable *planeSelectable = Instance_getPlaneSelectable(instance); - if (planeSelectable != 0) { - planeSelectable->selectPlanes(m_selector, m_test, m_selectedPlaneCallback); - } - } - } - return true; -} -}; - -class PlaneSelectableSelectReversedPlanes : public scene::Graph::Walker { -Selector &m_selector; -const SelectedPlanes &m_selectedPlanes; -public: -PlaneSelectableSelectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) - : m_selector(selector), m_selectedPlanes(selectedPlanes) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - PlaneSelectable *planeSelectable = Instance_getPlaneSelectable(instance); - if (planeSelectable != 0) { - planeSelectable->selectReversedPlanes(m_selector, m_selectedPlanes); - } - } - } - return true; -} -}; - -void Scene_forEachPlaneSelectable_selectPlanes(scene::Graph &graph, Selector &selector, SelectionTest &test, - const PlaneCallback &selectedPlaneCallback) -{ - graph.traverse(PlaneSelectableSelectPlanes(selector, test, selectedPlaneCallback)); -} - -void Scene_forEachPlaneSelectable_selectReversedPlanes(scene::Graph &graph, Selector &selector, - const SelectedPlanes &selectedPlanes) -{ - graph.traverse(PlaneSelectableSelectReversedPlanes(selector, selectedPlanes)); -} - - -class PlaneLess { -public: -bool operator()(const Plane3 &plane, const Plane3 &other) const -{ - if (plane.a < other.a) { - return true; - } - if (other.a < plane.a) { - return false; - } - - if (plane.b < other.b) { - return true; - } - if (other.b < plane.b) { - return false; - } - - if (plane.c < other.c) { - return true; - } - if (other.c < plane.c) { - return false; - } - - if (plane.d < other.d) { - return true; - } - if (other.d < plane.d) { - return false; - } - - return false; -} -}; - -typedef std::set PlaneSet; - -inline void PlaneSet_insert(PlaneSet &self, const Plane3 &plane) -{ - self.insert(plane); -} - -inline bool PlaneSet_contains(const PlaneSet &self, const Plane3 &plane) -{ - return self.find(plane) != self.end(); -} - - -class SelectedPlaneSet : public SelectedPlanes { -PlaneSet m_selectedPlanes; -public: -bool empty() const -{ - return m_selectedPlanes.empty(); -} - -void insert(const Plane3 &plane) -{ - PlaneSet_insert(m_selectedPlanes, plane); -} - -bool contains(const Plane3 &plane) const -{ - return PlaneSet_contains(m_selectedPlanes, plane); -} - -typedef MemberCaller InsertCaller; -}; - - -bool Scene_forEachPlaneSelectable_selectPlanes(scene::Graph &graph, Selector &selector, SelectionTest &test) -{ - SelectedPlaneSet selectedPlanes; - - Scene_forEachPlaneSelectable_selectPlanes(graph, selector, test, SelectedPlaneSet::InsertCaller(selectedPlanes)); - Scene_forEachPlaneSelectable_selectReversedPlanes(graph, selector, selectedPlanes); - - return !selectedPlanes.empty(); -} - -void Scene_Translate_Component_Selected(scene::Graph &graph, const Vector3 &translation); - -void Scene_Translate_Selected(scene::Graph &graph, const Vector3 &translation); - -void Scene_TestSelect_Primitive(Selector &selector, SelectionTest &test, const VolumeTest &volume); - -void Scene_TestSelect_Component(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode); - -void Scene_TestSelect_Component_Selected(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode); - -void Scene_SelectAll_Component(bool select, SelectionSystem::EComponentMode componentMode); - -class ResizeTranslatable : public Translatable { -void translate(const Vector3 &translation) -{ - Scene_Translate_Component_Selected(GlobalSceneGraph(), translation); -} -}; - -class DragTranslatable : public Translatable { -void translate(const Vector3 &translation) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - Scene_Translate_Component_Selected(GlobalSceneGraph(), translation); - } else { - Scene_Translate_Selected(GlobalSceneGraph(), translation); - } -} -}; - -class SelectionVolume : public SelectionTest { -Matrix4 m_local2view; -const View &m_view; -clipcull_t m_cull; -Vector3 m_near; -Vector3 m_far; -public: -SelectionVolume(const View &view) - : m_view(view) -{ -} - -const VolumeTest &getVolume() const -{ - return m_view; -} - -const Vector3 &getNear() const -{ - return m_near; -} - -const Vector3 &getFar() const -{ - return m_far; -} - -void BeginMesh(const Matrix4 &localToWorld, bool twoSided) -{ - m_local2view = matrix4_multiplied_by_matrix4(m_view.GetViewMatrix(), localToWorld); - - // Cull back-facing polygons based on winding being clockwise or counter-clockwise. - // Don't cull if the view is wireframe and the polygons are two-sided. - m_cull = twoSided && !m_view.fill() ? eClipCullNone : (matrix4_handedness(localToWorld) == MATRIX4_RIGHTHANDED) - ? eClipCullCW : eClipCullCCW; - - { - Matrix4 screen2world(matrix4_full_inverse(m_local2view)); - - m_near = vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, -1, 1) - ) - ); - - m_far = vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, 1, 1) - ) - ); - } - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(m_view.GetViewMatrix()); -#endif -} - -void TestPoint(const Vector3 &point, SelectionIntersection &best) -{ - Vector4 clipped; - if (matrix4_clip_point(m_local2view, point, clipped) == c_CLIP_PASS) { - best = select_point_from_clipped(clipped); - } -} - -void TestPolygon(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (std::size_t i = 0; i + 2 < count; ++i) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[0] ), - reinterpret_cast( vertices[i + 1] ), - reinterpret_cast( vertices[i + 2] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLineLoop(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count, prev = i + (count - 1); - i != end; prev = i, ++i) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*prev)), - reinterpret_cast((*i)), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLineStrip(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count, next = i + 1; - next != end; i = next, ++next) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*i)), - reinterpret_cast((*next)), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLines(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count; i != end; i += 2) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*i)), - reinterpret_cast((*(i + 1))), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestTriangles(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i != indices.end(); i += 3) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestQuads(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i != indices.end(); i += 4) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestQuadStrip(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i + 2 != indices.end(); i += 2) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - clipped - ), - clipped, - best, - m_cull - ); - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*(i + 2)] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} -}; - -class SelectionCounter { -public: -using func = void (const Selectable &); - -SelectionCounter(const SelectionChangeCallback &onchanged) - : m_count(0), m_onchanged(onchanged) -{ -} - -void operator()(const Selectable &selectable) -{ - if (selectable.isSelected()) { - ++m_count; - } else { - ASSERT_MESSAGE(m_count != 0, "selection counter underflow"); - --m_count; - } - - m_onchanged(selectable); -} - -bool empty() const -{ - return m_count == 0; -} - -std::size_t size() const -{ - return m_count; -} - -private: -std::size_t m_count; -SelectionChangeCallback m_onchanged; -}; - -inline void ConstructSelectionTest(View &view, const rect_t selection_box) -{ - view.EnableScissor(selection_box.min[0], selection_box.max[0], selection_box.min[1], selection_box.max[1]); -} - -inline const rect_t SelectionBoxForPoint(const float device_point[2], const float device_epsilon[2]) -{ - rect_t selection_box; - selection_box.min[0] = device_point[0] - device_epsilon[0]; - selection_box.min[1] = device_point[1] - device_epsilon[1]; - selection_box.max[0] = device_point[0] + device_epsilon[0]; - selection_box.max[1] = device_point[1] + device_epsilon[1]; - return selection_box; -} - -inline const rect_t SelectionBoxForArea(const float device_point[2], const float device_delta[2]) -{ - rect_t selection_box; - selection_box.min[0] = (device_delta[0] < 0) ? (device_point[0] + device_delta[0]) : (device_point[0]); - selection_box.min[1] = (device_delta[1] < 0) ? (device_point[1] + device_delta[1]) : (device_point[1]); - selection_box.max[0] = (device_delta[0] > 0) ? (device_point[0] + device_delta[0]) : (device_point[0]); - selection_box.max[1] = (device_delta[1] > 0) ? (device_point[1] + device_delta[1]) : (device_point[1]); - return selection_box; -} - -Quaternion construct_local_rotation(const Quaternion &world, const Quaternion &localToWorld) -{ - return quaternion_normalised(quaternion_multiplied_by_quaternion( - quaternion_normalised(quaternion_multiplied_by_quaternion( - quaternion_inverse(localToWorld), - world - )), - localToWorld - )); -} - -inline void matrix4_assign_rotation(Matrix4 &matrix, const Matrix4 &other) -{ - matrix[0] = other[0]; - matrix[1] = other[1]; - matrix[2] = other[2]; - matrix[4] = other[4]; - matrix[5] = other[5]; - matrix[6] = other[6]; - matrix[8] = other[8]; - matrix[9] = other[9]; - matrix[10] = other[10]; -} - -void matrix4_assign_rotation_for_pivot(Matrix4 &matrix, scene::Instance &instance) -{ - Editable *editable = Node_getEditable(instance.path().top()); - if (editable != 0) { - matrix4_assign_rotation(matrix, - matrix4_multiplied_by_matrix4(instance.localToWorld(), editable->getLocalPivot())); - } else { - matrix4_assign_rotation(matrix, instance.localToWorld()); - } -} - -inline bool Instance_isSelectedComponents(scene::Instance &instance) -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - return componentSelectionTestable != 0 - && componentSelectionTestable->isSelectedComponents(); -} - -class TranslateSelected : public SelectionSystem::Visitor { -const Vector3 &m_translate; -public: -TranslateSelected(const Vector3 &translate) - : m_translate(translate) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setTranslation(m_translate); - } -} -}; - -void Scene_Translate_Selected(scene::Graph &graph, const Vector3 &translation) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(TranslateSelected(translation)); - } -} - -Vector3 get_local_pivot(const Vector3 &world_pivot, const Matrix4 &localToWorld) -{ - return Vector3( - matrix4_transformed_point( - matrix4_full_inverse(localToWorld), - world_pivot - ) - ); -} - -void translation_for_pivoted_matrix_transform(Vector3 &parent_translation, const Matrix4 &local_transform, - const Vector3 &world_pivot, const Matrix4 &localToWorld, - const Matrix4 &localToParent) -{ - // we need a translation inside the parent system to move the origin of this object to the right place - - // mathematically, it must fulfill: - // - // local_translation local_transform local_pivot = local_pivot - // local_translation = local_pivot - local_transform local_pivot - // - // or maybe? - // local_transform local_translation local_pivot = local_pivot - // local_translation local_pivot = local_transform^-1 local_pivot - // local_translation + local_pivot = local_transform^-1 local_pivot - // local_translation = local_transform^-1 local_pivot - local_pivot - - Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld)); - - Vector3 local_translation( - vector3_subtracted( - local_pivot, - matrix4_transformed_point( - local_transform, - local_pivot - ) - /* - matrix4_transformed_point( - matrix4_full_inverse(local_transform), - local_pivot - ), - local_pivot - */ - ) - ); - - translation_local2object(parent_translation, local_translation, localToParent); - - /* - // verify it! - globalOutputStream() << "World pivot is at " << world_pivot << "\n"; - globalOutputStream() << "Local pivot is at " << local_pivot << "\n"; - globalOutputStream() << "Transformation " << local_transform << " moves it to: " << matrix4_transformed_point(local_transform, local_pivot) << "\n"; - globalOutputStream() << "Must move by " << local_translation << " in the local system" << "\n"; - globalOutputStream() << "Must move by " << parent_translation << " in the parent system" << "\n"; - */ -} - -void translation_for_pivoted_rotation(Vector3 &parent_translation, const Quaternion &local_rotation, - const Vector3 &world_pivot, const Matrix4 &localToWorld, - const Matrix4 &localToParent) -{ - translation_for_pivoted_matrix_transform(parent_translation, - matrix4_rotation_for_quaternion_quantised(local_rotation), world_pivot, - localToWorld, localToParent); -} - -void translation_for_pivoted_scale(Vector3 &parent_translation, const Vector3 &world_scale, const Vector3 &world_pivot, - const Matrix4 &localToWorld, const Matrix4 &localToParent) -{ - Matrix4 local_transform( - matrix4_multiplied_by_matrix4( - matrix4_full_inverse(localToWorld), - matrix4_multiplied_by_matrix4( - matrix4_scale_for_vec3(world_scale), - localToWorld - ) - ) - ); - local_transform.tx() = local_transform.ty() = local_transform.tz() = 0; // cancel translation parts - translation_for_pivoted_matrix_transform(parent_translation, local_transform, world_pivot, localToWorld, - localToParent); -} - -class rotate_selected : public SelectionSystem::Visitor { -const Quaternion &m_rotate; -const Vector3 &m_world_pivot; -public: -rotate_selected(const Quaternion &rotation, const Vector3 &world_pivot) - : m_rotate(rotation), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(instance.path().top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(c_scale_identity); - transform->setTranslation(c_translation_identity); - - transform->setType(TRANSFORM_PRIMITIVE); - transform->setRotation(m_rotate); - - { - Editable *editable = Node_getEditable(instance.path().top()); - const Matrix4 &localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity; - - Vector3 parent_translation; - translation_for_pivoted_rotation( - parent_translation, - m_rotate, - m_world_pivot, - matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot), - matrix4_multiplied_by_matrix4(transformNode->localToParent(), localPivot) - ); - - transform->setTranslation(parent_translation); - } - } - } -} -}; - -void Scene_Rotate_Selected(scene::Graph &graph, const Quaternion &rotation, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(rotate_selected(rotation, world_pivot)); - } -} - -class scale_selected : public SelectionSystem::Visitor { -const Vector3 &m_scale; -const Vector3 &m_world_pivot; -public: -scale_selected(const Vector3 &scaling, const Vector3 &world_pivot) - : m_scale(scaling), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(instance.path().top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(c_scale_identity); - transform->setTranslation(c_translation_identity); - - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(m_scale); - { - Editable *editable = Node_getEditable(instance.path().top()); - const Matrix4 &localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity; - - Vector3 parent_translation; - translation_for_pivoted_scale( - parent_translation, - m_scale, - m_world_pivot, - matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot), - matrix4_multiplied_by_matrix4(transformNode->localToParent(), localPivot) - ); - - transform->setTranslation(parent_translation); - } - } - } -} -}; - -void Scene_Scale_Selected(scene::Graph &graph, const Vector3 &scaling, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(scale_selected(scaling, world_pivot)); - } -} - - -class translate_component_selected : public SelectionSystem::Visitor { -const Vector3 &m_translate; -public: -translate_component_selected(const Vector3 &translate) - : m_translate(translate) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_COMPONENT); - transform->setTranslation(m_translate); - } -} -}; - -void Scene_Translate_Component_Selected(scene::Graph &graph, const Vector3 &translation) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(translate_component_selected(translation)); - } -} - -class rotate_component_selected : public SelectionSystem::Visitor { -const Quaternion &m_rotate; -const Vector3 &m_world_pivot; -public: -rotate_component_selected(const Quaternion &rotation, const Vector3 &world_pivot) - : m_rotate(rotation), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - Vector3 parent_translation; - translation_for_pivoted_rotation(parent_translation, m_rotate, m_world_pivot, instance.localToWorld(), - Node_getTransformNode(instance.path().top())->localToParent()); - - transform->setType(TRANSFORM_COMPONENT); - transform->setRotation(m_rotate); - transform->setTranslation(parent_translation); - } -} -}; - -void Scene_Rotate_Component_Selected(scene::Graph &graph, const Quaternion &rotation, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(rotate_component_selected(rotation, world_pivot)); - } -} - -class scale_component_selected : public SelectionSystem::Visitor { -const Vector3 &m_scale; -const Vector3 &m_world_pivot; -public: -scale_component_selected(const Vector3 &scaling, const Vector3 &world_pivot) - : m_scale(scaling), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - Vector3 parent_translation; - translation_for_pivoted_scale(parent_translation, m_scale, m_world_pivot, instance.localToWorld(), - Node_getTransformNode(instance.path().top())->localToParent()); - - transform->setType(TRANSFORM_COMPONENT); - transform->setScale(m_scale); - transform->setTranslation(parent_translation); - } -} -}; - -void Scene_Scale_Component_Selected(scene::Graph &graph, const Vector3 &scaling, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(scale_component_selected(scaling, world_pivot)); - } -} - - -class BooleanSelector : public Selector { -bool m_selected; -SelectionIntersection m_intersection; -Selectable *m_selectable; -public: -BooleanSelector() : m_selected(false) -{ -} - -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - if (m_intersection.valid()) { - m_selected = true; - } - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - if (m_selectable->isSelected()) { - assign_if_closer(m_intersection, intersection); - } -} - -bool isSelected() -{ - return m_selected; -} -}; - -class BestSelector : public Selector { -SelectionIntersection m_intersection; -Selectable *m_selectable; -SelectionIntersection m_bestIntersection; -std::list m_bestSelectable; -public: -BestSelector() : m_bestIntersection(SelectionIntersection()), m_bestSelectable(0) -{ -} - -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - if (m_intersection.equalEpsilon(m_bestIntersection, 0.25f, 0.001f)) { - m_bestSelectable.push_back(m_selectable); - m_bestIntersection = m_intersection; - } else if (m_intersection < m_bestIntersection) { - m_bestSelectable.clear(); - m_bestSelectable.push_back(m_selectable); - m_bestIntersection = m_intersection; - } - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - assign_if_closer(m_intersection, intersection); -} - -std::list &best() -{ - return m_bestSelectable; -} -}; - -class DragManipulator : public Manipulator { -TranslateFree m_freeResize; -TranslateFree m_freeDrag; -ResizeTranslatable m_resize; -DragTranslatable m_drag; -SelectableBool m_dragSelectable; -public: - -bool m_selected; - -DragManipulator() : m_freeResize(m_resize), m_freeDrag(m_drag), m_selected(false) -{ -} - -Manipulatable *GetManipulatable() -{ - return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - SelectionPool selector; - - SelectionVolume test(view); - - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - BooleanSelector booleanSelector; - - Scene_TestSelect_Primitive(booleanSelector, test, view); - - if (booleanSelector.isSelected()) { - selector.addSelectable(SelectionIntersection(0, 0), &m_dragSelectable); - m_selected = false; - } else { - m_selected = Scene_forEachPlaneSelectable_selectPlanes(GlobalSceneGraph(), selector, test); - } - } else { - BestSelector bestSelector; - Scene_TestSelect_Component_Selected(bestSelector, test, view, GlobalSelectionSystem().ComponentMode()); - for (std::list::iterator i = bestSelector.best().begin(); - i != bestSelector.best().end(); ++i) { - if (!(*i)->isSelected()) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } - m_selected = false; - selector.addSelectable(SelectionIntersection(0, 0), (*i)); - m_dragSelectable.setSelected(true); - } - } - - for (SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i) { - (*i).second->setSelected(true); - } -} - -void setSelected(bool select) -{ - m_selected = select; - m_dragSelectable.setSelected(select); -} - -bool isSelected() const -{ - return m_selected || m_dragSelectable.isSelected(); -} -}; - -class ClipManipulator : public Manipulator { -public: - -Manipulatable *GetManipulatable() -{ - ERROR_MESSAGE("clipper is not manipulatable"); - return 0; -} - -void setSelected(bool select) -{ -} - -bool isSelected() const -{ - return false; -} -}; - -class select_all : public scene::Graph::Walker { -bool m_select; -public: -select_all(bool select) - : m_select(select) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - selectable->setSelected(m_select); - } - return true; -} -}; - -class select_all_component : public scene::Graph::Walker { -bool m_select; -SelectionSystem::EComponentMode m_mode; -public: -select_all_component(bool select, SelectionSystem::EComponentMode mode) - : m_select(select), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->setSelectedComponents(m_select, m_mode); - } - return true; -} -}; - -void Scene_SelectAll_Component(bool select, SelectionSystem::EComponentMode componentMode) -{ - GlobalSceneGraph().traverse(select_all_component(select, componentMode)); -} -extern bool g_expansion_enabled; -extern bool g_addselect_enabled; - -void Scene_ExpandSelectionToEntities(); - -// RadiantSelectionSystem -class RadiantSelectionSystem : - public SelectionSystem, - public Translatable, - public Rotatable, - public Scalable, - public Renderable { -mutable Matrix4 m_pivot2world; -Matrix4 m_pivot2world_start; -Matrix4 m_manip2pivot_start; -Translation m_translation; -Rotation m_rotation; -Scale m_scale; -public: -static Shader *m_state; -private: -EManipulatorMode m_manipulator_mode; -Manipulator *m_manipulator; - -// state -bool m_undo_begun; -EMode m_mode; -EComponentMode m_componentmode; - -SelectionCounter m_count_primitive; -SelectionCounter m_count_component; - -TranslateManipulator m_translate_manipulator; -RotateManipulator m_rotate_manipulator; -ScaleManipulator m_scale_manipulator; -DragManipulator m_drag_manipulator; -ClipManipulator m_clip_manipulator; - -typedef SelectionList selection_t; -selection_t m_selection; -selection_t m_component_selection; - -Signal1 m_selectionChanged_callbacks; - -void ConstructPivot() const; - -mutable bool m_pivotChanged; -bool m_pivot_moving; - -void Scene_TestSelect(Selector &selector, SelectionTest &test, const View &view, SelectionSystem::EMode mode, - SelectionSystem::EComponentMode componentMode); - -bool nothingSelected() const -{ - return (Mode() == eComponent && m_count_component.empty()) - || (Mode() == ePrimitive && m_count_primitive.empty()); -} - - -public: -enum EModifier { - eManipulator, - eToggle, - eReplace, - eCycle, -}; - -RadiantSelectionSystem() : - m_undo_begun(false), - m_mode(ePrimitive), - m_componentmode(eDefault), - m_count_primitive(SelectionChangedCaller(*this)), - m_count_component(SelectionChangedCaller(*this)), - m_translate_manipulator(*this, 2, 64), - m_rotate_manipulator(*this, 8, 64), - m_scale_manipulator(*this, 0, 64), - m_pivotChanged(false), - m_pivot_moving(false) -{ - SetManipulatorMode(eTranslate); - pivotChanged(); - addSelectionChangeCallback(PivotChangedSelectionCaller(*this)); - AddGridChangeCallback(PivotChangedCaller(*this)); -} - -void pivotChanged() const -{ - m_pivotChanged = true; - SceneChangeNotify(); -} - -typedef ConstMemberCaller PivotChangedCaller; - -void pivotChangedSelection(const Selectable &selectable) -{ - pivotChanged(); -} - -typedef MemberCaller PivotChangedSelectionCaller; - -void SetMode(EMode mode) -{ - if (m_mode != mode) { - m_mode = mode; - pivotChanged(); - } -} - -EMode Mode() const -{ - return m_mode; -} - -void SetComponentMode(EComponentMode mode) -{ - m_componentmode = mode; -} - -EComponentMode ComponentMode() const -{ - return m_componentmode; -} - -void SetManipulatorMode(EManipulatorMode mode) -{ - m_manipulator_mode = mode; - switch (m_manipulator_mode) { - case eTranslate: - m_manipulator = &m_translate_manipulator; - break; - case eRotate: - m_manipulator = &m_rotate_manipulator; - break; - case eScale: - m_manipulator = &m_scale_manipulator; - break; - case eDrag: - m_manipulator = &m_drag_manipulator; - break; - case eClip: - m_manipulator = &m_clip_manipulator; - break; - } - pivotChanged(); -} - -EManipulatorMode ManipulatorMode() const -{ - return m_manipulator_mode; -} - -SelectionChangeCallback getObserver(EMode mode) -{ - if (mode == ePrimitive) { - return makeCallback(m_count_primitive); - } else { - return makeCallback(m_count_component); - } -} - -std::size_t countSelected() const -{ - return m_count_primitive.size(); -} - -std::size_t countSelectedComponents() const -{ - return m_count_component.size(); -} - -void onSelectedChanged(scene::Instance &instance, const Selectable &selectable) -{ - if (selectable.isSelected()) { - m_selection.append(instance); - } else { - m_selection.erase(instance); - } - - ASSERT_MESSAGE(m_selection.size() == m_count_primitive.size(), "selection-tracking error"); -} - -void onComponentSelection(scene::Instance &instance, const Selectable &selectable) -{ - if (selectable.isSelected()) { - m_component_selection.append(instance); - } else { - m_component_selection.erase(instance); - } - - ASSERT_MESSAGE(m_component_selection.size() == m_count_component.size(), "selection-tracking error"); -} - -scene::Instance &ultimateSelected() const -{ - ASSERT_MESSAGE(m_selection.size() > 0, "no instance selected"); - return m_selection.back(); -} - -scene::Instance &penultimateSelected() const -{ - ASSERT_MESSAGE(m_selection.size() > 1, "only one instance selected"); - return *(*(--(--m_selection.end()))); -} - -void setSelectedAll(bool selected) -{ - GlobalSceneGraph().traverse(select_all(selected)); - - m_manipulator->setSelected(selected); -} - -void setSelectedAllComponents(bool selected) -{ - Scene_SelectAll_Component(selected, SelectionSystem::eVertex); - Scene_SelectAll_Component(selected, SelectionSystem::eEdge); - Scene_SelectAll_Component(selected, SelectionSystem::eFace); - - m_manipulator->setSelected(selected); -} - -void foreachSelected(const Visitor &visitor) const -{ - selection_t::const_iterator i = m_selection.begin(); - while (i != m_selection.end()) { - visitor.visit(*(*(i++))); - } -} - -void foreachSelectedComponent(const Visitor &visitor) const -{ - selection_t::const_iterator i = m_component_selection.begin(); - while (i != m_component_selection.end()) { - visitor.visit(*(*(i++))); - } -} - -void addSelectionChangeCallback(const SelectionChangeHandler &handler) -{ - m_selectionChanged_callbacks.connectLast(handler); -} - -void selectionChanged(const Selectable &selectable) -{ - m_selectionChanged_callbacks(selectable); -} - -typedef MemberCaller SelectionChangedCaller; - - -void startMove() -{ - m_pivot2world_start = GetPivot2World(); -} - -bool SelectManipulator(const View &view, const float device_point[2], const float device_epsilon[2]) -{ - if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - m_manipulator->setSelected(false); - - if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon)); - m_manipulator->testSelect(scissored, GetPivot2World()); - } - - startMove(); - - m_pivot_moving = m_manipulator->isSelected(); - - if (m_pivot_moving) { - Pivot2World pivot; - pivot.update(GetPivot2World(), view.GetModelview(), view.GetProjection(), view.GetViewport()); - - m_manip2pivot_start = matrix4_multiplied_by_matrix4(matrix4_full_inverse(m_pivot2world_start), - pivot.m_worldSpace); - - Matrix4 device2manip; - ConstructDevice2Manip(device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), - view.GetViewport()); - m_manipulator->GetManipulatable()->Construct(device2manip, device_point[0], device_point[1]); - - m_undo_begun = false; - } - - SceneChangeNotify(); - } - - return m_pivot_moving; -} - -void deselectAll() -{ - if (Mode() == eComponent) { - setSelectedAllComponents(false); - } else { - setSelectedAll(false); - } -} - -void SelectPoint(const View &view, const float device_point[2], const float device_epsilon[2], - RadiantSelectionSystem::EModifier modifier, bool face) -{ - ASSERT_MESSAGE(fabs(device_point[0]) <= 1.0f && fabs(device_point[1]) <= 1.0f, "point-selection error"); - if (modifier == eReplace) { - if (face) { - setSelectedAllComponents(false); - } else { - deselectAll(); - } - } - -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon)); - - SelectionVolume volume(scissored); - SelectionPool selector; - if (face) { - Scene_TestSelect_Component(selector, volume, scissored, eFace); - } else { - Scene_TestSelect(selector, volume, scissored, Mode(), ComponentMode()); - } - - if (!selector.failed()) { - switch (modifier) { - case RadiantSelectionSystem::eToggle: { - if (g_addselect_enabled == false) - Selection_Deselect(); - - SelectableSortedSet::iterator best = selector.begin(); - // toggle selection of the object with least depth - if ((*best).second->isSelected()) { - (*best).second->setSelected(false); - } else { - (*best).second->setSelected(true); - - if (modifier == eToggle && g_expansion_enabled == true) { /* eukara: hack? */ - Scene_ExpandSelectionToEntities(); - } - } - } - break; - // if cycle mode not enabled, enable it - case RadiantSelectionSystem::eReplace: { - // select closest - (*selector.begin()).second->setSelected(true); - } - break; - // select the next object in the list from the one already selected - case RadiantSelectionSystem::eCycle: { - SelectionPool::iterator i = selector.begin(); - while (i != selector.end()) { - if ((*i).second->isSelected()) { - (*i).second->setSelected(false); - ++i; - if (i != selector.end()) { - i->second->setSelected(true); - } else { - selector.begin()->second->setSelected(true); - } - break; - } - ++i; - } - } - break; - default: - break; - } - } - } -} - -void SelectArea(const View &view, const float device_point[2], const float device_delta[2], - RadiantSelectionSystem::EModifier modifier, bool face) -{ - if (modifier == eReplace) { - if (face) { - setSelectedAllComponents(false); - } else { - deselectAll(); - } - } - -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForArea(device_point, device_delta)); - - SelectionVolume volume(scissored); - SelectionPool pool; - if (face) { - Scene_TestSelect_Component(pool, volume, scissored, eFace); - } else { - Scene_TestSelect(pool, volume, scissored, Mode(), ComponentMode()); - } - - for (SelectionPool::iterator i = pool.begin(); i != pool.end(); ++i) { - (*i).second->setSelected(!(modifier == RadiantSelectionSystem::eToggle && (*i).second->isSelected())); - } - } -} - - -void translate(const Vector3 &translation) -{ - if (!nothingSelected()) { - //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid"); - - m_translation = translation; - - m_pivot2world = m_pivot2world_start; - matrix4_translate_by_vec3(m_pivot2world, translation); - - if (Mode() == eComponent) { - Scene_Translate_Component_Selected(GlobalSceneGraph(), m_translation); - } else { - Scene_Translate_Selected(GlobalSceneGraph(), m_translation); - } - - SceneChangeNotify(); - } -} - -void outputTranslation(TextOutputStream &ostream) -{ - ostream << " -xyz " << m_translation.x() << " " << m_translation.y() << " " << m_translation.z(); -} - -void rotate(const Quaternion &rotation) -{ - if (!nothingSelected()) { - //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid"); - - m_rotation = rotation; - - if (Mode() == eComponent) { - Scene_Rotate_Component_Selected(GlobalSceneGraph(), m_rotation, vector4_to_vector3(m_pivot2world.t())); - - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - Scene_Rotate_Selected(GlobalSceneGraph(), m_rotation, vector4_to_vector3(m_pivot2world.t())); - - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - - SceneChangeNotify(); - } -} - -void outputRotation(TextOutputStream &ostream) -{ - ostream << " -eulerXYZ " << m_rotation.x() << " " << m_rotation.y() << " " << m_rotation.z(); -} - -void scale(const Vector3 &scaling) -{ - if (!nothingSelected()) { - m_scale = scaling; - - if (Mode() == eComponent) { - Scene_Scale_Component_Selected(GlobalSceneGraph(), m_scale, vector4_to_vector3(m_pivot2world.t())); - } else { - Scene_Scale_Selected(GlobalSceneGraph(), m_scale, vector4_to_vector3(m_pivot2world.t())); - } - - SceneChangeNotify(); - } -} - -void outputScale(TextOutputStream &ostream) -{ - ostream << " -scale " << m_scale.x() << " " << m_scale.y() << " " << m_scale.z(); -} - -void rotateSelected(const Quaternion &rotation) -{ - startMove(); - rotate(rotation); - freezeTransforms(); -} - -void translateSelected(const Vector3 &translation) -{ - startMove(); - translate(translation); - freezeTransforms(); -} - -void scaleSelected(const Vector3 &scaling) -{ - startMove(); - scale(scaling); - freezeTransforms(); -} - -void MoveSelected(const View &view, const float device_point[2]) -{ - if (m_manipulator->isSelected()) { - if (!m_undo_begun) { - m_undo_begun = true; - GlobalUndoSystem().start(); - } - - Matrix4 device2manip; - ConstructDevice2Manip(device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), - view.GetViewport()); - m_manipulator->GetManipulatable()->Transform(m_manip2pivot_start, device2manip, device_point[0], - device_point[1]); - } -} - -/// \todo Support view-dependent nudge. -void NudgeManipulator(const Vector3 &nudge, const Vector3 &view) -{ - if (ManipulatorMode() == eTranslate || ManipulatorMode() == eDrag) { - translateSelected(nudge); - } -} - -void endMove(); - -void freezeTransforms(); - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const; - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -const Matrix4 &GetPivot2World() const -{ - ConstructPivot(); - return m_pivot2world; -} - -static void constructStatic() -{ - m_state = GlobalShaderCache().capture("$POINT"); -#if defined( DEBUG_SELECTION ) - g_state_clipped = GlobalShaderCache().capture("$DEBUG_CLIPPED"); -#endif - TranslateManipulator::m_state_wire = GlobalShaderCache().capture("$WIRE_OVERLAY"); - TranslateManipulator::m_state_fill = GlobalShaderCache().capture("$FLATSHADE_OVERLAY"); - RotateManipulator::m_state_outer = GlobalShaderCache().capture("$WIRE_OVERLAY"); -} - -static void destroyStatic() -{ -#if defined( DEBUG_SELECTION ) - GlobalShaderCache().release("$DEBUG_CLIPPED"); -#endif - GlobalShaderCache().release("$WIRE_OVERLAY"); - GlobalShaderCache().release("$FLATSHADE_OVERLAY"); - GlobalShaderCache().release("$WIRE_OVERLAY"); - GlobalShaderCache().release("$POINT"); -} -}; - -Shader *RadiantSelectionSystem::m_state = 0; - - -namespace { -RadiantSelectionSystem *g_RadiantSelectionSystem; - -inline RadiantSelectionSystem &getSelectionSystem() -{ - return *g_RadiantSelectionSystem; -} -} - - -class testselect_entity_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -public: -testselect_entity_visible(Selector &selector, SelectionTest &test) - : m_selector(selector), m_test(test) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && Node_isEntity(path.top())) { - m_selector.pushSelectable(*selectable); - } - - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - selectionTestable->testSelect(m_selector, m_test); - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && Node_isEntity(path.top())) { - m_selector.popSelectable(); - } -} -}; - -class testselect_primitive_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -public: -testselect_primitive_visible(Selector &selector, SelectionTest &test) - : m_selector(selector), m_test(test) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - m_selector.pushSelectable(*selectable); - } - - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - selectionTestable->testSelect(m_selector, m_test); - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - m_selector.popSelectable(); - } -} -}; - -class testselect_component_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -SelectionSystem::EComponentMode m_mode; -public: -testselect_component_visible(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) - : m_selector(selector), m_test(test), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->testSelectComponents(m_selector, m_test, m_mode); - } - - return true; -} -}; - - -class testselect_component_visible_selected : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -SelectionSystem::EComponentMode m_mode; -public: -testselect_component_visible_selected(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) - : m_selector(selector), m_test(test), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->testSelectComponents(m_selector, m_test, m_mode); - } - } - - return true; -} -}; - -void Scene_TestSelect_Primitive(Selector &selector, SelectionTest &test, const VolumeTest &volume) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, testselect_primitive_visible(selector, test)); -} - -void Scene_TestSelect_Component_Selected(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, - testselect_component_visible_selected(selector, test, componentMode)); -} - -void Scene_TestSelect_Component(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, testselect_component_visible(selector, test, componentMode)); -} - -void RadiantSelectionSystem::Scene_TestSelect(Selector &selector, SelectionTest &test, const View &view, - SelectionSystem::EMode mode, - SelectionSystem::EComponentMode componentMode) -{ - switch (mode) { - case eEntity: { - Scene_forEachVisible(GlobalSceneGraph(), view, testselect_entity_visible(selector, test)); - } - break; - case ePrimitive: - Scene_TestSelect_Primitive(selector, test, view); - break; - case eComponent: - Scene_TestSelect_Component_Selected(selector, test, view, componentMode); - break; - } -} - -class FreezeTransforms : public scene::Graph::Walker { -public: -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(path.top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->freezeTransform(); - } - } - return true; -} -}; - -void RadiantSelectionSystem::freezeTransforms() -{ - GlobalSceneGraph().traverse(FreezeTransforms()); -} - - -void RadiantSelectionSystem::endMove() -{ - freezeTransforms(); - - if (Mode() == ePrimitive) { - if (ManipulatorMode() == eDrag) { - Scene_SelectAll_Component(false, SelectionSystem::eFace); - } - } - - m_pivot_moving = false; - pivotChanged(); - - SceneChangeNotify(); - - if (m_undo_begun) { - StringOutputStream command; - - if (ManipulatorMode() == eTranslate) { - command << "translateTool"; - outputTranslation(command); - } else if (ManipulatorMode() == eRotate) { - command << "rotateTool"; - outputRotation(command); - } else if (ManipulatorMode() == eScale) { - command << "scaleTool"; - outputScale(command); - } else if (ManipulatorMode() == eDrag) { - command << "dragTool"; - } - - GlobalUndoSystem().finish(command.c_str()); - } - -} - -inline AABB Instance_getPivotBounds(scene::Instance &instance) -{ - Entity *entity = Node_getEntity(instance.path().top()); - if (entity != 0 - && (entity->getEntityClass().fixedsize - || !node_is_group(instance.path().top()))) { - Editable *editable = Node_getEditable(instance.path().top()); - if (editable != 0) { - return AABB(vector4_to_vector3( - matrix4_multiplied_by_matrix4(instance.localToWorld(), editable->getLocalPivot()).t()), - Vector3(0, 0, 0)); - } else { - return AABB(vector4_to_vector3(instance.localToWorld().t()), Vector3(0, 0, 0)); - } - } - - return instance.worldAABB(); -} - -class bounds_selected : public scene::Graph::Walker { -AABB &m_bounds; -public: -bounds_selected(AABB &bounds) - : m_bounds(bounds) -{ - m_bounds = AABB(); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - aabb_extend_by_aabb_safe(m_bounds, Instance_getPivotBounds(instance)); - } - return true; -} -}; - -class bounds_selected_component : public scene::Graph::Walker { -AABB &m_bounds; -public: -bounds_selected_component(AABB &bounds) - : m_bounds(bounds) -{ - m_bounds = AABB(); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - ComponentEditable *componentEditable = Instance_getComponentEditable(instance); - if (componentEditable) { - aabb_extend_by_aabb_safe(m_bounds, - aabb_for_oriented_aabb_safe(componentEditable->getSelectedComponentsBounds(), - instance.localToWorld())); - } - } - return true; -} -}; - -void Scene_BoundsSelected(scene::Graph &graph, AABB &bounds) -{ - graph.traverse(bounds_selected(bounds)); -} - -void Scene_BoundsSelectedComponent(scene::Graph &graph, AABB &bounds) -{ - graph.traverse(bounds_selected_component(bounds)); -} - -#if 0 -inline void pivot_for_node( Matrix4& pivot, scene::Node& node, scene::Instance& instance ){ - ComponentEditable* componentEditable = Instance_getComponentEditable( instance ); - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && componentEditable != 0 ) { - pivot = matrix4_translation_for_vec3( componentEditable->getSelectedComponentsBounds().origin ); - } - else - { - Bounded* bounded = Instance_getBounded( instance ); - if ( bounded != 0 ) { - pivot = matrix4_translation_for_vec3( bounded->localAABB().origin ); - } - else - { - pivot = g_matrix4_identity; - } - } -} -#endif - -void RadiantSelectionSystem::ConstructPivot() const -{ - if (!m_pivotChanged || m_pivot_moving) { - return; - } - m_pivotChanged = false; - - Vector3 m_object_pivot; - - if (!nothingSelected()) { - { - AABB bounds; - if (Mode() == eComponent) { - Scene_BoundsSelectedComponent(GlobalSceneGraph(), bounds); - } else { - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - } - m_object_pivot = bounds.origin; - } - - vector3_snap(m_object_pivot, GetSnapGridSize()); - m_pivot2world = matrix4_translation_for_vec3(m_object_pivot); - - switch (m_manipulator_mode) { - case eTranslate: - break; - case eRotate: - if (Mode() == eComponent) { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - break; - case eScale: - if (Mode() == eComponent) { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - break; - default: - break; - } - } -} - -void RadiantSelectionSystem::renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - //if(view->TestPoint(m_object_pivot)) - if (!nothingSelected()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.Highlight(Renderer::eFace, false); - - renderer.SetState(m_state, Renderer::eWireframeOnly); - renderer.SetState(m_state, Renderer::eFullMaterials); - - m_manipulator->render(renderer, volume, GetPivot2World()); - } - -#if defined( DEBUG_SELECTION ) - renderer.SetState(g_state_clipped, Renderer::eWireframeOnly); - renderer.SetState(g_state_clipped, Renderer::eFullMaterials); - renderer.addRenderable(g_render_clipped, g_render_clipped.m_world); -#endif -} - - -void SelectionSystem_OnBoundsChanged() -{ - getSelectionSystem().pivotChanged(); -} - - -SignalHandlerId SelectionSystem_boundsChanged; - -void SelectionSystem_Construct() -{ - RadiantSelectionSystem::constructStatic(); - - g_RadiantSelectionSystem = new RadiantSelectionSystem; - - SelectionSystem_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( - FreeCaller()); - - GlobalShaderCache().attachRenderable(getSelectionSystem()); -} - -void SelectionSystem_Destroy() -{ - GlobalShaderCache().detachRenderable(getSelectionSystem()); - - GlobalSceneGraph().removeBoundsChangedCallback(SelectionSystem_boundsChanged); - - delete g_RadiantSelectionSystem; - - RadiantSelectionSystem::destroyStatic(); -} - - -inline float screen_normalised(float pos, std::size_t size) -{ - return ((2.0f * pos) / size) - 1.0f; -} - -typedef Vector2 DeviceVector; - -inline DeviceVector window_to_normalised_device(WindowVector window, std::size_t width, std::size_t height) -{ - return DeviceVector(screen_normalised(window.x(), width), screen_normalised(height - 1 - window.y(), height)); -} - -inline float device_constrained(float pos) -{ - return std::min(1.0f, std::max(-1.0f, pos)); -} - -inline DeviceVector device_constrained(DeviceVector device) -{ - return DeviceVector(device_constrained(device.x()), device_constrained(device.y())); -} - -inline float window_constrained(float pos, std::size_t origin, std::size_t size) -{ - return std::min(static_cast( origin + size ), std::max(static_cast( origin ), pos)); -} - -inline WindowVector -window_constrained(WindowVector window, std::size_t x, std::size_t y, std::size_t width, std::size_t height) -{ - return WindowVector(window_constrained(window.x(), x, width), window_constrained(window.y(), y, height)); -} - -typedef Callback MouseEventCallback; - -Single g_mouseMovedCallback; -Single g_mouseUpCallback; - - -const ButtonIdentifier c_button_select = c_buttonLeft; -const ButtonIdentifier c_button_texture = c_buttonMiddle; -const ModifierFlags c_modifier_manipulator = c_modifierNone; -const ModifierFlags c_modifier_toggle = c_modifierShift; -const ModifierFlags c_modifier_toggle_face = c_modifierShift | c_modifierControl; -const ModifierFlags c_modifier_face = c_modifierControl; -const ModifierFlags c_modifier_replace = c_modifierShift | c_modifierAlt; -const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face; -const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift; -const ModifierFlags c_modifier_apply_texture2 = c_modifierControl; -const ModifierFlags c_modifier_apply_texture3 = c_modifierShift; -const ModifierFlags c_modifier_copy_texture = c_modifierNone; - -class Selector_ { -RadiantSelectionSystem::EModifier modifier_for_state(ModifierFlags state) -{ - if (state == c_modifier_toggle || state == c_modifier_toggle_face) { - return RadiantSelectionSystem::eToggle; - } - if (state == c_modifier_replace || state == c_modifier_replace_face) { - return RadiantSelectionSystem::eReplace; - } - return RadiantSelectionSystem::eManipulator; -} - -rect_t getDeviceArea() const -{ - DeviceVector delta(m_current - m_start); - if (selecting() && fabs(delta.x()) > m_epsilon.x() && fabs(delta.y()) > m_epsilon.y()) { - return SelectionBoxForArea(&m_start[0], &delta[0]); - } else { - rect_t default_area = {{0, 0,}, - {0, 0,},}; - return default_area; - } -} - -public: -DeviceVector m_start; -DeviceVector m_current; -DeviceVector m_epsilon; -std::size_t m_unmoved_replaces; -ModifierFlags m_state; -const View *m_view; -RectangleCallback m_window_update; - -Selector_() : m_start(0.0f, 0.0f), m_current(0.0f, 0.0f), m_unmoved_replaces(0), m_state(c_modifierNone) -{ -} - -void draw_area() -{ - m_window_update(getDeviceArea()); -} - -void testSelect(DeviceVector position) -{ - RadiantSelectionSystem::EModifier modifier = modifier_for_state(m_state); - if (modifier != RadiantSelectionSystem::eManipulator) { - DeviceVector delta(position - m_start); - if (fabs(delta.x()) > m_epsilon.x() && fabs(delta.y()) > m_epsilon.y()) { - DeviceVector delta(position - m_start); - getSelectionSystem().SelectArea(*m_view, &m_start[0], &delta[0], modifier, - (m_state & c_modifier_face) != c_modifierNone); - } else { - if (modifier == RadiantSelectionSystem::eReplace && m_unmoved_replaces++ > 0) { - modifier = RadiantSelectionSystem::eCycle; - } - getSelectionSystem().SelectPoint(*m_view, &position[0], &m_epsilon[0], modifier, - (m_state & c_modifier_face) != c_modifierNone); - } - } - - m_start = m_current = DeviceVector(0.0f, 0.0f); - draw_area(); -} - -bool selecting() const -{ - return m_state != c_modifier_manipulator; -} - -void setState(ModifierFlags state) -{ - bool was_selecting = selecting(); - m_state = state; - if (was_selecting ^ selecting()) { - draw_area(); - } -} - -ModifierFlags getState() const -{ - return m_state; -} - -void modifierEnable(ModifierFlags type) -{ - setState(bitfield_enable(getState(), type)); -} - -void modifierDisable(ModifierFlags type) -{ - setState(bitfield_disable(getState(), type)); -} - -void mouseDown(DeviceVector position) -{ - m_start = m_current = device_constrained(position); -} - -void mouseMoved(DeviceVector position) -{ - m_current = device_constrained(position); - draw_area(); -} - -typedef MemberCaller MouseMovedCaller; - -void mouseUp(DeviceVector position) -{ - testSelect(device_constrained(position)); - - g_mouseMovedCallback.clear(); - g_mouseUpCallback.clear(); -} - -typedef MemberCaller MouseUpCaller; -}; - - -class Manipulator_ { -public: -DeviceVector m_epsilon; -const View *m_view; - -bool mouseDown(DeviceVector position) -{ - return getSelectionSystem().SelectManipulator(*m_view, &position[0], &m_epsilon[0]); -} - -void mouseMoved(DeviceVector position) -{ - getSelectionSystem().MoveSelected(*m_view, &position[0]); -} - -typedef MemberCaller MouseMovedCaller; - -void mouseUp(DeviceVector position) -{ - getSelectionSystem().endMove(); - g_mouseMovedCallback.clear(); - g_mouseUpCallback.clear(); -} - -typedef MemberCaller MouseUpCaller; -}; - -void Scene_copyClosestTexture(SelectionTest &test); - -void Scene_applyClosestTexture(SelectionTest &test); - -class RadiantWindowObserver : public SelectionSystemWindowObserver { -enum { - SELECT_EPSILON = 8, -}; - -int m_width; -int m_height; - -bool m_mouse_down; - -public: -Selector_ m_selector; -Manipulator_ m_manipulator; - -RadiantWindowObserver() : m_mouse_down(false) -{ -} - -void release() -{ - delete this; -} - -void setView(const View &view) -{ - m_selector.m_view = &view; - m_manipulator.m_view = &view; -} - -void setRectangleDrawCallback(const RectangleCallback &callback) -{ - m_selector.m_window_update = callback; -} - -void onSizeChanged(int width, int height) -{ - m_width = width; - m_height = height; - DeviceVector epsilon(SELECT_EPSILON / static_cast( m_width ), - SELECT_EPSILON / static_cast( m_height )); - m_selector.m_epsilon = m_manipulator.m_epsilon = epsilon; -} - -void onMouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - if (button == c_button_select) { - m_mouse_down = true; - - DeviceVector devicePosition(window_to_normalised_device(position, m_width, m_height)); - if (modifiers == c_modifier_manipulator && m_manipulator.mouseDown(devicePosition)) { - g_mouseMovedCallback.insert(MouseEventCallback(Manipulator_::MouseMovedCaller(m_manipulator))); - g_mouseUpCallback.insert(MouseEventCallback(Manipulator_::MouseUpCaller(m_manipulator))); - } else { - m_selector.mouseDown(devicePosition); - g_mouseMovedCallback.insert(MouseEventCallback(Selector_::MouseMovedCaller(m_selector))); - g_mouseUpCallback.insert(MouseEventCallback(Selector_::MouseUpCaller(m_selector))); - } - } else if (button == c_button_texture) { - DeviceVector devicePosition(device_constrained(window_to_normalised_device(position, m_width, m_height))); - - View scissored(*m_selector.m_view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(&devicePosition[0], &m_selector.m_epsilon[0])); - SelectionVolume volume(scissored); - - if (modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || - modifiers == c_modifier_apply_texture3) { - Scene_applyClosestTexture(volume); - } else if (modifiers == c_modifier_copy_texture) { - Scene_copyClosestTexture(volume); - } - } -} - -void onMouseMotion(const WindowVector &position, ModifierFlags modifiers) -{ - m_selector.m_unmoved_replaces = 0; - - if (m_mouse_down && !g_mouseMovedCallback.empty()) { - g_mouseMovedCallback.get()(window_to_normalised_device(position, m_width, m_height)); - } -} - -void onMouseUp(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - if (button == c_button_select && !g_mouseUpCallback.empty()) { - m_mouse_down = false; - - g_mouseUpCallback.get()(window_to_normalised_device(position, m_width, m_height)); - } -} - -void onModifierDown(ModifierFlags type) -{ - m_selector.modifierEnable(type); -} - -void onModifierUp(ModifierFlags type) -{ - m_selector.modifierDisable(type); -} -}; - - -SelectionSystemWindowObserver *NewWindowObserver() -{ - return new RadiantWindowObserver; -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class SelectionDependencies : - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalOpenGLModuleRef { -}; - -class SelectionAPI : public TypeSystemRef { -SelectionSystem *m_selection; -public: -typedef SelectionSystem Type; - -STRING_CONSTANT(Name, "*"); - -SelectionAPI() -{ - SelectionSystem_Construct(); - - m_selection = &getSelectionSystem(); -} - -~SelectionAPI() -{ - SelectionSystem_Destroy(); -} - -SelectionSystem *getTable() -{ - return m_selection; -} -}; - -typedef SingletonModule SelectionModule; -typedef Static StaticSelectionModule; -StaticRegisterModule staticRegisterSelection(StaticSelectionModule::instance()); diff --git a/src/selection.h b/src/selection.h deleted file mode 100644 index b28ae30..0000000 --- a/src/selection.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SELECTION_H ) -#define INCLUDED_SELECTION_H - -#include "windowobserver.h" -#include "generic/callback.h" - -struct rect_t { - float min[2]; - float max[2]; -}; - -typedef Callback RectangleCallback; - -class View; - -class SelectionSystemWindowObserver : public WindowObserver { -public: -virtual ~SelectionSystemWindowObserver() = default; - -virtual void setView(const View &view) = 0; - -virtual void setRectangleDrawCallback(const RectangleCallback &callback) = 0; -}; - -SelectionSystemWindowObserver *NewWindowObserver(); - -class AABB; -namespace scene { -class Graph; -} - -void Scene_BoundsSelected(scene::Graph &graph, AABB &bounds); - -#endif diff --git a/src/server.cpp b/src/server.cpp deleted file mode 100644 index 84d1650..0000000 --- a/src/server.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "server.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include -#include -#include "os/path.h" - -#include "modulesystem.h" - -class RadiantModuleServer : public ModuleServer { -typedef std::pair ModuleType; -typedef std::pair ModuleKey; -typedef std::map Modules_; -Modules_ m_modules; -bool m_error; - -public: -RadiantModuleServer() : m_error(false) -{ -} - -void setError(bool error) -{ - m_error = error; -} - -bool getError() const -{ - return m_error; -} - -TextOutputStream &getOutputStream() -{ - return globalOutputStream(); -} - -TextOutputStream &getErrorStream() -{ - return globalErrorStream(); -} - -DebugMessageHandler &getDebugMessageHandler() -{ - return globalDebugMessageHandler(); -} - -void registerModule(const char *type, int version, const char *name, Module &module) -{ - if (!m_modules.insert(Modules_::value_type(ModuleKey(ModuleType(type, version), name), &module)).second) { - globalErrorStream() << "module already registered: type=" << makeQuoted(type) << " name=" - << makeQuoted(name) << "\n"; - } else { - globalOutputStream() << "Module Registered: type=" << makeQuoted(type) << " version=" << makeQuoted(version) - << " name=" << makeQuoted(name) << "\n"; - } -} - -Module *findModule(const char *type, int version, const char *name) const -{ - Modules_::const_iterator i = m_modules.find(ModuleKey(ModuleType(type, version), name)); - if (i != m_modules.end()) { - return (*i).second; - } - return 0; -} - -void foreachModule(const char *type, int version, const Visitor &visitor) -{ - for (Modules_::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i) { - if (string_equal((*i).first.first.first.c_str(), type)) { - visitor.visit((*i).first.second.c_str(), *(*i).second); - } - } -} -}; - - -#if GDEF_OS_WINDOWS - -#include - -const int FORMAT_BUFSIZE = 2048; -const char* FormatGetLastError(){ - static char buf[FORMAT_BUFSIZE]; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language - buf, - FORMAT_BUFSIZE, - NULL - ); - return buf; -} - -class DynamicLibrary -{ -HMODULE m_library; -public: -typedef int ( __stdcall * FunctionPointer )(); - -DynamicLibrary( const char* filename ){ - m_library = LoadLibrary( filename ); - if ( m_library == 0 ) { - globalErrorStream() << "LoadLibrary failed: '" << filename << "'\n"; - globalErrorStream() << "GetLastError: " << FormatGetLastError(); - } -} -~DynamicLibrary(){ - if ( !failed() ) { - FreeLibrary( m_library ); - } -} -bool failed(){ - return m_library == 0; -} -FunctionPointer findSymbol( const char* symbol ){ - FunctionPointer address = (FunctionPointer) GetProcAddress( m_library, symbol ); - if ( address == 0 ) { - globalErrorStream() << "GetProcAddress failed: '" << symbol << "'\n"; - globalErrorStream() << "GetLastError: " << FormatGetLastError(); - } - return address; -} -}; - -#elif GDEF_OS_POSIX - -#include - -class DynamicLibrary { -void *m_library; -public: -typedef int ( *FunctionPointer )(); - -DynamicLibrary(const char *filename) -{ - m_library = dlopen(filename, RTLD_NOW); -} - -~DynamicLibrary() -{ - if (!failed()) { - dlclose(m_library); - } -} - -bool failed() -{ - return m_library == 0; -} - -FunctionPointer findSymbol(const char *symbol) -{ - FunctionPointer p = (FunctionPointer) dlsym(m_library, symbol); - if (p == 0) { - const char *error = reinterpret_cast( dlerror()); - if (error != 0) { - globalErrorStream() << error; - } - } - return p; -} -}; - -#else -#error "unsupported platform" -#endif - -class DynamicLibraryModule { -typedef void ( RADIANT_DLLIMPORT *RegisterModulesFunc )(ModuleServer &server); - -DynamicLibrary m_library; -RegisterModulesFunc m_registerModule; -public: -DynamicLibraryModule(const char *filename) - : m_library(filename), m_registerModule(0) -{ - if (!m_library.failed()) { - m_registerModule = reinterpret_cast( m_library.findSymbol("Radiant_RegisterModules")); -#if 0 - if ( !m_registerModule ) { - m_registerModule = reinterpret_cast( m_library.findSymbol( "Radiant_RegisterModules@4" ) ); - } -#endif - } -} - -bool failed() -{ - return m_registerModule == 0; -} - -void registerModules(ModuleServer &server) -{ - m_registerModule(server); -} -}; - - -class Libraries { -typedef std::vector libraries_t; -libraries_t m_libraries; - -public: -~Libraries() -{ - release(); -} - -void registerLibrary(const char *filename, ModuleServer &server) -{ - DynamicLibraryModule *library = new DynamicLibraryModule(filename); - - if (library->failed()) { - delete library; - } else { - m_libraries.push_back(library); - library->registerModules(server); - } -} - -void release() -{ - for (libraries_t::iterator i = m_libraries.begin(); i != m_libraries.end(); ++i) { - delete *i; - } -} - -void clear() -{ - m_libraries.clear(); -} -}; - - -Libraries g_libraries; -RadiantModuleServer g_server; - -ModuleServer &GlobalModuleServer_get() -{ - return g_server; -} - -void GlobalModuleServer_loadModule(const char *filename) -{ - g_libraries.registerLibrary(filename, g_server); -} - -void GlobalModuleServer_Initialise() -{ -} - -void GlobalModuleServer_Shutdown() -{ -} diff --git a/src/server.h b/src/server.h deleted file mode 100644 index c54b9d2..0000000 --- a/src/server.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SERVER_H ) -#define INCLUDED_SERVER_H - -class ModuleServer; - -ModuleServer &GlobalModuleServer_get(); - -void GlobalModuleServer_loadModule(const char *filename); - -void GlobalModuleServer_Initialise(); - -void GlobalModuleServer_Shutdown(); - -#endif diff --git a/tools/vmap/shaders.c b/src/shaders.c similarity index 100% rename from tools/vmap/shaders.c rename to src/shaders.c diff --git a/src/shaders.cpp b/src/shaders.cpp deleted file mode 100644 index 0a71b30..0000000 --- a/src/shaders.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "shaders.h" - -#include "ifilesystem.h" - -#include "stream/stringstream.h" - -#include "gtkdlgs.h" - -void ViewShader(const char *pFile, const char *pName) -{ - char *pBuff = 0; - //int nSize = - vfsLoadFile(pFile, reinterpret_cast( &pBuff )); - if (pBuff == 0) { - globalErrorStream() << "Failed to load shader file " << pFile << "\n"; - return; - } - // look for the shader declaration - StringOutputStream strFind(string_length(pName)); - strFind << LowerCase(pName); - StringOutputStream strLook(string_length(pBuff)); - strFind << LowerCase(pBuff); - // offset used when jumping over commented out definitions - std::size_t nOffset = 0; - while (true) { - const char *substr = strstr(strFind.c_str() + nOffset, strFind.c_str()); - if (substr == 0) { - break; - } - std::size_t nStart = substr - strLook.c_str(); - // we have found something, maybe it's a commented out shader name? - char *strCheck = new char[string_length(strLook.c_str()) + 1]; - strcpy(strCheck, strLook.c_str()); - strCheck[nStart] = 0; - char *pCheck = strrchr(strCheck, '\n'); - // if there's a commentary sign in-between we'll continue - if (pCheck && strstr(pCheck, "//")) { - delete[] strCheck; - nOffset = nStart + 1; - continue; - } - delete[] strCheck; - nOffset = nStart; - break; - } - // now close the file - vfsFreeFile(pBuff); - - DoTextEditor(pFile, static_cast( nOffset )); -} diff --git a/src/shaders.h b/src/shaders.h deleted file mode 100644 index 7c6bd2b..0000000 --- a/src/shaders.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H - -void ViewShader(const char *file, const char *shader); - -#endif diff --git a/src/sockets.cpp b/src/sockets.cpp deleted file mode 100644 index 8cba164..0000000 --- a/src/sockets.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "sockets.h" -#include "globaldefs.h" - -#if GDEF_OS_WINDOWS -#include -#elif GDEF_OS_POSIX - -#include - -const int SOCKET_ERROR = -1; -#else -#error "unsupported platform" -#endif - -#if GDEF_OS_MACOS -#include -#endif - -int Net_Wait(socket_t *sock, long sec, long usec) -{ -// used for select() -#if GDEF_OS_WINDOWS - TIMEVAL tout = { sec, usec }; -#endif -#if GDEF_OS_POSIX - timeval tout; - tout.tv_sec = sec; - tout.tv_usec = usec; -#endif - - // select() will identify if the socket needs an update - // if the socket is identified that means there's either a message or the connection has been closed/reset/terminated - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(((unsigned int) sock->socket), &readfds); - // from select man page: - // n is the highest-numbered descriptor in any of the three sets, plus 1 - // (no use on windows) - switch (select(sock->socket + 1, &readfds, 0, 0, &tout)) { - case SOCKET_ERROR: - return -1; - case 0: - return 0; - default: - return 1; - } -} diff --git a/src/sockets.h b/src/sockets.h deleted file mode 100644 index 2ab6264..0000000 --- a/src/sockets.h +++ /dev/null @@ -1,14 +0,0 @@ - -#if !defined( INCLUDED_SOCKETS_H ) -#define INCLUDED_SOCKETS_H - -#include "l_net/l_net.h" - -// waits for a socket to become ready -// returns -// -1: error -// 0: timeout -// 1: ready -int Net_Wait(socket_t *sock, long sec, long usec); - -#endif diff --git a/src/stacktrace.cpp b/src/stacktrace.cpp deleted file mode 100644 index 60d5b1e..0000000 --- a/src/stacktrace.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "stacktrace.h" -#include "globaldefs.h" - -#include "stream/textstream.h" - -#include "environment.h" - -#if GDEF_OS_LINUX - -#include - -void write_stack_trace(TextOutputStream &outputStream) -{ - const unsigned int MAX_SYMBOLS = 256; - void *symbols[MAX_SYMBOLS]; - - // get return addresses - int symbol_count = backtrace(symbols, MAX_SYMBOLS); - - if (!symbol_count) { - return; - } - - // resolve and print names - char **symbol_names = backtrace_symbols(symbols, symbol_count); - if (symbol_names) { - for (int i = 0; (i < symbol_count); ++i) { - outputStream << symbol_names[i] << "\n"; - } - - // not a memleak, see www.gnu.org/software/libc/manual (Debugging Support, Backtraces) - free(symbol_names); - } -} - -#elif GDEF_COMPILER_MSVC - -#include "windows.h" -#include "winnt.h" -#include "dbghelp.h" - -class Address -{ -public: -void* m_value; -Address( void* value ) : m_value( value ){ -} -}; - -/// \brief Writes an address \p p to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Address& p ){ - const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%0p", p.m_value ) ); - return ostream; -} - -class Offset -{ -public: -void* m_value; -Offset( void* value ) : m_value( value ){ -} -}; - -/// \brief Writes an address \p p to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Offset& p ){ - const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%X", p.m_value ) ); - return ostream; -} - -/// \brief Writes a WCHAR string \p s to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const WCHAR* s ){ - const std::size_t bufferSize = 1024; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%ls", s ) ); - return ostream; -} - -struct EnumerateSymbolsContext -{ - STACKFRAME64& sf; - TextOutputStream& outputStream; - std::size_t count; - EnumerateSymbolsContext( STACKFRAME64& sf, TextOutputStream& outputStream ) : sf( sf ), outputStream( outputStream ), count( 0 ){ - } -}; - -void write_symbol( PSYMBOL_INFO pSym, STACKFRAME64& sf, TextOutputStream& outputStream, std::size_t& count ){ -#if 0 - if ( pSym->Flags & SYMFLAG_PARAMETER ) { - - DWORD basicType; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_BASETYPE, &basicType ) ) { - int bleh = 0; - } - else - { - DWORD typeId; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_TYPEID, &typeId ) ) { - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_BASETYPE, &basicType ) ) { - int bleh = 0; - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - - WCHAR* name; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, typeId, - TI_GET_SYMNAME, &name ) ) { - outputStream << name << " "; - LocalFree( name ); - int bleh = 0; - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - } - } - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - } - } - if ( count != 0 ) { - outputStream << ", "; - } - outputStream << pSym->Name; - ++count; - } -#endif -} - -BOOL CALLBACK -EnumerateSymbolsCallback( - PSYMBOL_INFO pSymInfo, - ULONG SymbolSize, - PVOID UserContext ){ - write_symbol( pSymInfo, ( (EnumerateSymbolsContext*)UserContext )->sf, ( (EnumerateSymbolsContext*)UserContext )->outputStream, ( (EnumerateSymbolsContext*)UserContext )->count ); - - - return TRUE; -} - -void write_stack_trace( PCONTEXT pContext, TextOutputStream& outputStream ){ - HANDLE m_hProcess = GetCurrentProcess(); - DWORD dwMachineType = 0; - - CONTEXT context = *pContext; - - // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag - if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) ) { - return; - } - - STACKFRAME64 sf; - memset( &sf, 0, sizeof( sf ) ); - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Mode = AddrModeFlat; - -#ifdef _M_IX86 - // Initialize the STACKFRAME structure for the first call. This is only - // necessary for Intel CPUs, and isn't mentioned in the documentation. - sf.AddrPC.Offset = context.Eip; - sf.AddrStack.Offset = context.Esp; - sf.AddrFrame.Offset = context.Ebp; - - dwMachineType = IMAGE_FILE_MACHINE_I386; -#elif _M_X64 - sf.AddrPC.Offset = context.Rip; - sf.AddrStack.Offset = context.Rsp; - - // MSDN: x64: The frame pointer is RBP or RDI. This value is not always used. - // very funny, we'll try Rdi for now - sf.AddrFrame.Offset = context.Rdi; - - dwMachineType = IMAGE_FILE_MACHINE_AMD64; -#endif - - const unsigned int max_sym_name = 1024; // should be enough - - while ( 1 ) - { - // Get the next stack frame - if ( !StackWalk64( dwMachineType, - m_hProcess, - GetCurrentThread(), - &sf, - &context, - 0, - SymFunctionTableAccess64, - SymGetModuleBase64, - 0 ) ) { - break; - } - - if ( 0 == sf.AddrFrame.Offset ) { // Basic sanity check to make sure - break; // the frame is OK. Bail if not. - - } - // Get the name of the function for this stack frame entry - BYTE symbolBuffer[ sizeof( SYMBOL_INFO ) + max_sym_name ]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer; - pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO ); - pSymbol->MaxNameLen = max_sym_name; - - DWORD64 symDisplacement = 0; // Displacement of the input address, - // relative to the start of the symbol - - IMAGEHLP_MODULE64 module = { sizeof( IMAGEHLP_MODULE64 ) }; - if ( SymGetModuleInfo64( m_hProcess, sf.AddrPC.Offset, &module ) ) { - outputStream << module.ModuleName << "!"; - - if ( SymFromAddr( m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol ) ) { - char undecoratedName[max_sym_name]; - UnDecorateSymbolName( pSymbol->Name, undecoratedName, max_sym_name, UNDNAME_COMPLETE ); - - outputStream << undecoratedName; - - outputStream << "("; - // Use SymSetContext to get just the locals/params for this frame - IMAGEHLP_STACK_FRAME imagehlpStackFrame; - imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset; - SymSetContext( m_hProcess, &imagehlpStackFrame, 0 ); - - // Enumerate the locals/parameters - EnumerateSymbolsContext context( sf, outputStream ); - SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context ); - outputStream << ")"; - - outputStream << " + " << Offset( reinterpret_cast( symDisplacement ) ); - - // Get the source line for this stack frame entry - IMAGEHLP_LINE64 lineInfo = { sizeof( IMAGEHLP_LINE64 ) }; - DWORD dwLineDisplacement; - if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset, - &dwLineDisplacement, &lineInfo ) ) { - outputStream << " " << lineInfo.FileName << " line " << Unsigned( lineInfo.LineNumber ); - } - } - else - { - outputStream << Address( reinterpret_cast( sf.AddrPC.Offset ) ); - } - } - - outputStream << "\n"; - } - - SymCleanup( m_hProcess ); - - return; -} - -void write_stack_trace( TextOutputStream& outputStream ){ - __try { RaiseException( 0,0,0,0 ); } __except( write_stack_trace( ( GetExceptionInformation() )->ContextRecord, outputStream ), EXCEPTION_CONTINUE_EXECUTION ) { - } -} - -#elif GDEF_OS_WINDOWS -void write_stack_trace( TextOutputStream& outputStream ){ - outputStream << "\nStacktrace is disabled on this compiler\n"; -} -#else -void write_stack_trace( TextOutputStream& outputStream ){ - outputStream << "\nStacktrace is disabled on this platform\n"; -} -#endif diff --git a/src/stacktrace.h b/src/stacktrace.h deleted file mode 100644 index 8475ceb..0000000 --- a/src/stacktrace.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STACKTRACE_H ) -#define INCLUDED_STACKTRACE_H - -class TextOutputStream; - -void write_stack_trace(TextOutputStream &outputStream); - -#endif diff --git a/tools/vmap/surface.c b/src/surface.c similarity index 100% rename from tools/vmap/surface.c rename to src/surface.c diff --git a/tools/vmap/surface_extra.c b/src/surface_extra.c similarity index 100% rename from tools/vmap/surface_extra.c rename to src/surface_extra.c diff --git a/tools/vmap/surface_foliage.c b/src/surface_foliage.c similarity index 100% rename from tools/vmap/surface_foliage.c rename to src/surface_foliage.c diff --git a/tools/vmap/surface_fur.c b/src/surface_fur.c similarity index 100% rename from tools/vmap/surface_fur.c rename to src/surface_fur.c diff --git a/tools/vmap/surface_meta.c b/src/surface_meta.c similarity index 100% rename from tools/vmap/surface_meta.c rename to src/surface_meta.c diff --git a/src/surfacedialog.cpp b/src/surfacedialog.cpp deleted file mode 100644 index 04978d0..0000000 --- a/src/surfacedialog.cpp +++ /dev/null @@ -1,2506 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Surface Dialog -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "surfacedialog.h" - -#include - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "iscenegraph.h" -#include "itexdef.h" -#include "iundo.h" -#include "iselection.h" - -#include - -#include "signal/isignal.h" -#include "generic/object.h" -#include "math/vector.h" -#include "texturelib.h" -#include "shaderlib.h" -#include "stringio.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/dialog.h" -#include "gtkutil/entry.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/pointer.h" -#include "gtkutil/glwidget.h" //Shamus: For Textool -#include "gtkutil/button.h" -#include "map.h" -#include "select.h" -#include "patchmanip.h" -#include "brushmanip.h" -#include "patchdialog.h" -#include "preferences.h" -#include "brush_primit.h" -#include "xywindow.h" -#include "mainframe.h" -#include "gtkdlgs.h" -#include "dialog.h" -#include "brush.h" //Shamus: for Textool -#include "patch.h" -#include "commands.h" -#include "stream/stringstream.h" -#include "grid.h" -#include "textureentry.h" - -//NOTE: Proper functioning of Textool currently requires that the "#if 1" lines in -// brush_primit.h be changed to "#if 0". add/removeScale screws this up ATM. :-) -// Plus, Radiant seems to work just fine without that stuff. ;-) - -#define TEXTOOL_ENABLED 0 - -#if TEXTOOL_ENABLED - -namespace TexTool -{ - -//Shamus: Textool function prototypes -gboolean size_allocate( ui::Widget, GtkAllocation *, gpointer ); -gboolean expose( ui::Widget, GdkEventExpose *, gpointer ); -gboolean button_press( ui::Widget, GdkEventButton *, gpointer ); -gboolean button_release( ui::Widget, GdkEventButton *, gpointer ); -gboolean motion( ui::Widget, GdkEventMotion *, gpointer ); -void flipX( ui::ToggleButton, gpointer ); -void flipY( ui::ToggleButton, gpointer ); - -//End Textool function prototypes - -//Shamus: Textool globals -ui::Widget g_textoolWin; -//End Textool globals - -void queueDraw(){ - gtk_widget_queue_draw( g_textoolWin ); -} - -} - -#endif - -inline void spin_button_set_step(ui::SpinButton spin, gfloat step) -{ -#if 1 - gtk_adjustment_set_step_increment(gtk_spin_button_get_adjustment(spin), step); -#else - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_DOUBLE ); - g_value_set_double( &gvalue, step ); - g_object_set( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), "step-increment", &gvalue, NULL ); -#endif -} - -class Increment { -float &m_f; -public: -ui::SpinButton m_spin; -ui::Entry m_entry; - -Increment(float &f) : m_f(f), m_spin(ui::null), m_entry(ui::null) -{ -} - -void cancel() -{ - entry_set_float(m_entry, m_f); -} - -typedef MemberCaller CancelCaller; - -void apply() -{ - m_f = static_cast( entry_get_float(m_entry)); - spin_button_set_step(m_spin, m_f); -} - -typedef MemberCaller ApplyCaller; -}; - -void SurfaceInspector_GridChange(); - -class SurfaceInspector : public Dialog { -ui::Window BuildDialog(); - -NonModalEntry m_textureEntry; -NonModalSpinner m_hshiftSpinner; -NonModalEntry m_hshiftEntry; -NonModalSpinner m_vshiftSpinner; -NonModalEntry m_vshiftEntry; -NonModalSpinner m_hscaleSpinner; -NonModalEntry m_hscaleEntry; -NonModalSpinner m_vscaleSpinner; -NonModalEntry m_vscaleEntry; -NonModalSpinner m_rotateSpinner; -NonModalEntry m_rotateEntry; - -IdleDraw m_idleDraw; - -GtkCheckButton *m_surfaceFlags[32]; -GtkCheckButton *m_contentFlags[32]; - -NonModalEntry m_valueEntry; -ui::Entry m_valueEntryWidget{ui::null}; -public: -WindowPositionTracker m_positionTracker; - -// Dialog Data -float m_fitHorizontal; -float m_fitVertical; - -Increment m_hshiftIncrement; -Increment m_vshiftIncrement; -Increment m_hscaleIncrement; -Increment m_vscaleIncrement; -Increment m_rotateIncrement; -ui::Entry m_texture{ui::null}; - -SurfaceInspector() : - m_textureEntry(ApplyShaderCaller(*this), UpdateCaller(*this)), - m_hshiftSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_hshiftEntry(Increment::ApplyCaller(m_hshiftIncrement), Increment::CancelCaller(m_hshiftIncrement)), - m_vshiftSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_vshiftEntry(Increment::ApplyCaller(m_vshiftIncrement), Increment::CancelCaller(m_vshiftIncrement)), - m_hscaleSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_hscaleEntry(Increment::ApplyCaller(m_hscaleIncrement), Increment::CancelCaller(m_hscaleIncrement)), - m_vscaleSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_vscaleEntry(Increment::ApplyCaller(m_vscaleIncrement), Increment::CancelCaller(m_vscaleIncrement)), - m_rotateSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_rotateEntry(Increment::ApplyCaller(m_rotateIncrement), Increment::CancelCaller(m_rotateIncrement)), - m_idleDraw(UpdateCaller(*this)), - m_valueEntry(ApplyFlagsCaller(*this), UpdateCaller(*this)), - m_hshiftIncrement(g_si_globals.shift[0]), - m_vshiftIncrement(g_si_globals.shift[1]), - m_hscaleIncrement(g_si_globals.scale[0]), - m_vscaleIncrement(g_si_globals.scale[1]), - m_rotateIncrement(g_si_globals.rotate) -{ - m_fitVertical = 1; - m_fitHorizontal = 1; - m_positionTracker.setPosition(c_default_window_pos); -} - -void constructWindow(ui::Window main_window) -{ - m_parent = main_window; - Create(); - AddGridChangeCallback(FreeCaller()); -} - -void destroyWindow() -{ - Destroy(); -} - -bool visible() -{ - return GetWidget().visible(); -} - -void queueDraw() -{ - if (visible()) { - m_idleDraw.queueDraw(); - } -} - -void Update(); - -typedef MemberCaller UpdateCaller; - -void ApplyShader(); - -typedef MemberCaller ApplyShaderCaller; - -void ApplyTexdef(); - -typedef MemberCaller ApplyTexdefCaller; - -void ApplyFlags(); - -typedef MemberCaller ApplyFlagsCaller; -}; - -namespace { -SurfaceInspector *g_SurfaceInspector; - -inline SurfaceInspector &getSurfaceInspector() -{ - ASSERT_NOTNULL(g_SurfaceInspector); - return *g_SurfaceInspector; -} -} - -void SurfaceInspector_constructWindow(ui::Window main_window) -{ - getSurfaceInspector().constructWindow(main_window); -} - -void SurfaceInspector_destroyWindow() -{ - getSurfaceInspector().destroyWindow(); -} - -void SurfaceInspector_queueDraw() -{ - getSurfaceInspector().queueDraw(); -} - -namespace { -CopiedString g_selectedShader; -TextureProjection g_selectedTexdef; -ContentsFlagsValue g_selectedFlags; -size_t g_selectedShaderSize[2]; -} - -void SurfaceInspector_SetSelectedShader(const char *shader) -{ - g_selectedShader = shader; - SurfaceInspector_queueDraw(); -} - -void SurfaceInspector_SetSelectedTexdef(const TextureProjection &projection) -{ - g_selectedTexdef = projection; - SurfaceInspector_queueDraw(); -} - -void SurfaceInspector_SetSelectedFlags(const ContentsFlagsValue &flags) -{ - g_selectedFlags = flags; - SurfaceInspector_queueDraw(); -} - -static bool s_texture_selection_dirty = false; - -void SurfaceInspector_updateSelection() -{ - s_texture_selection_dirty = true; - SurfaceInspector_queueDraw(); - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - TexTool::queueDraw(); - //globalOutputStream() << "textool texture changed..\n"; - } -#endif -} - -void SurfaceInspector_SelectionChanged(const Selectable &selectable) -{ - SurfaceInspector_updateSelection(); -} - -void SurfaceInspector_SetCurrent_FromSelected() -{ - if (s_texture_selection_dirty == true) { - s_texture_selection_dirty = false; - if (!g_SelectedFaceInstances.empty()) { - TextureProjection projection; -//This *may* be the point before it fucks up... Let's see! -//Yep, there was a call to removeScale in there... - Scene_BrushGetTexdef_Component_Selected(GlobalSceneGraph(), projection); - - SurfaceInspector_SetSelectedTexdef(projection); - - Scene_BrushGetShaderSize_Component_Selected(GlobalSceneGraph(), g_selectedShaderSize[0], - g_selectedShaderSize[1]); - g_selectedTexdef.m_brushprimit_texdef.coords[0][2] = float_mod( - g_selectedTexdef.m_brushprimit_texdef.coords[0][2], (float) g_selectedShaderSize[0]); - g_selectedTexdef.m_brushprimit_texdef.coords[1][2] = float_mod( - g_selectedTexdef.m_brushprimit_texdef.coords[1][2], (float) g_selectedShaderSize[1]); - - CopiedString name; - Scene_BrushGetShader_Component_Selected(GlobalSceneGraph(), name); - if (string_not_empty(name.c_str())) { - SurfaceInspector_SetSelectedShader(name.c_str()); - } - - ContentsFlagsValue flags; - Scene_BrushGetFlags_Component_Selected(GlobalSceneGraph(), flags); - SurfaceInspector_SetSelectedFlags(flags); - } else { - TextureProjection projection; - Scene_BrushGetTexdef_Selected(GlobalSceneGraph(), projection); - SurfaceInspector_SetSelectedTexdef(projection); - - CopiedString name; - Scene_BrushGetShader_Selected(GlobalSceneGraph(), name); - if (string_empty(name.c_str())) { - Scene_PatchGetShader_Selected(GlobalSceneGraph(), name); - } - if (string_not_empty(name.c_str())) { - SurfaceInspector_SetSelectedShader(name.c_str()); - } - - ContentsFlagsValue flags(0, 0, 0, false); - Scene_BrushGetFlags_Selected(GlobalSceneGraph(), flags); - SurfaceInspector_SetSelectedFlags(flags); - } - } -} - -const char *SurfaceInspector_GetSelectedShader() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedShader.c_str(); -} - -const TextureProjection &SurfaceInspector_GetSelectedTexdef() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedTexdef; -} - -const ContentsFlagsValue &SurfaceInspector_GetSelectedFlags() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedFlags; -} - - -/* - =================================================== - - SURFACE INSPECTOR - - =================================================== - */ - -si_globals_t g_si_globals; - - -// make the shift increments match the grid settings -// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size -// this depends on a scale value if you have selected a particular texture on which you want it to work: -// we move the textures in pixels, not world units. (i.e. increment values are in pixel) -// depending on the texture scale it doesn't take the same amount of pixels to move of GetGridSize() -// increment * scale = gridsize -// hscale and vscale are optional parameters, if they are zero they will be set to the default scale -// NOTE: the default scale depends if you are using BP mode or regular. -// For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f -// see fenris #2810 -void DoSnapTToGrid(float hscale, float vscale) -{ - g_si_globals.shift[0] = static_cast( float_to_integer(static_cast( GetGridSize()) / hscale)); - g_si_globals.shift[1] = static_cast( float_to_integer(static_cast( GetGridSize()) / vscale)); - getSurfaceInspector().queueDraw(); -} - -void SurfaceInspector_GridChange() -{ - if (g_si_globals.m_bSnapTToGrid) { - DoSnapTToGrid(Texdef_getDefaultTextureScale(), Texdef_getDefaultTextureScale()); - } -} - -// make the shift increments match the grid settings -// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size -// this depends on the current texture scale used? -// we move the textures in pixels, not world units. (i.e. increment values are in pixel) -// depending on the texture scale it doesn't take the same amount of pixels to move of GetGridSize() -// increment * scale = gridsize -static void OnBtnMatchGrid(ui::Widget widget, gpointer data) -{ - float hscale, vscale; - hscale = static_cast( gtk_spin_button_get_value(getSurfaceInspector().m_hscaleIncrement.m_spin)); - vscale = static_cast( gtk_spin_button_get_value(getSurfaceInspector().m_vscaleIncrement.m_spin)); - - if (hscale == 0.0f || vscale == 0.0f) { - globalOutputStream() << "ERROR: unexpected scale == 0.0f\n"; - return; - } - - DoSnapTToGrid(hscale, vscale); -} - -// DoSurface will always try to show the surface inspector -// or update it because something new has been selected -// Shamus: It does get called when the SI is hidden, but not when you select something new. ;-) -void DoSurface(void) -{ - if (!getSurfaceInspector().GetWidget()) { - getSurfaceInspector().Create(); - - } - getSurfaceInspector().Update(); - getSurfaceInspector().importData(); - getSurfaceInspector().ShowDlg(); -} - -void SurfaceInspector_toggleShown() -{ - if (getSurfaceInspector().visible()) { - getSurfaceInspector().HideDlg(); - } else { - DoSurface(); - } -} - -void SurfaceInspector_FitTexture() -{ - UndoableCommand undo("textureAutoFit"); - Select_FitTexture(getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical); -} - -void SurfaceInspector_AlignTopLeft() -{ - Select_AlignTexture(0); -} -void SurfaceInspector_AlignTop() -{ - Select_AlignTexture(1); -} -void SurfaceInspector_AlignTopRight() -{ - Select_AlignTexture(2); -} -void SurfaceInspector_AlignLeft() -{ - Select_AlignTexture(3); -} -void SurfaceInspector_AlignCenter() -{ - Select_AlignTexture(4); -} -void SurfaceInspector_AlignRight() -{ - Select_AlignTexture(5); -} -void SurfaceInspector_AlignBottomLeft() -{ - Select_AlignTexture(6); -} -void SurfaceInspector_AlignBottom() -{ - Select_AlignTexture(7); -} -void SurfaceInspector_AlignBottomRight() -{ - Select_AlignTexture(8); -} - -static void OnBtnPatchdetails(ui::Widget widget, gpointer data) -{ - Patch_CapTexture(); -} - -static void OnBtnPatchnatural(ui::Widget widget, gpointer data) -{ - Patch_NaturalTexture(); -} - -static void OnBtnPatchreset(ui::Widget widget, gpointer data) -{ - Patch_ResetTexture(); -} - -static void OnBtnPatchFit(ui::Widget widget, gpointer data) -{ - Patch_FitTexture(); -} - -static void OnBtnAxial(ui::Widget widget, gpointer data) -{ -//globalOutputStream() << "--> [OnBtnAxial]...\n"; - UndoableCommand undo("textureDefault"); - TextureProjection projection; -//globalOutputStream() << " TexDef_Construct_Default()...\n"; - TexDef_Construct_Default(projection); -//globalOutputStream() << " Select_SetTexdef()...\n"; - -#if TEXTOOL_ENABLED - - //Shamus: - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - // Scale up texture width/height if in BP mode... -//NOTE: This may not be correct any more! :-P - if ( !g_SelectedFaceInstances.empty() ) { - Face & face = g_SelectedFaceInstances.last().getFace(); - float x = face.getShader().m_state->getTexture().width; - float y = face.getShader().m_state->getTexture().height; - projection.m_brushprimit_texdef.coords[0][0] /= x; - projection.m_brushprimit_texdef.coords[0][1] /= y; - projection.m_brushprimit_texdef.coords[1][0] /= x; - projection.m_brushprimit_texdef.coords[1][1] /= y; - } - } -#endif - - Select_SetTexdef(projection, true); -} - -static void OnBtnFaceFit(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_FitTexture(); -} - - -static void OnBtnTopLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTopLeft(); -} -static void OnBtnTopCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTop(); -} -static void OnBtnTopRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTopRight(); -} - - -static void OnBtnMiddleLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignLeft(); -} -static void OnBtnMiddleCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignCenter(); -} -static void OnBtnMiddleRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignRight(); -} - - -static void OnBtnBottomLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottomLeft(); -} -static void OnBtnBottomCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottom(); -} -static void OnBtnBottomRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottomRight(); -} - -typedef const char *FlagName; - -const FlagName surfaceflagNamesDefault[32] = { - "surf1", - "surf2", - "surf3", - "surf4", - "surf5", - "surf6", - "surf7", - "surf8", - "surf9", - "surf10", - "surf11", - "surf12", - "surf13", - "surf14", - "surf15", - "surf16", - "surf17", - "surf18", - "surf19", - "surf20", - "surf21", - "surf22", - "surf23", - "surf24", - "surf25", - "surf26", - "surf27", - "surf28", - "surf29", - "surf30", - "surf31", - "surf32" -}; - -const FlagName contentflagNamesDefault[32] = { - "cont1", - "cont2", - "cont3", - "cont4", - "cont5", - "cont6", - "cont7", - "cont8", - "cont9", - "cont10", - "cont11", - "cont12", - "cont13", - "cont14", - "cont15", - "cont16", - "cont17", - "cont18", - "cont19", - "cont20", - "cont21", - "cont22", - "cont23", - "cont24", - "cont25", - "cont26", - "cont27", - "cont28", - "cont29", - "cont30", - "cont31", - "cont32" -}; - -const char *getSurfaceFlagName(std::size_t bit) -{ - const char *value = g_pGameDescription->getKeyValue(surfaceflagNamesDefault[bit]); - if (string_empty(value)) { - return surfaceflagNamesDefault[bit]; - } - return value; -} - -const char *getContentFlagName(std::size_t bit) -{ - const char *value = g_pGameDescription->getKeyValue(contentflagNamesDefault[bit]); - if (string_empty(value)) { - return contentflagNamesDefault[bit]; - } - return value; -} - - -// ============================================================================= -// SurfaceInspector class - -guint togglebutton_connect_toggled(ui::ToggleButton button, const Callback &callback) -{ - return g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -} - -ui::Window SurfaceInspector::BuildDialog() -{ - ui::Window window = ui::Window(create_floating_window("Surface Inspector", m_parent)); - - m_positionTracker.connect(window); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - - { - // replaced by only the vbox: - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - window.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - { - auto hbox2 = ui::HBox(FALSE, 5); - hbox2.show(); - vbox.pack_start(hbox2, FALSE, FALSE, 0); - - { - ui::Widget label = ui::Label("Texture"); - label.show(); - hbox2.pack_start(label, FALSE, TRUE, 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - hbox2.pack_start(entry, TRUE, TRUE, 0); - m_texture = entry; - m_textureEntry.connect(entry); - GlobalTextureEntryCompletion::instance().connect(entry); - } - } - - - { - auto table = ui::Table(6, 4, FALSE); - table.show(); - vbox.pack_start(table, FALSE, FALSE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - ui::Widget label = ui::Label("Horizontal shift"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_hshiftIncrement.m_spin = spin; - m_hshiftSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 0, 1}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - entry.dimensions(50, -1); - m_hshiftIncrement.m_entry = entry; - m_hshiftEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Vertical shift"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_vshiftIncrement.m_spin = spin; - m_vshiftSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 1, 2}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 1, 2}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_vshiftIncrement.m_entry = entry; - m_vshiftEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Horizontal stretch"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 5); - m_hscaleIncrement.m_spin = spin; - m_hscaleSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 2, 3}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 2, 3}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_hscaleIncrement.m_entry = entry; - m_hscaleEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Vertical stretch"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 3, 4}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 5); - m_vscaleIncrement.m_spin = spin; - m_vscaleSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 3, 4}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 3, 4}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 3, 4}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_vscaleIncrement.m_entry = entry; - m_vscaleEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Rotate"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 4, 5}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_rotateIncrement.m_spin = spin; - m_rotateSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 4, 5}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - gtk_spin_button_set_wrap(spin, TRUE); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 4, 5}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 4, 5}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_rotateIncrement.m_entry = entry; - m_rotateEntry.connect(entry); - } - { - // match grid button - ui::Widget button = ui::Button("Match Grid"); - button.show(); - table.attach(button, {2, 4, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnMatchGrid), 0); - } - } - - { - auto frame = ui::Frame("Texturing"); - frame.show(); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = ui::Table(4, 4, FALSE); - table.show(); - frame.add(table); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); - { - ui::Widget label = ui::Label("Brush"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Patch"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Width"); - label.show(); - table.attach(label, {2, 3, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Height"); - label.show(); - table.attach(label, {3, 4, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget button = ui::Button("Axial"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnAxial), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Fit"); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnFaceFit), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("CAP"); - button.show(); - table.attach(button, {0, 1, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchdetails), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Set..."); - button.show(); - table.attach(button, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchreset), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Natural"); - button.show(); - table.attach(button, {2, 3, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchnatural), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Fit"); - button.show(); - table.attach(button, {3, 4, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchFit), 0); - button.dimensions(60, -1); - } - { - auto spin = ui::SpinButton(ui::Adjustment(1, 0, 1 << 16, 1, 10, 0), 0, 6); - spin.show(); - table.attach(spin, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - AddDialogData(spin, m_fitHorizontal); - } - { - auto spin = ui::SpinButton(ui::Adjustment(1, 0, 1 << 16, 1, 10, 0), 0, 6); - spin.show(); - table.attach(spin, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - AddDialogData(spin, m_fitVertical); - } - } - } - { - auto frame = ui::Frame("Alignment"); - frame.show(); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = ui::Table(3, 3, FALSE); - table.show(); - frame.add(table); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); - { - ui::Widget button = ui::Button("Top-Left"); - button.show(); - table.attach(button, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Top"); - button.show(); - table.attach(button, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Top-Right"); - button.show(); - table.attach(button, {2, 3, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopRight), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Left"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Center"); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Right"); - button.show(); - table.attach(button, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleRight), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom-Left"); - button.show(); - table.attach(button, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom"); - button.show(); - table.attach(button, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom-Right"); - button.show(); - table.attach(button, {2, 3, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomRight), 0); - button.dimensions(60, -1); - } - } - } - - if (!string_empty(g_pGameDescription->getKeyValue("si_flags"))) { - { - auto frame = ui::Frame("Surface Flags"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(8, 4, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 0); - gtk_table_set_col_spacings(table, 0); - - GtkCheckButton **p = m_surfaceFlags; - - for (unsigned int c = 0; c != 4; ++c) { - for (unsigned int r = 0; r != 8; ++r) { - auto check = ui::CheckButton(getSurfaceFlagName(c * 8 + r)); - check.show(); - table.attach(check, {c, c + 1, r, r + 1}, {GTK_EXPAND | GTK_FILL, 0}); - *p++ = check; - guint handler_id = togglebutton_connect_toggled(check, ApplyFlagsCaller(*this)); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - } - } - } - } - } - { - auto frame = ui::Frame("Content Flags"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - { - - auto table = ui::Table(8, 4, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 0); - gtk_table_set_col_spacings(table, 0); - - GtkCheckButton **p = m_contentFlags; - - for (unsigned int c = 0; c != 4; ++c) { - for (unsigned int r = 0; r != 8; ++r) { - auto check = ui::CheckButton(getContentFlagName(c * 8 + r)); - check.show(); - table.attach(check, {c, c + 1, r, r + 1}, {GTK_EXPAND | GTK_FILL, 0}); - *p++ = check; - guint handler_id = togglebutton_connect_toggled(check, ApplyFlagsCaller(*this)); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - } - } - - // not allowed to modify detail flag using Surface Inspector - gtk_widget_set_sensitive(ui::CheckButton::from(m_contentFlags[BRUSH_DETAIL_FLAG]), FALSE); - } - } - } - { - auto frame = ui::Frame("Value"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - vbox3.pack_start(entry, TRUE, TRUE, 0); - m_valueEntryWidget = entry; - m_valueEntry.connect(entry); - } - } - } - } - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { -// Shamus: Textool goodies... - ui::Widget frame = ui::Frame( "Textool" ); - frame.show(); - vbox.pack_start( frame, FALSE, FALSE, 0 ); - { - //Prolly should make this a member or global var, so the SI can draw on it... - TexTool::g_textoolWin = glwidget_new( FALSE ); - // --> Dunno, but this stuff may be necessary... (Looks like it!) - g_object_ref( TexTool::g_textoolWin ); - gtk_widget_set_events( TexTool::g_textoolWin, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK ); - gtk_widget_set_can_focus( TexTool::g_textoolWin, true ); - // <-- end stuff... - TexTool::g_textoolWin.show(); - TexTool::g_textoolWin.dimensions( -1, 240 ); //Yeah! - frame.add(TexTool::g_textoolWin); - - TexTool::g_textoolWin.connect( "size_allocate", G_CALLBACK( TexTool::size_allocate ), NULL ); - TexTool::g_textoolWin.connect( "expose_event", G_CALLBACK( TexTool::expose ), NULL ); - TexTool::g_textoolWin.connect( "button_press_event", G_CALLBACK( TexTool::button_press ), NULL ); - TexTool::g_textoolWin.connect( "button_release_event", G_CALLBACK( TexTool::button_release ), NULL ); - TexTool::g_textoolWin.connect( "motion_notify_event", G_CALLBACK( TexTool::motion ), NULL ); - } - { - ui::Widget hbox = ui::HBox( FALSE, 5 ); - hbox.show(); - vbox.pack_start( hbox, FALSE, FALSE, 0 ); - // Checkboxes go here... (Flip X/Y) - ui::Widget flipX = ui::CheckButton( "Flip X axis" ); - ui::Widget flipY = ui::CheckButton( "Flip Y axis" ); - flipX.show(); - flipY.show(); - hbox.pack_start( flipX, FALSE, FALSE, 0 ); - hbox.pack_start( flipY, FALSE, FALSE, 0 ); - -//Instead of this, we probably need to create a vbox to put into the frame, then the -//window, then the hbox. !!! FIX !!! -// frame.add(hbox); - -//Hmm. Do we really need g_object_set_data? Mebbe not... And we don't! :-) -// g_object_set_data(G_OBJECT(flipX), "handler", gint_to_pointer(flipX.connect("toggled", G_CALLBACK(TexTool::flipX), 0))); -// g_object_set_data(G_OBJECT(flipY), "handler", gint_to_pointer(flipY.connect("toggled", G_CALLBACK(TexTool::flipY), 0))); -//Instead, just do: - flipX.connect( "toggled", G_CALLBACK( TexTool::flipX ), NULL ); - flipY.connect( "toggled", G_CALLBACK( TexTool::flipY ), NULL ); - } - } -#endif - } - - /* make small */ - gtk_window_set_default_size(GTK_WINDOW(window), 8, 8); - return window; -} - -/* - ============== - Update - - Set the fields to the current texdef (i.e. map/texdef -> dialog widgets) - if faces selected (instead of brushes) -> will read this face texdef, else current texdef - if only patches selected, will read the patch texdef - =============== - */ - -void spin_button_set_value_no_signal(ui::SpinButton spin, gdouble value) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(spin), "handler")); - g_signal_handler_block(G_OBJECT(gtk_spin_button_get_adjustment(spin)), handler_id); - gtk_spin_button_set_value(spin, value); - g_signal_handler_unblock(G_OBJECT(gtk_spin_button_get_adjustment(spin)), handler_id); -} - -void spin_button_set_step_increment(ui::SpinButton spin, gdouble value) -{ - auto adjust = gtk_spin_button_get_adjustment(spin); - gtk_adjustment_set_step_increment(adjust, value); -} - -void SurfaceInspector::Update() -{ - const char *name = SurfaceInspector_GetSelectedShader(); - - if (shader_is_texture(name)) { - m_texture.text(shader_get_textureName(name)); - } else { - m_texture.text(""); - } - - texdef_t shiftScaleRotate; -//Shamus: This is where we get into trouble--the BP code tries to convert to a "faked" -//shift, rotate & scale values from the brush face, which seems to screw up for some reason. -//!!! FIX !!! -/*globalOutputStream() << "--> SI::Update. About to do ShiftScaleRotate_fromFace()...\n"; - SurfaceInspector_GetSelectedBPTexdef(); - globalOutputStream() << "BP: (" << g_selectedBrushPrimitTexdef.coords[0][0] << ", " << g_selectedBrushPrimitTexdef.coords[0][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[1][0] << ", " << g_selectedBrushPrimitTexdef.coords[1][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[0][2] << ", " << g_selectedBrushPrimitTexdef.coords[1][2] << ") SurfaceInspector::Update\n";//*/ -//Ok, it's screwed up *before* we get here... - ShiftScaleRotate_fromFace(shiftScaleRotate, SurfaceInspector_GetSelectedTexdef()); - - // normalize again to hide the ridiculously high scale values that get created when using texlock - shiftScaleRotate.shift[0] = float_mod(shiftScaleRotate.shift[0], (float) g_selectedShaderSize[0]); - shiftScaleRotate.shift[1] = float_mod(shiftScaleRotate.shift[1], (float) g_selectedShaderSize[1]); - - { - spin_button_set_value_no_signal(m_hshiftIncrement.m_spin, shiftScaleRotate.shift[0]); - spin_button_set_step_increment(m_hshiftIncrement.m_spin, g_si_globals.shift[0]); - entry_set_float(m_hshiftIncrement.m_entry, g_si_globals.shift[0]); - } - - { - spin_button_set_value_no_signal(m_vshiftIncrement.m_spin, shiftScaleRotate.shift[1]); - spin_button_set_step_increment(m_vshiftIncrement.m_spin, g_si_globals.shift[1]); - entry_set_float(m_vshiftIncrement.m_entry, g_si_globals.shift[1]); - } - - { - spin_button_set_value_no_signal(m_hscaleIncrement.m_spin, shiftScaleRotate.scale[0]); - spin_button_set_step_increment(m_hscaleIncrement.m_spin, g_si_globals.scale[0]); - entry_set_float(m_hscaleIncrement.m_entry, g_si_globals.scale[0]); - } - - { - spin_button_set_value_no_signal(m_vscaleIncrement.m_spin, shiftScaleRotate.scale[1]); - spin_button_set_step_increment(m_vscaleIncrement.m_spin, g_si_globals.scale[1]); - entry_set_float(m_vscaleIncrement.m_entry, g_si_globals.scale[1]); - } - - { - spin_button_set_value_no_signal(m_rotateIncrement.m_spin, shiftScaleRotate.rotate); - spin_button_set_step_increment(m_rotateIncrement.m_spin, g_si_globals.rotate); - entry_set_float(m_rotateIncrement.m_entry, g_si_globals.rotate); - } - - if (!string_empty(g_pGameDescription->getKeyValue("si_flags"))) { - ContentsFlagsValue flags(SurfaceInspector_GetSelectedFlags()); - - entry_set_int(m_valueEntryWidget, flags.m_value); - - for (GtkCheckButton **p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p) { - toggle_button_set_active_no_signal(ui::CheckButton::from(*p), - flags.m_surfaceFlags & (1 << (p - m_surfaceFlags))); - } - - for (GtkCheckButton **p = m_contentFlags; p != m_contentFlags + 32; ++p) { - toggle_button_set_active_no_signal(ui::CheckButton::from(*p), - flags.m_contentFlags & (1 << (p - m_contentFlags))); - } - } -} - -/* - ============== - Apply - - Reads the fields to get the current texdef (i.e. widgets -> MAP) - in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix - =============== - */ -void SurfaceInspector::ApplyShader() -{ - StringOutputStream name(256); - name << GlobalTexturePrefix_get() << gtk_entry_get_text(m_texture); - - // TTimo: detect and refuse invalid texture names (at least the ones with spaces) - if (!texdef_name_valid(name.c_str())) { - globalErrorStream() << "invalid texture name '" << name.c_str() << "'\n"; - SurfaceInspector_queueDraw(); - return; - } - - UndoableCommand undo("textureNameSetSelected"); - Select_SetShader(name.c_str()); -} - -void SurfaceInspector::ApplyTexdef() -{ - texdef_t shiftScaleRotate; - - shiftScaleRotate.shift[0] = static_cast( gtk_spin_button_get_value(m_hshiftIncrement.m_spin)); - shiftScaleRotate.shift[1] = static_cast( gtk_spin_button_get_value(m_vshiftIncrement.m_spin)); - shiftScaleRotate.scale[0] = static_cast( gtk_spin_button_get_value(m_hscaleIncrement.m_spin)); - shiftScaleRotate.scale[1] = static_cast( gtk_spin_button_get_value(m_vscaleIncrement.m_spin)); - shiftScaleRotate.rotate = static_cast( gtk_spin_button_get_value(m_rotateIncrement.m_spin)); - - TextureProjection projection; -//Shamus: This is the other place that screws up, it seems, since it doesn't seem to do the -//conversion from the face (I think) and so bogus values end up in the thing... !!! FIX !!! -//This is actually OK. :-P - ShiftScaleRotate_toFace(shiftScaleRotate, projection); - - UndoableCommand undo("textureProjectionSetSelected"); - Select_SetTexdef(projection, true); -} - -void SurfaceInspector::ApplyFlags() -{ - unsigned int surfaceflags = 0; - for (GtkCheckButton **p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*p))) { - surfaceflags |= (1 << (p - m_surfaceFlags)); - } - } - - unsigned int contentflags = 0; - for (GtkCheckButton **p = m_contentFlags; p != m_contentFlags + 32; ++p) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*p))) { - contentflags |= (1 << (p - m_contentFlags)); - } - } - - int value = entry_get_int(m_valueEntryWidget); - - UndoableCommand undo("flagsSetSelected"); - Select_SetFlags(ContentsFlagsValue(surfaceflags, contentflags, value, true)); -} - - -void Face_getTexture(Face &face, CopiedString &shader, TextureProjection &projection, ContentsFlagsValue &flags) -{ - shader = face.GetShader(); - face.GetTexdef(projection); - flags = face.getShader().m_flags; -} - -typedef Function FaceGetTexture; - -void -Face_setTexture(Face &face, const char *shader, const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - face.SetShader(shader); - face.SetTexdef(projection, false); - face.SetFlags(flags); -} - -typedef Function FaceSetTexture; - - -void Patch_getTexture(Patch &patch, CopiedString &shader, TextureProjection &projection, ContentsFlagsValue &flags) -{ - shader = patch.GetShader(); - projection = TextureProjection(texdef_t(), brushprimit_texdef_t(), Vector3(0, 0, 0), Vector3(0, 0, 0)); - flags = ContentsFlagsValue(0, 0, 0, false); -} - -typedef Function PatchGetTexture; - -void -Patch_setTexture(Patch &patch, const char *shader, const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - patch.SetShader(shader); -} - -typedef Function PatchSetTexture; - - -typedef Callback GetTextureCallback; -typedef Callback SetTextureCallback; - -struct Texturable { - GetTextureCallback getTexture; - SetTextureCallback setTexture; -}; - - -void Face_getClosest(Face &face, SelectionTest &test, SelectionIntersection &bestIntersection, Texturable &texturable) -{ - SelectionIntersection intersection; - face.testSelect(test, intersection); - if (intersection.valid() - && SelectionIntersection_closer(intersection, bestIntersection)) { - bestIntersection = intersection; - texturable.setTexture = makeCallback(FaceSetTexture(), face); - texturable.getTexture = makeCallback(FaceGetTexture(), face); - } -} - - -class OccludeSelector : public Selector { -SelectionIntersection &m_bestIntersection; -bool &m_occluded; -public: -OccludeSelector(SelectionIntersection &bestIntersection, bool &occluded) : m_bestIntersection(bestIntersection), - m_occluded(occluded) -{ - m_occluded = false; -} - -void pushSelectable(Selectable &selectable) -{ -} - -void popSelectable() -{ -} - -void addIntersection(const SelectionIntersection &intersection) -{ - if (SelectionIntersection_closer(intersection, m_bestIntersection)) { - m_bestIntersection = intersection; - m_occluded = true; - } -} -}; - -class BrushGetClosestFaceVisibleWalker : public scene::Graph::Walker { -SelectionTest &m_test; -Texturable &m_texturable; -mutable SelectionIntersection m_bestIntersection; -public: -BrushGetClosestFaceVisibleWalker(SelectionTest &test, Texturable &texturable) : m_test(test), - m_texturable(texturable) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_test.BeginMesh(brush->localToWorld()); - - for (Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i) { - Face_getClosest(*(*i), m_test, m_bestIntersection, m_texturable); - } - } else { - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - bool occluded; - OccludeSelector selector(m_bestIntersection, occluded); - selectionTestable->testSelect(selector, m_test); - if (occluded) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0) { - m_texturable.setTexture = makeCallback(PatchSetTexture(), *patch); - m_texturable.getTexture = makeCallback(PatchGetTexture(), *patch); - } else { - m_texturable = Texturable(); - } - } - } - } - } - return true; -} -}; - -Texturable Scene_getClosestTexturable(scene::Graph &graph, SelectionTest &test) -{ - Texturable texturable; - graph.traverse(BrushGetClosestFaceVisibleWalker(test, texturable)); - return texturable; -} - -bool -Scene_getClosestTexture(scene::Graph &graph, SelectionTest &test, CopiedString &shader, TextureProjection &projection, - ContentsFlagsValue &flags) -{ - Texturable texturable = Scene_getClosestTexturable(graph, test); - if (texturable.getTexture != GetTextureCallback()) { - texturable.getTexture(shader, projection, flags); - return true; - } - return false; -} - -void Scene_setClosestTexture(scene::Graph &graph, SelectionTest &test, const char *shader, - const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - Texturable texturable = Scene_getClosestTexturable(graph, test); - if (texturable.setTexture != SetTextureCallback()) { - texturable.setTexture(shader, projection, flags); - } -} - - -class FaceTexture { -public: -TextureProjection m_projection; -ContentsFlagsValue m_flags; -}; - -FaceTexture g_faceTextureClipboard; - -void FaceTextureClipboard_setDefault() -{ - g_faceTextureClipboard.m_flags = ContentsFlagsValue(0, 0, 0, false); - TexDef_Construct_Default(g_faceTextureClipboard.m_projection); -} - -void TextureClipboard_textureSelected(const char *shader) -{ - FaceTextureClipboard_setDefault(); -} - -class TextureBrowser; - -extern TextureBrowser g_TextureBrowser; - -void TextureBrowser_SetSelectedShader(TextureBrowser &textureBrowser, const char *shader); - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrowser); - -void Scene_copyClosestTexture(SelectionTest &test) -{ - CopiedString shader; - if (Scene_getClosestTexture(GlobalSceneGraph(), test, shader, g_faceTextureClipboard.m_projection, - g_faceTextureClipboard.m_flags)) { - TextureBrowser_SetSelectedShader(g_TextureBrowser, shader.c_str()); - } -} - -void Scene_applyClosestTexture(SelectionTest &test) -{ - UndoableCommand command("facePaintTexture"); - - Scene_setClosestTexture(GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader(g_TextureBrowser), - g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags); - - SceneChangeNotify(); -} - - -void SelectedFaces_copyTexture() -{ - if (!g_SelectedFaceInstances.empty()) { - Face &face = g_SelectedFaceInstances.last().getFace(); - face.GetTexdef(g_faceTextureClipboard.m_projection); - g_faceTextureClipboard.m_flags = face.getShader().m_flags; - - TextureBrowser_SetSelectedShader(g_TextureBrowser, face.getShader().getShader()); - } -} - -void FaceInstance_pasteTexture(FaceInstance &faceInstance) -{ - faceInstance.getFace().SetTexdef(g_faceTextureClipboard.m_projection, false); - faceInstance.getFace().SetShader(TextureBrowser_GetSelectedShader(g_TextureBrowser)); - faceInstance.getFace().SetFlags(g_faceTextureClipboard.m_flags); - SceneChangeNotify(); -} - -bool SelectedFaces_empty() -{ - return g_SelectedFaceInstances.empty(); -} - -void SelectedFaces_pasteTexture() -{ - UndoableCommand command("facePasteTexture"); - g_SelectedFaceInstances.foreach(FaceInstance_pasteTexture); -} - - -void SurfaceInspector_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Surface Inspector Increments Match Grid", g_si_globals.m_bSnapTToGrid); -} - -void SurfaceInspector_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Surface Inspector", "Surface Inspector Preferences")); - SurfaceInspector_constructPreferences(page); -} - -void SurfaceInspector_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(SurfaceInspector_constructPage)); -} - -void SurfaceInspector_registerCommands() -{ - GlobalCommands_insert("FitTexture", makeCallbackF(SurfaceInspector_FitTexture), - Accelerator('B', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("SurfaceInspector", makeCallbackF(SurfaceInspector_toggleShown), Accelerator('S')); - - GlobalCommands_insert("FaceCopyTexture", makeCallbackF(SelectedFaces_copyTexture)); - GlobalCommands_insert("FacePasteTexture", makeCallbackF(SelectedFaces_pasteTexture)); -} - - -#include "preferencesystem.h" - - -void SurfaceInspector_Construct() -{ - g_SurfaceInspector = new SurfaceInspector; - - SurfaceInspector_registerCommands(); - - FaceTextureClipboard_setDefault(); - - GlobalPreferenceSystem().registerPreference("SurfaceWnd", make_property( - getSurfaceInspector().m_positionTracker)); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale1", make_property_string(g_si_globals.scale[0])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale2", make_property_string(g_si_globals.scale[1])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Shift1", make_property_string(g_si_globals.shift[0])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Shift2", make_property_string(g_si_globals.shift[1])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Rotate", make_property_string(g_si_globals.rotate)); - GlobalPreferenceSystem().registerPreference("SnapTToGrid", make_property_string(g_si_globals.m_bSnapTToGrid)); - - typedef FreeCaller SurfaceInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(SurfaceInspectorSelectionChangedCaller()); - typedef FreeCaller SurfaceInspectorUpdateSelectionCaller; - Brush_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); - Patch_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); - - SurfaceInspector_registerPreferencesPage(); -} - -void SurfaceInspector_Destroy() -{ - delete g_SurfaceInspector; -} - - -#if TEXTOOL_ENABLED - -namespace TexTool { // namespace hides these symbols from other object-files -// -//Shamus: Textool functions, including GTK+ callbacks -// - -//NOTE: Black screen when TT first comes up is caused by an uninitialized Extent... !!! FIX !!! -// But... You can see down below that it *is* initialized! WTF? -struct Extent -{ - float minX, minY, maxX, maxY; - float width( void ) { - return fabs( maxX - minX ); - } - float height( void ) { - return fabs( maxY - minY ); - } -}; - -//This seems to control the texture scale... (Yep! ;-) -Extent extents = { -2.0f, -2.0f, +2.0f, +2.0f }; -brushprimit_texdef_t tm; // Texture transform matrix -Vector2 pts[c_brush_maxFaces]; -Vector2 center; -int numPts; -int textureNum; -Vector2 textureSize; -Vector2 windowSize; -#define VP_PADDING 1.2 -#define PI 3.14159265358979 -bool lButtonDown = false; -bool rButtonDown = false; -//int dragPoint; -//int anchorPoint; -bool haveAnchor = false; -brushprimit_texdef_t currentBP; -brushprimit_texdef_t origBP; // Original brush primitive (before we muck it up) -float controlRadius = 5.0f; -float rotationAngle = 0.0f; -float rotationAngle2 = 0.0f; -float oldRotationAngle; -Vector2 rotationPoint; -bool translatingX = false; // Widget state variables -bool translatingY = false; -bool scalingX = false; -bool scalingY = false; -bool rotating = false; -bool resizingX = false; // Not sure what this means... :-/ -bool resizingY = false; -float origAngle, origScaleX, origScaleY; -Vector2 oldCenter; - - -// Function prototypes (move up to top later...) - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ); - - -void CopyPointsFromSelectedFace( void ){ - // Make sure that there's a face and winding to get! - - if ( g_SelectedFaceInstances.empty() ) { - numPts = 0; - return; - } - - Face & face = g_SelectedFaceInstances.last().getFace(); - textureNum = face.getShader().m_state->getTexture().texture_number; - textureSize.x() = face.getShader().m_state->getTexture().width; - textureSize.y() = face.getShader().m_state->getTexture().height; -//globalOutputStream() << "--> Texture #" << textureNum << ": " << textureSize.x() << " x " << textureSize.y() << "...\n"; - - currentBP = SurfaceInspector_GetSelectedTexdef().m_brushprimit_texdef; - - face.EmitTextureCoordinates(); - Winding & w = face.getWinding(); - int count = 0; - - for ( Winding::const_iterator i = w.begin(); i != w.end(); i++ ) - { - //globalOutputStream() << (*i).texcoord.x() << " " << (*i).texcoord.y() << ", "; - pts[count].x() = ( *i ).texcoord.x(); - pts[count].y() = ( *i ).texcoord.y(); - count++; - } - - numPts = count; - - //globalOutputStream() << " ..copied points\n"; -} - -brushprimit_texdef_t bp; -//This approach is probably wrongheaded and just not right anyway. So, !!! FIX !!! [DONE] -void CommitChanges( void ){ - texdef_t t; // Throwaway, since this is BP only - - bp.coords[0][0] = tm.coords[0][0] * origBP.coords[0][0] + tm.coords[0][1] * origBP.coords[1][0]; - bp.coords[0][1] = tm.coords[0][0] * origBP.coords[0][1] + tm.coords[0][1] * origBP.coords[1][1]; - bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2]; -//Ok, this works for translation... -// bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2] * textureSize.x(); - bp.coords[1][0] = tm.coords[1][0] * origBP.coords[0][0] + tm.coords[1][1] * origBP.coords[1][0]; - bp.coords[1][1] = tm.coords[1][0] * origBP.coords[0][1] + tm.coords[1][1] * origBP.coords[1][1]; - bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2]; -// bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2] * textureSize.y(); - -//This doesn't work: g_brush_texture_changed(); -// Let's try this: -//Note: We should only set an undo *after* the button has been released... !!! FIX !!! -//Definitely *should* have an undo, though! -// UndoableCommand undo("textureProjectionSetSelected"); - Select_SetTexdef( TextureProjection( t, bp, Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ) ); -//This is working, but for some reason the translate is causing the rest of the SI -//widgets to yield bad readings... !!! FIX !!! -//I.e., click on textool window, translate face wireframe, then controls go crazy. Dunno why. -//It's because there were some uncommented out add/removeScale functions in brush.h and a -//removeScale in brushmanip.cpp... :-/ -//Translate isn't working at all now... :-( -//It's because we need to multiply in some scaling factor (prolly the texture width/height) -//Yep. :-P -} - -void UpdateControlPoints( void ){ - CommitChanges(); - - // Init texture transform matrix - - tm.coords[0][0] = 1.0f; tm.coords[0][1] = 0.0f; tm.coords[0][2] = 0.0f; - tm.coords[1][0] = 0.0f; tm.coords[1][1] = 1.0f; tm.coords[1][2] = 0.0f; -} - - -/* - For shifting we have: - */ -/* - The code that should provide reasonable defaults, but doesn't for some reason: - It's scaling the BP by 128 for some reason, between the time it's created and the - time we get back to the SI widgets: - - static void OnBtnAxial(GtkWidget *widget, gpointer data) - { - UndoableCommand undo("textureDefault"); - TextureProjection projection; - TexDef_Construct_Default(projection); - Select_SetTexdef(projection); - } - - Select_SetTexdef() calls Scene_BrushSetTexdef_Component_Selected(GlobalSceneGraph(), projection) - which is in brushmanip.h: This eventually calls - Texdef_Assign(m_texdef, texdef, m_brushprimit_texdef, brushprimit_texdef) in class Face... - which just copies from brushpr to m_brushpr... - */ - -//Small problem with this thing: It's scaled to the texture which is all screwed up... !!! FIX !!! [DONE] -//Prolly should separate out the grid drawing so that we can draw it behind the polygon. -const float gridWidth = 1.3f; // Let's try an absolute height... WORKS!!! -// NOTE that 2.0 is the height of the viewport. Dunno why... Should make collision -// detection easier... -const float gridRadius = gridWidth * 0.5f; - -typedef const float WidgetColor[3]; -const WidgetColor widgetColor[10] = { - { 1.0000f, 0.2000f, 0.0000f }, // Red - { 0.9137f, 0.9765f, 0.4980f }, // Yellow - { 0.0000f, 0.6000f, 0.3216f }, // Green - { 0.6157f, 0.7726f, 0.8196f }, // Cyan - { 0.4980f, 0.5000f, 0.4716f }, // Grey - - // Highlight colors - { 1.0000f, 0.6000f, 0.4000f }, // Light Red - { 1.0000f, 1.0000f, 0.8980f }, // Light Yellow - { 0.4000f, 1.0000f, 0.7216f }, // Light Green - { 1.0000f, 1.0000f, 1.0000f }, // Light Cyan - { 0.8980f, 0.9000f, 0.8716f } // Light Grey -}; - -#define COLOR_RED 0 -#define COLOR_YELLOW 1 -#define COLOR_GREEN 2 -#define COLOR_CYAN 3 -#define COLOR_GREY 4 -#define COLOR_LT_RED 5 -#define COLOR_LT_YELLOW 6 -#define COLOR_LT_GREEN 7 -#define COLOR_LT_CYAN 8 -#define COLOR_LT_GREY 9 - -void DrawControlWidgets( void ){ -//Note that the grid should go *behind* the face outline... !!! FIX !!! - // Grid - float xStart = center.x() - ( gridWidth / 2.0f ); - float yStart = center.y() - ( gridWidth / 2.0f ); - float xScale = ( extents.height() / extents.width() ) * ( textureSize.y() / textureSize.x() ); - - glPushMatrix(); -//Small problem with this approach: Changing the center point in the TX code doesn't seem to -//change anything here--prolly because we load a new identity matrix. A couple of ways to fix -//this would be to get rid of that code, or change the center to a new point by taking into -//account the transforms that we toss with the new identity matrix. Dunno which is better. - glLoadIdentity(); - glScalef( xScale, 1.0, 1.0 ); // Will that square it up? Yup. - glRotatef( static_cast( radians_to_degrees( atan2( -currentBP.coords[0][1], currentBP.coords[0][0] ) ) ), 0.0, 0.0, -1.0 ); - glTranslatef( -center.x(), -center.y(), 0.0 ); - - // Circle - glColor3fv( translatingX && translatingY ? widgetColor[COLOR_LT_YELLOW] : widgetColor[COLOR_YELLOW] ); - glBegin( GL_LINE_LOOP ); - DrawCircularArc( center, 0, 2.0f * PI, gridRadius * 0.16 ); - - glEnd(); - - // Axes - glBegin( GL_LINES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 0.16 ) ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.00 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 0.16 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 1.00 ), center.y() ); - glEnd(); - - // Arrowheads - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBegin( GL_TRIANGLES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glVertex2f( center.x() - ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() + ( gridRadius * 0.06 ) ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() - ( gridRadius * 0.06 ) ); - glEnd(); - - // Arc - glBegin( GL_LINE_STRIP ); - glColor3fv( rotating ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - DrawCircularArc( center, 0.03f * PI, 0.47f * PI, gridRadius * 0.90 ); - glEnd(); - - // Boxes - glColor3fv( scalingY && !scalingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() - ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glEnd(); - - glColor3fv( scalingX && !scalingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 0.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() - ( gridRadius * 0.20 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 0.10 ) ); - glEnd(); - - glColor3fv( scalingX && scalingY ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - glBegin( GL_LINE_STRIP ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.40 ) ); - glEnd(); - - glPopMatrix(); -} - -void DrawControlPoints( void ){ - glColor3f( 1, 1, 1 ); - glBegin( GL_LINE_LOOP ); - - for ( int i = 0; i < numPts; i++ ) - glVertex2f( pts[i].x(), pts[i].y() ); - - glEnd(); -} - -// Note: Setup and all that jazz must be done by the caller! - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ){ - float stepSize = ( 2.0f * PI ) / 200.0f; - - for ( float angle = startAngle; angle <= endAngle; angle += stepSize ) - glVertex2f( ctr.x() + radius * cos( angle ), ctr.y() + radius * sin( angle ) ); -} - - -void focus(){ - if ( numPts == 0 ) { - return; - } - - // Find selected texture's extents... - - extents.minX = extents.maxX = pts[0].x(), - extents.minY = extents.maxY = pts[0].y(); - - for ( int i = 1; i < numPts; i++ ) - { - if ( pts[i].x() < extents.minX ) { - extents.minX = pts[i].x(); - } - if ( pts[i].x() > extents.maxX ) { - extents.maxX = pts[i].x(); - } - if ( pts[i].y() < extents.minY ) { - extents.minY = pts[i].y(); - } - if ( pts[i].y() > extents.maxY ) { - extents.maxY = pts[i].y(); - } - } - - // Do some viewport fitting stuff... - -//globalOutputStream() << "--> Center: " << center.x() << ", " << center.y() << "\n"; -//globalOutputStream() << "--> Extents (stage 1): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - // TTimo: Apply a ratio to get the area we'll draw. - center.x() = 0.5f * ( extents.minX + extents.maxX ), - center.y() = 0.5f * ( extents.minY + extents.maxY ); - extents.minX = center.x() + VP_PADDING * ( extents.minX - center.x() ), - extents.minY = center.y() + VP_PADDING * ( extents.minY - center.y() ), - extents.maxX = center.x() + VP_PADDING * ( extents.maxX - center.x() ), - extents.maxY = center.y() + VP_PADDING * ( extents.maxY - center.y() ); -//globalOutputStream() << "--> Extents (stage 2): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - - // TTimo: We want a texture with the same X / Y ratio. - // TTimo: Compute XY space / window size ratio. - float SSize = extents.width(), TSize = extents.height(); - float ratioX = textureSize.x() * extents.width() / windowSize.x(), - ratioY = textureSize.y() * extents.height() / windowSize.y(); -//globalOutputStream() << "--> Texture size: " << textureSize.x() << ", " << textureSize.y() << "\n"; -//globalOutputStream() << "--> Window size: " << windowSize.x() << ", " << windowSize.y() << "\n"; - - if ( ratioX > ratioY ) { - TSize = ( windowSize.y() * ratioX ) / textureSize.y(); -// TSize = extents.width() * (windowSize.y() / windowSize.x()) * (textureSize.x() / textureSize.y()); - } - else - { - SSize = ( windowSize.x() * ratioY ) / textureSize.x(); -// SSize = extents.height() * (windowSize.x() / windowSize.y()) * (textureSize.y() / textureSize.x()); - } - - extents.minX = center.x() - 0.5f * SSize, extents.maxX = center.x() + 0.5f * SSize, - extents.minY = center.y() - 0.5f * TSize, extents.maxY = center.y() + 0.5f * TSize; -//globalOutputStream() << "--> Extents (stage 3): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; -} - -gboolean size_allocate( ui::Widget win, GtkAllocation * a, gpointer ){ - windowSize.x() = a->width; - windowSize.y() = a->height; - queueDraw(); - return false; -} - -gboolean expose( ui::Widget win, GdkEventExpose * e, gpointer ){ -// globalOutputStream() << "--> Textool Window was exposed!\n"; -// globalOutputStream() << " (window width/height: " << cc << "/" << e->area.height << ")\n"; - -// windowSize.x() = e->area.width, windowSize.y() = e->area.height; -//This needs to go elsewhere... -// InitTextool(); - - if ( glwidget_make_current( win ) == FALSE ) { - globalOutputStream() << " FAILED to make current! Oh, the agony! :-(\n"; - return true; - } - - CopyPointsFromSelectedFace(); - - if ( !lButtonDown ) { - focus(); - } - - // Probably should init button/anchor states here as well... -// rotationAngle = 0.0f; - glClearColor( 0, 0, 0, 0 ); - glViewport( 0, 0, e->area.width, e->area.height ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - -//??? - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); - - glOrtho( extents.minX, extents.maxX, extents.maxY, extents.minY, -1, 1 ); - - glColor3f( 1, 1, 1 ); - // draw the texture background - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBindTexture( GL_TEXTURE_2D, textureNum ); - - glEnable( GL_TEXTURE_2D ); - glBegin( GL_QUADS ); - glTexCoord2f( extents.minX, extents.minY ); - glVertex2f( extents.minX, extents.minY ); - glTexCoord2f( extents.maxX, extents.minY ); - glVertex2f( extents.maxX, extents.minY ); - glTexCoord2f( extents.maxX, extents.maxY ); - glVertex2f( extents.maxX, extents.maxY ); - glTexCoord2f( extents.minX, extents.maxY ); - glVertex2f( extents.minX, extents.maxY ); - glEnd(); - glDisable( GL_TEXTURE_2D ); - - // draw the texture-space grid - glColor3fv( widgetColor[COLOR_GREY] ); - glBegin( GL_LINES ); - - const int gridSubdivisions = 8; - const float gridExtents = 4.0f; - - for ( int i = 0; i < gridSubdivisions + 1; ++i ) - { - float y = i * ( gridExtents / float(gridSubdivisions) ); - float x = i * ( gridExtents / float(gridSubdivisions) ); - glVertex2f( 0, y ); - glVertex2f( gridExtents, y ); - glVertex2f( x, 0 ); - glVertex2f( x, gridExtents ); - } - - glEnd(); - - DrawControlPoints(); - DrawControlWidgets(); -//??? - // reset the current texture -// glBindTexture(GL_TEXTURE_2D, 0); -// glFinish(); - glwidget_swap_buffers( win ); - - return false; -} - -/*int FindSelectedPoint(int x, int y) - { - for(int i=0; i Textool button press...\n"; - - if ( e->button == 1 ) { - lButtonDown = true; - GlobalUndoSystem().start(); - - origBP = currentBP; - - //globalOutputStream() << "--> Original BP: [" << origBP.coords[0][0] << "][" << origBP.coords[0][1] << "][" << origBP.coords[0][2] << "]\n"; - //globalOutputStream() << " [" << origBP.coords[1][0] << "][" << origBP.coords[1][1] << "][" << origBP.coords[1][2] << "]\n"; - //float angle = atan2(origBP.coords[0][1], origBP.coords[0][0]) * 180.0f / 3.141592653589f; - origAngle = ( origBP.coords[0][1] > 0 ? PI : -PI ); // Could also be -PI... !!! FIX !!! [DONE] - - if ( origBP.coords[0][0] != 0.0f ) { - origAngle = atan( origBP.coords[0][1] / origBP.coords[0][0] ); - } - - origScaleX = origBP.coords[0][0] / cos( origAngle ); - origScaleY = origBP.coords[1][1] / cos( origAngle ); - rotationAngle = origAngle; - oldCenter[0] = oldCenter[1] = 0; - - //globalOutputStream() << "--> BP stats: ang=" << origAngle * RAD_TO_DEG << ", scale=" << origScaleX << "/" << origScaleY << "\n"; - //Should also set the Flip X/Y checkboxes here as well... !!! FIX !!! - //Also: should reverse texture left/right up/down instead of flipping the points... - -//disnowok -//float nx = windowSize.x() * (e->x - extents.minX) / (extents.maxX - extents.minX); -//float ny = windowSize.y() * (e->y - extents.minY) / (extents.maxY - extents.minY); -//disdoes... -//But I want it to scroll the texture window, not the points... !!! FIX !!! -//Actually, should scroll the texture window only when mouse is down on no widgets... - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - trans.x() = -tm.coords[0][0] * nx - tm.coords[0][1] * ny; - trans.y() = -tm.coords[1][0] * nx - tm.coords[1][1] * ny; - - dragPoint.x() = e->x, dragPoint.y() = e->y; - trans2.x() = nx, trans2.y() = ny; - oldRotationAngle = rotationAngle; -// oldTrans.x() = tm.coords[0][2] - nx * textureSize.x(); -// oldTrans.y() = tm.coords[1][2] - ny * textureSize.y(); - oldTrans.x() = tm.coords[0][2]; - oldTrans.y() = tm.coords[1][2]; - oldCenter.x() = center.x(); - oldCenter.y() = center.y(); - - queueDraw(); - - return true; - } -/* else if (e->button == 3) - { - rButtonDown = true; - }//*/ - -//globalOutputStream() << "(" << (haveAnchor ? "anchor" : "released") << ")\n"; - - return false; -} - -gboolean button_release( ui::Widget win, GdkEventButton * e, gpointer ){ -// globalOutputStream() << "--> Textool button release...\n"; - - if ( e->button == 1 ) { -/* float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - - //This prolly should go into the mouse move code... - //Doesn't work correctly anyway... - if (translatingX || translatingY) - center.x() = ptx, center.y() = pty;//*/ - - lButtonDown = false; - - if ( translatingX || translatingY ) { - GlobalUndoSystem().finish( "translateTexture" ); - } - else if ( rotating ) { - GlobalUndoSystem().finish( "rotateTexture" ); - } - else if ( scalingX || scalingY ) { - GlobalUndoSystem().finish( "scaleTexture" ); - } - else if ( resizingX || resizingY ) { - GlobalUndoSystem().finish( "resizeTexture" ); - } - else - { - GlobalUndoSystem().finish( "textoolUnknown" ); - } - - rotating = translatingX = translatingY = scalingX = scalingY - = resizingX = resizingY = false; - - queueDraw(); - } - else if ( e->button == 3 ) { - rButtonDown = false; - } - - return true; -} - -/* - void C2DView::GridForWindow( float c[2], int x, int y) - { - SpaceForWindow( c, x, y ); - if ( !m_bDoGrid ) - return; - c[0] /= m_GridStep[0]; - c[1] /= m_GridStep[1]; - c[0] = (float)floor( c[0] + 0.5f ); - c[1] = (float)floor( c[1] + 0.5f ); - c[0] *= m_GridStep[0]; - c[1] *= m_GridStep[1]; - } - void C2DView::SpaceForWindow( float c[2], int x, int y) - { - c[0] = ((float)(x))/((float)(m_rect.right-m_rect.left))*(m_Maxs[0]-m_Mins[0])+m_Mins[0]; - c[1] = ((float)(y))/((float)(m_rect.bottom-m_rect.top))*(m_Maxs[1]-m_Mins[1])+m_Mins[1]; - } - */ -gboolean motion( ui::Widget win, GdkEventMotion * e, gpointer ){ -// globalOutputStream() << "--> Textool motion...\n"; - - if ( lButtonDown ) { - if ( translatingX || translatingY ) { - float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - -//Need to fix this to take the rotation angle into account, so that it moves along -//the rotated X/Y axis... - if ( translatingX ) { -// tm.coords[0][2] = (trans.x() + ptx) * textureSize.x(); -//This works, but only when the angle is zero. !!! FIX !!! [DONE] -// tm.coords[0][2] = oldCenter.x() + (ptx * textureSize.x()); - tm.coords[0][2] = oldTrans.x() + ( ptx - trans2.x() ) * textureSize.x(); -// center.x() = oldCenter.x() + (ptx - trans2.x()); - } - - if ( translatingY ) { -// tm.coords[1][2] = (trans.y() + pty) * textureSize.y(); -// tm.coords[1][2] = oldCenter.y() + (pty * textureSize.y()); - tm.coords[1][2] = oldTrans.y() + ( pty - trans2.y() ) * textureSize.y(); -// center.y() = oldCenter.y() + (pty - trans2.y()); - } - -//Need to update center.x/y() so that the widget translates as well. Also, oldCenter -//is badly named... Should be oldTrans or something like that... !!! FIX !!! -//Changing center.x/y() here doesn't seem to change anything... :-/ - UpdateControlPoints(); - } - else if ( rotating ) { - // Shamus: New rotate code - int cx = (int)( windowSize.x() * ( center.x() - extents.minX ) / extents.width() ); - int cy = (int)( windowSize.y() * ( center.y() - extents.minY ) / extents.height() ); - Vector3 v1( dragPoint.x() - cx, dragPoint.y() - cy, 0 ), v2( e->x - cx, e->y - cy, 0 ); - - vector3_normalise( v1 ); - vector3_normalise( v2 ); - float c = vector3_dot( v1, v2 ); - Vector3 cross = vector3_cross( v1, v2 ); - float s = vector3_length( cross ); - - if ( cross[2] > 0 ) { - s = -s; - } - -// Problem with this: arcsin/cos seems to only return -90 to 90 and 0 to 180... -// Can't derive angle from that! - -//rotationAngle = asin(s);// * 180.0f / 3.141592653589f; - rotationAngle = acos( c ); -//rotationAngle2 = asin(s); - if ( cross[2] < 0 ) { - rotationAngle = -rotationAngle; - } - -//NO! DOESN'T WORK! rotationAngle -= 45.0f * DEG_TO_RAD; -//Let's try this: -//No wok. -/*c = cos(rotationAngle - oldRotationAngle); - s = sin(rotationAngle - oldRotationAngle); - rotationAngle += oldRotationAngle; - //c += cos(oldRotationAngle); - //s += sin(oldRotationAngle); - //rotationAngle += oldRotationAngle; - //c %= 2.0 * PI; - //s %= 2.0 * PI; - //rotationAngle %= 2.0 * PI;//*/ - -//This is wrong... Hmm... -//It seems to shear the texture instead of rotating it... !!! FIX !!! -// Now it rotates correctly. Seems TTimo was overcomplicating things here... ;-) - -// Seems like what needs to happen here is multiplying these rotations by tm... !!! FIX !!! - -// See brush_primit.cpp line 244 (Texdef_EmitTextureCoordinates()) for where texcoords come from... - - tm.coords[0][0] = c; - tm.coords[0][1] = s; - tm.coords[1][0] = -s; - tm.coords[1][1] = c; -//It doesn't work anymore... Dunno why... -//tm.coords[0][2] = -trans.x(); // This works!!! Yeah!!! -//tm.coords[1][2] = -trans.y(); -//nope. -//tm.coords[0][2] = rotationPoint.x(); // This works, but strangely... -//tm.coords[1][2] = rotationPoint.y(); -//tm.coords[0][2] = 0;// center.x() / 2.0f; -//tm.coords[1][2] = 0;// center.y() / 2.0f; -//No. -//tm.coords[0][2] = -(center.x() * textureSize.x()); -//tm.coords[1][2] = -(center.y() * textureSize.y()); -//Eh? No, but seems to be getting closer... -/*float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - tm.coords[0][2] = -c * center.x() - s * center.y() + ptx; - tm.coords[1][2] = s * center.x() - c * center.x() + pty;//*/ -//Kinda works, but center drifts around on non-square textures... -/*tm.coords[0][2] = (-c * center.x() - s * center.y()) * textureSize.x(); - tm.coords[1][2] = ( s * center.x() - c * center.y()) * textureSize.y();//*/ -//Rotates correctly, but not around the actual center of the face's points... -/*tm.coords[0][2] = -c * center.x() * textureSize.x() - s * center.y() * textureSize.y(); - tm.coords[1][2] = s * center.x() * textureSize.x() - c * center.y() * textureSize.y();//*/ -//Yes!!! - tm.coords[0][2] = ( -c * center.x() * textureSize.x() - s * center.y() * textureSize.y() ) + center.x() * textureSize.x(); - tm.coords[1][2] = ( s * center.x() * textureSize.x() - c * center.y() * textureSize.y() ) + center.y() * textureSize.y(); //*/ -//This doesn't work... -//And this is the wrong place for this anyway (I'm pretty sure). -/*tm.coords[0][2] += oldCenter.x(); - tm.coords[1][2] += oldCenter.y();//*/ - UpdateControlPoints(); // will cause a redraw - } - - return true; - } - else // Check for widget mouseovers - { - Vector2 tran; - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - // Translate nx/y to the "center" point... - nx -= center.x(); - ny -= center.y(); - ny = -ny; // Flip Y-axis so that increasing numbers move up - - tran.x() = tm.coords[0][0] * nx + tm.coords[0][1] * ny; - tran.y() = tm.coords[1][0] * nx + tm.coords[1][1] * ny; -//This doesn't seem to generate a valid distance from the center--for some reason it -//calculates a fixed number every time -//Look at nx/y above: they're getting fixed there! !!! FIX !!! [DONE] - float dist = sqrt( ( nx * nx ) + ( ny * ny ) ); - // Normalize to the 2.0 = height standard (for now) -//globalOutputStream() << "--> Distance before: " << dist; - dist = dist * 2.0f / extents.height(); -//globalOutputStream() << ". After: " << dist; - tran.x() = tran.x() * 2.0f / extents.height(); - tran.y() = tran.y() * 2.0f / extents.height(); -//globalOutputStream() << ". Trans: " << tran.x() << ", " << tran.y() << "\n"; - -//Let's try this instead... -//Interesting! It seems that e->x/y are rotated -//(no, they're not--the TM above is what's doing it...) - nx = ( ( e->x / windowSize.y() ) * 2.0f ) - ( windowSize.x() / windowSize.y() ); - ny = ( ( e->y / windowSize.y() ) * 2.0f ) - ( windowSize.y() / windowSize.y() ); - ny = -ny; -//Cool! It works! Now just need to do rotation... - - rotating = translatingX = translatingY = scalingX = scalingY - = resizingX = resizingY = false; - - if ( dist < ( gridRadius * 0.16f ) ) { - translatingX = translatingY = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( ny ) < ( gridRadius * 0.05f ) && nx > 0 ) { - translatingX = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( nx ) < ( gridRadius * 0.05f ) && ny > 0 ) { - translatingY = true; - } - // Should tighten up the angle on this, or put this test after the axis tests... - else if ( tran.x() > 0 && tran.y() > 0 - && ( dist > ( gridRadius * 0.82f ) && dist < ( gridRadius * 0.98f ) ) ) { - rotating = true; - } - - queueDraw(); - - return true; - } - - return false; -} - -//It seems the fake tex coords conversion is screwing this stuff up... !!! FIX !!! -//This is still wrong... Prolly need to do something with the oldScaleX/Y stuff... -void flipX( ui::ToggleButton, gpointer ){ -// globalOutputStream() << "--> Flip X...\n"; - //Shamus: -// SurfaceInspector_GetSelectedBPTexdef(); // Refresh g_selectedBrushPrimitTexdef... -// tm.coords[0][0] = -tm.coords[0][0]; -// tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now...Nope. -// tm.coords[1][1] = -tm.coords[1][1]; - tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now... - tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[2][0] = -tm.coords[2][0];//wil wok? no. - UpdateControlPoints(); -} - -void flipY( ui::ToggleButton, gpointer ){ -// globalOutputStream() << "--> Flip Y...\n"; -// tm.coords[0][1] = -tm.coords[0][1]; -// tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now...Nope. -// tm.coords[1][0] = -tm.coords[1][0]; - tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now... - tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[2][1] = -tm.coords[2][1];//wil wok? no. - UpdateControlPoints(); -} - -} // end namespace TexTool - -#endif diff --git a/src/surfacedialog.h b/src/surfacedialog.h deleted file mode 100644 index ae8e9c0..0000000 --- a/src/surfacedialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_SURFACEDIALOG_H ) -#define INCLUDED_SURFACEDIALOG_H - - -void SurfaceInspector_Construct(); - -void SurfaceInspector_Destroy(); - -void SurfaceInspector_constructWindow(ui::Window widget); - -void SurfaceInspector_destroyWindow(); - -bool SelectedFaces_empty(); - -void SelectedFaces_copyTexture(); - -void SelectedFaces_pasteTexture(); - -void FaceTextureClipboard_setDefault(); - - -// the increment we are using for the surface inspector (this is saved in the prefs) -struct si_globals_t { - float shift[2]; - float scale[2]; - float rotate; - - bool m_bSnapTToGrid; - - si_globals_t() : m_bSnapTToGrid(false) - { - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } -}; - -extern si_globals_t g_si_globals; - -#endif diff --git a/src/texmanip.cpp b/src/texmanip.cpp deleted file mode 100644 index 9ccc1ef..0000000 --- a/src/texmanip.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (c) 2002 Forest "LordHavoc" Hale - - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Forest Hale nor the names of other contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "texmanip.h" - -#include -#include "stream/textstream.h" - -static byte *row1 = NULL, *row2 = NULL; -static int rowsize = 0; - -void R_ResampleTextureLerpLine(const byte *in, byte *out, int inwidth, int outwidth, int bytesperpixel) -{ - int j, xi, oldx = 0, f, fstep, endx, lerp; -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - fstep = (int) (inwidth * 65536.0f / outwidth); - endx = (inwidth - 1); - if (bytesperpixel == 4) { - for (j = 0, f = 0; j < outwidth; j++, f += fstep) { - xi = f >> 16; - if (xi != oldx) { - in += (xi - oldx) * 4; - oldx = xi; - } - - if (xi < endx) { - lerp = f & 0xFFFF; - *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]); - *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]); - } else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - *out++ = in[3]; - } - } - } else if (bytesperpixel == 3) { - for (j = 0, f = 0; j < outwidth; j++, f += fstep) { - xi = f >> 16; - if (xi != oldx) { - in += (xi - oldx) * 3; - oldx = xi; - } - - if (xi < endx) { - lerp = f & 0xFFFF; - *out++ = (byte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (byte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (byte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]); - } else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - } - } - } else { - globalOutputStream() << "R_ResampleTextureLerpLine: unsupported bytesperpixel " << bytesperpixel << "\n"; - } -} - -/* - ================ - R_ResampleTexture - ================ - */ -void R_ResampleTexture(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, - int bytesperpixel) -{ - if (rowsize < outwidth * bytesperpixel) { - if (row1) { - free(row1); - } - if (row2) { - free(row2); - } - - rowsize = outwidth * bytesperpixel; - row1 = (byte *) malloc(rowsize); - row2 = (byte *) malloc(rowsize); - } - - if (bytesperpixel == 4) { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight - 1), inwidth4 = inwidth * 4, outwidth4 = outwidth * 4; - byte *inrow, *out; - out = (byte *) outdata; - fstep = (int) (inheight * 65536.0f / outheight); -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - inrow = (byte *) indata; - oldy = 0; - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine(inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - - for (i = 0, f = 0; i < outheight; i++, f += fstep) { - yi = f >> 16; - if (yi < endy) { - lerp = f & 0xFFFF; - if (yi != oldy) { - inrow = (byte *) indata + inwidth4 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth4); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - R_ResampleTextureLerpLine(inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while (j >= 0) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - LERPBYTE(8); - LERPBYTE(9); - LERPBYTE(10); - LERPBYTE(11); - LERPBYTE(12); - LERPBYTE(13); - LERPBYTE(14); - LERPBYTE(15); - out += 16; - row1 += 16; - row2 += 16; - j -= 4; - } - if (j & 2) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - out += 8; - row1 += 8; - row2 += 8; - } - if (j & 1) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - out += 4; - row1 += 4; - row2 += 4; - } - row1 -= outwidth4; - row2 -= outwidth4; - } else { - if (yi != oldy) { - inrow = (byte *) indata + inwidth4 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth4); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - oldy = yi; - } - memcpy(out, row1, outwidth4); - } - } - } else if (bytesperpixel == 3) { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight - 1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3; - byte *inrow, *out; - out = (byte *) outdata; - fstep = (int) (inheight * 65536.0f / outheight); -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - inrow = (byte *) indata; - oldy = 0; - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine(inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - for (i = 0, f = 0; i < outheight; i++, f += fstep) { - yi = f >> 16; - if (yi < endy) { - lerp = f & 0xFFFF; - if (yi != oldy) { - inrow = (byte *) indata + inwidth3 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth3); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - R_ResampleTextureLerpLine(inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while (j >= 0) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - LERPBYTE(8); - LERPBYTE(9); - LERPBYTE(10); - LERPBYTE(11); - out += 12; - row1 += 12; - row2 += 12; - j -= 4; - } - if (j & 2) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - out += 6; - row1 += 6; - row2 += 6; - } - if (j & 1) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - out += 3; - row1 += 3; - row2 += 3; - } - row1 -= outwidth3; - row2 -= outwidth3; - } else { - if (yi != oldy) { - inrow = (byte *) indata + inwidth3 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth3); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - oldy = yi; - } - memcpy(out, row1, outwidth3); - } - } - } else { - globalOutputStream() << "R_ResampleTexture: unsupported bytesperpixel " << bytesperpixel << "\n"; - } -} - -// in can be the same as out -void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight) -{ - int x, y, width2, height2, nextrow; - if (width > destwidth) { - if (height > destheight) { - // reduce both - width2 = width >> 1; - height2 = height >> 1; - nextrow = width << 2; - for (y = 0; y < height2; y++) { - for (x = 0; x < width2; x++) { - out[0] = (byte) ((in[0] + in[4] + in[nextrow] + in[nextrow + 4]) >> 2); - out[1] = (byte) ((in[1] + in[5] + in[nextrow + 1] + in[nextrow + 5]) >> 2); - out[2] = (byte) ((in[2] + in[6] + in[nextrow + 2] + in[nextrow + 6]) >> 2); - out[3] = (byte) ((in[3] + in[7] + in[nextrow + 3] + in[nextrow + 7]) >> 2); - out += 4; - in += 8; - } - in += nextrow; // skip a line - } - } else { - // reduce width - width2 = width >> 1; - for (y = 0; y < height; y++) { - for (x = 0; x < width2; x++) { - out[0] = (byte) ((in[0] + in[4]) >> 1); - out[1] = (byte) ((in[1] + in[5]) >> 1); - out[2] = (byte) ((in[2] + in[6]) >> 1); - out[3] = (byte) ((in[3] + in[7]) >> 1); - out += 4; - in += 8; - } - } - } - } else { - if (height > destheight) { - // reduce height - height2 = height >> 1; - nextrow = width << 2; - for (y = 0; y < height2; y++) { - for (x = 0; x < width; x++) { - out[0] = (byte) ((in[0] + in[nextrow]) >> 1); - out[1] = (byte) ((in[1] + in[nextrow + 1]) >> 1); - out[2] = (byte) ((in[2] + in[nextrow + 2]) >> 1); - out[3] = (byte) ((in[3] + in[nextrow + 3]) >> 1); - out += 4; - in += 4; - } - in += nextrow; // skip a line - } - } else { - globalOutputStream() << "GL_MipReduce: desired size already achieved\n"; - } - } -} diff --git a/src/texmanip.h b/src/texmanip.h deleted file mode 100644 index cd01ab0..0000000 --- a/src/texmanip.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2002 Forest "LordHavoc" Hale - - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Forest Hale nor the names of other contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_TEXMANIP_H ) -#define INCLUDED_TEXMANIP_H - -typedef unsigned char byte; - -void R_ResampleTexture(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, - int bytesperpixel); - -void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight); - -#endif diff --git a/src/textureentry.cpp b/src/textureentry.cpp deleted file mode 100644 index fcfe8be..0000000 --- a/src/textureentry.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "textureentry.h" - -#include - -template -void EntryCompletion::connect(ui::Entry entry) -{ - if (!m_store) { - m_store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - fill(); - - StringList().connect(IdleDraw::QueueDrawCaller(m_idleUpdate)); - } - - auto completion = ui::EntryCompletion::from(gtk_entry_completion_new()); - gtk_entry_set_completion(entry, completion); - gtk_entry_completion_set_model(completion, m_store); - gtk_entry_completion_set_text_column(completion, 0); -} - -template -void EntryCompletion::append(const char *string) -{ - m_store.append(0, string); -} - -template -void EntryCompletion::fill() -{ - StringList().forEach(AppendCaller(*this)); -} - -template -void EntryCompletion::clear() -{ - m_store.clear(); -} - -template -void EntryCompletion::update() -{ - clear(); - fill(); -} - -template -class EntryCompletion; - -template -class EntryCompletion; diff --git a/src/textureentry.h b/src/textureentry.h deleted file mode 100644 index d7731ee..0000000 --- a/src/textureentry.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TEXTUREENTRY_H ) -#define INCLUDED_TEXTUREENTRY_H - -#include "gtkutil/idledraw.h" - -#include "generic/static.h" -#include "signal/isignal.h" -#include "shaderlib.h" - -#include "texwindow.h" - -template -class EntryCompletion { -ui::ListStore m_store; -IdleDraw m_idleUpdate; -public: -EntryCompletion() : m_store(ui::null), m_idleUpdate(UpdateCaller(*this)) -{ -} - -void connect(ui::Entry entry); - -void append(const char *string); - -using AppendCaller = MemberCaller; - -void fill(); - -void clear(); - -void update(); - -using UpdateCaller = MemberCaller; -}; - -class TextureNameList { -public: -void forEach(const ShaderNameCallback &callback) const -{ - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (shader_equal_prefix(shader->getName(), "textures/")) { - callback(shader->getName() + 9); - } - } -} - -void connect(const SignalHandler &update) const -{ - TextureBrowser_addActiveShadersChangedCallback(update); -} -}; - -typedef Static > GlobalTextureEntryCompletion; - - -class ShaderList { -public: -void forEach(const ShaderNameCallback &callback) const -{ - GlobalShaderSystem().foreachShaderName(callback); -} - -void connect(const SignalHandler &update) const -{ - TextureBrowser_addShadersRealiseCallback(update); -} -}; - -typedef Static > GlobalShaderEntryCompletion; - - -#endif diff --git a/src/textures.cpp b/src/textures.cpp deleted file mode 100644 index ab7672b..0000000 --- a/src/textures.cpp +++ /dev/null @@ -1,902 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "textures.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "itextures.h" -#include "igl.h" -#include "preferencesystem.h" -#include "qgl.h" - -#include "texturelib.h" -#include "container/hashfunc.h" -#include "container/cache.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "image.h" -#include "texmanip.h" -#include "preferences.h" - - -enum ETexturesMode { - eTextures_NEAREST = 0, - eTextures_NEAREST_MIPMAP_NEAREST = 1, - eTextures_NEAREST_MIPMAP_LINEAR = 2, - eTextures_LINEAR = 3, - eTextures_LINEAR_MIPMAP_NEAREST = 4, - eTextures_LINEAR_MIPMAP_LINEAR = 5, - eTextures_MAX_ANISOTROPY = 6, -}; - -enum TextureCompressionFormat { - TEXTURECOMPRESSION_NONE = 0, - TEXTURECOMPRESSION_RGBA = 1, - TEXTURECOMPRESSION_RGBA_S3TC_DXT1 = 2, - TEXTURECOMPRESSION_RGBA_S3TC_DXT3 = 3, - TEXTURECOMPRESSION_RGBA_S3TC_DXT5 = 4, -}; - -struct texture_globals_t { - // RIANT - // texture compression format - TextureCompressionFormat m_nTextureCompressionFormat; - - float fGamma; - - bool bTextureCompressionSupported; // is texture compression supported by hardware? - GLint texture_components; - - // temporary values that should be initialised only once at run-time - bool m_bOpenGLCompressionSupported; - bool m_bS3CompressionSupported; - - texture_globals_t(GLint components) : - m_nTextureCompressionFormat(TEXTURECOMPRESSION_NONE), - fGamma(1.0f), - bTextureCompressionSupported(false), - texture_components(components), - m_bOpenGLCompressionSupported(false), - m_bS3CompressionSupported(false) - { - } -}; - -texture_globals_t g_texture_globals(GL_RGBA); - -void SetTexParameters(ETexturesMode mode) -{ - float maxAniso = QGL_maxTextureAnisotropy(); - if (maxAniso > 1) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } else if (mode == eTextures_MAX_ANISOTROPY) { - mode = eTextures_LINEAR_MIPMAP_LINEAR; - } - - switch (mode) { - case eTextures_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_NEAREST_MIPMAP_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_NEAREST_MIPMAP_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_LINEAR_MIPMAP_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_LINEAR_MIPMAP_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_MAX_ANISOTROPY: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); - break; - default: - globalOutputStream() << "invalid texture mode\n"; - } -} - -ETexturesMode g_texture_mode = eTextures_NEAREST_MIPMAP_NEAREST; - - -byte g_gammatable[256]; - -void ResampleGamma(float fGamma) -{ - int i, inf; - if (fGamma == 1.0) { - for (i = 0; i < 256; i++) { - g_gammatable[i] = i; - } - } else { - for (i = 0; i < 256; i++) { - inf = (int) (255 * pow(static_cast((i + 0.5) / 255.5 ), static_cast( fGamma )) + 0.5); - if (inf < 0) { - inf = 0; - } - if (inf > 255) { - inf = 255; - } - g_gammatable[i] = inf; - } - } -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -int max_tex_size = 0; -const int max_texture_quality = 3; -LatchedValue g_Textures_textureQuality(3, "Texture Quality"); - -/// \brief This function does the actual processing of raw RGBA data into a GL texture. -/// It will also resample to power-of-two dimensions, generate the mipmaps and adjust gamma. -void LoadTextureRGBA(qtexture_t *q, unsigned char *pPixels, int nWidth, int nHeight) -{ - static float fGamma = -1; - float total[3]; - byte *outpixels = 0; - int nCount = nWidth * nHeight; - - if (fGamma != g_texture_globals.fGamma) { - fGamma = g_texture_globals.fGamma; - ResampleGamma(fGamma); - } - - q->width = nWidth; - q->height = nHeight; - - total[0] = total[1] = total[2] = 0.0f; - - // resample texture gamma according to user settings - for (int i = 0; i < (nCount * 4); i += 4) { - for (int j = 0; j < 3; j++) { - total[j] += (pPixels + i)[j]; - byte b = (pPixels + i)[j]; - (pPixels + i)[j] = g_gammatable[b]; - } - } - - q->color[0] = total[0] / (nCount * 255); - q->color[1] = total[1] / (nCount * 255); - q->color[2] = total[2] / (nCount * 255); - - glGenTextures(1, &q->texture_number); - - glBindTexture(GL_TEXTURE_2D, q->texture_number); - - SetTexParameters(g_texture_mode); - - int gl_width = 1; - while (gl_width < nWidth) { - gl_width <<= 1; - } - - int gl_height = 1; - while (gl_height < nHeight) { - gl_height <<= 1; - } - - bool resampled = false; - if (!(gl_width == nWidth && gl_height == nHeight)) { - resampled = true; - outpixels = (byte *) malloc(gl_width * gl_height * 4); - R_ResampleTexture(pPixels, nWidth, nHeight, outpixels, gl_width, gl_height, 4); - } else { - outpixels = pPixels; - } - - int quality_reduction = max_texture_quality - g_Textures_textureQuality.m_value; - int target_width = min_int(gl_width >> quality_reduction, max_tex_size); - int target_height = min_int(gl_height >> quality_reduction, max_tex_size); - - while (gl_width > target_width || gl_height > target_height) { - GL_MipReduce(outpixels, outpixels, gl_width, gl_height, target_width, target_height); - - if (gl_width > target_width) { - gl_width >>= 1; - } - if (gl_height > target_height) { - gl_height >>= 1; - } - } - - int mip = 0; - glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, outpixels); - while (gl_width > 1 || gl_height > 1) { - GL_MipReduce(outpixels, outpixels, gl_width, gl_height, 1, 1); - - if (gl_width > 1) { - gl_width >>= 1; - } - if (gl_height > 1) { - gl_height >>= 1; - } - - glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, outpixels); - } - - glBindTexture(GL_TEXTURE_2D, 0); - if (resampled) { - free(outpixels); - } -} - -#if 0 -/* - ============== - Texture_InitPalette - ============== - */ -void Texture_InitPalette( byte *pal ){ - int r,g,b; - int i; - int inf; - byte gammatable[256]; - float gamma; - - gamma = g_texture_globals.fGamma; - - if ( gamma == 1.0 ) { - for ( i = 0; i < 256; i++ ) - gammatable[i] = i; - } - else - { - for ( i = 0; i < 256; i++ ) - { - inf = (int)( 255 * pow( ( i + 0.5 ) / 255.5, gamma ) + 0.5 ); - if ( inf < 0 ) { - inf = 0; - } - if ( inf > 255 ) { - inf = 255; - } - gammatable[i] = inf; - } - } - - for ( i = 0; i < 256; i++ ) - { - r = gammatable[pal[0]]; - g = gammatable[pal[1]]; - b = gammatable[pal[2]]; - pal += 3; - - //v = (r<<24) + (g<<16) + (b<<8) + 255; - //v = BigLong (v); - - //tex_palette[i] = v; - tex_palette[i * 3 + 0] = r; - tex_palette[i * 3 + 1] = g; - tex_palette[i * 3 + 2] = b; - } -} -#endif - -#if 0 -class TestHashtable -{ -public: -TestHashtable(){ - HashTable strings; - strings["Monkey"] = "bleh"; - strings["MonkeY"] = "blah"; -} -}; - -const TestHashtable g_testhashtable; - -#endif - -typedef std::pair TextureKey; - -void qtexture_realise(qtexture_t &texture, const TextureKey &key) -{ - texture.texture_number = 0; - if (!string_empty(key.second.c_str())) { - Image *image = key.first.loadImage(key.second.c_str()); - if (image != 0) { - LoadTextureRGBA(&texture, image->getRGBAPixels(), image->getWidth(), image->getHeight()); - texture.surfaceFlags = image->getSurfaceFlags(); - texture.contentFlags = image->getContentFlags(); - texture.value = image->getValue(); - image->release(); - // We only want to report when errors happen - //globalOutputStream() << "Loaded Texture: \"" << key.second.c_str() << "\"\n"; - GlobalOpenGL_debugAssertNoErrors(); - } else { - globalErrorStream() << "Texture load failed: \"" << key.second.c_str() << "\"\n"; - } - } -} - -void qtexture_unrealise(qtexture_t &texture) -{ - if (GlobalOpenGL().contextValid && texture.texture_number != 0) { - glDeleteTextures(1, &texture.texture_number); - GlobalOpenGL_debugAssertNoErrors(); - } -} - -class TextureKeyEqualNoCase { -public: -bool operator()(const TextureKey &key, const TextureKey &other) const -{ - return key.first == other.first && string_equal_nocase(key.second.c_str(), other.second.c_str()); -} -}; - -class TextureKeyHashNoCase { -public: -typedef hash_t hash_type; - -hash_t operator()(const TextureKey &key) const -{ - return hash_combine(string_hash_nocase(key.second.c_str()), pod_hash(key.first)); -} -}; - -#define DEBUG_TEXTURES 0 - -class TexturesMap : public TexturesCache { -class TextureConstructor { -TexturesMap *m_cache; -public: -explicit TextureConstructor(TexturesMap *cache) - : m_cache(cache) -{ -} - -qtexture_t *construct(const TextureKey &key) -{ - qtexture_t *texture = new qtexture_t(key.first, key.second.c_str()); - if (m_cache->realised()) { - qtexture_realise(*texture, key); - } - return texture; -} - -void destroy(qtexture_t *texture) -{ - if (m_cache->realised()) { - qtexture_unrealise(*texture); - } - delete texture; -} -}; - -typedef HashedCache qtextures_t; -qtextures_t m_qtextures; -TexturesCacheObserver *m_observer; -std::size_t m_unrealised; - -public: -virtual ~TexturesMap() = default; - -TexturesMap() : m_qtextures(TextureConstructor(this)), m_observer(0), m_unrealised(1) -{ -} - -typedef qtextures_t::iterator iterator; - -iterator begin() -{ - return m_qtextures.begin(); -} - -iterator end() -{ - return m_qtextures.end(); -} - -LoadImageCallback defaultLoader() const -{ - return LoadImageCallback(0, QERApp_LoadImage); -} - -Image *loadImage(const char *name) -{ - return defaultLoader().loadImage(name); -} - -qtexture_t *capture(const char *name) -{ - return capture(defaultLoader(), name); -} - -qtexture_t *capture(const LoadImageCallback &loader, const char *name) -{ -#if DEBUG_TEXTURES - globalOutputStream() << "textures capture: " << makeQuoted( name ) << '\n'; -#endif - return m_qtextures.capture(TextureKey(loader, name)).get(); -} - -void release(qtexture_t *texture) -{ -#if DEBUG_TEXTURES - globalOutputStream() << "textures release: " << makeQuoted( texture->name ) << '\n'; -#endif - m_qtextures.release(TextureKey(texture->load, texture->name)); -} - -void attach(TexturesCacheObserver &observer) -{ - ASSERT_MESSAGE(m_observer == 0, "TexturesMap::attach: cannot attach observer"); - m_observer = &observer; -} - -void detach(TexturesCacheObserver &observer) -{ - ASSERT_MESSAGE(m_observer == &observer, "TexturesMap::detach: cannot detach observer"); - m_observer = 0; -} - -void realise() -{ - if (--m_unrealised == 0) { - g_texture_globals.bTextureCompressionSupported = false; - - if (GlobalOpenGL().ARB_texture_compression()) { - g_texture_globals.bTextureCompressionSupported = true; - g_texture_globals.m_bOpenGLCompressionSupported = true; - } - - if (GlobalOpenGL().EXT_texture_compression_s3tc()) { - g_texture_globals.bTextureCompressionSupported = true; - g_texture_globals.m_bS3CompressionSupported = true; - } - - switch (g_texture_globals.texture_components) { - case GL_RGBA: - break; - case GL_COMPRESSED_RGBA_ARB: - if (!g_texture_globals.m_bOpenGLCompressionSupported) { - globalOutputStream() - << "OpenGL extension GL_ARB_texture_compression not supported by current graphics drivers\n"; - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (!g_texture_globals.m_bS3CompressionSupported) { - globalOutputStream() - << "OpenGL extension GL_EXT_texture_compression_s3tc not supported by current graphics drivers\n"; - if (g_texture_globals.m_bOpenGLCompressionSupported) { - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_RGBA; - g_texture_globals.texture_components = GL_COMPRESSED_RGBA_ARB; - } else { - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - } - } - break; - default: - globalOutputStream() << "Unknown texture compression selected, reverting\n"; - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - break; - } - - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); - if (max_tex_size == 0) { - max_tex_size = 1024; - } - - for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) { - if (!(*i).value.empty()) { - qtexture_realise(*(*i).value, (*i).key); - } - } - if (m_observer != 0) { - m_observer->realise(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (m_observer != 0) { - m_observer->unrealise(); - } - for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) { - if (!(*i).value.empty()) { - qtexture_unrealise(*(*i).value); - } - } - } -} - -bool realised() -{ - return m_unrealised == 0; -} -}; - -TexturesMap *g_texturesmap; - -TexturesCache &GetTexturesCache() -{ - return *g_texturesmap; -} - - -void Textures_Realise() -{ - g_texturesmap->realise(); -} - -void Textures_Unrealise() -{ - g_texturesmap->unrealise(); -} - - -Callback g_texturesModeChangedNotify; - -void Textures_setModeChangedNotify(const Callback ¬ify) -{ - g_texturesModeChangedNotify = notify; -} - -void Textures_ModeChanged() -{ - if (g_texturesmap->realised()) { - SetTexParameters(g_texture_mode); - - for (TexturesMap::iterator i = g_texturesmap->begin(); i != g_texturesmap->end(); ++i) { - glBindTexture(GL_TEXTURE_2D, (*i).value->texture_number); - SetTexParameters(g_texture_mode); - } - - glBindTexture(GL_TEXTURE_2D, 0); - } - g_texturesModeChangedNotify(); -} - -void Textures_SetMode(ETexturesMode mode) -{ - if (g_texture_mode != mode) { - g_texture_mode = mode; - - Textures_ModeChanged(); - } -} - -void Textures_setTextureComponents(GLint texture_components) -{ - if (g_texture_globals.texture_components != texture_components) { - Textures_Unrealise(); - g_texture_globals.texture_components = texture_components; - Textures_Realise(); - } -} - -void Textures_UpdateTextureCompressionFormat() -{ - GLint texture_components = GL_RGBA; - - switch (g_texture_globals.m_nTextureCompressionFormat) { - case (TEXTURECOMPRESSION_NONE): { - texture_components = GL_RGBA; - break; - } - case (TEXTURECOMPRESSION_RGBA): { - texture_components = GL_COMPRESSED_RGBA_ARB; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT1): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT3): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT5): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - } - } - - Textures_setTextureComponents(texture_components); -} - -struct TextureCompression { - static void Export(const TextureCompressionFormat &self, const Callback &returnz) - { - returnz(self); - } - - static void Import(TextureCompressionFormat &self, int value) - { - if (!g_texture_globals.m_bOpenGLCompressionSupported - && g_texture_globals.m_bS3CompressionSupported - && value >= 1) { - ++value; - } - switch (value) { - case 0: - self = TEXTURECOMPRESSION_NONE; - break; - case 1: - self = TEXTURECOMPRESSION_RGBA; - break; - case 2: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT1; - break; - case 3: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT3; - break; - case 4: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT5; - break; - } - Textures_UpdateTextureCompressionFormat(); - } -}; - -struct TextureGamma { - static void Export(const float &self, const Callback &returnz) - { - returnz(self); - } - - static void Import(float &self, float value) - { - if (value != self) { - Textures_Unrealise(); - self = value; - Textures_Realise(); - } - } -}; - -struct TextureMode { - static void Export(const ETexturesMode &self, const Callback &returnz) - { - switch (self) { - case eTextures_NEAREST: - returnz(0); - break; - case eTextures_NEAREST_MIPMAP_NEAREST: - returnz(1); - break; - case eTextures_LINEAR: - returnz(2); - break; - case eTextures_NEAREST_MIPMAP_LINEAR: - returnz(3); - break; - case eTextures_LINEAR_MIPMAP_NEAREST: - returnz(4); - break; - case eTextures_LINEAR_MIPMAP_LINEAR: - returnz(5); - break; - case eTextures_MAX_ANISOTROPY: - returnz(6); - break; - default: - returnz(4); - } - } - - static void Import(ETexturesMode &self, int value) - { - switch (value) { - case 0: - Textures_SetMode(eTextures_NEAREST); - break; - case 1: - Textures_SetMode(eTextures_NEAREST_MIPMAP_NEAREST); - break; - case 2: - Textures_SetMode(eTextures_LINEAR); - break; - case 3: - Textures_SetMode(eTextures_NEAREST_MIPMAP_LINEAR); - break; - case 4: - Textures_SetMode(eTextures_LINEAR_MIPMAP_NEAREST); - break; - case 5: - Textures_SetMode(eTextures_LINEAR_MIPMAP_LINEAR); - break; - case 6: - Textures_SetMode(eTextures_MAX_ANISOTROPY); - } - } -}; - -void Textures_constructPreferences(PreferencesPage &page) -{ - { - const char *percentages[] = {"12.5%", "25%", "50%", "100%",}; - page.appendRadio( - "Texture Quality", - STRING_ARRAY_RANGE(percentages), - make_property(g_Textures_textureQuality) - ); - } - page.appendSpinner( - "Texture Gamma", - 1.0, - 0.0, - 1.0, - make_property(g_texture_globals.fGamma) - ); - { - const char *texture_mode[] = {"Nearest", "Nearest Mipmap", "Linear", "Bilinear", "Bilinear Mipmap", "Trilinear", - "Anisotropy"}; - page.appendCombo( - "Texture Render Mode", - STRING_ARRAY_RANGE(texture_mode), - make_property(g_texture_mode) - ); - } - { - const char *compression_none[] = {"None"}; - const char *compression_opengl[] = {"None", "OpenGL ARB"}; - const char *compression_s3tc[] = {"None", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"}; - const char *compression_opengl_s3tc[] = {"None", "OpenGL ARB", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"}; - StringArrayRange compression( - (g_texture_globals.m_bOpenGLCompressionSupported) - ? (g_texture_globals.m_bS3CompressionSupported) - ? STRING_ARRAY_RANGE(compression_opengl_s3tc) - : STRING_ARRAY_RANGE(compression_opengl) - : (g_texture_globals.m_bS3CompressionSupported) - ? STRING_ARRAY_RANGE(compression_s3tc) - : STRING_ARRAY_RANGE(compression_none) - ); - page.appendCombo( - "Hardware Texture Compression", - compression, - make_property(g_texture_globals.m_nTextureCompressionFormat) - ); - } -} - -void Textures_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Textures", "Texture Settings")); - Textures_constructPreferences(page); -} - -void Textures_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Textures_constructPage)); -} - -struct TextureCompressionPreference { - static void Export(const Callback &returnz) - { - returnz(g_texture_globals.m_nTextureCompressionFormat); - } - - static void Import(int value) - { - g_texture_globals.m_nTextureCompressionFormat = static_cast( value ); - Textures_UpdateTextureCompressionFormat(); - } -}; - -void Textures_Construct() -{ - g_texturesmap = new TexturesMap; - - GlobalPreferenceSystem().registerPreference("TextureCompressionFormat", - make_property_string()); - GlobalPreferenceSystem().registerPreference("TextureFiltering", - make_property_string(reinterpret_cast( g_texture_mode ))); - GlobalPreferenceSystem().registerPreference("TextureQuality", - make_property_string(g_Textures_textureQuality.m_latched)); - GlobalPreferenceSystem().registerPreference("SI_Gamma", make_property_string(g_texture_globals.fGamma)); - - g_Textures_textureQuality.useLatched(); - - Textures_registerPreferencesPage(); - - Textures_ModeChanged(); -} - -void Textures_Destroy() -{ - delete g_texturesmap; -} - - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class TexturesDependencies : - public GlobalRadiantModuleRef, - public GlobalOpenGLModuleRef, - public GlobalPreferenceSystemModuleRef { -ImageModulesRef m_image_modules; -public: -TexturesDependencies() : - m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")) -{ -} - -ImageModules &getImageModules() -{ - return m_image_modules.get(); -} -}; - -class TexturesAPI { -TexturesCache *m_textures; -public: -typedef TexturesCache Type; - -STRING_CONSTANT(Name, "*"); - -TexturesAPI() -{ - Textures_Construct(); - - m_textures = &GetTexturesCache(); -} - -~TexturesAPI() -{ - Textures_Destroy(); -} - -TexturesCache *getTable() -{ - return m_textures; -} -}; - -typedef SingletonModule TexturesModule; -typedef Static StaticTexturesModule; -StaticRegisterModule staticRegisterTextures(StaticTexturesModule::instance()); - -ImageModules &Textures_getImageModules() -{ - return StaticTexturesModule::instance().getDependencies().getImageModules(); -} diff --git a/src/textures.h b/src/textures.h deleted file mode 100644 index 35f22f3..0000000 --- a/src/textures.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TEXTURES_H ) -#define INCLUDED_TEXTURES_H - -#include "generic/callback.h" - -void Textures_Realise(); - -void Textures_Unrealise(); - -void Textures_sharedContextDestroyed(); - -void Textures_setModeChangedNotify(const Callback ¬ify); - -#endif diff --git a/src/texwindow.cpp b/src/texwindow.cpp deleted file mode 100644 index af0f16a..0000000 --- a/src/texwindow.cpp +++ /dev/null @@ -1,2975 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Texture Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "texwindow.h" - -#include - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "ifilesystem.h" -#include "iundo.h" -#include "igl.h" -#include "iarchive.h" -#include "moduleobserver.h" - -#include -#include -#include - -#include - -#include "signal/signal.h" -#include "math/vector.h" -#include "texturelib.h" -#include "string/string.h" -#include "shaderlib.h" -#include "os/file.h" -#include "os/path.h" -#include "stream/memstream.h" -#include "stream/textfilestream.h" -#include "stream/stringstream.h" -#include "cmdlib.h" -#include "texmanip.h" -#include "textures.h" -#include "convert.h" - -#include "gtkutil/menu.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/cursor.h" -#include "gtkutil/widget.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/messagebox.h" - -#include "error.h" -#include "map.h" -#include "qgl.h" -#include "select.h" -#include "brush_primit.h" -#include "brushmanip.h" -#include "patchmanip.h" -#include "plugin.h" -#include "qe3.h" -#include "gtkdlgs.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "findtexturedialog.h" -#include "surfacedialog.h" -#include "patchdialog.h" -#include "groupdialog.h" -#include "preferences.h" -#include "shaders.h" -#include "commands.h" - -#define NOTEX_BASENAME "notex" -#define SHADERNOTEX_BASENAME "shadernotex" - -bool TextureBrowser_showWads() -{ - return !string_empty(g_pGameDescription->getKeyValue("show_wads")); -} - -void TextureBrowser_queueDraw(TextureBrowser &textureBrowser); - -bool string_equal_start(const char *string, StringRange start) -{ - return string_equal_n(string, start.first, start.last - start.first); -} - -typedef std::set TextureGroups; - -void TextureGroups_addWad(TextureGroups &groups, const char *archive) -{ - if (extension_equal(path_get_extension(archive), "wad")) { -#if 1 - groups.insert(archive); -#else - CopiedString archiveBaseName( path_get_filename_start( archive ), path_get_filename_base_end( archive ) ); - groups.insert( archiveBaseName ); -#endif - } -} - -typedef ReferenceCaller TextureGroupsAddWadCaller; - -namespace { -bool g_TextureBrowser_shaderlistOnly = false; -bool g_TextureBrowser_fixedSize = true; -bool g_TextureBrowser_filterMissing = false; -bool g_TextureBrowser_filterFallback = true; -bool g_TextureBrowser_enableAlpha = true; -} - -CopiedString g_notex; -CopiedString g_shadernotex; - -bool isMissing(const char *name); - -bool isNotex(const char *name); - -bool isMissing(const char *name) -{ - if (string_equal(g_notex.c_str(), name)) { - return true; - } - if (string_equal(g_shadernotex.c_str(), name)) { - return true; - } - return false; -} - -bool isNotex(const char *name) -{ - if (string_equal_suffix(name, "/" NOTEX_BASENAME)) { - return true; - } - if (string_equal_suffix(name, "/" SHADERNOTEX_BASENAME)) { - return true; - } - return false; -} - -void TextureGroups_addShader(TextureGroups &groups, const char *shaderName) -{ - const char *texture = path_make_relative(shaderName, "textures/"); - - // hide notex / shadernotex images - if (g_TextureBrowser_filterFallback) { - if (isNotex(shaderName)) { - return; - } - if (isNotex(texture)) { - return; - } - } - - if (texture != shaderName) { - const char *last = path_remove_directory(texture); - if (!string_empty(last)) { - groups.insert(CopiedString(StringRange(texture, --last))); - } - } -} - -typedef ReferenceCaller TextureGroupsAddShaderCaller; - -void TextureGroups_addDirectory(TextureGroups &groups, const char *directory) -{ - groups.insert(directory); -} - -typedef ReferenceCaller TextureGroupsAddDirectoryCaller; - -class DeferredAdjustment { -gdouble m_value; -guint m_handler; - -typedef void ( *ValueChangedFunction )(void *data, gdouble value); - -ValueChangedFunction m_function; -void *m_data; - -static gboolean deferred_value_changed(gpointer data) -{ - reinterpret_cast( data )->m_function( - reinterpret_cast( data )->m_data, - reinterpret_cast( data )->m_value - ); - reinterpret_cast( data )->m_handler = 0; - reinterpret_cast( data )->m_value = 0; - return FALSE; -} - -public: -DeferredAdjustment(ValueChangedFunction function, void *data) : m_value(0), m_handler(0), m_function(function), - m_data(data) -{ -} - -void flush() -{ - if (m_handler != 0) { - g_source_remove(m_handler); - deferred_value_changed(this); - } -} - -void value_changed(gdouble value) -{ - m_value = value; - if (m_handler == 0) { - m_handler = g_idle_add(deferred_value_changed, this); - } -} - -static void adjustment_value_changed(ui::Adjustment adjustment, DeferredAdjustment *self) -{ - self->value_changed(gtk_adjustment_get_value(adjustment)); -} -}; - - -class TextureBrowser; - -typedef ReferenceCaller TextureBrowserQueueDrawCaller; - -void TextureBrowser_scrollChanged(void *data, gdouble value); - - -enum StartupShaders { - STARTUPSHADERS_NONE = 0, - STARTUPSHADERS_COMMON, -}; - -void TextureBrowser_hideUnusedExport(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport; - -void TextureBrowser_showShadersExport(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport; - -void TextureBrowser_showShaderlistOnly(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport; - -void TextureBrowser_fixedSize(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_fixedSize> TextureBrowserFixedSizeExport; - -void TextureBrowser_filterMissing(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_filterMissing> TextureBrowserFilterMissingExport; - -void TextureBrowser_filterFallback(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_filterFallback> TextureBrowserFilterFallbackExport; - -void TextureBrowser_enableAlpha(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_enableAlpha> TextureBrowserEnableAlphaExport; - -class TextureBrowser { -public: -int width, height; -int originy; -int m_nTotalHeight; - -CopiedString shader; - -ui::Window m_parent{ui::null}; -ui::GLArea m_gl_widget{ui::null}; -ui::Widget m_texture_scroll{ui::null}; -ui::TreeView m_treeViewTree{ui::New}; -ui::TreeView m_treeViewTags{ui::null}; -ui::Frame m_tag_frame{ui::null}; -ui::ListStore m_assigned_store{ui::null}; -ui::ListStore m_available_store{ui::null}; -ui::TreeView m_assigned_tree{ui::null}; -ui::TreeView m_available_tree{ui::null}; -ui::Widget m_scr_win_tree{ui::null}; -ui::Widget m_scr_win_tags{ui::null}; -ui::Widget m_tag_notebook{ui::null}; -ui::Button m_search_button{ui::null}; -ui::Widget m_shader_info_item{ui::null}; - -std::set m_all_tags; -ui::ListStore m_all_tags_list{ui::null}; -std::vector m_copied_tags; -std::set m_found_shaders; - -ToggleItem m_hideunused_item; -ToggleItem m_hidenotex_item; -ToggleItem m_showshaders_item; -ToggleItem m_showshaderlistonly_item; -ToggleItem m_fixedsize_item; -ToggleItem m_filternotex_item; -ToggleItem m_enablealpha_item; - -guint m_sizeHandler; -guint m_exposeHandler; - -bool m_heightChanged; -bool m_originInvalid; - -DeferredAdjustment m_scrollAdjustment; -FreezePointer m_freezePointer; - -Vector3 color_textureback; -// the increment step we use against the wheel mouse -std::size_t m_mouseWheelScrollIncrement; -std::size_t m_textureScale; -// make the texture increments match the grid changes -bool m_showShaders; -bool m_showTextureScrollbar; -StartupShaders m_startupShaders; -// if true, the texture window will only display in-use shaders -// if false, all the shaders in memory are displayed -bool m_hideUnused; -bool m_rmbSelected; -bool m_searchedTags; -bool m_tags; -// The uniform size (in pixels) that textures are resized to when m_resizeTextures is true. -int m_uniformTextureSize; - -// Return the display width of a texture in the texture browser -int getTextureWidth(qtexture_t *tex) -{ - int width; - if (!g_TextureBrowser_fixedSize) { - // Don't use uniform size - width = (int) (tex->width * ((float) m_textureScale / 100)); - } else if - (tex->width >= tex->height) { - // Texture is square, or wider than it is tall - width = m_uniformTextureSize; - } else { - // Otherwise, preserve the texture's aspect ratio - width = (int) (m_uniformTextureSize * ((float) tex->width / tex->height)); - } - return width; -} - -// Return the display height of a texture in the texture browser -int getTextureHeight(qtexture_t *tex) -{ - int height; - if (!g_TextureBrowser_fixedSize) { - // Don't use uniform size - height = (int) (tex->height * ((float) m_textureScale / 100)); - } else if (tex->height >= tex->width) { - // Texture is square, or taller than it is wide - height = m_uniformTextureSize; - } else { - // Otherwise, preserve the texture's aspect ratio - height = (int) (m_uniformTextureSize * ((float) tex->height / tex->width)); - } - return height; -} - -TextureBrowser() : - m_texture_scroll(ui::null), - m_hideunused_item(TextureBrowserHideUnusedExport()), - m_hidenotex_item(TextureBrowserFilterFallbackExport()), - m_showshaders_item(TextureBrowserShowShadersExport()), - m_showshaderlistonly_item(TextureBrowserShowShaderlistOnlyExport()), - m_fixedsize_item(TextureBrowserFixedSizeExport()), - m_filternotex_item(TextureBrowserFilterMissingExport()), - m_enablealpha_item(TextureBrowserEnableAlphaExport()), - m_heightChanged(true), - m_originInvalid(true), - m_scrollAdjustment(TextureBrowser_scrollChanged, this), - color_textureback(0.25f, 0.25f, 0.25f), - m_mouseWheelScrollIncrement(64), - m_textureScale(50), - m_showShaders(true), - m_showTextureScrollbar(true), - m_startupShaders(STARTUPSHADERS_NONE), - m_hideUnused(false), - m_rmbSelected(false), - m_searchedTags(false), - m_tags(false), - m_uniformTextureSize(96) -{ -} -}; - -void ( *TextureBrowser_textureSelected )(const char *shader); - - -void TextureBrowser_updateScroll(TextureBrowser &textureBrowser); - - -const char *TextureBrowser_getComonShadersName() -{ - const char *value = g_pGameDescription->getKeyValue("common_shaders_name"); - if (!string_empty(value)) { - return value; - } - return "Common"; -} - -const char *TextureBrowser_getComonShadersDir() -{ - const char *value = g_pGameDescription->getKeyValue("common_shaders_dir"); - if (!string_empty(value)) { - return value; - } - return "common/"; -} - -inline int TextureBrowser_fontHeight(TextureBrowser &textureBrowser) -{ - return GlobalOpenGL().m_font->getPixelHeight(); -} - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrowser) -{ - return textureBrowser.shader.c_str(); -} - -void TextureBrowser_SetStatus(TextureBrowser &textureBrowser, const char *name) -{ - IShader *shader = QERApp_Shader_ForName(name); - qtexture_t *q = shader->getTexture(); - StringOutputStream strTex(256); - strTex << name << " W: " << Unsigned(q->width) << " H: " << Unsigned(q->height); - shader->DecRef(); - g_pParentWnd->SetStatusText(g_pParentWnd->m_texture_status, strTex.c_str()); -} - -void TextureBrowser_Focus(TextureBrowser &textureBrowser, const char *name); - -void TextureBrowser_SetSelectedShader(TextureBrowser &textureBrowser, const char *shader) -{ - textureBrowser.shader = shader; - TextureBrowser_SetStatus(textureBrowser, shader); - TextureBrowser_Focus(textureBrowser, shader); - - if (FindTextureDialog_isOpen()) { - FindTextureDialog_selectTexture(shader); - } - - // disable the menu item "shader info" if no shader was selected - IShader *ishader = QERApp_Shader_ForName(shader); - CopiedString filename = ishader->getShaderFileName(); - - if (filename.empty()) { - if (textureBrowser.m_shader_info_item != NULL) { - gtk_widget_set_sensitive(textureBrowser.m_shader_info_item, FALSE); - } - } else { - gtk_widget_set_sensitive(textureBrowser.m_shader_info_item, TRUE); - } - - ishader->DecRef(); -} - - -CopiedString g_TextureBrowser_currentDirectory; - -/* - ============================================================================ - - TEXTURE LAYOUT - - TTimo: now based on a rundown through all the shaders - NOTE: we expect the Active shaders count doesn't change during a Texture_StartPos .. Texture_NextPos cycle - otherwise we may need to rely on a list instead of an array storage - ============================================================================ - */ - -class TextureLayout { -public: -// texture layout functions -// TTimo: now based on shaders -int current_x, current_y, current_row; -}; - -void Texture_StartPos(TextureLayout &layout) -{ - layout.current_x = 8; - layout.current_y = -8; - layout.current_row = 0; -} - -void Texture_NextPos(TextureBrowser &textureBrowser, TextureLayout &layout, qtexture_t *current_texture, int *x, int *y) -{ - qtexture_t *q = current_texture; - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - if (layout.current_x + nWidth > textureBrowser.width - 8 && - layout.current_row) { // go to the next row unless the texture is the first on the row - layout.current_x = 8; - layout.current_y -= layout.current_row + TextureBrowser_fontHeight(textureBrowser) + 4; - layout.current_row = 0; - } - - *x = layout.current_x; - *y = layout.current_y; - - // Is our texture larger than the row? If so, grow the - // row height to match it - - if (layout.current_row < nHeight) { - layout.current_row = nHeight; - } - - // never go less than 96, or the names get all crunched up - layout.current_x += nWidth < 96 ? 96 : nWidth; - layout.current_x += 8; -} - -bool TextureSearch_IsShown(const char *name) -{ - std::set::iterator iter; - - iter = GlobalTextureBrowser().m_found_shaders.find(name); - - if (iter == GlobalTextureBrowser().m_found_shaders.end()) { - return false; - } else { - return true; - } -} - -// if texture_showinuse jump over non in-use textures -bool Texture_IsShown(IShader *shader, bool show_shaders, bool hideUnused) -{ - // filter missing shaders - // ugly: filter on built-in fallback name after substitution - if (g_TextureBrowser_filterMissing) { - if (isMissing(shader->getTexture()->name)) { - return false; - } - } - // filter the fallback (notex/shadernotex) for missing shaders or editor image - if (g_TextureBrowser_filterFallback) { - if (isNotex(shader->getName())) { - return false; - } - if (isNotex(shader->getTexture()->name)) { - return false; - } - } - - if (g_TextureBrowser_currentDirectory == "Untagged") { - std::set::iterator iter; - - iter = GlobalTextureBrowser().m_found_shaders.find(shader->getName()); - - if (iter == GlobalTextureBrowser().m_found_shaders.end()) { - return false; - } else { - return true; - } - } - - if (!shader_equal_prefix(shader->getName(), "textures/")) { - return false; - } - - if (!show_shaders && !shader->IsDefault()) { - return false; - } - - if (hideUnused && !shader->IsInUse()) { - return false; - } - - if (GlobalTextureBrowser().m_searchedTags) { - if (!TextureSearch_IsShown(shader->getName())) { - return false; - } else { - return true; - } - } else { - if (!shader_equal_prefix(shader_get_textureName(shader->getName()), - g_TextureBrowser_currentDirectory.c_str())) { - return false; - } - } - - return true; -} - -void TextureBrowser_heightChanged(TextureBrowser &textureBrowser) -{ - textureBrowser.m_heightChanged = true; - - TextureBrowser_updateScroll(textureBrowser); - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_evaluateHeight(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_heightChanged) { - textureBrowser.m_heightChanged = false; - - textureBrowser.m_nTotalHeight = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - textureBrowser.m_nTotalHeight = std::max(textureBrowser.m_nTotalHeight, - abs(layout.current_y) + TextureBrowser_fontHeight(textureBrowser) + - textureBrowser.getTextureHeight(shader->getTexture()) + 4); - } - } -} - -int TextureBrowser_TotalHeight(TextureBrowser &textureBrowser) -{ - TextureBrowser_evaluateHeight(textureBrowser); - return textureBrowser.m_nTotalHeight; -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -void TextureBrowser_clampOriginY(TextureBrowser &textureBrowser) -{ - if (textureBrowser.originy > 0) { - textureBrowser.originy = 0; - } - int lower = min_int(textureBrowser.height - TextureBrowser_TotalHeight(textureBrowser), 0); - if (textureBrowser.originy < lower) { - textureBrowser.originy = lower; - } -} - -int TextureBrowser_getOriginY(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_originInvalid) { - textureBrowser.m_originInvalid = false; - TextureBrowser_clampOriginY(textureBrowser); - TextureBrowser_updateScroll(textureBrowser); - } - return textureBrowser.originy; -} - -void TextureBrowser_setOriginY(TextureBrowser &textureBrowser, int originy) -{ - textureBrowser.originy = originy; - TextureBrowser_clampOriginY(textureBrowser); - TextureBrowser_updateScroll(textureBrowser); - TextureBrowser_queueDraw(textureBrowser); -} - - -Signal0 g_activeShadersChangedCallbacks; - -void TextureBrowser_addActiveShadersChangedCallback(const SignalHandler &handler) -{ - g_activeShadersChangedCallbacks.connectLast(handler); -} - -void TextureBrowser_constructTreeStore(); - -class ShadersObserver : public ModuleObserver { -Signal0 m_realiseCallbacks; -public: -void realise() -{ - m_realiseCallbacks(); - TextureBrowser_constructTreeStore(); -} - -void unrealise() -{ -} - -void insert(const SignalHandler &handler) -{ - m_realiseCallbacks.connectLast(handler); -} -}; - -namespace { -ShadersObserver g_ShadersObserver; -} - -void TextureBrowser_addShadersRealiseCallback(const SignalHandler &handler) -{ - g_ShadersObserver.insert(handler); -} - -void TextureBrowser_activeShadersChanged(TextureBrowser &textureBrowser) -{ - TextureBrowser_heightChanged(textureBrowser); - textureBrowser.m_originInvalid = true; - - g_activeShadersChangedCallbacks(); -} - -struct TextureBrowser_ShowScrollbar { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - returnz(self.m_showTextureScrollbar); - } - - static void Import(TextureBrowser &self, bool value) - { - self.m_showTextureScrollbar = value; - if (self.m_texture_scroll) { - self.m_texture_scroll.visible(self.m_showTextureScrollbar); - TextureBrowser_updateScroll(self); - } - } -}; - - -/* - ============== - TextureBrowser_ShowDirectory - relies on texture_directory global for the directory to use - 1) Load the shaders for the given directory - 2) Scan the remaining texture, load them and assign them a default shader (the "noshader" shader) - NOTE: when writing a texture plugin, or some texture extensions, this function may need to be overriden, and made - available through the IShaders interface - NOTE: for texture window layout: - all shaders are stored with alphabetical order after load - previously loaded and displayed stuff is hidden, only in-use and newly loaded is shown - ( the GL textures are not flushed though) - ============== - */ - -bool endswith(const char *haystack, const char *needle) -{ - size_t lh = strlen(haystack); - size_t ln = strlen(needle); - if (lh < ln) { - return false; - } - return !memcmp(haystack + (lh - ln), needle, ln); -} - -bool texture_name_ignore(const char *name) -{ - StringOutputStream strTemp(string_length(name)); - strTemp << LowerCase(name); - - return - endswith(strTemp.c_str(), ".specular") || - endswith(strTemp.c_str(), ".glow") || - endswith(strTemp.c_str(), ".bump") || - endswith(strTemp.c_str(), ".diffuse") || - endswith(strTemp.c_str(), ".blend") || - endswith(strTemp.c_str(), ".alpha") || - endswith(strTemp.c_str(), "_alpha") || - /* Quetoo */ - endswith(strTemp.c_str(), "_h") || - endswith(strTemp.c_str(), "_local") || - endswith(strTemp.c_str(), "_nm") || - endswith(strTemp.c_str(), "_s") || - /* DarkPlaces */ - endswith(strTemp.c_str(), "_bump") || - endswith(strTemp.c_str(), "_glow") || - endswith(strTemp.c_str(), "_gloss") || - endswith(strTemp.c_str(), "_luma") || - endswith(strTemp.c_str(), "_norm") || - endswith(strTemp.c_str(), "_pants") || - endswith(strTemp.c_str(), "_shirt") || - endswith(strTemp.c_str(), "_reflect") || - /* Unvanquished */ - endswith(strTemp.c_str(), "_d") || - endswith(strTemp.c_str(), "_n") || - endswith(strTemp.c_str(), "_p") || - endswith(strTemp.c_str(), "_g") || - endswith(strTemp.c_str(), "_a") || - 0; -} - -class LoadShaderVisitor : public Archive::Visitor { -public: -void visit(const char *name) -{ - IShader *shader = QERApp_Shader_ForName( - CopiedString(StringRange(name, path_get_filename_base_end(name))).c_str()); - shader->DecRef(); -} -}; - -void TextureBrowser_SetHideUnused(TextureBrowser &textureBrowser, bool hideUnused); - -ui::Widget g_page_textures{ui::null}; - -void TextureBrowser_toggleShow() -{ - GroupDialog_showPage(g_page_textures); -} - - -void TextureBrowser_updateTitle() -{ - GroupDialog_updatePageTitle(g_page_textures); -} - - -class TextureCategoryLoadShader { -const char *m_directory; -std::size_t &m_count; -public: -using func = void (const char *); - -TextureCategoryLoadShader(const char *directory, std::size_t &count) - : m_directory(directory), m_count(count) -{ - m_count = 0; -} - -void operator()(const char *name) const -{ - if (shader_equal_prefix(name, "textures/") - && shader_equal_prefix(name + string_length("textures/"), m_directory)) { - ++m_count; - // request the shader, this will load the texture if needed - // this Shader_ForName call is a kind of hack - IShader *pFoo = QERApp_Shader_ForName(name); - pFoo->DecRef(); - } -} -}; - -void TextureDirectory_loadTexture(const char *directory, const char *texture) -{ - StringOutputStream name(256); - name << directory << StringRange(texture, path_get_filename_base_end(texture)); - - if (texture_name_ignore(name.c_str())) { - return; - } - - if (!shader_valid(name.c_str())) { - globalOutputStream() << "Skipping invalid texture name: [" << name.c_str() << "]\n"; - return; - } - - // if a texture is already in use to represent a shader, ignore it - IShader *shader = QERApp_Shader_ForName(name.c_str()); - shader->DecRef(); -} - -typedef ConstPointerCaller TextureDirectoryLoadTextureCaller; - -class LoadTexturesByTypeVisitor : public ImageModules::Visitor { -const char *m_dirstring; -public: -LoadTexturesByTypeVisitor(const char *dirstring) - : m_dirstring(dirstring) -{ -} - -void visit(const char *minor, const _QERPlugImageTable &table) const -{ - GlobalFileSystem().forEachFile(m_dirstring, minor, TextureDirectoryLoadTextureCaller(m_dirstring)); -} -}; - -void TextureBrowser_ShowDirectory(TextureBrowser &textureBrowser, const char *directory) -{ - if (TextureBrowser_showWads()) { - Archive *archive = GlobalFileSystem().getArchive(directory); - ASSERT_NOTNULL(archive); - LoadShaderVisitor visitor; - archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eFiles, 0), "textures/"); - } else { - g_TextureBrowser_currentDirectory = directory; - TextureBrowser_heightChanged(textureBrowser); - - std::size_t shaders_count; - GlobalShaderSystem().foreachShaderName(makeCallback(TextureCategoryLoadShader(directory, shaders_count))); - globalOutputStream() << "Showing " << Unsigned(shaders_count) << " shaders.\n"; - - if (g_pGameDescription->mGameType != "doom3") { - // load remaining texture files - - StringOutputStream dirstring(64); - dirstring << "textures/" << directory; - - Radiant_getImageModules().foreachModule(LoadTexturesByTypeVisitor(dirstring.c_str())); - } - } - - // we'll display the newly loaded textures + all the ones already in use - TextureBrowser_SetHideUnused(textureBrowser, false); - - TextureBrowser_updateTitle(); -} - -void TextureBrowser_ShowTagSearchResult(TextureBrowser &textureBrowser, const char *directory) -{ - g_TextureBrowser_currentDirectory = directory; - TextureBrowser_heightChanged(textureBrowser); - - std::size_t shaders_count; - GlobalShaderSystem().foreachShaderName(makeCallback(TextureCategoryLoadShader(directory, shaders_count))); - globalOutputStream() << "Showing " << Unsigned(shaders_count) << " shaders.\n"; - - if (g_pGameDescription->mGameType != "doom3") { - // load remaining texture files - StringOutputStream dirstring(64); - dirstring << "textures/" << directory; - - { - LoadTexturesByTypeVisitor visitor(dirstring.c_str()); - Radiant_getImageModules().foreachModule(visitor); - } - } - - // we'll display the newly loaded textures + all the ones already in use - TextureBrowser_SetHideUnused(textureBrowser, false); -} - - -bool TextureBrowser_hideUnused(); - -void TextureBrowser_hideUnusedExport(const Callback &importer) -{ - importer(TextureBrowser_hideUnused()); -} - -typedef FreeCaller &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport; - -void TextureBrowser_showShadersExport(const Callback &importer) -{ - importer(GlobalTextureBrowser().m_showShaders); -} - -typedef FreeCaller &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport; - -void TextureBrowser_showShaderlistOnly(const Callback &importer) -{ - importer(g_TextureBrowser_shaderlistOnly); -} - -typedef FreeCaller &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport; - -void TextureBrowser_fixedSize(const Callback &importer) -{ - importer(g_TextureBrowser_fixedSize); -} - -typedef FreeCaller &), TextureBrowser_fixedSize> TextureBrowser_FixedSizeExport; - -void TextureBrowser_filterMissing(const Callback &importer) -{ - importer(g_TextureBrowser_filterMissing); -} - -typedef FreeCaller &), TextureBrowser_filterMissing> TextureBrowser_filterMissingExport; - -void TextureBrowser_filterFallback(const Callback &importer) -{ - importer(g_TextureBrowser_filterFallback); -} - -typedef FreeCaller &), TextureBrowser_filterFallback> TextureBrowser_filterFallbackExport; - -void TextureBrowser_enableAlpha(const Callback &importer) -{ - importer(g_TextureBrowser_enableAlpha); -} - -typedef FreeCaller &), TextureBrowser_enableAlpha> TextureBrowser_enableAlphaExport; - -void TextureBrowser_SetHideUnused(TextureBrowser &textureBrowser, bool hideUnused) -{ - if (hideUnused) { - textureBrowser.m_hideUnused = true; - } else { - textureBrowser.m_hideUnused = false; - } - - textureBrowser.m_hideunused_item.update(); - - TextureBrowser_heightChanged(textureBrowser); - textureBrowser.m_originInvalid = true; -} - -void TextureBrowser_ShowStartupShaders(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_startupShaders == STARTUPSHADERS_COMMON) { - TextureBrowser_ShowDirectory(textureBrowser, TextureBrowser_getComonShadersDir()); - } -} - - -//++timo NOTE: this is a mix of Shader module stuff and texture explorer -// it might need to be split in parts or moved out .. dunno -// scroll origin so the specified texture is completely on screen -// if current texture is not displayed, nothing is changed -void TextureBrowser_Focus(TextureBrowser &textureBrowser, const char *name) -{ - TextureLayout layout; - // scroll origin so the texture is completely on screen - Texture_StartPos(layout); - - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - // we have found when texdef->name and the shader name match - // NOTE: as everywhere else for our comparisons, we are not case sensitive - if (shader_equal(name, shader->getName())) { - int textureHeight = (int) (q->height * ((float) textureBrowser.m_textureScale / 100)) - + 2 * TextureBrowser_fontHeight(textureBrowser); - - int originy = TextureBrowser_getOriginY(textureBrowser); - if (y > originy) { - originy = y; - } - - if (y - textureHeight < originy - textureBrowser.height) { - originy = (y - textureHeight) + textureBrowser.height; - } - - TextureBrowser_setOriginY(textureBrowser, originy); - return; - } - } -} - -IShader *Texture_At(TextureBrowser &textureBrowser, int mx, int my) -{ - my += TextureBrowser_getOriginY(textureBrowser) - textureBrowser.height; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - if (mx > x && mx - x < nWidth - && my < y && y - my < nHeight + TextureBrowser_fontHeight(textureBrowser)) { - return shader; - } - } - - return 0; -} - -/* - ============== - SelectTexture - - By mouse click - ============== - */ -void SelectTexture(TextureBrowser &textureBrowser, int mx, int my, bool bShift) -{ - IShader *shader = Texture_At(textureBrowser, mx, my); - if (shader != 0) { - if (bShift) { - if (shader->IsDefault()) { - globalOutputStream() << "ERROR: " << shader->getName() << " is not a shader, it's a texture.\n"; - } else { - ViewShader(shader->getShaderFileName(), shader->getName()); - } - } else { - TextureBrowser_SetSelectedShader(textureBrowser, shader->getName()); - TextureBrowser_textureSelected(shader->getName()); - - if (!FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected) { - UndoableCommand undo("textureNameSetSelected"); - Select_SetShader(shader->getName()); - } - } - } -} - -/* - ============================================================================ - - MOUSE ACTIONS - - ============================================================================ - */ - -void TextureBrowser_trackingDelta(int x, int y, unsigned int state, void *data) -{ - TextureBrowser &textureBrowser = *reinterpret_cast( data ); - if (y != 0) { - int scale = 1; - - if (state & GDK_SHIFT_MASK) { - scale = 4; - } - - int originy = TextureBrowser_getOriginY(textureBrowser); - originy += y * scale; - TextureBrowser_setOriginY(textureBrowser, originy); - } -} - -void TextureBrowser_Tracking_MouseDown(TextureBrowser &textureBrowser) -{ - textureBrowser.m_freezePointer.freeze_pointer(textureBrowser.m_parent, TextureBrowser_trackingDelta, - &textureBrowser); -} - -void TextureBrowser_Tracking_MouseUp(TextureBrowser &textureBrowser) -{ - textureBrowser.m_freezePointer.unfreeze_pointer(textureBrowser.m_parent); -} - -void TextureBrowser_Selection_MouseDown(TextureBrowser &textureBrowser, guint32 flags, int pointx, int pointy) -{ - SelectTexture(textureBrowser, pointx, textureBrowser.height - 1 - pointy, (flags & GDK_SHIFT_MASK) != 0); -} - -/* - ============================================================================ - - DRAWING - - ============================================================================ - */ - -/* - ============ - Texture_Draw - TTimo: relying on the shaders list to display the textures - we must query all qtexture_t* to manage and display through the IShaders interface - this allows a plugin to completely override the texture system - ============ - */ -void Texture_Draw(TextureBrowser &textureBrowser) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - glClearColor(textureBrowser.color_textureback[0], - textureBrowser.color_textureback[1], - textureBrowser.color_textureback[2], - 0); - glViewport(0, 0, textureBrowser.width, textureBrowser.height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - if (g_TextureBrowser_enableAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - glOrtho(0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100); - glEnable(GL_TEXTURE_2D); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - int last_y = 0, last_height = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - - if (y != last_y) { - last_y = y; - last_height = 0; - } - last_height = std::max(nHeight, last_height); - - // Is this texture visible? - if ((y - nHeight - TextureBrowser_fontHeight(textureBrowser) < originy) - && (y > originy - textureBrowser.height)) { - // borders rules: - // if it's the current texture, draw a thick red line, else: - // shaders have a white border, simple textures don't - // if !texture_showinuse: (some textures displayed may not be in use) - // draw an additional square around with 0.5 1 0.5 color - if (shader_equal(TextureBrowser_GetSelectedShader(textureBrowser), shader->getName())) { - glLineWidth(3); - if (textureBrowser.m_rmbSelected) { - glColor3f(0, 0, 1); - } else { - glColor3f(1, 0, 0); - } - glDisable(GL_TEXTURE_2D); - - glBegin(GL_LINE_LOOP); - glVertex2i(x - 4, y - TextureBrowser_fontHeight(textureBrowser) + 4); - glVertex2i(x - 4, y - TextureBrowser_fontHeight(textureBrowser) - nHeight - 4); - glVertex2i(x + 4 + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight - 4); - glVertex2i(x + 4 + nWidth, y - TextureBrowser_fontHeight(textureBrowser) + 4); - glEnd(); - - glEnable(GL_TEXTURE_2D); - glLineWidth(1); - } else { - glLineWidth(1); - // shader border: - if (!shader->IsDefault()) { - glColor3f(1, 1, 1); - glDisable(GL_TEXTURE_2D); - - glBegin(GL_LINE_LOOP); - glVertex2i(x - 1, y + 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x - 1, y - nHeight - 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 1 + nWidth, y - nHeight - 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 1 + nWidth, y + 1 - TextureBrowser_fontHeight(textureBrowser)); - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // highlight in-use textures - if (!textureBrowser.m_hideUnused && shader->IsInUse()) { - glColor3f(0.5, 1, 0.5); - glDisable(GL_TEXTURE_2D); - glBegin(GL_LINE_LOOP); - glVertex2i(x - 3, y + 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x - 3, y - nHeight - 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 3 + nWidth, y - nHeight - 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 3 + nWidth, y + 3 - TextureBrowser_fontHeight(textureBrowser)); - glEnd(); - glEnable(GL_TEXTURE_2D); - } - } - - // draw checkerboard for transparent textures - if (g_TextureBrowser_enableAlpha) { - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - int font_height = TextureBrowser_fontHeight(textureBrowser); - for (int i = 0; i < nHeight; i += 8) { - for (int j = 0; j < nWidth; j += 8) { - unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99; - glColor3ub(color, color, color); - int left = j; - int right = std::min(j + 8, nWidth); - int top = i; - int bottom = std::min(i + 8, nHeight); - glVertex2i(x + right, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + bottom); - glVertex2i(x + right, y - nHeight - font_height + bottom); - } - } - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // Draw the texture - glBindTexture(GL_TEXTURE_2D, q->texture_number); - GlobalOpenGL_debugAssertNoErrors(); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 0); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 0); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 1); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glTexCoord2i(0, 1); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glEnd(); - - // draw the texture name - glDisable(GL_TEXTURE_2D); - glColor3f(1, 1, 1); - - glRasterPos2i(x, y - TextureBrowser_fontHeight(textureBrowser) + 5); - - // don't draw the directory name - const char *name = shader->getName(); - name += strlen(name); - while (name != shader->getName() && *(name - 1) != '/' && *(name - 1) != '\\') { - name--; - } - - GlobalOpenGL().drawString(name); - glEnable(GL_TEXTURE_2D); - } - - //int totalHeight = abs(y) + last_height + TextureBrowser_fontHeight(textureBrowser) + 4; - } - - - // reset the current texture - glBindTexture(GL_TEXTURE_2D, 0); - //qglFinish(); -} - - -void Texture_DrawSingle(TextureBrowser &textureBrowser) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - glClearColor(textureBrowser.color_textureback[0], - textureBrowser.color_textureback[1], - textureBrowser.color_textureback[2], - 0); - glViewport(0, 0, textureBrowser.width, textureBrowser.height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - if (g_TextureBrowser_enableAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - glOrtho(0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100); - glEnable(GL_TEXTURE_2D); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - int last_y = 0, last_height = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - - if (!shader_equal(TextureBrowser_GetSelectedShader(textureBrowser), shader->getName())) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - - if (y != last_y) { - last_y = y; - last_height = 0; - } - last_height = std::max(nHeight, last_height); - - // Is this texture visible? - if ((y - nHeight - TextureBrowser_fontHeight(textureBrowser) < originy) - && (y > originy - textureBrowser.height)) { - // borders rules: - // if it's the current texture, draw a thick red line, else: - // shaders have a white border, simple textures don't - // if !texture_showinuse: (some textures displayed may not be in use) - // draw an additional square around with 0.5 1 0.5 color - - glLineWidth(3); - if (textureBrowser.m_rmbSelected) { - glColor3f(0, 0, 1); - } else { - glColor3f(1, 0, 0); - } - glDisable(GL_TEXTURE_2D); - - glBegin(GL_LINE_LOOP); - glVertex2i(x - 4, y - TextureBrowser_fontHeight(textureBrowser) + 4); - glVertex2i(x - 4, y - TextureBrowser_fontHeight(textureBrowser) - nHeight - 4); - glVertex2i(x + 4 + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight - 4); - glVertex2i(x + 4 + nWidth, y - TextureBrowser_fontHeight(textureBrowser) + 4); - glEnd(); - - glEnable(GL_TEXTURE_2D); - glLineWidth(1); - - // draw checkerboard for transparent textures - if (g_TextureBrowser_enableAlpha) { - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - int font_height = TextureBrowser_fontHeight(textureBrowser); - for (int i = 0; i < nHeight; i += 8) { - for (int j = 0; j < nWidth; j += 8) { - unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99; - glColor3ub(color, color, color); - int left = j; - int right = std::min(j + 8, nWidth); - int top = i; - int bottom = std::min(i + 8, nHeight); - glVertex2i(x + right, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + bottom); - glVertex2i(x + right, y - nHeight - font_height + bottom); - } - } - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // Draw the texture - glBindTexture(GL_TEXTURE_2D, q->texture_number); - GlobalOpenGL_debugAssertNoErrors(); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 0); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 0); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 1); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glTexCoord2i(0, 1); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glEnd(); - - // draw the texture name - glDisable(GL_TEXTURE_2D); - glColor3f(1, 1, 1); - - glRasterPos2i(x, y - TextureBrowser_fontHeight(textureBrowser) + 5); - - // don't draw the directory name - const char *name = shader->getName(); - name += strlen(name); - while (name != shader->getName() && *(name - 1) != '/' && *(name - 1) != '\\') { - name--; - } - - GlobalOpenGL().drawString(name); - glEnable(GL_TEXTURE_2D); - } - - //int totalHeight = abs(y) + last_height + TextureBrowser_fontHeight(textureBrowser) + 4; - } - - - // reset the current texture - glBindTexture(GL_TEXTURE_2D, 0); - //qglFinish(); -} - -void TextureBrowser_queueDraw(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_gl_widget) { - gtk_widget_queue_draw(textureBrowser.m_gl_widget); - } -} - - -void TextureBrowser_setScale(TextureBrowser &textureBrowser, std::size_t scale) -{ - textureBrowser.m_textureScale = scale; - - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_setUniformSize(TextureBrowser &textureBrowser, std::size_t scale) -{ - textureBrowser.m_uniformTextureSize = scale; - - TextureBrowser_queueDraw(textureBrowser); -} - - -void TextureBrowser_MouseWheel(TextureBrowser &textureBrowser, bool bUp) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - if (bUp) { - originy += int(textureBrowser.m_mouseWheelScrollIncrement); - } else { - originy -= int(textureBrowser.m_mouseWheelScrollIncrement); - } - - TextureBrowser_setOriginY(textureBrowser, originy); -} - -XmlTagBuilder TagBuilder; - -enum { - TAG_COLUMN, - N_COLUMNS -}; - -void BuildStoreAssignedTags(ui::ListStore store, const char *shader, TextureBrowser *textureBrowser) -{ - GtkTreeIter iter; - - store.clear(); - - std::vector assigned_tags; - TagBuilder.GetShaderTags(shader, assigned_tags); - - for (size_t i = 0; i < assigned_tags.size(); i++) { - store.append(TAG_COLUMN, assigned_tags[i].c_str()); - } -} - -void BuildStoreAvailableTags(ui::ListStore storeAvailable, - ui::ListStore storeAssigned, - const std::set &allTags, - TextureBrowser *textureBrowser) -{ - GtkTreeIter iterAssigned; - GtkTreeIter iterAvailable; - std::set::const_iterator iterAll; - gchar *tag_assigned; - - storeAvailable.clear(); - - bool row = gtk_tree_model_get_iter_first(storeAssigned, &iterAssigned) != 0; - - if (!row) { // does the shader have tags assigned? - for (iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll) { - storeAvailable.append(TAG_COLUMN, (*iterAll).c_str()); - } - } else { - while (row) // available tags = all tags - assigned tags - { - gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1); - - for (iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll) { - if (strcmp((char *) tag_assigned, (*iterAll).c_str()) != 0) { - storeAvailable.append(TAG_COLUMN, (*iterAll).c_str()); - } else { - row = gtk_tree_model_iter_next(storeAssigned, &iterAssigned) != 0; - - if (row) { - gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1); - } - } - } - } - } -} - -gboolean TextureBrowser_button_press(ui::Widget widget, GdkEventButton *event, TextureBrowser *textureBrowser) -{ - if (event->type == GDK_BUTTON_PRESS) { - if (event->button == 3) { - if (GlobalTextureBrowser().m_tags) { - textureBrowser->m_rmbSelected = true; - TextureBrowser_Selection_MouseDown(*textureBrowser, event->state, static_cast( event->x ), - static_cast( event->y )); - - BuildStoreAssignedTags(textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), - textureBrowser); - BuildStoreAvailableTags(textureBrowser->m_available_store, textureBrowser->m_assigned_store, - textureBrowser->m_all_tags, textureBrowser); - textureBrowser->m_heightChanged = true; - textureBrowser->m_tag_frame.show(); - - ui::process(); - - TextureBrowser_Focus(*textureBrowser, textureBrowser->shader.c_str()); - } else { - TextureBrowser_Tracking_MouseDown(*textureBrowser); - } - } else if (event->button == 1) { - TextureBrowser_Selection_MouseDown(*textureBrowser, event->state, static_cast( event->x ), - static_cast( event->y )); - - if (GlobalTextureBrowser().m_tags) { - textureBrowser->m_rmbSelected = false; - textureBrowser->m_tag_frame.hide(); - } - } - } - return FALSE; -} - -gboolean TextureBrowser_button_release(ui::Widget widget, GdkEventButton *event, TextureBrowser *textureBrowser) -{ - if (event->type == GDK_BUTTON_RELEASE) { - if (event->button == 3) { - if (!GlobalTextureBrowser().m_tags) { - TextureBrowser_Tracking_MouseUp(*textureBrowser); - } - } - } - return FALSE; -} - -gboolean TextureBrowser_motion(ui::Widget widget, GdkEventMotion *event, TextureBrowser *textureBrowser) -{ - return FALSE; -} - -gboolean TextureBrowser_scroll(ui::Widget widget, GdkEventScroll *event, TextureBrowser *textureBrowser) -{ - if (event->direction == GDK_SCROLL_UP) { - TextureBrowser_MouseWheel(*textureBrowser, true); - } else if (event->direction == GDK_SCROLL_DOWN) { - TextureBrowser_MouseWheel(*textureBrowser, false); - } - return FALSE; -} - -void TextureBrowser_scrollChanged(void *data, gdouble value) -{ - //globalOutputStream() << "vertical scroll\n"; - TextureBrowser_setOriginY(*reinterpret_cast( data ), -(int) value); -} - -static void TextureBrowser_verticalScroll(ui::Adjustment adjustment, TextureBrowser *textureBrowser) -{ - textureBrowser->m_scrollAdjustment.value_changed(gtk_adjustment_get_value(adjustment)); -} - -void TextureBrowser_updateScroll(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_showTextureScrollbar) { - int totalHeight = TextureBrowser_TotalHeight(textureBrowser); - - totalHeight = std::max(totalHeight, textureBrowser.height); - - auto vadjustment = gtk_range_get_adjustment(GTK_RANGE(textureBrowser.m_texture_scroll)); - - gtk_adjustment_set_value(vadjustment, -TextureBrowser_getOriginY(textureBrowser)); - gtk_adjustment_set_page_size(vadjustment, textureBrowser.height); - gtk_adjustment_set_page_increment(vadjustment, textureBrowser.height / 2); - gtk_adjustment_set_step_increment(vadjustment, 20); - gtk_adjustment_set_lower(vadjustment, 0); - gtk_adjustment_set_upper(vadjustment, totalHeight); - - g_signal_emit_by_name(G_OBJECT(vadjustment), "changed"); - } -} - -gboolean TextureBrowser_size_allocate(ui::Widget widget, GtkAllocation *allocation, TextureBrowser *textureBrowser) -{ - textureBrowser->width = allocation->width; - textureBrowser->height = allocation->height; - TextureBrowser_heightChanged(*textureBrowser); - textureBrowser->m_originInvalid = true; - TextureBrowser_queueDraw(*textureBrowser); - return FALSE; -} - -gboolean TextureBrowser_expose(ui::Widget widget, GdkEventExpose *event, TextureBrowser *textureBrowser) -{ - if (glwidget_make_current(textureBrowser->m_gl_widget) != FALSE) { - GlobalOpenGL_debugAssertNoErrors(); - TextureBrowser_evaluateHeight(*textureBrowser); - Texture_Draw(*textureBrowser); - GlobalOpenGL_debugAssertNoErrors(); - glwidget_swap_buffers(textureBrowser->m_gl_widget); - } - return FALSE; -} - - -TextureBrowser g_TextureBrowser; - -TextureBrowser &GlobalTextureBrowser() -{ - return g_TextureBrowser; -} - -bool TextureBrowser_hideUnused() -{ - return g_TextureBrowser.m_hideUnused; -} - -void TextureBrowser_ToggleHideUnused() -{ - if (g_TextureBrowser.m_hideUnused) { - TextureBrowser_SetHideUnused(g_TextureBrowser, false); - } else { - TextureBrowser_SetHideUnused(g_TextureBrowser, true); - } -} - -void TextureGroups_constructTreeModel(TextureGroups groups, ui::TreeStore store) -{ - // put the information from the old textures menu into a treeview - GtkTreeIter iter, child; - - TextureGroups::const_iterator i = groups.begin(); - while (i != groups.end()) { - const char *dirName = (*i).c_str(); - const char *firstUnderscore = strchr(dirName, '_'); - StringRange dirRoot(dirName, (firstUnderscore == 0) ? dirName : firstUnderscore + 1); - - TextureGroups::const_iterator next = i; - ++next; - if (firstUnderscore != 0 - && next != groups.end() - && string_equal_start((*next).c_str(), dirRoot)) { - gtk_tree_store_append(store, &iter, NULL); - gtk_tree_store_set(store, &iter, 0, CopiedString(StringRange(dirName, firstUnderscore)).c_str(), -1); - - // keep going... - while (i != groups.end() && string_equal_start((*i).c_str(), dirRoot)) { - gtk_tree_store_append(store, &child, &iter); - gtk_tree_store_set(store, &child, 0, (*i).c_str(), -1); - ++i; - } - } else { - gtk_tree_store_append(store, &iter, NULL); - gtk_tree_store_set(store, &iter, 0, dirName, -1); - ++i; - } - } -} - -TextureGroups TextureGroups_constructTreeView() -{ - TextureGroups groups; - - if (TextureBrowser_showWads()) { - GlobalFileSystem().forEachArchive(TextureGroupsAddWadCaller(groups)); - } else { - // scan texture dirs and pak files only if not restricting to shaderlist - if (g_pGameDescription->mGameType != "doom3" && !g_TextureBrowser_shaderlistOnly) { - GlobalFileSystem().forEachDirectory("textures/", TextureGroupsAddDirectoryCaller(groups)); - } - - GlobalShaderSystem().foreachShaderName(TextureGroupsAddShaderCaller(groups)); - } - - return groups; -} - -void TextureBrowser_constructTreeStore() -{ - TextureGroups groups = TextureGroups_constructTreeView(); - auto store = ui::TreeStore::from(gtk_tree_store_new(1, G_TYPE_STRING)); - TextureGroups_constructTreeModel(groups, store); - - gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTree, store); - - g_object_unref(G_OBJECT(store)); -} - -void TextureBrowser_constructTreeStoreTags() -{ - TextureGroups groups; - auto store = ui::TreeStore::from(gtk_tree_store_new(1, G_TYPE_STRING)); - auto model = g_TextureBrowser.m_all_tags_list; - - gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTags, model); - - g_object_unref(G_OBJECT(store)); -} - -void TreeView_onRowActivated(ui::TreeView treeview, ui::TreePath path, ui::TreeViewColumn col, gpointer userdata) -{ - GtkTreeIter iter; - - auto model = gtk_tree_view_get_model(treeview); - - if (gtk_tree_model_get_iter(model, &iter, path)) { - gchar dirName[1024]; - - gchar *buffer; - gtk_tree_model_get(model, &iter, 0, &buffer, -1); - strcpy(dirName, buffer); - g_free(buffer); - - g_TextureBrowser.m_searchedTags = false; - - if (!TextureBrowser_showWads()) { - strcat(dirName, "/"); - } - - ScopeDisableScreenUpdates disableScreenUpdates(dirName, "Loading Textures"); - TextureBrowser_ShowDirectory(GlobalTextureBrowser(), dirName); - TextureBrowser_queueDraw(GlobalTextureBrowser()); - } -} - -void TextureBrowser_createTreeViewTree() -{ - gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTree, FALSE); - - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTree, FALSE); - g_TextureBrowser.m_treeViewTree.connect("row-activated", (GCallback) TreeView_onRowActivated, NULL); - - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTree, -1, "", renderer, "text", 0, NULL); - - TextureBrowser_constructTreeStore(); -} - -void TextureBrowser_addTag(); - -void TextureBrowser_renameTag(); - -void TextureBrowser_deleteTag(); - -void TextureBrowser_createContextMenu(ui::Widget treeview, GdkEventButton *event) -{ - ui::Widget menu = ui::Menu(ui::New); - - ui::Widget menuitem = ui::MenuItem("Add tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_addTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = ui::MenuItem("Rename tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_renameTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = ui::MenuItem("Delete tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_deleteTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - gtk_widget_show_all(menu); - - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, - gdk_event_get_time((GdkEvent *) event)); -} - -gboolean TreeViewTags_onButtonPressed(ui::TreeView treeview, GdkEventButton *event) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - GtkTreePath *path; - auto selection = gtk_tree_view_get_selection(treeview); - - if (gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, &path, NULL, NULL, NULL)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - gtk_tree_path_free(path); - } - - TextureBrowser_createContextMenu(treeview, event); - return TRUE; - } - return FALSE; -} - -void TextureBrowser_createTreeViewTags() -{ - g_TextureBrowser.m_treeViewTags = ui::TreeView(ui::New); - gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTags, FALSE); - - g_TextureBrowser.m_treeViewTags.connect("button-press-event", (GCallback) TreeViewTags_onButtonPressed, NULL); - - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTags, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTags, -1, "", renderer, "text", 0, NULL); - - TextureBrowser_constructTreeStoreTags(); -} - -ui::MenuItem TextureBrowser_constructViewMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("_View")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_check_menu_item_with_mnemonic(menu, "Hide _Unused", "ShowInUse"); - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - create_check_menu_item_with_mnemonic(menu, "Hide Image Missing", "FilterMissing"); - } - - // hide notex and shadernotex on texture browser: no one wants to apply them - create_check_menu_item_with_mnemonic(menu, "Hide Fallback", "FilterFallback"); - - menu_separator(menu); - - create_menu_item_with_mnemonic(menu, "Show All", "ShowAllTextures"); - - // we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games - if (!string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - g_TextureBrowser.m_showShaders = true; - } else { - create_check_menu_item_with_mnemonic(menu, "Show shaders", "ToggleShowShaders"); - } - - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - create_check_menu_item_with_mnemonic(menu, "Shaders Only", "ToggleShowShaderlistOnly"); - } - if (g_TextureBrowser.m_tags) { - create_menu_item_with_mnemonic(menu, "Show Untagged", "ShowUntagged"); - } - - menu_separator(menu); - create_check_menu_item_with_mnemonic(menu, "Fixed Size", "FixedSize"); - create_check_menu_item_with_mnemonic(menu, "Transparency", "EnableAlpha"); - - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - menu_separator(menu); - g_TextureBrowser.m_shader_info_item = ui::Widget( - create_menu_item_with_mnemonic(menu, "Shader Info", "ShaderInfo")); - gtk_widget_set_sensitive(g_TextureBrowser.m_shader_info_item, FALSE); - } - - - return textures_menu_item; -} - -ui::MenuItem TextureBrowser_constructToolsMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("_Tools")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Flush & Reload Shaders", "RefreshShaders"); - create_menu_item_with_mnemonic(menu, "Find / Replace...", "FindReplaceTextures"); - - return textures_menu_item; -} - -ui::MenuItem TextureBrowser_constructTagsMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("T_ags")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Add tag", "AddTag"); - create_menu_item_with_mnemonic(menu, "Rename tag", "RenameTag"); - create_menu_item_with_mnemonic(menu, "Delete tag", "DeleteTag"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Copy tags from selected", "CopyTag"); - create_menu_item_with_mnemonic(menu, "Paste tags to selected", "PasteTag"); - - return textures_menu_item; -} - -gboolean TextureBrowser_tagMoveHelper(ui::TreeModel model, ui::TreePath path, GtkTreeIter iter, GSList **selected) -{ - g_assert(selected != NULL); - - auto rowref = gtk_tree_row_reference_new(model, path); - - if (rowref != NULL) - *selected = g_slist_append(*selected, rowref); - - return FALSE; -} - -void TextureBrowser_assignTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag_assigned; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_available_store, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, &tag_assigned, -1); - if (!TagBuilder.CheckShaderTag(g_TextureBrowser.shader.c_str())) { - // create a custom shader/texture entry - IShader *ishader = QERApp_Shader_ForName(g_TextureBrowser.shader.c_str()); - CopiedString filename = ishader->getShaderFileName(); - - if (filename.empty()) { - // it's a texture - TagBuilder.AddShaderNode(g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE); - } else { - // it's a shader - TagBuilder.AddShaderNode(g_TextureBrowser.shader.c_str(), CUSTOM, SHADER); - } - ishader->DecRef(); - } - TagBuilder.AddShaderTag(g_TextureBrowser.shader.c_str(), (char *) tag_assigned, TAG); - - gtk_list_store_remove(g_TextureBrowser.m_available_store, &iter); - g_TextureBrowser.m_assigned_store.append(TAG_COLUMN, tag_assigned); - } - } - } - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - // Save changes - TagBuilder.SaveXmlDoc(); - } - g_slist_free(selected); -} - -void TextureBrowser_removeTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_assigned_store, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_assigned_store, &iter, TAG_COLUMN, &tag, -1); - TagBuilder.DeleteShaderTag(g_TextureBrowser.shader.c_str(), tag); - gtk_list_store_remove(g_TextureBrowser.m_assigned_store, &iter); - } - } - } - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - // Update the "available tags list" - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - - // Save changes - TagBuilder.SaveXmlDoc(); - } - g_slist_free(selected); -} - -void TextureBrowser_buildTagList() -{ - g_TextureBrowser.m_all_tags_list.clear(); - - std::set::iterator iter; - - for (iter = g_TextureBrowser.m_all_tags.begin(); iter != g_TextureBrowser.m_all_tags.end(); ++iter) { - g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, (*iter).c_str()); - } -} - -void TextureBrowser_searchTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag; - char buffer[256]; - char tags_searched[256]; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - strcpy(buffer, "/root/*/*[tag='"); - strcpy(tags_searched, "[TAGS] "); - - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_all_tags_list, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iter, TAG_COLUMN, &tag, -1); - - strcat(buffer, tag); - strcat(tags_searched, tag); - if (node != g_slist_last(node)) { - strcat(buffer, "' and tag='"); - strcat(tags_searched, ", "); - } - } - } - } - - strcat(buffer, "']"); - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - g_TextureBrowser.m_found_shaders.clear(); // delete old list - TagBuilder.TagSearch(buffer, g_TextureBrowser.m_found_shaders); - - if (!g_TextureBrowser.m_found_shaders.empty()) { // found something - size_t shaders_found = g_TextureBrowser.m_found_shaders.size(); - - globalOutputStream() << "Found " << (unsigned int) shaders_found << " textures and shaders with " - << tags_searched << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates("Searching...", "Loading Textures"); - - std::set::iterator iter; - - for (iter = g_TextureBrowser.m_found_shaders.begin(); - iter != g_TextureBrowser.m_found_shaders.end(); iter++) { - std::string path = (*iter).c_str(); - size_t pos = path.find_last_of("/", path.size()); - std::string name = path.substr(pos + 1, path.size()); - path = path.substr(0, pos + 1); - TextureDirectory_loadTexture(path.c_str(), name.c_str()); - } - } - g_TextureBrowser.m_searchedTags = true; - g_TextureBrowser_currentDirectory = tags_searched; - - g_TextureBrowser.m_nTotalHeight = 0; - TextureBrowser_setOriginY(g_TextureBrowser, 0); - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); - } - g_slist_free(selected); -} - -void TextureBrowser_toggleSearchButton() -{ - gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook)); - - if (page == 0) { // tag page - gtk_widget_show_all(g_TextureBrowser.m_search_button); - } else { - g_TextureBrowser.m_search_button.hide(); - } -} - -void TextureBrowser_constructTagNotebook() -{ - g_TextureBrowser.m_tag_notebook = ui::Widget::from(gtk_notebook_new()); - ui::Widget labelTags = ui::Label("Tags"); - ui::Widget labelTextures = ui::Label("Textures"); - - gtk_notebook_append_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook), g_TextureBrowser.m_scr_win_tree, - labelTextures); - gtk_notebook_append_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook), g_TextureBrowser.m_scr_win_tags, labelTags); - - g_TextureBrowser.m_tag_notebook.connect("switch-page", G_CALLBACK(TextureBrowser_toggleSearchButton), NULL); - - gtk_widget_show_all(g_TextureBrowser.m_tag_notebook); -} - -void TextureBrowser_constructSearchButton() -{ - auto image = ui::Widget::from(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR)); - g_TextureBrowser.m_search_button = ui::Button(ui::New); - g_TextureBrowser.m_search_button.connect("clicked", G_CALLBACK(TextureBrowser_searchTags), NULL); - gtk_widget_set_tooltip_text(g_TextureBrowser.m_search_button, "Search with selected tags"); - g_TextureBrowser.m_search_button.add(image); -} - -void TextureBrowser_checkTagFile() -{ - const char SHADERTAG_FILE[] = "shadertags.xml"; - CopiedString default_filename, rc_filename; - StringOutputStream stream(256); - - stream << LocalRcPath_get(); - stream << SHADERTAG_FILE; - rc_filename = stream.c_str(); - - if (file_exists(rc_filename.c_str())) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc(rc_filename.c_str()); - - if (g_TextureBrowser.m_tags) { - globalOutputStream() << "Loading tag file " << rc_filename.c_str() << ".\n"; - } - } else { - // load default tagfile - stream.clear(); - stream << g_pGameDescription->mGameToolsPath.c_str(); - stream << SHADERTAG_FILE; - default_filename = stream.c_str(); - - if (file_exists(default_filename.c_str())) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc(default_filename.c_str(), rc_filename.c_str()); - - if (g_TextureBrowser.m_tags) { - globalOutputStream() << "Loading default tag file " << default_filename.c_str() << ".\n"; - } - } else { - globalErrorStream() << "Unable to find default tag file " << default_filename.c_str() - << ". No tag support.\n"; - } - } -} - -void TextureBrowser_SetNotex() -{ - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" NOTEX_BASENAME ".xpm"; - g_notex = name.c_str(); - - name = StringOutputStream(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" SHADERNOTEX_BASENAME " .xpm"; - g_shadernotex = name.c_str(); -} - -ui::Widget TextureBrowser_constructWindow(ui::Window toplevel) -{ - // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider - // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't - // seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing - // for the "once-the-gtk-libs-are-updated-TODO-list" :x - - TextureBrowser_checkTagFile(); - TextureBrowser_SetNotex(); - - GlobalShaderSystem().setActiveShadersChangedNotify( - ReferenceCaller(g_TextureBrowser)); - - g_TextureBrowser.m_parent = toplevel; - - auto table = ui::Table(3, 3, FALSE); - auto vbox = ui::VBox(FALSE, 0); - table.attach(vbox, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL}); - vbox.show(); - - ui::Widget menu_bar{ui::null}; - - { // menu bar - menu_bar = ui::Widget::from(gtk_menu_bar_new()); - auto menu_view = ui::Menu(ui::New); - auto view_item = TextureBrowser_constructViewMenu(menu_view); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), menu_view); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view_item); - - auto menu_tools = ui::Menu(ui::New); - auto tools_item = TextureBrowser_constructToolsMenu(menu_tools); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(tools_item), menu_tools); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tools_item); - - table.attach(menu_bar, {0, 3, 0, 1}, {GTK_FILL, GTK_SHRINK}); - menu_bar.show(); - } - { // Texture TreeView - g_TextureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tree), 0); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree), GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_scr_win_tree.show(); - - TextureBrowser_createTreeViewTree(); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree), - g_TextureBrowser.m_treeViewTree); - g_TextureBrowser.m_treeViewTree.show(); - } - { // gl_widget scrollbar - auto w = ui::Widget::from(gtk_vscrollbar_new(ui::Adjustment(0, 0, 0, 1, 1, 0))); - table.attach(w, {2, 3, 1, 2}, {GTK_SHRINK, GTK_FILL}); - w.show(); - g_TextureBrowser.m_texture_scroll = w; - - auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment(GTK_RANGE(g_TextureBrowser.m_texture_scroll))); - vadjustment.connect("value_changed", G_CALLBACK(TextureBrowser_verticalScroll), &g_TextureBrowser); - - g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar); - } - { // gl_widget - g_TextureBrowser.m_gl_widget = glwidget_new(FALSE); - g_object_ref(g_TextureBrowser.m_gl_widget._handle); - - gtk_widget_set_events(g_TextureBrowser.m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(g_TextureBrowser.m_gl_widget, true); - - table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2}); - g_TextureBrowser.m_gl_widget.show(); - - g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect("size_allocate", - G_CALLBACK(TextureBrowser_size_allocate), - &g_TextureBrowser); - g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render(G_CALLBACK(TextureBrowser_expose), - &g_TextureBrowser); - - g_TextureBrowser.m_gl_widget.connect("button_press_event", G_CALLBACK(TextureBrowser_button_press), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("button_release_event", G_CALLBACK(TextureBrowser_button_release), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("motion_notify_event", G_CALLBACK(TextureBrowser_motion), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("scroll_event", G_CALLBACK(TextureBrowser_scroll), &g_TextureBrowser); - } - - // tag stuff - if (g_TextureBrowser.m_tags) { - { // fill tag GtkListStore - g_TextureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_all_tags_list); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - TagBuilder.GetAllTags(g_TextureBrowser.m_all_tags); - TextureBrowser_buildTagList(); - } - { // tag menu bar - auto menu_tags = ui::Menu(ui::New); - auto tags_item = TextureBrowser_constructTagsMenu(menu_tags); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(tags_item), menu_tags); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tags_item); - } - { // Tag TreeView - g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tags), 0); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags), GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - - TextureBrowser_createTreeViewTags(); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags), - g_TextureBrowser.m_treeViewTags); - g_TextureBrowser.m_treeViewTags.show(); - } - { // Texture/Tag notebook - TextureBrowser_constructTagNotebook(); - vbox.pack_start(g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0); - } - { // Tag search button - TextureBrowser_constructSearchButton(); - vbox.pack_end(g_TextureBrowser.m_search_button, FALSE, FALSE, 0); - } - auto frame_table = ui::Table(3, 3, FALSE); - { // Tag frame - - g_TextureBrowser.m_tag_frame = ui::Frame("Tag assignment"); - gtk_frame_set_label_align(GTK_FRAME(g_TextureBrowser.m_tag_frame), 0.5, 0.5); - gtk_frame_set_shadow_type(GTK_FRAME(g_TextureBrowser.m_tag_frame), GTK_SHADOW_NONE); - - table.attach(g_TextureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK}); - - frame_table.show(); - - g_TextureBrowser.m_tag_frame.add(frame_table); - } - { // assigned tag list - ui::Widget scrolled_win = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_assigned_store); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - auto renderer = ui::CellRendererText(ui::New); - - g_TextureBrowser.m_assigned_tree = ui::TreeView( - ui::TreeModel::from(g_TextureBrowser.m_assigned_store._handle)); - g_TextureBrowser.m_assigned_store.unref(); - g_TextureBrowser.m_assigned_tree.connect("row-activated", (GCallback) TextureBrowser_removeTags, NULL); - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_assigned_tree, FALSE); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}}); - gtk_tree_view_append_column(g_TextureBrowser.m_assigned_tree, column); - g_TextureBrowser.m_assigned_tree.show(); - - scrolled_win.show(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_assigned_tree); - - frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL}); - } - { // available tag list - ui::Widget scrolled_win = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_available_store); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - auto renderer = ui::CellRendererText(ui::New); - - g_TextureBrowser.m_available_tree = ui::TreeView( - ui::TreeModel::from(g_TextureBrowser.m_available_store._handle)); - g_TextureBrowser.m_available_store.unref(); - g_TextureBrowser.m_available_tree.connect("row-activated", (GCallback) TextureBrowser_assignTags, NULL); - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_available_tree, FALSE); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}}); - gtk_tree_view_append_column(g_TextureBrowser.m_available_tree, column); - g_TextureBrowser.m_available_tree.show(); - - scrolled_win.show(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_available_tree); - - frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL}); - } - { // tag arrow buttons - auto m_btn_left = ui::Button(ui::New); - auto m_btn_right = ui::Button(ui::New); - auto m_arrow_left = ui::Widget::from(gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT)); - auto m_arrow_right = ui::Widget::from(gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT)); - m_btn_left.add(m_arrow_left); - m_btn_right.add(m_arrow_right); - - // workaround. the size of the tag frame depends of the requested size of the arrow buttons. - m_arrow_left.dimensions(-1, 68); - m_arrow_right.dimensions(-1, 68); - - frame_table.attach(m_btn_left, {1, 2, 1, 2}, {GTK_SHRINK, GTK_EXPAND}); - frame_table.attach(m_btn_right, {1, 2, 2, 3}, {GTK_SHRINK, GTK_EXPAND}); - - m_btn_left.connect("clicked", G_CALLBACK(TextureBrowser_assignTags), NULL); - m_btn_right.connect("clicked", G_CALLBACK(TextureBrowser_removeTags), NULL); - - m_btn_left.show(); - m_btn_right.show(); - m_arrow_left.show(); - m_arrow_right.show(); - } - { // tag fram labels - ui::Widget m_lbl_assigned = ui::Label("Assigned"); - ui::Widget m_lbl_unassigned = ui::Label("Available"); - - frame_table.attach(m_lbl_assigned, {0, 1, 0, 1}, {GTK_EXPAND, GTK_SHRINK}); - frame_table.attach(m_lbl_unassigned, {2, 3, 0, 1}, {GTK_EXPAND, GTK_SHRINK}); - - m_lbl_assigned.show(); - m_lbl_unassigned.show(); - } - } else { // no tag support, show the texture tree only - vbox.pack_start(g_TextureBrowser.m_scr_win_tree, TRUE, TRUE, 0); - } - - // TODO do we need this? - //gtk_container_set_focus_chain(GTK_CONTAINER(hbox_table), NULL); - - return table; -} - -void TextureBrowser_destroyWindow() -{ - GlobalShaderSystem().setActiveShadersChangedNotify(Callback()); - - g_signal_handler_disconnect(G_OBJECT(g_TextureBrowser.m_gl_widget), g_TextureBrowser.m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(g_TextureBrowser.m_gl_widget), g_TextureBrowser.m_exposeHandler); - - g_TextureBrowser.m_gl_widget.unref(); -} - -const Vector3 &TextureBrowser_getBackgroundColour(TextureBrowser &textureBrowser) -{ - return textureBrowser.color_textureback; -} - -void TextureBrowser_setBackgroundColour(TextureBrowser &textureBrowser, const Vector3 &colour) -{ - textureBrowser.color_textureback = colour; - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_selectionHelper(ui::TreeModel model, ui::TreePath path, GtkTreeIter *iter, GSList **selected) -{ - g_assert(selected != NULL); - - gchar *name; - gtk_tree_model_get(model, iter, TAG_COLUMN, &name, -1); - *selected = g_slist_append(*selected, name); -} - -void TextureBrowser_shaderInfo() -{ - const char *name = TextureBrowser_GetSelectedShader(g_TextureBrowser); - IShader *shader = QERApp_Shader_ForName(name); - - DoShaderInfoDlg(name, shader->getShaderFileName(), "Shader Info"); - - shader->DecRef(); -} - -void TextureBrowser_addTag() -{ - CopiedString tag; - - EMessageBoxReturn result = DoShaderTagDlg(&tag, "Add shader tag"); - - if (result == eIDOK && !tag.empty()) { - GtkTreeIter iter; - g_TextureBrowser.m_all_tags.insert(tag.c_str()); - gtk_list_store_append(g_TextureBrowser.m_available_store, &iter); - gtk_list_store_set(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1); - - // Select the currently added tag in the available list - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - gtk_tree_selection_select_iter(selection, &iter); - - g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, tag.c_str()); - } -} - -void TextureBrowser_renameTag() -{ - /* WORKAROUND: The tag treeview is set to GTK_SELECTION_MULTIPLE. Because - gtk_tree_selection_get_selected() doesn't work with GTK_SELECTION_MULTIPLE, - we need to count the number of selected rows first and use - gtk_tree_selection_selected_foreach() then to go through the list of selected - rows (which always containins a single row). - */ - - GSList *selected = NULL; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_selected_foreach(selection, GtkTreeSelectionForeachFunc(TextureBrowser_selectionHelper), - &selected); - - if (g_slist_length(selected) == 1) { // we only rename a single tag - CopiedString newTag; - EMessageBoxReturn result = DoShaderTagDlg(&newTag, "Rename shader tag"); - - if (result == eIDOK && !newTag.empty()) { - GtkTreeIter iterList; - gchar *rowTag; - gchar *oldTag = (char *) selected->data; - - bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterList) != 0; - - while (row) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, &rowTag, -1); - - if (strcmp(rowTag, oldTag) == 0) { - gtk_list_store_set(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1); - } - row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterList) != 0; - } - - TagBuilder.RenameShaderTag(oldTag, newTag.c_str()); - - g_TextureBrowser.m_all_tags.erase((CopiedString) oldTag); - g_TextureBrowser.m_all_tags.insert(newTag); - - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), - &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - } - } else { - ui::alert(g_TextureBrowser.m_parent, "Select a single tag for renaming."); - } -} - -void TextureBrowser_deleteTag() -{ - GSList *selected = NULL; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_selected_foreach(selection, GtkTreeSelectionForeachFunc(TextureBrowser_selectionHelper), - &selected); - - if (g_slist_length(selected) == 1) { // we only delete a single tag - auto result = ui::alert(g_TextureBrowser.m_parent, "Are you sure you want to delete the selected tag?", - "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question); - - if (result == ui::alert_response::YES) { - GtkTreeIter iterSelected; - gchar *rowTag; - - gchar *tagSelected = (char *) selected->data; - - bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterSelected) != 0; - - while (row) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterSelected, TAG_COLUMN, &rowTag, -1); - - if (strcmp(rowTag, tagSelected) == 0) { - gtk_list_store_remove(g_TextureBrowser.m_all_tags_list, &iterSelected); - break; - } - row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterSelected) != 0; - } - - TagBuilder.DeleteTag(tagSelected); - g_TextureBrowser.m_all_tags.erase((CopiedString) tagSelected); - - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), - &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - } - } else { - ui::alert(g_TextureBrowser.m_parent, "Select a single tag for deletion."); - } -} - -void TextureBrowser_copyTag() -{ - g_TextureBrowser.m_copied_tags.clear(); - TagBuilder.GetShaderTags(g_TextureBrowser.shader.c_str(), g_TextureBrowser.m_copied_tags); -} - -void TextureBrowser_pasteTag() -{ - IShader *ishader = QERApp_Shader_ForName(g_TextureBrowser.shader.c_str()); - CopiedString shader = g_TextureBrowser.shader.c_str(); - - if (!TagBuilder.CheckShaderTag(shader.c_str())) { - CopiedString shaderFile = ishader->getShaderFileName(); - if (shaderFile.empty()) { - // it's a texture - TagBuilder.AddShaderNode(shader.c_str(), CUSTOM, TEXTURE); - } else { - // it's a shader - TagBuilder.AddShaderNode(shader.c_str(), CUSTOM, SHADER); - } - - for (size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i) { - TagBuilder.AddShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG); - } - } else { - for (size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i) { - if (!TagBuilder.CheckShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str())) { - // the tag doesn't exist - let's add it - TagBuilder.AddShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG); - } - } - } - - ishader->DecRef(); - - TagBuilder.SaveXmlDoc(); - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, shader.c_str(), &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); -} - -void TextureBrowser_RefreshShaders() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Shaders"); - GlobalShaderSystem().refresh(); - UpdateAllWindows(); - auto selection = gtk_tree_view_get_selection(GlobalTextureBrowser().m_treeViewTree); - GtkTreeModel *model = NULL; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - gchar dirName[1024]; - - gchar *buffer; - gtk_tree_model_get(model, &iter, 0, &buffer, -1); - strcpy(dirName, buffer); - g_free(buffer); - if (!TextureBrowser_showWads()) { - strcat(dirName, "/"); - } - TextureBrowser_ShowDirectory(GlobalTextureBrowser(), dirName); - TextureBrowser_queueDraw(GlobalTextureBrowser()); - } -} - -void TextureBrowser_ToggleShowShaders() -{ - g_TextureBrowser.m_showShaders ^= 1; - g_TextureBrowser.m_showshaders_item.update(); - TextureBrowser_queueDraw(g_TextureBrowser); -} - -void TextureBrowser_ToggleShowShaderListOnly() -{ - g_TextureBrowser_shaderlistOnly ^= 1; - g_TextureBrowser.m_showshaderlistonly_item.update(); - - TextureBrowser_constructTreeStore(); -} - -void TextureBrowser_showAll() -{ - g_TextureBrowser_currentDirectory = ""; - g_TextureBrowser.m_searchedTags = false; - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); -} - -void TextureBrowser_showUntagged() -{ - auto result = ui::alert(g_TextureBrowser.m_parent, - "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", - "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning); - - if (result == ui::alert_response::YES) { - g_TextureBrowser.m_found_shaders.clear(); - TagBuilder.GetUntagged(g_TextureBrowser.m_found_shaders); - std::set::iterator iter; - - ScopeDisableScreenUpdates disableScreenUpdates("Searching untagged textures...", "Loading Textures"); - - for (iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++) { - std::string path = (*iter).c_str(); - size_t pos = path.find_last_of("/", path.size()); - std::string name = path.substr(pos + 1, path.size()); - path = path.substr(0, pos + 1); - TextureDirectory_loadTexture(path.c_str(), name.c_str()); - globalErrorStream() << path.c_str() << name.c_str() << "\n"; - } - - g_TextureBrowser_currentDirectory = "Untagged"; - TextureBrowser_queueDraw(GlobalTextureBrowser()); - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); - } -} - -void TextureBrowser_FixedSize() -{ - g_TextureBrowser_fixedSize ^= 1; - GlobalTextureBrowser().m_fixedsize_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); -} - -void TextureBrowser_FilterMissing() -{ - g_TextureBrowser_filterMissing ^= 1; - GlobalTextureBrowser().m_filternotex_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); - TextureBrowser_RefreshShaders(); -} - -void TextureBrowser_FilterFallback() -{ - g_TextureBrowser_filterFallback ^= 1; - GlobalTextureBrowser().m_hidenotex_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); - TextureBrowser_RefreshShaders(); -} - -void TextureBrowser_EnableAlpha() -{ - g_TextureBrowser_enableAlpha ^= 1; - GlobalTextureBrowser().m_enablealpha_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); -} - -void TextureBrowser_exportTitle(const Callback &importer) -{ - StringOutputStream buffer(64); - buffer << "Textures: "; - if (!string_empty(g_TextureBrowser_currentDirectory.c_str())) { - buffer << g_TextureBrowser_currentDirectory.c_str(); - } else { - buffer << "all"; - } - importer(buffer.c_str()); -} - -struct TextureScale { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - switch (self.m_textureScale) { - case 10: - returnz(0); - break; - case 25: - returnz(1); - break; - case 50: - returnz(2); - break; - case 100: - returnz(3); - break; - case 200: - returnz(4); - break; - } - } - - static void Import(TextureBrowser &self, int value) - { - switch (value) { - case 0: - TextureBrowser_setScale(self, 10); - break; - case 1: - TextureBrowser_setScale(self, 25); - break; - case 2: - TextureBrowser_setScale(self, 50); - break; - case 3: - TextureBrowser_setScale(self, 100); - break; - case 4: - TextureBrowser_setScale(self, 200); - break; - } - } -}; - -struct UniformTextureSize { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - returnz(g_TextureBrowser.m_uniformTextureSize); - } - - static void Import(TextureBrowser &self, int value) - { - if (value > 16) { - TextureBrowser_setUniformSize(self, value); - } - } -}; - -void TextureBrowser_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "", "Texture scrollbar", - make_property(GlobalTextureBrowser()) - ); - { - const char *texture_scale[] = {"10%", "25%", "50%", "100%", "200%"}; - page.appendCombo( - "Texture Thumbnail Scale", - STRING_ARRAY_RANGE(texture_scale), - make_property(GlobalTextureBrowser()) - ); - } - page.appendSpinner( - "Texture Thumbnail Size", - GlobalTextureBrowser().m_uniformTextureSize, - GlobalTextureBrowser().m_uniformTextureSize, - 16, 8192 - ); - page.appendEntry("Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement); - { - const char *startup_shaders[] = {"None", TextureBrowser_getComonShadersName()}; - page.appendCombo("Load Shaders at Startup", reinterpret_cast( GlobalTextureBrowser().m_startupShaders ), - STRING_ARRAY_RANGE(startup_shaders)); - } -} - -void TextureBrowser_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Texture Browser", "Texture Browser Preferences")); - TextureBrowser_constructPreferences(page); -} - -void TextureBrowser_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(TextureBrowser_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - - -void TextureClipboard_textureSelected(const char *shader); - -void TextureBrowser_Construct() -{ - GlobalCommands_insert("ShaderInfo", makeCallbackF(TextureBrowser_shaderInfo)); - GlobalCommands_insert("ShowUntagged", makeCallbackF(TextureBrowser_showUntagged)); - GlobalCommands_insert("AddTag", makeCallbackF(TextureBrowser_addTag)); - GlobalCommands_insert("RenameTag", makeCallbackF(TextureBrowser_renameTag)); - GlobalCommands_insert("DeleteTag", makeCallbackF(TextureBrowser_deleteTag)); - GlobalCommands_insert("CopyTag", makeCallbackF(TextureBrowser_copyTag)); - GlobalCommands_insert("PasteTag", makeCallbackF(TextureBrowser_pasteTag)); - GlobalCommands_insert("RefreshShaders", makeCallbackF(VFS_Refresh)); - GlobalToggles_insert("ShowInUse", makeCallbackF(TextureBrowser_ToggleHideUnused), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_hideunused_item), Accelerator('U')); - GlobalCommands_insert("ShowAllTextures", makeCallbackF(TextureBrowser_showAll), - Accelerator('A', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("ToggleTextures", makeCallbackF(TextureBrowser_toggleShow), Accelerator('T')); - GlobalToggles_insert("ToggleShowShaders", makeCallbackF(TextureBrowser_ToggleShowShaders), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_showshaders_item)); - GlobalToggles_insert("ToggleShowShaderlistOnly", makeCallbackF(TextureBrowser_ToggleShowShaderListOnly), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_showshaderlistonly_item)); - GlobalToggles_insert("FixedSize", makeCallbackF(TextureBrowser_FixedSize), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_fixedsize_item)); - GlobalToggles_insert("FilterMissing", makeCallbackF(TextureBrowser_FilterMissing), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_filternotex_item)); - GlobalToggles_insert("FilterFallback", makeCallbackF(TextureBrowser_FilterFallback), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_hidenotex_item)); - GlobalToggles_insert("EnableAlpha", makeCallbackF(TextureBrowser_EnableAlpha), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_enablealpha_item)); - - GlobalPreferenceSystem().registerPreference("TextureScale", make_property_string(g_TextureBrowser)); - GlobalPreferenceSystem().registerPreference("UniformTextureSize", - make_property_string(g_TextureBrowser)); - GlobalPreferenceSystem().registerPreference("TextureScrollbar", make_property_string( - GlobalTextureBrowser())); - GlobalPreferenceSystem().registerPreference("ShowShaders", - make_property_string(GlobalTextureBrowser().m_showShaders)); - GlobalPreferenceSystem().registerPreference("ShowShaderlistOnly", - make_property_string(g_TextureBrowser_shaderlistOnly)); - GlobalPreferenceSystem().registerPreference("FixedSize", make_property_string(g_TextureBrowser_fixedSize)); - GlobalPreferenceSystem().registerPreference("FilterMissing", make_property_string(g_TextureBrowser_filterMissing)); - GlobalPreferenceSystem().registerPreference("EnableAlpha", make_property_string(g_TextureBrowser_enableAlpha)); - GlobalPreferenceSystem().registerPreference("LoadShaders", make_property_string( - reinterpret_cast( GlobalTextureBrowser().m_startupShaders ))); - GlobalPreferenceSystem().registerPreference("WheelMouseInc", make_property_string( - GlobalTextureBrowser().m_mouseWheelScrollIncrement)); - GlobalPreferenceSystem().registerPreference("SI_Colors0", - make_property_string(GlobalTextureBrowser().color_textureback)); - - g_TextureBrowser.shader = texdef_name_default(); - - Textures_setModeChangedNotify(ReferenceCaller(g_TextureBrowser)); - - TextureBrowser_registerPreferencesPage(); - - GlobalShaderSystem().attach(g_ShadersObserver); - - TextureBrowser_textureSelected = TextureClipboard_textureSelected; -} - -void TextureBrowser_Destroy() -{ - GlobalShaderSystem().detach(g_ShadersObserver); - - Textures_setModeChangedNotify(Callback()); -} diff --git a/src/texwindow.h b/src/texwindow.h deleted file mode 100644 index 64decd7..0000000 --- a/src/texwindow.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TEXWINDOW_H ) -#define INCLUDED_TEXWINDOW_H - -#include -#include "property.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "xml/xmltextags.h" - -class TextureBrowser; - -TextureBrowser &GlobalTextureBrowser(); - -ui::Widget TextureBrowser_constructWindow(ui::Window toplevel); - -void TextureBrowser_destroyWindow(); - - -void TextureBrowser_ShowDirectory(TextureBrowser &textureBrowser, const char *name); - -void TextureBrowser_ShowStartupShaders(TextureBrowser &textureBrowser); - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrower); - -void TextureBrowser_Construct(); - -void TextureBrowser_Destroy(); - -extern ui::Widget g_page_textures; - -void TextureBrowser_exportTitle(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_exportTitle> TextureBrowserExportTitleCaller; - -const Vector3 &TextureBrowser_getBackgroundColour(TextureBrowser &textureBrowser); - -void TextureBrowser_setBackgroundColour(TextureBrowser &textureBrowser, const Vector3 &colour); - -void TextureBrowser_addActiveShadersChangedCallback(const SignalHandler &handler); - -void TextureBrowser_addShadersRealiseCallback(const SignalHandler &handler); - -void TextureBrowser_RefreshShaders(); - -#endif diff --git a/src/timer.cpp b/src/timer.cpp deleted file mode 100644 index 3971ec6..0000000 --- a/src/timer.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "timer.h" -#include "globaldefs.h" - - -#if GDEF_OS_WINDOWS - -#include - -MillisecondTime MillisecondTime::current(){ - static class Cached - { - LONGLONG m_frequency; - LONGLONG m_base; -public: - Cached(){ - QueryPerformanceFrequency( (LARGE_INTEGER *) &m_frequency ); - QueryPerformanceCounter( (LARGE_INTEGER *) &m_base ); - } - LONGLONG frequency(){ - return m_frequency; - } - LONGLONG base(){ - return m_base; - } - } cached; - - if ( cached.frequency() > 0 ) { - LONGLONG count; - QueryPerformanceCounter( (LARGE_INTEGER *) &count ); - return time_from_ticks( count - cached.base(), cached.frequency() ); - } - else - { -#if 1 - return MillisecondTime(); -#else - return time_from_ticks( timeGetTime(), 1000 ); -#endif - } -} - - - - -#elif GDEF_OS_POSIX - -#include -#include "sys/time.h" - -MillisecondTime MillisecondTime::current() -{ - static class Cached { - time_t m_base; -public: - Cached() - { - time(&m_base); - } - - time_t base() - { - return m_base; - } - } cached; - - timeval time; - gettimeofday(&time, 0); - return MillisecondTime((time.tv_sec - cached.base()) * 1000 + time.tv_usec / 1000); -} - - -#else - -#include - -MillisecondTime MillisecondTime::current(){ - return time_from_ticks( std::clock(), CLOCKS_PER_SEC ); -} - - - -#endif diff --git a/src/timer.h b/src/timer.h deleted file mode 100644 index 3b31405..0000000 --- a/src/timer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TIMER_H ) -#define INCLUDED_TIMER_H - -#if 1 - -const int msec_per_sec = 1000; - -class MillisecondTime { -unsigned int m_milliseconds; -public: -MillisecondTime(unsigned int milliseconds) - : m_milliseconds(milliseconds) -{ -} - -MillisecondTime() -{ -} - -static MillisecondTime current(); - -unsigned int milliseconds_since(const MillisecondTime &other) const -{ - return m_milliseconds - other.m_milliseconds; -} -}; - -template -inline MillisecondTime time_from_ticks(tick_type tick_count, tick_type ticks_per_sec) -{ - return MillisecondTime( - static_cast( tick_count / static_cast( ticks_per_sec / msec_per_sec ))); -} - -#else - -const unsigned int usec_per_sec = 1000000; - -class MillisecondTime -{ -unsigned int m_sec; -unsigned int m_usec; -public: -MillisecondTime( unsigned int sec, unsigned int usec ) - : m_sec( sec ), m_usec( usec ){ -} -MillisecondTime(){ -} -staticMillisecondTime current(); - -unsigned int milliseconds_since( const MillisecondTime& other ) const { - return static_cast( ( m_sec * static_cast( usec_per_sec ) + m_usec ) - - ( other.m_sec * static_cast( usec_per_sec ) + other.m_usec ) ) / 1000; -} -}; - -template -inline MillisecondTime time_from_ticks( tick_type tick_count, tick_type ticks_per_sec ){ - return MillisecondTime( static_cast( tick_count / ticks_per_sec ), - static_cast( ( tick_count % ticks_per_sec ) * ( usec_per_sec / static_cast( ticks_per_sec ) ) ) ); -} - -#endif - -class Timer { -MillisecondTime m_start; - -public: -void start() -{ - m_start = MillisecondTime::current(); -} - -unsigned int elapsed_msec() -{ - return MillisecondTime::current().milliseconds_since(m_start); -} -}; - -#endif diff --git a/tools/vmap/tjunction.c b/src/tjunction.c similarity index 100% rename from tools/vmap/tjunction.c rename to src/tjunction.c diff --git a/tools/vmap/tree.c b/src/tree.c similarity index 100% rename from tools/vmap/tree.c rename to src/tree.c diff --git a/src/treemodel.cpp b/src/treemodel.cpp deleted file mode 100644 index 414a201..0000000 --- a/src/treemodel.cpp +++ /dev/null @@ -1,1488 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "treemodel.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "iscenegraph.h" -#include "nameable.h" - -#include "generic/callback.h" -#include "scenelib.h" -#include "string/string.h" -#include "generic/reference.h" - -inline Nameable *Node_getNameable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -#if 0 - -#include "gtkutil/gtktreestore.h" - -template -inline void gtk_tree_model_get_pointer( ui::TreeModel model, GtkTreeIter* iter, gint column, value_type** pointer ){ - GValue value = GValue_default(); - gtk_tree_model_get_value( model, iter, column, &value ); - *pointer = (value_type*)g_value_get_pointer( &value ); -} - - -typedef GtkTreeStore GraphTreeModel; - -ui::TreeStore graph_tree_model_new( graph_type* graph ){ - return gtk_tree_store_new( 2, G_TYPE_POINTER, G_TYPE_POINTER ); -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - g_object_unref( G_OBJECT( model ) ); -} - - -bool graph_tree_model_subtree_find_node( GraphTreeModel* model, GtkTreeIter* parent, const scene::Node& node, GtkTreeIter* iter ){ - for ( gboolean success = gtk_tree_model_iter_children( model, iter, parent ); - success != FALSE; - success = gtk_tree_model_iter_next( model, iter ) ) - { - scene::Node* current; - gtk_tree_model_get_pointer( model, iter, 0, ¤t ); - if ( current == node ) { - return true; - } - } - return false; -} - -typedef GtkTreeIter DoubleGtkTreeIter[2]; - -bool graph_tree_model_find_top( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - GtkTreeIter parent; - for ( scene::Path::const_iterator i = path.begin(); i != path.end(); ++i ) - { - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &iter ) ) { - return false; - } - parent = iter; - parent_pointer = &parent; - } - return true; -} - -bool graph_tree_model_find_parent( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - ASSERT_MESSAGE( path.size() > 1, "path too short" ); - for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i ) - { - GtkTreeIter child; - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &child ) ) { - return false; - } - iter = child; - parent_pointer = &iter; - } - return true; -} - -void node_attach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->attach( callback ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->detach( callback ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_model_row_changed( const scene::Instance& instance ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, instance.path().top(), -1 ); -} - -void graph_tree_model_row_inserted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter parent; - GtkTreeIter* parent_pointer = NULL; - if ( instance.path().size() != 1 ) { - ASSERT_MESSAGE( graph_tree_model_find_parent( model, instance.path(), parent ), "RUNTIME ERROR" ); - parent_pointer = &parent; - } - - gpointer node = instance.path().top(); - gconstpointer selectable = Instance_getSelectable( instance ); - - GtkTreeIter child; - gtk_tree_store_append( GTK_TREE_STORE( model ), &child, parent_pointer ); - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, node, 1, selectable, -1 ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); - - gtk_tree_store_remove( GTK_TREE_STORE( model ), &child ); -} - -#elif 0 - -const char* node_get_name( scene::Node& node ); - -typedef scene::Node* NodePointer; - -class NodeNameLess -{ -public: -bool operator()( const NodePointer& self, const NodePointer& other ) const { - if ( self == 0 ) { - return true; - } - if ( other == 0 ) { - return false; - } - int result = string_compare( node_get_name( self ), node_get_name( other ) ); - if ( result == 0 ) { - return self < other; - } - return result < 0; -} -}; - -class PathNameLess -{ -public: -bool operator()( const PathConstReference& self, const PathConstReference& other ) const { - return std::lexicographical_compare( self.get().begin(), self.get().end(), other.get().begin(), other.get().end(), NodeNameLess() ); -} -}; - -typedef std::map graph_type; - -struct GraphTreeModel -{ - GObject parent; - - graph_type* graph; -}; - -struct GraphTreeModelClass -{ - GObjectClass parent_class; -}; - -#define GRAPH_TREE_MODEL( p ) ( reinterpret_cast( p ) ) - -static GtkTreeModelFlags graph_tree_model_get_flags( GtkTreeModel* tree_model ){ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns( ui::TreeModel tree_model ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline graph_type::iterator graph_iterator_read_tree_iter( GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); - ASSERT_MESSAGE( iter->stamp == c_stamp, "tree model error" ); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter( graph_type::iterator i, GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); -} - -static GType graph_tree_model_get_column_type( ui::TreeModel tree_model, gint index ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter( ui::TreeModel tree_model, GtkTreeIter* iter, ui::TreePath path ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - gint* indices = gtk_tree_path_get_indices( path ); - gint depth = gtk_tree_path_get_depth( path ); - - g_return_val_if_fail( depth > 0, FALSE ); - - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - - if ( graph.empty() ) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter* parent = 0; - - for ( gint i = 0; i < depth; i++ ) - { - if ( !gtk_tree_model_iter_nth_child( tree_model, iter, parent, indices[i] ) ) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static ui::TreePath graph_tree_model_get_path( ui::TreeModel tree_model, GtkTreeIter* iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - auto path = ui::TreePath(); - - for ( std::size_t depth = ( *i ).first.get().size(); depth != 0; --depth ) - { - std::size_t index = 0; - - while ( i != graph.begin() && ( *i ).first.get().size() >= depth ) - { - --i; - if ( ( *i ).first.get().size() == depth ) { - ++index; - } - } - - gtk_tree_path_prepend_index( path, index ); - } - - return path; -} - - -static void graph_tree_model_get_value( ui::TreeModel tree_model, GtkTreeIter *iter, gint column, GValue *value ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - ASSERT_MESSAGE( column == 0 || column == 1, "tree model error" ); - - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - g_value_init( value, G_TYPE_POINTER ); - - if ( column == 0 ) { - g_value_set_pointer( value, reinterpret_cast( ( *i ).first.get().top() ) ); - } - else{ - g_value_set_pointer( value, reinterpret_cast( Instance_getSelectable( *( *i ).second ) ) ); - } -} - -static gboolean graph_tree_model_iter_next( ui::TreeModel tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size(); - - ++i; - - while ( i != graph.end() && ( *i ).first.get().size() > depth ) - { - ++i; - } - - if ( i == graph.end() || ( *i ).first.get().size() != depth ) { - return FALSE; - } - - graph_iterator_write_tree_iter( i, iter ); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - if ( i != graph.end() && ( *i ).first.get().size() == depth ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child( ui::TreeModel tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size() + 1; - - return ++i != graph.end() && ( *i ).first.get().size() == depth; -} - -static gint graph_tree_model_iter_n_children( ui::TreeModel tree_model, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - gint count = 0; - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - ++count; - ++i; - } - - return count; -} - -static gboolean graph_tree_model_iter_nth_child( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - if ( ( *i ).first.get().size() == depth && n-- == 0 ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - ++i; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *child ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( child ); - std::size_t depth = ( *i ).first.get().size(); - if ( depth == 1 ) { - return FALSE; - } - else - { - do - { - --i; - } - while ( ( *i ).first.get().size() >= depth ); - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } -} - -static GObjectClass *g_parent_class = 0; - -static void graph_tree_model_init( GraphTreeModel *graph_tree_model ){ - graph_tree_model->graph = 0; -} - -static void graph_tree_model_finalize( GObject* object ){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( object ); - - /* must chain up */ - ( *g_parent_class->finalize )( object ); -} - -static void graph_tree_model_class_init( GraphTreeModelClass *class_ ){ - GObjectClass *object_class; - - g_parent_class = (GObjectClass*)g_type_class_peek_parent( class_ ); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init( GtkTreeModelIface *iface ){ - iface->get_flags = graph_tree_model_get_flags; - iface->get_n_columns = graph_tree_model_get_n_columns; - iface->get_column_type = graph_tree_model_get_column_type; - iface->get_iter = graph_tree_model_get_iter; - iface->get_path = graph_tree_model_get_path; - iface->get_value = graph_tree_model_get_value; - iface->iter_next = graph_tree_model_iter_next; - iface->iter_children = graph_tree_model_iter_children; - iface->iter_has_child = graph_tree_model_iter_has_child; - iface->iter_n_children = graph_tree_model_iter_n_children; - iface->iter_nth_child = graph_tree_model_iter_nth_child; - iface->iter_parent = graph_tree_model_iter_parent; -} - -static gboolean graph_tree_model_row_draggable( GtkTreeDragSource *drag_source, ui::TreePath path ){ -#if GDEF_DEBUG - gint depth = gtk_tree_path_get_depth( path ); -#endif - return gtk_tree_path_get_depth( path ) > 1; -} - -static gboolean graph_tree_model_drag_data_delete( GtkTreeDragSource *drag_source, ui::TreePath path ){ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( drag_source, &iter, path ) ) { - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - Path_deleteTop( ( *i ).first ); - return TRUE; - } - else - { - return FALSE; - } -} - -static gboolean graph_tree_model_drag_data_get( GtkTreeDragSource *drag_source, ui::TreePath path, GtkSelectionData *selection_data ){ - if ( gtk_tree_set_row_drag_data( selection_data, drag_source, path ) ) { - return TRUE; - } - else - { - /* FIXME handle text targets at least. */ - } - - return FALSE; -} - -static void graph_tree_model_drag_source_init( GtkTreeDragSourceIface *iface ){ - iface->row_draggable = graph_tree_model_row_draggable; - iface->drag_data_delete = graph_tree_model_drag_data_delete; - iface->drag_data_get = graph_tree_model_drag_data_get; -} - -static gboolean graph_tree_model_drag_data_received( GtkTreeDragDest *drag_dest, ui::TreePath dest, GtkSelectionData *selection_data ){ - auto tree_model = drag_dest; - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) - && src_model == tree_model ) { - /* Copy the given row to a new position */ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( src_model, &iter, src_path ) ) { - int bleh = 0; - } - } - else - { - /* FIXME maybe add some data targets eventually, or handle text - * targets in the simple case. - */ - } - - return FALSE; -} - -static gboolean graph_tree_model_row_drop_possible( GtkTreeDragDest *drag_dest, ui::TreePath dest_path, GtkSelectionData *selection_data ){ - gboolean retval = FALSE; - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) != FALSE ) { - /* can only drag to ourselves */ - if ( src_model == drag_dest ) { - /* Can't drop into ourself. */ - if ( !gtk_tree_path_is_ancestor( src_path, dest_path ) ) { - /* Can't drop if dest_path's parent doesn't exist */ - if ( gtk_tree_path_get_depth( dest_path ) > 1 ) { - auto tmp = gtk_tree_path_copy( dest_path ); - gtk_tree_path_up( tmp ); - - GtkTreeIter iter; - retval = gtk_tree_model_get_iter( drag_dest, &iter, tmp ); - - gtk_tree_path_free( tmp ); - } - } - } - - gtk_tree_path_free( src_path ); - } - - return retval; -} - -static void graph_tree_model_drag_dest_init( GtkTreeDragDestIface *iface ){ - iface->drag_data_received = graph_tree_model_drag_data_received; - iface->row_drop_possible = graph_tree_model_row_drop_possible; -} - -GType graph_tree_model_get_type( void ){ - static GType graph_tree_model_type = 0; - - if ( !graph_tree_model_type ) { - static const GTypeInfo graph_tree_model_info = - { - sizeof( GraphTreeModelClass ), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof( GraphTreeModel ), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_source_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_source_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_dest_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_dest_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static( G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags)0 ); - - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_SOURCE, - &drag_source_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_DEST, - &drag_dest_info ); - } - - return graph_tree_model_type; -} - -GraphTreeModel* graph_tree_model_new(){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( g_object_new( graph_tree_model_get_type(), 0 ) ); - - graph_tree_model->graph = new graph_type; - - return graph_tree_model; -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - delete model->graph; - g_object_unref( G_OBJECT( model ) ); -} - - -class TempNameable : public Nameable -{ -const char* m_name; -public: -TempNameable( const char* name ) : m_name( name ){ -} -const char* name() const { - return m_name; -} -void attach( const NameCallback& callback ){ -} -void detach( const NameCallback& callback ){ -} -}; - -void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - // Reference cannot be bound to dereferenced null pointer in well-defined - // C++ code, and Clang will assume that comparison below always evaluates - // to true, resulting in a segmentation fault. Use a dirty hack to force - // Clang to check those "bad" references for null nonetheless. - volatile intptr_t n = (intptr_t)&node; - - if ( n != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->attach( callback ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 - - if ( n != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->detach( callback ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_model_row_inserted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - auto tree_path = graph_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( tree_path ); - gint* indices = gtk_tree_path_get_indices( tree_path ); - - gtk_tree_model_row_inserted( model, tree_path, &iter ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - auto tree_path = graph_tree_model_get_path( model, &iter ); - - gtk_tree_model_row_deleted( model, tree_path ); - - gtk_tree_path_free( tree_path ); -} - -#include "generic/referencecounted.h" - -void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - if ( string_empty( name ) ) { // hack! - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); - } - else - { - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - } -} - -void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){ - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); -} - -void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){ - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); - - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); -} - -#elif 1 - -class GraphTreeNode; - -void graph_tree_model_row_changed(GraphTreeNode &node); - -class GraphTreeNode { -typedef std::map, GraphTreeNode *> ChildNodes; -ChildNodes m_childnodes; -public: -Reference m_instance; -GraphTreeNode *m_parent; - -typedef ChildNodes::iterator iterator; -typedef ChildNodes::key_type key_type; -typedef ChildNodes::value_type value_type; -typedef ChildNodes::size_type size_type; - -GraphTreeNode(scene::Instance &instance) : m_instance(instance), m_parent(0) -{ - m_instance.get().setChildSelectedChangedCallback(RowChangedCaller(*this)); -} - -~GraphTreeNode() -{ - m_instance.get().setChildSelectedChangedCallback(Callback()); - ASSERT_MESSAGE(empty(), "GraphTreeNode::~GraphTreeNode: memory leak"); -} - -iterator begin() -{ - return m_childnodes.begin(); -} - -iterator end() -{ - return m_childnodes.end(); -} - -size_type size() const -{ - return m_childnodes.size(); -} - -bool empty() const -{ - return m_childnodes.empty(); -} - -iterator insert(const value_type &value) -{ - iterator i = m_childnodes.insert(value).first; - (*i).second->m_parent = this; - return i; -} - -void erase(iterator i) -{ - m_childnodes.erase(i); -} - -iterator find(const key_type &key) -{ - return m_childnodes.find(key); -} - -void swap(GraphTreeNode &other) -{ - std::swap(m_parent, other.m_parent); - std::swap(m_childnodes, other.m_childnodes); - std::swap(m_instance, other.m_instance); -} - -void rowChanged() -{ - graph_tree_model_row_changed(*this); -} - -typedef MemberCaller RowChangedCaller; -}; - -struct GraphTreeModel { - GObject parent; - - GraphTreeNode *m_graph; -}; - -struct GraphTreeModelClass { - GObjectClass parent_class; -}; - -static GtkTreeModelFlags graph_tree_model_get_flags(ui::TreeModel tree_model) -{ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns(ui::TreeModel tree_model) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - //GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline GraphTreeNode::iterator graph_iterator_read_tree_iter(GtkTreeIter *iter) -{ - ASSERT_MESSAGE(iter != 0, "tree model error"); - ASSERT_MESSAGE(iter->user_data != 0, "tree model error"); - ASSERT_MESSAGE(iter->stamp == c_stamp, "tree model error"); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter(GraphTreeNode::iterator i, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(iter != 0, "tree model error"); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE(iter->user_data != 0, "tree model error"); -} - -static GType graph_tree_model_get_column_type(ui::TreeModel tree_model, gint index) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - //GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter(GraphTreeModel *tree_model, GtkTreeIter *iter, ui::TreePath path) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - gint *indices = gtk_tree_path_get_indices(path); - gint depth = gtk_tree_path_get_depth(path); - - g_return_val_if_fail(depth > 0, FALSE); - - GraphTreeNode *graph = tree_model->m_graph; - - if (graph->empty()) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter *parent = 0; - - for (gint i = 0; i < depth; i++) { - if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(tree_model), iter, parent, indices[i])) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static ui::TreePath graph_tree_model_get_path(GraphTreeModel *tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode *graph = tree_model->m_graph; - - auto path = ui::TreePath(ui::New); - - for (GraphTreeNode *node = (*graph_iterator_read_tree_iter(iter)).second; node != graph; node = node->m_parent) { - std::size_t index = 0; - for (GraphTreeNode::iterator i = node->m_parent->begin(); i != node->m_parent->end(); ++i, ++index) { - if ((*i).second == node) { - gtk_tree_path_prepend_index(path, gint(index)); - break; - } - } - ASSERT_MESSAGE(index != node->m_parent->size(), "error resolving tree path"); - } - - return path; -} - - -static void graph_tree_model_get_value(ui::TreeModel tree_model, GtkTreeIter *iter, gint column, GValue *value) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - ASSERT_MESSAGE(column == 0 || column == 1, "tree model error"); - - GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter); - - g_value_init(value, G_TYPE_POINTER); - - if (column == 0) { - g_value_set_pointer(value, reinterpret_cast((*i).first.second )); - } else { - g_value_set_pointer(value, reinterpret_cast( &(*i).second->m_instance.get())); - } -} - -static gboolean graph_tree_model_iter_next(ui::TreeModel tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter); - GraphTreeNode &parent = *(*i).second->m_parent; - - ASSERT_MESSAGE(i != parent.end(), "RUNTIME ERROR"); - - if (++i == parent.end()) { - return FALSE; - } - - graph_iterator_write_tree_iter(i, iter); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - if (!node.empty()) { - graph_iterator_write_tree_iter(node.begin(), iter); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child(ui::TreeModel tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode &node = *(*graph_iterator_read_tree_iter(iter)).second; - return !node.empty(); -} - -static gint graph_tree_model_iter_n_children(GraphTreeModel *tree_model, GtkTreeIter *parent) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - return static_cast( node.size()); -} - -static gboolean -graph_tree_model_iter_nth_child(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - if (static_cast( n ) < node.size()) { - GraphTreeNode::iterator i = node.begin(); - std::advance(i, n); - graph_iterator_write_tree_iter(i, iter); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = *(*graph_iterator_read_tree_iter(child)).second; - if (node.m_parent != tree_model->m_graph) { - GraphTreeNode &parentParent = *node.m_parent->m_parent; - for (GraphTreeNode::iterator i = parentParent.begin(); i != parentParent.end(); ++i) { - if ((*i).second == node.m_parent) { - graph_iterator_write_tree_iter(i, iter); - return TRUE; - } - } - } - return FALSE; -} - -static GObjectClass *g_parent_class = 0; - -namespace { -scene::Node *g_null_node = 0; -} - -class NullInstance : public scene::Instance { -public: -NullInstance() : scene::Instance(scene::Path(makeReference(*g_null_node)), 0, 0, - Static::instance()) -{ -} -}; - -namespace { -NullInstance g_null_instance; -} - -static void graph_tree_model_init(GraphTreeModel *graph_tree_model) -{ - graph_tree_model->m_graph = new GraphTreeNode(g_null_instance); -} - -static void graph_tree_model_finalize(GObject *object) -{ - auto graph_tree_model = reinterpret_cast(object); - - delete graph_tree_model->m_graph; - - /* must chain up */ - (*g_parent_class->finalize)(object); -} - -static void graph_tree_model_class_init(GraphTreeModelClass *class_) -{ - GObjectClass *object_class; - - g_parent_class = (GObjectClass *) g_type_class_peek_parent(class_); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init(GtkTreeModelIface *iface) -{ - iface->get_flags = reinterpret_cast(graph_tree_model_get_flags); - iface->get_n_columns = reinterpret_cast(graph_tree_model_get_n_columns); - iface->get_column_type = reinterpret_cast(graph_tree_model_get_column_type); - iface->get_iter = reinterpret_cast(graph_tree_model_get_iter); - iface->get_path = reinterpret_cast(graph_tree_model_get_path); - iface->get_value = reinterpret_cast(graph_tree_model_get_value); - iface->iter_next = reinterpret_cast(graph_tree_model_iter_next); - iface->iter_children = reinterpret_cast(graph_tree_model_iter_children); - iface->iter_has_child = reinterpret_cast(graph_tree_model_iter_has_child); - iface->iter_n_children = reinterpret_cast(graph_tree_model_iter_n_children); - iface->iter_nth_child = reinterpret_cast(graph_tree_model_iter_nth_child); - iface->iter_parent = reinterpret_cast(graph_tree_model_iter_parent); -} - -GType graph_tree_model_get_type(void) -{ - static GType graph_tree_model_type = 0; - - if (!graph_tree_model_type) { - static const GTypeInfo graph_tree_model_info = - { - sizeof(GraphTreeModelClass), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof(GraphTreeModel), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init, - 0 - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static(G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags) 0); - - g_type_add_interface_static(graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return graph_tree_model_type; -} - -GraphTreeModel *graph_tree_model_new() -{ - auto graph_tree_model = reinterpret_cast(g_object_new(graph_tree_model_get_type(), 0)); - - return graph_tree_model; -} - -void graph_tree_model_delete(GraphTreeModel *model) -{ - g_object_unref(G_OBJECT(model)); -} - -void graph_tree_model_row_changed(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_changed(GTK_TREE_MODEL(model), tree_path, &iter); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_inserted(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), tree_path, &iter); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_deleted(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tree_path); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_inserted(GraphTreeModel &model, GraphTreeNode::iterator i) -{ - graph_tree_model_row_inserted(&model, i); -} - -void graph_tree_model_row_deleted(GraphTreeModel &model, GraphTreeNode::iterator i) -{ - graph_tree_model_row_deleted(&model, i); -} - -const char *node_get_name(scene::Node &node); - -const char *node_get_name_safe(scene::Node &node) -{ - volatile intptr_t n = (intptr_t) &node; // see the comment on line 650 - if (n == 0) { - return ""; - } - return node_get_name(node); -} - -GraphTreeNode *graph_tree_model_find_parent(GraphTreeModel *model, const scene::Path &path) -{ - GraphTreeNode *parent = model->m_graph; - for (scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i) { - GraphTreeNode::iterator child = parent->find( - GraphTreeNode::key_type(node_get_name_safe((*i).get()), (*i).get_pointer())); - ASSERT_MESSAGE(child != parent->end(), "ERROR"); - parent = (*child).second; - } - return parent; -} - -void node_attach_name_changed_callback(scene::Node &node, const NameCallback &callback) -{ - volatile intptr_t n = (intptr_t) &node; // see the comment on line 650 - if (n != 0) { - Nameable *nameable = Node_getNameable(node); - if (nameable != 0) { - nameable->attach(callback); - } - } -} - -void node_detach_name_changed_callback(scene::Node &node, const NameCallback &callback) -{ - volatile intptr_t n = (intptr_t) &node; // see the comment on line 650 - if (n != 0) { - Nameable *nameable = Node_getNameable(node); - if (nameable != 0) { - nameable->detach(callback); - } - } -} - -GraphTreeModel *scene_graph_get_tree_model(); // temp hack - -void graph_tree_node_foreach_pre(GraphTreeNode::iterator root, const Callback &callback) -{ - callback(root); - for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) { - graph_tree_node_foreach_pre(i, callback); - } -} - -void graph_tree_node_foreach_post(GraphTreeNode::iterator root, const Callback &callback) -{ - for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) { - graph_tree_node_foreach_post(i, callback); - } - callback(root); -} - -void graph_tree_model_row_changed(GraphTreeNode &node) -{ - GraphTreeModel *model = scene_graph_get_tree_model(); - const scene::Instance &instance = node.m_instance.get(); - - GraphTreeNode::iterator i = node.m_parent->find( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - - graph_tree_model_row_changed(model, i); -} - -void graph_tree_model_set_name(const scene::Instance &instance, const char *name) -{ - GraphTreeModel *model = scene_graph_get_tree_model(); - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator oldNode = parent->find( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - graph_tree_node_foreach_post(oldNode, ReferenceCaller(*model)); - GraphTreeNode *node((*oldNode).second); - parent->erase(oldNode); - - GraphTreeNode::iterator newNode = parent->insert( - GraphTreeNode::value_type(GraphTreeNode::key_type(name, &instance.path().top().get()), node)); - graph_tree_node_foreach_pre(newNode, ReferenceCaller(*model)); -} - -void graph_tree_model_insert(GraphTreeModel *model, const scene::Instance &instance) -{ - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator i = parent->insert(GraphTreeNode::value_type( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer()), - new GraphTreeNode(const_cast( instance )))); - - graph_tree_model_row_inserted(model, i); - - node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller(instance)); -} - -void graph_tree_model_erase(GraphTreeModel *model, const scene::Instance &instance) -{ - node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller(instance)); - - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator i = parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - - graph_tree_model_row_deleted(model, i); - - GraphTreeNode *node((*i).second); - parent->erase(i); - delete node; -} - - -#endif - - -#if 0 -class TestGraphTreeModel -{ -public: -TestGraphTreeModel(){ - gtk_init( 0, 0 ); - - graph_type graph; - - scene::Node* root = *(scene::Node*)0xa0000000; - scene::Node* node1 = (scene::Node*)0xa0000001; - scene::Node* node2 = (scene::Node*)0xa0000002; - scene::Node* node3 = (scene::Node*)0xa0000003; - scene::Node* node4 = (scene::Node*)0xa0000004; - scene::Instance* instance = (scene::Instance*)0xaaaaaaaa; - - scene::Path rootpath( root ); - - graph.insert( graph_type::value_type( rootpath, instance ) ); - - rootpath.push( node1 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - - rootpath.push( node2 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.push( node3 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.push( node4 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.pop(); - - auto model = graph_tree_model_new( &graph ); - - { - gint n_columns = gtk_tree_model_get_n_columns( model ); - ASSERT_MESSAGE( n_columns == 2, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 0 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 1 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) == FALSE, "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 0, "test failed!" ); - - gtk_tree_model_iter_next( model, &iter ); - - ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) != FALSE, "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 2, "test failed!" ); - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 0 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node3, "test failed!" ); - - { - GtkTreeIter parent; - gtk_tree_model_iter_parent( model, &parent, &child ); - - scene::Node* test; - gtk_tree_model_get_value( model, &parent, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node2, "test failed!" ); - } - } - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 1 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node4, "test failed!" ); - } - } - - { - GtkTreeIter iter; - std::size_t count = 0; - for ( gboolean good = gtk_tree_model_get_iter_first( model, &iter ); good; good = gtk_tree_model_iter_next( model, &iter ) ) - { - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - - ASSERT_MESSAGE( ( count == 0 && test == node1 ) || ( count == 1 && test == node2 ), "test failed!" ); - ++count; - } - - ASSERT_MESSAGE( count == 2, "test failed!" ); - - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - auto path = ui::TreePath( "0" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - auto path = ui::TreePath( "1" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node2, "test failed!" ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - auto path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 0, "test failed!" ); - - gtk_tree_path_free( path ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - auto path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 1, "test failed!" ); - - gtk_tree_path_free( path ); - } -} -}; - - -TestGraphTreeModel g_TestGraphTreeModel; - -#endif diff --git a/src/treemodel.h b/src/treemodel.h deleted file mode 100644 index 80fe224..0000000 --- a/src/treemodel.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TREEMODEL_H ) -#define INCLUDED_TREEMODEL_H - -struct GraphTreeModel; - -GraphTreeModel *graph_tree_model_new(); - -void graph_tree_model_delete(GraphTreeModel *model); - -namespace scene { -class Instance; -} - -void graph_tree_model_insert(GraphTreeModel *model, const scene::Instance &instance); - -void graph_tree_model_erase(GraphTreeModel *model, const scene::Instance &instance); - -#endif diff --git a/src/undo.cpp b/src/undo.cpp deleted file mode 100644 index 364edd2..0000000 --- a/src/undo.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "undo.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "iundo.h" -#include "preferencesystem.h" -#include "string/string.h" -#include "generic/callback.h" -#include "preferences.h" -#include "stringio.h" - -#include -#include -#include - -#include "timer.h" - -void Undo_SetButtonlabel(const char *title); -void Undo_DisableButton(void); - -void Redo_SetButtonlabel(const char *title); -void Redo_DisableButton(void); - -class DebugScopeTimer { -Timer m_timer; -const char *m_operation; -public: -DebugScopeTimer(const char *operation) - : m_operation(operation) -{ - m_timer.start(); -} - -~DebugScopeTimer() -{ - unsigned int elapsed = m_timer.elapsed_msec(); - if (elapsed > 0) { - globalOutputStream() << m_operation << ": " << elapsed << " msec\n"; - } -} -}; - - -class RadiantUndoSystem : public UndoSystem { -UINT_CONSTANT(MAX_UNDO_LEVELS, 1024); - -class Snapshot { -class StateApplicator { -public: -Undoable *m_undoable; -private: -UndoMemento *m_data; -public: - -StateApplicator(Undoable *undoable, UndoMemento *data) - : m_undoable(undoable), m_data(data) -{ -} - -void restore() -{ - m_undoable->importState(m_data); -} - -void release() -{ - m_data->release(); -} -}; - -typedef std::list states_t; -states_t m_states; - -public: -bool empty() const -{ - return m_states.empty(); -} - -std::size_t size() const -{ - return m_states.size(); -} - -void save(Undoable *undoable) -{ - m_states.push_front(StateApplicator(undoable, undoable->exportState())); -} - -void restore() -{ - for (states_t::iterator i = m_states.begin(); i != m_states.end(); ++i) { - (*i).restore(); - } -} - -void release() -{ - for (states_t::iterator i = m_states.begin(); i != m_states.end(); ++i) { - (*i).release(); - } -} -}; - -struct Operation { - Snapshot m_snapshot; - CopiedString m_command; - - Operation(const char *command) - : m_command(command) - { - } - - ~Operation() - { - m_snapshot.release(); - } -}; - - -class UndoStack { -//! Note: using std::list instead of vector/deque, to avoid copying of undos -typedef std::list Operations; - -Operations m_stack; -Operation *m_pending; - -public: -UndoStack() : m_pending(0) -{ -} - -~UndoStack() -{ - clear(); -} - -bool empty() const -{ - return m_stack.empty(); -} - -std::size_t size() const -{ - return m_stack.size(); -} - -Operation *back() -{ - return m_stack.back(); -} - -const Operation *back() const -{ - return m_stack.back(); -} - -Operation *front() -{ - return m_stack.front(); -} - -const Operation *front() const -{ - return m_stack.front(); -} - -void pop_front() -{ - delete m_stack.front(); - m_stack.pop_front(); -} - -void pop_back() -{ - delete m_stack.back(); - m_stack.pop_back(); -} - -void clear() -{ - if (!m_stack.empty()) { - for (Operations::iterator i = m_stack.begin(); i != m_stack.end(); ++i) { - delete *i; - } - m_stack.clear(); - } -} - -void start(const char *command) -{ - if (m_pending != 0) { - delete m_pending; - } - m_pending = new Operation(command); -} - -bool finish(const char *command) -{ - if (m_pending != 0) { - delete m_pending; - m_pending = 0; - return false; - } else { - ASSERT_MESSAGE(!m_stack.empty(), "undo stack empty"); - m_stack.back()->m_command = command; - return true; - } -} - -void save(Undoable *undoable) -{ - if (m_pending != 0) { - m_stack.push_back(m_pending); - m_pending = 0; - } - back()->m_snapshot.save(undoable); -} -}; - -UndoStack m_undo_stack; -UndoStack m_redo_stack; - -class UndoStackFiller : public UndoObserver { -UndoStack *m_stack; -public: - -UndoStackFiller() - : m_stack(0) -{ -} - -void save(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - if (m_stack != 0) { - m_stack->save(undoable); - m_stack = 0; - } -} - -void setStack(UndoStack *stack) -{ - m_stack = stack; -} -}; - -typedef std::map undoables_t; -undoables_t m_undoables; - -void mark_undoables(UndoStack *stack) -{ - for (undoables_t::iterator i = m_undoables.begin(); i != m_undoables.end(); ++i) { - (*i).second.setStack(stack); - } -} - -std::size_t m_undo_levels; - -typedef std::set Trackers; -Trackers m_trackers; -public: -RadiantUndoSystem() - : m_undo_levels(64) -{ -} - -~RadiantUndoSystem() -{ - clear(); -} - -UndoObserver *observer(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - return &m_undoables[undoable]; -} - -void release(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - m_undoables.erase(undoable); -} - -void setLevels(std::size_t levels) -{ - if (levels > MAX_UNDO_LEVELS()) { - levels = MAX_UNDO_LEVELS(); - } - - while (m_undo_stack.size() > levels) { - m_undo_stack.pop_front(); - } - m_undo_levels = levels; -} - -std::size_t getLevels() const -{ - return m_undo_levels; -} - -std::size_t size() const -{ - return m_undo_stack.size(); -} - -void startUndo() -{ - m_undo_stack.start("unnamedCommand"); - mark_undoables(&m_undo_stack); -} - -bool finishUndo(const char *command) -{ - bool changed = m_undo_stack.finish(command); - mark_undoables(0); - return changed; -} - -void startRedo() -{ - m_redo_stack.start("unnamedCommand"); - mark_undoables(&m_redo_stack); -} - -bool finishRedo(const char *command) -{ - bool changed = m_redo_stack.finish(command); - mark_undoables(0); - return changed; -} - -void start() -{ - m_redo_stack.clear(); - if (m_undo_stack.size() == m_undo_levels) { - m_undo_stack.pop_front(); - } - startUndo(); - trackersBegin(); -} - -void finish(const char *command) -{ - if (finishUndo(command)) { - globalOutputStream() << command << '\n'; - Undo_SetButtonlabel(command); - Redo_DisableButton(); - } -} - -void undo() -{ - if (m_undo_stack.empty()) { - globalOutputStream() << "Undo: no undo available\n"; - } else { - Operation *operation = m_undo_stack.back(); - globalOutputStream() << "Undo: " << operation->m_command.c_str() << "\n"; - Redo_SetButtonlabel(operation->m_command.c_str()); - - startRedo(); - trackersUndo(); - operation->m_snapshot.restore(); - finishRedo(operation->m_command.c_str()); - m_undo_stack.pop_back(); - - Operation *operation2 = m_undo_stack.back(); - if (operation2) { - Undo_SetButtonlabel(operation2->m_command.c_str()); - } else - Undo_DisableButton(); - } -} - -void redo() -{ - if (m_redo_stack.empty()) { - globalOutputStream() << "Redo: no redo available\n"; - } else { - Operation *operation = m_redo_stack.back(); - globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n"; - - startUndo(); - trackersRedo(); - operation->m_snapshot.restore(); - finishUndo(operation->m_command.c_str()); - m_redo_stack.pop_back(); - Operation *operationu = m_undo_stack.back(); - Undo_SetButtonlabel(operationu->m_command.c_str()); - - Operation *next = m_redo_stack.back(); - if (!next) - Redo_DisableButton(); - else - Redo_SetButtonlabel(next->m_command.c_str()); - } -} - -void clear() -{ - mark_undoables(0); - m_undo_stack.clear(); - m_redo_stack.clear(); - trackersClear(); -} - -void trackerAttach(UndoTracker &tracker) -{ - ASSERT_MESSAGE(m_trackers.find(&tracker) == m_trackers.end(), "undo tracker already attached"); - m_trackers.insert(&tracker); -} - -void trackerDetach(UndoTracker &tracker) -{ - ASSERT_MESSAGE(m_trackers.find(&tracker) != m_trackers.end(), "undo tracker cannot be detached"); - m_trackers.erase(&tracker); -} - -void trackersClear() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->clear(); - } -} - -void trackersBegin() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->begin(); - } -} - -void trackersUndo() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->undo(); - } -} - -void trackersRedo() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->redo(); - } -} -}; - - -void UndoLevels_importString(RadiantUndoSystem &undo, const char *value) -{ - int levels; - PropertyImpl::Import(levels, value); - undo.setLevels(levels); -} - -typedef ReferenceCaller UndoLevelsImportStringCaller; - -void UndoLevels_exportString(const RadiantUndoSystem &undo, const Callback &importer) -{ - PropertyImpl::Export(static_cast( undo.getLevels()), importer); -} - -typedef ConstReferenceCaller &), UndoLevels_exportString> UndoLevelsExportStringCaller; - -#include "generic/callback.h" - -struct UndoLevels { - static void Export(const RadiantUndoSystem &self, const Callback &returnz) - { - returnz(static_cast(self.getLevels())); - } - - static void Import(RadiantUndoSystem &self, int value) - { - self.setLevels(value); - } -}; - -void Undo_constructPreferences(RadiantUndoSystem &undo, PreferencesPage &page) -{ - page.appendSpinner("Undo Queue Size", 64, 0, 1024, make_property(undo)); -} - -void Undo_constructPage(RadiantUndoSystem &undo, PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Undo", "Undo Queue Settings")); - Undo_constructPreferences(undo, page); -} - -void Undo_registerPreferencesPage(RadiantUndoSystem &undo) -{ - PreferencesDialog_addSettingsPage( - ReferenceCaller(undo)); -} - -class UndoSystemDependencies : public GlobalPreferenceSystemModuleRef { -}; - -class UndoSystemAPI { -RadiantUndoSystem m_undosystem; -public: -typedef UndoSystem Type; - -STRING_CONSTANT(Name, "*"); - -UndoSystemAPI() -{ - GlobalPreferenceSystem().registerPreference("UndoLevels", make_property_string(m_undosystem)); - - Undo_registerPreferencesPage(m_undosystem); -} - -UndoSystem *getTable() -{ - return &m_undosystem; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule UndoSystemModule; -typedef Static StaticUndoSystemModule; -StaticRegisterModule staticRegisterUndoSystem(StaticUndoSystemModule::instance()); - - -class undoable_test : public Undoable { -struct state_type : public UndoMemento { - state_type() : test_data(0) - { - } - - state_type(const state_type &other) : UndoMemento(other), test_data(other.test_data) - { - } - - void release() - { - delete this; - } - - int test_data; -}; - -state_type m_state; -UndoObserver *m_observer; -public: -undoable_test() - : m_observer(GlobalUndoSystem().observer(this)) -{ -} - -~undoable_test() -{ - GlobalUndoSystem().release(this); -} - -UndoMemento *exportState() const -{ - return new state_type(m_state); -} - -void importState(const UndoMemento *state) -{ - ASSERT_NOTNULL(state); - - m_observer->save(this); - m_state = *(static_cast( state )); -} - -void mutate(unsigned int data) -{ - m_observer->save(this); - m_state.test_data = data; -} -}; - -#if 0 - -class TestUndo -{ -public: -TestUndo(){ - undoable_test test; - GlobalUndoSystem().begin( "bleh" ); - test.mutate( 3 ); - GlobalUndoSystem().begin( "blah" ); - test.mutate( 4 ); - GlobalUndoSystem().undo(); - GlobalUndoSystem().undo(); - GlobalUndoSystem().redo(); - GlobalUndoSystem().redo(); -} -}; - -TestUndo g_TestUndo; - -#endif diff --git a/src/undo.h b/src/undo.h deleted file mode 100644 index 89e6337..0000000 --- a/src/undo.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_UNDO_H ) -#define INCLUDED_UNDO_H - -#endif diff --git a/src/url.cpp b/src/url.cpp deleted file mode 100644 index ca90d04..0000000 --- a/src/url.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "url.h" -#include "globaldefs.h" - -#include "mainframe.h" -#include "gtkutil/messagebox.h" - -#if GDEF_OS_WINDOWS -#include -#include -#include -bool open_url( const char* url ){ - return ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( MainFrame_getWindow() ) ), "open", url, 0, 0, SW_SHOW ) > (HINSTANCE)32; -} -#endif - -#if GDEF_OS_LINUX || GDEF_OS_BSD - -#include - -bool open_url(const char *url) -{ - char command[2 * PATH_MAX]; - snprintf(command, sizeof(command), - "xdg-open \"%s\" &", url); - return system(command) == 0; -} - -#endif - -#if GDEF_OS_MACOS -#include -bool open_url( const char* url ){ - char command[2 * PATH_MAX]; - snprintf( command, sizeof( command ), "open \"%s\" &", url ); - return system( command ) == 0; -} -#endif - -void OpenURL(const char *url) -{ - // let's put a little comment - globalOutputStream() << "OpenURL: " << url << "\n"; - if (!open_url(url)) { - ui::alert(MainFrame_getWindow(), "Failed to launch browser!"); - } -} diff --git a/src/url.h b/src/url.h deleted file mode 100644 index 829b039..0000000 --- a/src/url.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_URL_H ) -#define INCLUDED_URL_H - -void OpenURL(const char *url); - -#endif diff --git a/src/view.cpp b/src/view.cpp deleted file mode 100644 index 8c3c18f..0000000 --- a/src/view.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "view.h" - -#if defined( DEBUG_CULLING ) - -#include - -char g_cull_stats[1024]; -int g_count_dots; -int g_count_planes; -int g_count_oriented_planes; -int g_count_bboxs; -int g_count_oriented_bboxs; - -#endif - -void Cull_ResetStats() -{ -#if defined( DEBUG_CULLING ) - g_count_dots = 0; - g_count_planes = 0; - g_count_oriented_planes = 0; - g_count_bboxs = 0; - g_count_oriented_bboxs = 0; -#endif -} - - -const char *Cull_GetStats() -{ -#if defined( DEBUG_CULLING ) - sprintf(g_cull_stats, "dots: %d | planes %d + %d | bboxs %d + %d", g_count_dots, g_count_planes, - g_count_oriented_planes, g_count_bboxs, g_count_oriented_bboxs); - return g_cull_stats; -#else - return ""; -#endif -} diff --git a/src/view.h b/src/view.h deleted file mode 100644 index fa64b31..0000000 --- a/src/view.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_VIEW_H ) -#define INCLUDED_VIEW_H - -#include "globaldefs.h" -#include "cullable.h" -#include "math/frustum.h" - - -#if GDEF_DEBUG -#define DEBUG_CULLING -#endif - - -#if defined( DEBUG_CULLING ) - -extern int g_count_dots; -extern int g_count_planes; -extern int g_count_oriented_planes; -extern int g_count_bboxs; -extern int g_count_oriented_bboxs; - -#endif - -inline void debug_count_dot() -{ -#if defined( DEBUG_CULLING ) - ++g_count_dots; -#endif -} - -inline void debug_count_plane() -{ -#if defined( DEBUG_CULLING ) - ++g_count_planes; -#endif -} - -inline void debug_count_oriented_plane() -{ -#if defined( DEBUG_CULLING ) - ++g_count_oriented_planes; -#endif -} - -inline void debug_count_bbox() -{ -#if defined( DEBUG_CULLING ) - ++g_count_bboxs; -#endif -} - -inline void debug_count_oriented_bbox() -{ -#if defined( DEBUG_CULLING ) - ++g_count_oriented_bboxs; -#endif -} - - -/// \brief View-volume culling and transformations. -class View : public VolumeTest { -/// modelview matrix -Matrix4 m_modelview; -/// projection matrix -Matrix4 m_projection; -/// device-to-screen transform -Matrix4 m_viewport; - -Matrix4 m_scissor; - -/// combined modelview and projection matrix -Matrix4 m_viewproj; -/// camera position in world space -Vector4 m_viewer; -/// view frustum in world space -Frustum m_frustum; - -bool m_fill; - -void construct() -{ - m_viewproj = matrix4_multiplied_by_matrix4(matrix4_multiplied_by_matrix4(m_scissor, m_projection), m_modelview); - - m_frustum = frustum_from_viewproj(m_viewproj); - m_viewer = viewer_from_viewproj(m_viewproj); -} - -public: -View(bool fill = false) : - m_modelview(g_matrix4_identity), - m_projection(g_matrix4_identity), - m_scissor(g_matrix4_identity), - m_fill(fill) -{ -} - -void Construct(const Matrix4 &projection, const Matrix4 &modelview, std::size_t width, std::size_t height) -{ - // modelview - m_modelview = modelview; - - // projection - m_projection = projection; - - // viewport - m_viewport = g_matrix4_identity; - m_viewport[0] = float(width / 2); - m_viewport[5] = float(height / 2); - if (fabs(m_projection[11]) > 0.0000001) { - m_viewport[10] = m_projection[0] * m_viewport[0]; - } else { - m_viewport[10] = 1 / m_projection[10]; - } - - construct(); -} - -void EnableScissor(float min_x, float max_x, float min_y, float max_y) -{ - m_scissor = g_matrix4_identity; - m_scissor[0] = static_cast((max_x - min_x) * 0.5 ); - m_scissor[5] = static_cast((max_y - min_y) * 0.5 ); - m_scissor[12] = static_cast((min_x + max_x) * 0.5 ); - m_scissor[13] = static_cast((min_y + max_y) * 0.5 ); - matrix4_full_invert(m_scissor); - - construct(); -} - -void DisableScissor() -{ - m_scissor = g_matrix4_identity; - - construct(); -} - -bool TestPoint(const Vector3 &point) const -{ - return viewproj_test_point(m_viewproj, point); -} - -bool TestLine(const Segment &segment) const -{ - return frustum_test_line(m_frustum, segment); -} - -bool TestPlane(const Plane3 &plane) const -{ - debug_count_plane(); - return viewer_test_plane(m_viewer, plane); -} - -bool TestPlane(const Plane3 &plane, const Matrix4 &localToWorld) const -{ - debug_count_oriented_plane(); - return viewer_test_transformed_plane(m_viewer, plane, localToWorld); -} - -VolumeIntersectionValue TestAABB(const AABB &aabb) const -{ - debug_count_bbox(); - return frustum_test_aabb(m_frustum, aabb); -} - -VolumeIntersectionValue TestAABB(const AABB &aabb, const Matrix4 &localToWorld) const -{ - debug_count_oriented_bbox(); - return frustum_intersects_transformed_aabb(m_frustum, aabb, localToWorld); -} - -const Matrix4 &GetViewMatrix() const -{ - return m_viewproj; -} - -const Matrix4 &GetViewport() const -{ - return m_viewport; -}; - -const Matrix4 &GetModelview() const -{ - return m_modelview; -} - -const Matrix4 &GetProjection() const -{ - return m_projection; -} - -bool fill() const -{ - return m_fill; -} - -const Vector3 &getViewer() const -{ - return vector4_to_vector3(m_viewer); -} -}; - -#endif diff --git a/tools/vmap/vis.c b/src/vis.c similarity index 100% rename from tools/vmap/vis.c rename to src/vis.c diff --git a/tools/vmap/visflow.c b/src/visflow.c similarity index 100% rename from tools/vmap/visflow.c rename to src/visflow.c diff --git a/tools/vmap/vmap.h b/src/vmap.h similarity index 100% rename from tools/vmap/vmap.h rename to src/vmap.h diff --git a/src/watchbsp.cpp b/src/watchbsp.cpp deleted file mode 100644 index a965c58..0000000 --- a/src/watchbsp.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// monitoring window for running BSP processes (and possibly various other stuff) - -#include "watchbsp.h" -#include "globaldefs.h" - -#include - -#include "cmdlib.h" -#include "convert.h" -#include "string/string.h" -#include "stream/stringstream.h" - -#include "gtkutil/messagebox.h" -#include "xmlstuff.h" -#include "console.h" -#include "preferences.h" -#include "points.h" -#include "feedback.h" -#include "mainframe.h" -#include "sockets.h" - -void message_flush(message_info_t *self) -{ - Sys_Print(self->msg_level, self->m_buffer, self->m_length); - self->m_length = 0; -} - -void message_print(message_info_t *self, const char *characters, std::size_t length) -{ - const char *end = characters + length; - while (characters != end) { - std::size_t space = message_info_t::bufsize - 1 - self->m_length; - if (space == 0) { - message_flush(self); - } else { - std::size_t size = std::min(space, std::size_t(end - characters)); - memcpy(self->m_buffer + self->m_length, characters, size); - self->m_length += size; - characters += size; - } - } -} - - -#include -#include -#include "xmlstuff.h" - -class CWatchBSP { -private: -// a flag we have set to true when using an external BSP plugin -// the resulting code with that is a bit dirty, cleaner solution would be to seperate the succession of commands from the listening loop -// (in two seperate classes probably) -bool m_bBSPPlugin; - -// EIdle: we are not listening -// DoMonitoringLoop will change state to EBeginStep -// EBeginStep: the socket is up for listening, we are expecting incoming connection -// incoming connection will change state to EWatching -// EWatching: we have a connection, monitor it -// connection closed will see if we start a new step (EBeginStep) or launch Quake3 and end (EIdle) -enum EWatchBSPState { EIdle, EBeginStep, EWatching } m_eState; -socket_t *m_pListenSocket; -socket_t *m_pInSocket; -netmessage_t msg; -GPtrArray *m_pCmd; -// used to timeout EBeginStep -GTimer *m_pTimer; -std::size_t m_iCurrentStep; -// name of the map so we can run the engine -char *m_sBSPName; -// buffer we use in push mode to receive data directly from the network -xmlParserInputBufferPtr m_xmlInputBuffer; -xmlParserInputPtr m_xmlInput; -xmlParserCtxtPtr m_xmlParserCtxt; - -// call this to switch the set listening mode -bool SetupListening(); - -// start a new EBeginStep -void DoEBeginStep(); - -// the xml and sax parser state -char m_xmlBuf[MAX_NETMESSAGE]; -bool m_bNeedCtxtInit; -message_info_t m_message_info; - -public: -CWatchBSP() -{ - m_pCmd = 0; - m_bBSPPlugin = false; - m_pListenSocket = NULL; - m_pInSocket = NULL; - m_eState = EIdle; - m_pTimer = g_timer_new(); - m_sBSPName = NULL; - m_xmlInputBuffer = NULL; - m_bNeedCtxtInit = true; -} - -virtual ~CWatchBSP() -{ - EndMonitoringLoop(); - Net_Shutdown(); - - g_timer_destroy(m_pTimer); -} - -bool HasBSPPlugin() const -{ - return m_bBSPPlugin; -} - -// called regularly to keep listening -void RoutineProcessing(); - -// start a monitoring loop with the following steps -void DoMonitoringLoop(GPtrArray *pCmd, const char *sBSPName); - -void EndMonitoringLoop() -{ - Reset(); - if (m_sBSPName) { - string_release(m_sBSPName, string_length(m_sBSPName)); - m_sBSPName = 0; - } - if (m_pCmd) { - g_ptr_array_free(m_pCmd, TRUE); - m_pCmd = 0; - } -} - -// close everything - may be called from the outside to abort the process -void Reset(); - -// start a listening loop for an external process, possibly a BSP plugin -void ExternalListen(); -}; - -CWatchBSP *g_pWatchBSP; - -// watch the BSP process through network connections -// true: trigger the BSP steps one by one and monitor them through the network -// false: create a BAT / .sh file and execute it. don't bother monitoring it. -bool g_WatchBSP_Enabled = true; -// do we stop the compilation process if we come accross a leak? -bool g_WatchBSP_LeakStop = true; -bool g_WatchBSP_RunQuake = false; -// store prefs setting for automatic sleep mode activation -bool g_WatchBSP_DoSleep = true; -// timeout when beginning a step (in seconds) -// if we don't get a connection quick enough we assume something failed and go back to idling -int g_WatchBSP_Timeout = 10; - - -void Build_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton monitorbsp = page.appendCheckBox("", "Enable Build Process Monitoring", g_WatchBSP_Enabled); - ui::CheckButton leakstop = page.appendCheckBox("", "Stop Compilation on Leak", g_WatchBSP_LeakStop); - ui::CheckButton runengine = page.appendCheckBox("", "Run Engine After Compile", g_WatchBSP_RunQuake); - ui::CheckButton sleep = page.appendCheckBox("", "Sleep When Running the Engine", g_WatchBSP_DoSleep); - Widget_connectToggleDependency(leakstop, monitorbsp); - Widget_connectToggleDependency(runengine, monitorbsp); - Widget_connectToggleDependency(sleep, runengine); -} - -void Build_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Build", "Build Preferences")); - Build_constructPreferences(page); -} - -void Build_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Build_constructPage)); -} - -#include "preferencesystem.h" -#include "stringio.h" - -void BuildMonitor_Construct() -{ - g_pWatchBSP = new CWatchBSP(); - - g_WatchBSP_Enabled = !string_equal(g_pGameDescription->getKeyValue("no_bsp_monitor"), "1"); - - GlobalPreferenceSystem().registerPreference("WatchBSP", make_property_string(g_WatchBSP_Enabled)); - GlobalPreferenceSystem().registerPreference("RunQuake2Run", make_property_string(g_WatchBSP_RunQuake)); - GlobalPreferenceSystem().registerPreference("LeakStop", make_property_string(g_WatchBSP_LeakStop)); - GlobalPreferenceSystem().registerPreference("SleepMode", make_property_string(g_WatchBSP_DoSleep)); - - Build_registerPreferencesPage(); -} - -void BuildMonitor_Destroy() -{ - delete g_pWatchBSP; -} - -CWatchBSP *GetWatchBSP() -{ - return g_pWatchBSP; -} - -void BuildMonitor_Run(GPtrArray *commands, const char *mapName) -{ - GetWatchBSP()->DoMonitoringLoop(commands, mapName); -} - - -// Static functions for the SAX callbacks ------------------------------------------------------- - -// utility for saxStartElement below -static void abortStream(message_info_t *data) -{ - GetWatchBSP()->EndMonitoringLoop(); - // tell there has been an error -#if 0 - if ( GetWatchBSP()->HasBSPPlugin() ) { - g_BSPFrontendTable.m_pfnEndListen( 2 ); - } -#endif - // yeah this doesn't look good.. but it's needed so that everything will be ignored until the stream goes out - data->ignore_depth = -1; - data->recurse++; -} - -#include "stream_version.h" - -static void saxStartElement(message_info_t *data, const xmlChar *name, const xmlChar **attrs) -{ -#if 0 - globalOutputStream() << "<" << name; - if ( attrs != 0 ) { - for ( const xmlChar** p = attrs; *p != 0; p += 2 ) - { - globalOutputStream() << " " << p[0] << "=" << makeQuoted( p[1] ); - } - } - globalOutputStream() << ">\n"; -#endif - - if (data->ignore_depth == 0) { - if (data->pGeometry != 0) { - // we have a handler - data->pGeometry->saxStartElement(data, name, attrs); - } else { - if (strcmp(reinterpret_cast( name ), "q3map_feedback") == 0) { - // check the correct version - // old q3map don't send a version attribute - // the ones we support .. send Q3MAP_STREAM_VERSION - if (!attrs[0] || !attrs[1] || (strcmp(reinterpret_cast( attrs[0] ), "version") != 0)) { - message_flush(data); - globalErrorStream() - << "No stream version given in the feedback stream, this is an old q3map version.\n" - "Please turn off monitored compiling if you still wish to use this q3map executable\n"; - abortStream(data); - return; - } else if (strcmp(reinterpret_cast( attrs[1] ), Q3MAP_STREAM_VERSION) != 0) { - message_flush(data); - globalErrorStream() << - "This version of Radiant reads version " Q3MAP_STREAM_VERSION " debug streams, I got an incoming connection with version " - << reinterpret_cast( attrs[1] ) << "\n" - "Please make sure your versions of Radiant and q3map are matching.\n"; - abortStream(data); - return; - } - } - // we don't treat locally - else if (strcmp(reinterpret_cast( name ), "message") == 0) { - int msg_level = atoi(reinterpret_cast( attrs[1] )); - if (msg_level != data->msg_level) { - message_flush(data); - data->msg_level = msg_level; - } - } else if (strcmp(reinterpret_cast( name ), "polyline") == 0) { - // polyline has a particular status .. right now we only use it for leakfile .. - data->geometry_depth = data->recurse; - data->pGeometry = &g_pointfile; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "select") == 0) { - CSelectMsg *pSelect = new CSelectMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pSelect; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "pointmsg") == 0) { - CPointMsg *pPoint = new CPointMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pPoint; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "windingmsg") == 0) { - CWindingMsg *pWinding = new CWindingMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pWinding; - data->pGeometry->saxStartElement(data, name, attrs); - } else { - globalErrorStream() << "Warning: ignoring unrecognized node in XML stream (" - << reinterpret_cast( name ) << ")\n"; - // we don't recognize this node, jump over it - // (NOTE: the ignore mechanism is a bit screwed, only works when starting an ignore at the highest level) - data->ignore_depth = data->recurse; - } - } - } - data->recurse++; -} - -static void saxEndElement(message_info_t *data, const xmlChar *name) -{ -#if 0 - globalOutputStream() << "<" << name << "/>\n"; -#endif - - data->recurse--; - // we are out of an ignored chunk - if (data->recurse == data->ignore_depth) { - data->ignore_depth = 0; - return; - } - if (data->pGeometry != 0) { - data->pGeometry->saxEndElement(data, name); - // we add the object to the debug window - if (data->geometry_depth == data->recurse) { - g_DbgDlg.Push(data->pGeometry); - data->pGeometry = 0; - } - } - if (data->recurse == data->stop_depth) { - message_flush(data); -#if GDEF_DEBUG - globalOutputStream() << "Received error msg .. shutting down..\n"; -#endif - GetWatchBSP()->EndMonitoringLoop(); - // tell there has been an error -#if 0 - if ( GetWatchBSP()->HasBSPPlugin() ) { - g_BSPFrontendTable.m_pfnEndListen( 2 ); - } -#endif - return; - } -} - -class MessageOutputStream : public TextOutputStream { -message_info_t *m_data; -public: -MessageOutputStream(message_info_t *data) : m_data(data) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - if (m_data->pGeometry != 0) { - m_data->pGeometry->saxCharacters(m_data, reinterpret_cast( buffer ), int(length)); - } else { - if (m_data->ignore_depth == 0) { - // output the message using the level - message_print(m_data, buffer, length); - // if this message has error level flag, we mark the depth to stop the compilation when we get out - // we don't set the msg level if we don't stop on leak - if (m_data->msg_level == 3) { - m_data->stop_depth = m_data->recurse - 1; - } - } - } - - return length; -} -}; - -template -inline MessageOutputStream &operator<<(MessageOutputStream &ostream, const T &t) -{ - return ostream_write(ostream, t); -} - -static void saxCharacters(message_info_t *data, const xmlChar *ch, int len) -{ - MessageOutputStream ostream(data); - ostream << StringRange(reinterpret_cast( ch ), reinterpret_cast( ch + len )); -} - -static void saxComment(void *ctx, const xmlChar *msg) -{ - globalOutputStream() << "XML comment: " << reinterpret_cast( msg ) << "\n"; -} - -static void saxWarning(void *ctx, const char *msg, ...) -{ - char saxMsgBuffer[4096]; - va_list args; - - va_start(args, msg); - vsprintf(saxMsgBuffer, msg, args); - va_end(args); - globalOutputStream() << "XML warning: " << saxMsgBuffer << "\n"; -} - -static void saxError(void *ctx, const char *msg, ...) -{ - char saxMsgBuffer[4096]; - va_list args; - - va_start(args, msg); - vsprintf(saxMsgBuffer, msg, args); - va_end(args); - globalErrorStream() << "XML error: " << saxMsgBuffer << "\n"; -} - -static void saxFatal(void *ctx, const char *msg, ...) -{ - char buffer[4096]; - - va_list args; - - va_start(args, msg); - vsprintf(buffer, msg, args); - va_end(args); - globalErrorStream() << "XML fatal error: " << buffer << "\n"; -} - -static xmlSAXHandler saxParser = { - 0, /* internalSubset */ - 0, /* isStandalone */ - 0, /* hasInternalSubset */ - 0, /* hasExternalSubset */ - 0, /* resolveEntity */ - 0, /* getEntity */ - 0, /* entityDecl */ - 0, /* notationDecl */ - 0, /* attributeDecl */ - 0, /* elementDecl */ - 0, /* unparsedEntityDecl */ - 0, /* setDocumentLocator */ - 0, /* startDocument */ - 0, /* endDocument */ - (startElementSAXFunc) saxStartElement, /* startElement */ - (endElementSAXFunc) saxEndElement, /* endElement */ - 0, /* reference */ - (charactersSAXFunc) saxCharacters, /* characters */ - 0, /* ignorableWhitespace */ - 0, /* processingInstruction */ - (commentSAXFunc) saxComment, /* comment */ - (warningSAXFunc) saxWarning, /* warning */ - (errorSAXFunc) saxError, /* error */ - (fatalErrorSAXFunc) saxFatal, /* fatalError */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -// ------------------------------------------------------------------------------------------------ - - -guint s_routine_id; - -static gint watchbsp_routine(gpointer data) -{ - reinterpret_cast( data )->RoutineProcessing(); - return TRUE; -} - -void CWatchBSP::Reset() -{ - if (m_pInSocket) { - Net_Disconnect(m_pInSocket); - m_pInSocket = NULL; - } - if (m_pListenSocket) { - Net_Disconnect(m_pListenSocket); - m_pListenSocket = NULL; - } - if (m_xmlInputBuffer) { - xmlFreeParserInputBuffer(m_xmlInputBuffer); - m_xmlInputBuffer = NULL; - } - m_eState = EIdle; - if (s_routine_id) { - g_source_remove(s_routine_id); - } -} - -bool CWatchBSP::SetupListening() -{ -#if GDEF_DEBUG - if (m_pListenSocket) { - globalOutputStream() << "ERROR: m_pListenSocket != NULL in CWatchBSP::SetupListening\n"; - return false; - } -#endif - globalOutputStream() << "Setting up\n"; - Net_Setup(); - m_pListenSocket = Net_ListenSocket(39000); - if (m_pListenSocket == NULL) { - return false; - } - globalOutputStream() << "Listening...\n"; - return true; -} - -void CWatchBSP::DoEBeginStep() -{ - Reset(); - if (SetupListening() == false) { - const char *msg = "Failed to get a listening socket on port 39000.\nTry running with Build monitoring disabled if you can't fix this.\n"; - globalOutputStream() << msg; - ui::alert(MainFrame_getWindow(), msg, "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error); - return; - } - // set the timer for timeouts and step cancellation - g_timer_reset(m_pTimer); - g_timer_start(m_pTimer); - - if (!m_bBSPPlugin) { - globalOutputStream() << "=== running build command ===\n" - << static_cast(g_ptr_array_index(m_pCmd, m_iCurrentStep) ) << "\n"; - - if (!Q_Exec(NULL, (char *) g_ptr_array_index(m_pCmd, m_iCurrentStep), NULL, true, false)) { - StringOutputStream msg(256); - msg << "Failed to execute the following command: "; - msg << reinterpret_cast(g_ptr_array_index(m_pCmd, m_iCurrentStep) ); - msg << "\nCheck that the file exists and that you don't run out of system resources.\n"; - globalOutputStream() << msg.c_str(); - ui::alert(MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, - ui::alert_icon::Error); - return; - } - // re-initialise the debug window - if (m_iCurrentStep == 0) { - g_DbgDlg.Init(); - } - } - m_eState = EBeginStep; - s_routine_id = g_timeout_add(25, watchbsp_routine, this); -} - - -#if GDEF_OS_WINDOWS -const char *ENGINE_ATTRIBUTE = "engine_win32"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_win32"; -#elif GDEF_OS_LINUX || GDEF_OS_BSD -const char *ENGINE_ATTRIBUTE = "engine_linux"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_linux"; -#elif GDEF_OS_MACOS -const char *ENGINE_ATTRIBUTE = "engine_macos"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_macos"; -#else -#error "unsupported platform" -#endif - -class RunEngineConfiguration { -public: -const char *executable; -const char *mp_executable; -bool do_sp_mp; - -RunEngineConfiguration() : - executable(g_pGameDescription->getRequiredKeyValue(ENGINE_ATTRIBUTE)), - mp_executable(g_pGameDescription->getKeyValue(MP_ENGINE_ATTRIBUTE)) -{ - do_sp_mp = !string_empty(mp_executable); -} -}; - -inline void GlobalGameDescription_string_write_mapparameter(StringOutputStream &string, const char *mapname) -{ - if (g_pGameDescription->mGameType == "q2" - || g_pGameDescription->mGameType == "heretic2") { - string << ". +exec radiant.cfg +map " << mapname; - } else { - string << "+set sv_pure 0 "; - // TTimo: a check for vm_* but that's all fine - //cmdline = "+set sv_pure 0 +set vm_ui 0 +set vm_cgame 0 +set vm_game 0 "; - const char *fs_game = gamename_get(); - if (!string_equal(fs_game, basegame_get())) { - string << "+set fs_game " << fs_game << " "; - } - if (g_pGameDescription->mGameType == "wolf") { - //|| g_pGameDescription->mGameType == "et") - if (string_equal(gamemode_get(), "mp")) { - // MP - string << "+devmap " << mapname; - } else { - // SP - string << "+set nextmap \"spdevmap " << mapname << "\""; - } - } else { - string << "+devmap " << mapname; - } - } -} - - -void CWatchBSP::RoutineProcessing() -{ - switch (m_eState) { - case EBeginStep: - // timeout: if we don't get an incoming connection fast enough, go back to idle - if (g_timer_elapsed(m_pTimer, NULL) > g_WatchBSP_Timeout) { - ui::alert(MainFrame_getWindow(), - "The connection timed out, assuming the build process failed\nMake sure you are using a networked version of Q3Map?\nOtherwise you need to disable BSP Monitoring in prefs.", - "BSP process monitoring", ui::alert_type::OK); - EndMonitoringLoop(); -#if 0 - if ( m_bBSPPlugin ) { - // status == 1 : didn't get the connection - g_BSPFrontendTable.m_pfnEndListen( 1 ); - } -#endif - return; - } -#if GDEF_DEBUG - // some debug checks - if (!m_pListenSocket) { - globalErrorStream() - << "ERROR: m_pListenSocket == NULL in CWatchBSP::RoutineProcessing EBeginStep state\n"; - return; - } -#endif - // we are not connected yet, accept any incoming connection - m_pInSocket = Net_Accept(m_pListenSocket); - if (m_pInSocket) { - globalOutputStream() << "Connected.\n"; - // prepare the message info struct for diving in - memset(&m_message_info, 0, sizeof(message_info_t)); - // a dumb flag to make sure we init the push parser context when first getting a msg - m_bNeedCtxtInit = true; - m_eState = EWatching; - } - break; - case EWatching: { -#if GDEF_DEBUG - // some debug checks - if (!m_pInSocket) { - globalErrorStream() << "ERROR: m_pInSocket == NULL in CWatchBSP::RoutineProcessing EWatching state\n"; - return; - } -#endif - - int ret = Net_Wait(m_pInSocket, 0, 0); - if (ret == -1) { - globalOutputStream() << "WARNING: SOCKET_ERROR in CWatchBSP::RoutineProcessing\n"; - globalOutputStream() << "Terminating the connection.\n"; - EndMonitoringLoop(); - return; - } - - if (ret == 1) { - // the socket has been identified, there's something (message or disconnection) - // see if there's anything in input - ret = Net_Receive(m_pInSocket, &msg); - if (ret > 0) { - // unsigned int size = msg.size; //++timo just a check - strcpy(m_xmlBuf, NMSG_ReadString(&msg)); - if (m_bNeedCtxtInit) { - m_xmlParserCtxt = NULL; - m_xmlParserCtxt = xmlCreatePushParserCtxt(&saxParser, &m_message_info, m_xmlBuf, - static_cast( strlen(m_xmlBuf)), NULL); - - if (m_xmlParserCtxt == NULL) { - globalErrorStream() << "Failed to create the XML parser (incoming stream began with: " - << m_xmlBuf << ")\n"; - EndMonitoringLoop(); - } - m_bNeedCtxtInit = false; - } else { - xmlParseChunk(m_xmlParserCtxt, m_xmlBuf, static_cast( strlen(m_xmlBuf)), 0); - } - } else { - message_flush(&m_message_info); - // error or connection closed/reset - // NOTE: if we get an error down the XML stream we don't reach here - Net_Disconnect(m_pInSocket); - m_pInSocket = NULL; - globalOutputStream() << "Connection closed.\n"; -#if 0 - if ( m_bBSPPlugin ) { - EndMonitoringLoop(); - // let the BSP plugin know that the job is done - g_BSPFrontendTable.m_pfnEndListen( 0 ); - return; - } -#endif - // move to next step or finish - m_iCurrentStep++; - if (m_iCurrentStep < m_pCmd->len) { - DoEBeginStep(); - } else { - // launch the engine .. OMG - if (g_WatchBSP_RunQuake) { -#if 0 - // do we enter sleep mode before? - if ( g_WatchBSP_DoSleep ) { - globalOutputStream() << "Going into sleep mode..\n"; - g_pParentWnd->OnSleep(); - } -#endif - globalOutputStream() << "Running engine...\n"; - StringOutputStream cmd(256); - // build the command line - cmd << EnginePath_get(); - // this is game dependant - - RunEngineConfiguration engineConfig; - - if (engineConfig.do_sp_mp) { - if (string_equal(gamemode_get(), "mp")) { - cmd << engineConfig.mp_executable; - } else { - cmd << engineConfig.executable; - } - } else { - cmd << engineConfig.executable; - } - - StringOutputStream cmdline; - - GlobalGameDescription_string_write_mapparameter(cmdline, m_sBSPName); - - globalOutputStream() << cmd.c_str() << " " << cmdline.c_str() << "\n"; - - // execute now - if (!Q_Exec(cmd.c_str(), (char *) cmdline.c_str(), EnginePath_get(), false, false)) { - StringOutputStream msg; - msg << "Failed to execute the following command: " << cmd.c_str() << cmdline.c_str(); - globalOutputStream() << msg.c_str(); - ui::alert(MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, - ui::alert_icon::Error); - } - } - EndMonitoringLoop(); - } - } - } - } - break; - default: - break; - } -} - -GPtrArray *str_ptr_array_clone(GPtrArray *array) -{ - GPtrArray *cloned = g_ptr_array_sized_new(array->len); - for (guint i = 0; i < array->len; ++i) { - g_ptr_array_add(cloned, g_strdup((char *) g_ptr_array_index(array, i))); - } - return cloned; -} - -void CWatchBSP::DoMonitoringLoop(GPtrArray *pCmd, const char *sBSPName) -{ - m_sBSPName = string_clone(sBSPName); - if (m_eState != EIdle) { - globalOutputStream() << "WatchBSP got a monitoring request while not idling...\n"; - // prompt the user, should we cancel the current process and go ahead? - if (ui::alert(MainFrame_getWindow(), - "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?", - "Build process monitoring", ui::alert_type::YESNO) == ui::alert_response::YES) { - // disconnect and set EIdle state - Reset(); - } - } - m_pCmd = str_ptr_array_clone(pCmd); - m_iCurrentStep = 0; - DoEBeginStep(); -} - -void CWatchBSP::ExternalListen() -{ - m_bBSPPlugin = true; - DoEBeginStep(); -} - -// the part of the watchbsp interface we export to plugins -// NOTE: in the long run, the whole watchbsp.cpp interface needs to go out and be handled at the BSP plugin level -// for now we provide something really basic and limited, the essential is to have something that works fine and fast (for 1.1 final) -void QERApp_Listen() -{ - // open the listening socket - GetWatchBSP()->ExternalListen(); -} diff --git a/src/watchbsp.h b/src/watchbsp.h deleted file mode 100644 index b8f4345..0000000 --- a/src/watchbsp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_WATCHBSP_H ) -#define INCLUDED_WATCHBSP_H - -void BuildMonitor_Construct(); - -void BuildMonitor_Destroy(); - -typedef struct _GPtrArray GPtrArray; - -void BuildMonitor_Run(GPtrArray *commands, const char *mapName); - -extern bool g_WatchBSP_Enabled; -extern bool g_WatchBSP_LeakStop; - -#endif diff --git a/src/winding.cpp b/src/winding.cpp deleted file mode 100644 index c443e47..0000000 --- a/src/winding.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "winding.h" - -#include - -#include "math/line.h" - - -inline double plane3_distance_to_point(const Plane3 &plane, const DoubleVector3 &point) -{ - return vector3_dot(point, plane.normal()) - plane.dist(); -} - -inline double plane3_distance_to_point(const Plane3 &plane, const Vector3 &point) -{ - return vector3_dot(point, plane.normal()) - plane.dist(); -} - -/// \brief Returns the point at which \p line intersects \p plane, or an undefined value if there is no intersection. -inline DoubleVector3 line_intersect_plane(const DoubleLine &line, const Plane3 &plane) -{ - return line.origin + vector3_scaled( - line.direction, - -plane3_distance_to_point(plane, line.origin) - / vector3_dot(line.direction, plane.normal()) - ); -} - -inline bool float_is_largest_absolute(double axis, double other) -{ - return fabs(axis) > fabs(other); -} - -/// \brief Returns the index of the component of \p v that has the largest absolute value. -inline int vector3_largest_absolute_component_index(const DoubleVector3 &v) -{ - return (float_is_largest_absolute(v[1], v[0])) - ? (float_is_largest_absolute(v[1], v[2])) - ? 1 - : 2 - : (float_is_largest_absolute(v[0], v[2])) - ? 0 - : 2; -} - -/// \brief Returns the infinite line that is the intersection of \p plane and \p other. -inline DoubleLine plane3_intersect_plane3(const Plane3 &plane, const Plane3 &other) -{ - DoubleLine line; - line.direction = vector3_cross(plane.normal(), other.normal()); - switch (vector3_largest_absolute_component_index(line.direction)) { - case 0: - line.origin.x() = 0; - line.origin.y() = - (-other.dist() * plane.normal().z() - -plane.dist() * other.normal().z()) / line.direction.x(); - line.origin.z() = - (-plane.dist() * other.normal().y() - -other.dist() * plane.normal().y()) / line.direction.x(); - break; - case 1: - line.origin.x() = - (-plane.dist() * other.normal().z() - -other.dist() * plane.normal().z()) / line.direction.y(); - line.origin.y() = 0; - line.origin.z() = - (-other.dist() * plane.normal().x() - -plane.dist() * other.normal().x()) / line.direction.y(); - break; - case 2: - line.origin.x() = - (-other.dist() * plane.normal().y() - -plane.dist() * other.normal().y()) / line.direction.z(); - line.origin.y() = - (-plane.dist() * other.normal().x() - -other.dist() * plane.normal().x()) / line.direction.z(); - line.origin.z() = 0; - break; - default: - break; - } - - return line; -} - - -/// \brief Keep the value of \p infinity as small as possible to improve precision in Winding_Clip. -void Winding_createInfinite(FixedWinding &winding, const Plane3 &plane, double infinity) -{ - double max = -infinity; - int x = -1; - for (int i = 0; i < 3; i++) { - double d = fabs(plane.normal()[i]); - if (d > max) { - x = i; - max = d; - } - } - if (x == -1) { - globalErrorStream() << "invalid plane\n"; - return; - } - - DoubleVector3 vup = g_vector3_identity; - switch (x) { - case 0: - case 1: - vup[2] = 1; - break; - case 2: - vup[0] = 1; - break; - } - - - vector3_add(vup, vector3_scaled(plane.normal(), -vector3_dot(vup, plane.normal()))); - vector3_normalise(vup); - - DoubleVector3 org = vector3_scaled(plane.normal(), plane.dist()); - - DoubleVector3 vright = vector3_cross(vup, plane.normal()); - - vector3_scale(vup, infinity); - vector3_scale(vright, infinity); - - // project a really big axis aligned box onto the plane - - DoubleLine r1, r2, r3, r4; - r1.origin = vector3_added(vector3_subtracted(org, vright), vup); - r1.direction = vector3_normalised(vright); - winding.push_back(FixedWindingVertex(r1.origin, r1, c_brush_maxFaces)); - r2.origin = vector3_added(vector3_added(org, vright), vup); - r2.direction = vector3_normalised(vector3_negated(vup)); - winding.push_back(FixedWindingVertex(r2.origin, r2, c_brush_maxFaces)); - r3.origin = vector3_subtracted(vector3_added(org, vright), vup); - r3.direction = vector3_normalised(vector3_negated(vright)); - winding.push_back(FixedWindingVertex(r3.origin, r3, c_brush_maxFaces)); - r4.origin = vector3_subtracted(vector3_subtracted(org, vright), vup); - r4.direction = vector3_normalised(vup); - winding.push_back(FixedWindingVertex(r4.origin, r4, c_brush_maxFaces)); -} - - -inline PlaneClassification Winding_ClassifyDistance(const double distance, const double epsilon) -{ - if (distance > epsilon) { - return ePlaneFront; - } - if (distance < -epsilon) { - return ePlaneBack; - } - return ePlaneOn; -} - -/// \brief Returns true if -/// !flipped && winding is completely BACK or ON -/// or flipped && winding is completely FRONT or ON -bool Winding_TestPlane(const Winding &winding, const Plane3 &plane, bool flipped) -{ - const int test = (flipped) ? ePlaneBack : ePlaneFront; - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - if (test == Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)) { - return false; - } - } - return true; -} - -/// \brief Returns true if any point in \p w1 is in front of plane2, or any point in \p w2 is in front of plane1 -bool Winding_PlanesConcave(const Winding &w1, const Winding &w2, const Plane3 &plane1, const Plane3 &plane2) -{ - return !Winding_TestPlane(w1, plane2, false) || !Winding_TestPlane(w2, plane1, false); -} - -brushsplit_t Winding_ClassifyPlane(const Winding &winding, const Plane3 &plane) -{ - brushsplit_t split; - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - ++split.counts[Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)]; - } - return split; -} - - -#define DEBUG_EPSILON ON_EPSILON -const double DEBUG_EPSILON_SQUARED = DEBUG_EPSILON * DEBUG_EPSILON; - -#define WINDING_DEBUG 0 - -/// \brief Clip \p winding which lies on \p plane by \p clipPlane, resulting in \p clipped. -/// If \p winding is completely in front of the plane, \p clipped will be identical to \p winding. -/// If \p winding is completely in back of the plane, \p clipped will be empty. -/// If \p winding intersects the plane, the edge of \p clipped which lies on \p clipPlane will store the value of \p adjacent. -void Winding_Clip(const FixedWinding &winding, const Plane3 &plane, const Plane3 &clipPlane, std::size_t adjacent, - FixedWinding &clipped) -{ - PlaneClassification classification = Winding_ClassifyDistance( - plane3_distance_to_point(clipPlane, winding.back().vertex), ON_EPSILON); - PlaneClassification nextClassification; - // for each edge - for (std::size_t next = 0, i = winding.size() - 1; - next != winding.size(); i = next, ++next, classification = nextClassification) { - nextClassification = Winding_ClassifyDistance(plane3_distance_to_point(clipPlane, winding[next].vertex), - ON_EPSILON); - const FixedWindingVertex &vertex = winding[i]; - - // if first vertex of edge is ON - if (classification == ePlaneOn) { - // append first vertex to output winding - if (nextClassification == ePlaneBack) { - // this edge lies on the clip plane - clipped.push_back( - FixedWindingVertex(vertex.vertex, plane3_intersect_plane3(plane, clipPlane), adjacent)); - } else { - clipped.push_back(vertex); - } - continue; - } - - // if first vertex of edge is FRONT - if (classification == ePlaneFront) { - // add first vertex to output winding - clipped.push_back(vertex); - } - // if second vertex of edge is ON - if (nextClassification == ePlaneOn) { - continue; - } - // else if second vertex of edge is same as first - else if (nextClassification == classification) { - continue; - } - // else if first vertex of edge is FRONT and there are only two edges - else if (classification == ePlaneFront && winding.size() == 2) { - continue; - } - // else first vertex is FRONT and second is BACK or vice versa - else { - // append intersection point of line and plane to output winding - DoubleVector3 mid(line_intersect_plane(vertex.edge, clipPlane)); - - if (classification == ePlaneFront) { - // this edge lies on the clip plane - clipped.push_back(FixedWindingVertex(mid, plane3_intersect_plane3(plane, clipPlane), adjacent)); - } else { - clipped.push_back(FixedWindingVertex(mid, vertex.edge, vertex.adjacent)); - } - } - } -} - -std::size_t Winding_FindAdjacent(const Winding &winding, std::size_t face) -{ - for (std::size_t i = 0; i < winding.numpoints; ++i) { - ASSERT_MESSAGE(winding[i].adjacent != c_brush_maxFaces, "edge connectivity data is invalid"); - if (winding[i].adjacent == face) { - return i; - } - } - return c_brush_maxFaces; -} - -std::size_t Winding_Opposite(const Winding &winding, const std::size_t index, const std::size_t other) -{ - ASSERT_MESSAGE(index < winding.numpoints && other < winding.numpoints, "Winding_Opposite: index out of range"); - - double dist_best = 0; - std::size_t index_best = c_brush_maxFaces; - - Ray edge(ray_for_points(winding[index].vertex, winding[other].vertex)); - - for (std::size_t i = 0; i < winding.numpoints; ++i) { - if (i == index || i == other) { - continue; - } - - double dist_squared = ray_squared_distance_to_point(edge, winding[i].vertex); - - if (dist_squared > dist_best) { - dist_best = dist_squared; - index_best = i; - } - } - return index_best; -} - -std::size_t Winding_Opposite(const Winding &winding, const std::size_t index) -{ - return Winding_Opposite(winding, index, Winding_next(winding, index)); -} - -/// \brief Calculate the \p centroid of the polygon defined by \p winding which lies on plane \p plane. -void Winding_Centroid(const Winding &winding, const Plane3 &plane, Vector3 ¢roid) -{ - double area2 = 0, x_sum = 0, y_sum = 0; - const ProjectionAxis axis = projectionaxis_for_normal(plane.normal()); - const indexremap_t remap = indexremap_for_projectionaxis(axis); - for (std::size_t i = winding.numpoints - 1, j = 0; j < winding.numpoints; i = j, ++j) { - const double ai = winding[i].vertex[remap.x] * winding[j].vertex[remap.y] - - winding[j].vertex[remap.x] * winding[i].vertex[remap.y]; - area2 += ai; - x_sum += (winding[j].vertex[remap.x] + winding[i].vertex[remap.x]) * ai; - y_sum += (winding[j].vertex[remap.y] + winding[i].vertex[remap.y]) * ai; - } - - centroid[remap.x] = static_cast( x_sum / (3 * area2)); - centroid[remap.y] = static_cast( y_sum / (3 * area2)); - { - Ray ray(Vector3(0, 0, 0), Vector3(0, 0, 0)); - ray.origin[remap.x] = centroid[remap.x]; - ray.origin[remap.y] = centroid[remap.y]; - ray.direction[remap.z] = 1; - centroid[remap.z] = static_cast( ray_distance_to_plane(ray, plane)); - } -} diff --git a/src/winding.h b/src/winding.h deleted file mode 100644 index 8ac6f32..0000000 --- a/src/winding.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WINDING_H ) -#define INCLUDED_WINDING_H - -#include "debugging/debugging.h" - -#include - -#include "math/vector.h" -#include "container/array.h" - -enum ProjectionAxis { - eProjectionAxisX = 0, - eProjectionAxisY = 1, - eProjectionAxisZ = 2, -}; - -const float ProjectionAxisEpsilon = static_cast( 0.0001 ); - -inline bool projectionaxis_better(float axis, float other) -{ - return fabs(axis) > fabs(other) + ProjectionAxisEpsilon; -} - -/// \brief Texture axis precedence: Z > X > Y -inline ProjectionAxis projectionaxis_for_normal(const Vector3 &normal) -{ - return (projectionaxis_better(normal[eProjectionAxisY], normal[eProjectionAxisX])) - ? (projectionaxis_better(normal[eProjectionAxisY], normal[eProjectionAxisZ])) - ? eProjectionAxisY - : eProjectionAxisZ - : (projectionaxis_better(normal[eProjectionAxisX], normal[eProjectionAxisZ])) - ? eProjectionAxisX - : eProjectionAxisZ; -} - - -struct indexremap_t { - indexremap_t(std::size_t _x, std::size_t _y, std::size_t _z) - : x(_x), y(_y), z(_z) - { - } - - std::size_t x, y, z; -}; - -inline indexremap_t indexremap_for_projectionaxis(const ProjectionAxis axis) -{ - switch (axis) { - case eProjectionAxisX: - return indexremap_t(1, 2, 0); - case eProjectionAxisY: - return indexremap_t(2, 0, 1); - default: - return indexremap_t(0, 1, 2); - } -} - -enum PlaneClassification { - ePlaneFront = 0, - ePlaneBack = 1, - ePlaneOn = 2, -}; - -#define MAX_POINTS_ON_WINDING 64 -const std::size_t c_brush_maxFaces = 1024; - - -class WindingVertex { -public: -Vector3 vertex; -Vector2 texcoord; -Vector3 tangent; -Vector3 bitangent; -std::size_t adjacent; -}; - - -struct Winding { - typedef Array container_type; - - std::size_t numpoints; - container_type points; - - typedef container_type::iterator iterator; - typedef container_type::const_iterator const_iterator; - - Winding() : numpoints(0) - { - } - - Winding(std::size_t size) : numpoints(0), points(size) - { - } - - void resize(std::size_t size) - { - points.resize(size); - numpoints = 0; - } - - iterator begin() - { - return points.begin(); - } - - const_iterator begin() const - { - return points.begin(); - } - - iterator end() - { - return points.begin() + numpoints; - } - - const_iterator end() const - { - return points.begin() + numpoints; - } - - WindingVertex &operator[](std::size_t index) - { - ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds"); - return points[index]; - } - - const WindingVertex &operator[](std::size_t index) const - { - ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds"); - return points[index]; - } - - void push_back(const WindingVertex &point) - { - points[numpoints] = point; - ++numpoints; - } - - void erase(iterator point) - { - for (iterator i = point + 1; i != end(); point = i, ++i) { - *point = *i; - } - --numpoints; - } -}; - -typedef BasicVector3 DoubleVector3; - -class DoubleLine { -public: -DoubleVector3 origin; -DoubleVector3 direction; -}; - -class FixedWindingVertex { -public: -DoubleVector3 vertex; -DoubleLine edge; -std::size_t adjacent; - -FixedWindingVertex(const DoubleVector3 &vertex_, const DoubleLine &edge_, std::size_t adjacent_) - : vertex(vertex_), edge(edge_), adjacent(adjacent_) -{ -} -}; - -struct FixedWinding { - typedef std::vector Points; - Points points; - - FixedWinding() - { - points.reserve(MAX_POINTS_ON_WINDING); - } - - FixedWindingVertex &front() - { - return points.front(); - } - - const FixedWindingVertex &front() const - { - return points.front(); - } - - FixedWindingVertex &back() - { - return points.back(); - } - - const FixedWindingVertex &back() const - { - return points.back(); - } - - void clear() - { - points.clear(); - } - - void push_back(const FixedWindingVertex &point) - { - points.push_back(point); - } - - std::size_t size() const - { - return points.size(); - } - - FixedWindingVertex &operator[](std::size_t index) - { - //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds"); - return points[index]; - } - - const FixedWindingVertex &operator[](std::size_t index) const - { - //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds"); - return points[index]; - } - -}; - - -inline void Winding_forFixedWinding(Winding &winding, const FixedWinding &fixed) -{ - winding.resize(fixed.size()); - winding.numpoints = fixed.size(); - for (std::size_t i = 0; i < fixed.size(); ++i) { - winding[i].vertex[0] = static_cast( fixed[i].vertex[0] ); - winding[i].vertex[1] = static_cast( fixed[i].vertex[1] ); - winding[i].vertex[2] = static_cast( fixed[i].vertex[2] ); - winding[i].adjacent = fixed[i].adjacent; - } -} - -inline std::size_t Winding_wrap(const Winding &winding, std::size_t i) -{ - ASSERT_MESSAGE(winding.numpoints != 0, "Winding_wrap: empty winding"); - return i % winding.numpoints; -} - -inline std::size_t Winding_next(const Winding &winding, std::size_t i) -{ - return Winding_wrap(winding, ++i); -} - - -class Plane3; - -void Winding_createInfinite(FixedWinding &w, const Plane3 &plane, double infinity); - -const double ON_EPSILON = 1.0 / (1 << 8); - -/// \brief Returns true if edge (\p x, \p y) is smaller than the epsilon used to classify winding points against a plane. -inline bool Edge_isDegenerate(const Vector3 &x, const Vector3 &y) -{ - return vector3_length_squared(y - x) < (ON_EPSILON * ON_EPSILON); -} - -void Winding_Clip(const FixedWinding &winding, const Plane3 &plane, const Plane3 &clipPlane, std::size_t adjacent, - FixedWinding &clipped); - -struct brushsplit_t { - brushsplit_t() - { - counts[0] = 0; - counts[1] = 0; - counts[2] = 0; - } - - brushsplit_t &operator+=(const brushsplit_t &other) - { - counts[0] += other.counts[0]; - counts[1] += other.counts[1]; - counts[2] += other.counts[2]; - return *this; - } - - std::size_t counts[3]; -}; - -brushsplit_t Winding_ClassifyPlane(const Winding &w, const Plane3 &plane); - -bool Winding_PlanesConcave(const Winding &w1, const Winding &w2, const Plane3 &plane1, const Plane3 &plane2); - -bool Winding_TestPlane(const Winding &w, const Plane3 &plane, bool flipped); - -std::size_t Winding_FindAdjacent(const Winding &w, std::size_t face); - -std::size_t Winding_Opposite(const Winding &w, const std::size_t index, const std::size_t other); - -std::size_t Winding_Opposite(const Winding &w, std::size_t index); - -void Winding_Centroid(const Winding &w, const Plane3 &plane, Vector3 ¢roid); - - -inline void Winding_printConnectivity(Winding &winding) -{ - for (Winding::iterator i = winding.begin(); i != winding.end(); ++i) { - std::size_t vertexIndex = std::distance(winding.begin(), i); - globalOutputStream() << "vertex: " << Unsigned(vertexIndex) << " adjacent: " << Unsigned((*i).adjacent) << "\n"; - } -} - -#endif diff --git a/src/windowobservers.cpp b/src/windowobservers.cpp deleted file mode 100644 index 49b92bf..0000000 --- a/src/windowobservers.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "windowobservers.h" - -#include -#include -#include "generic/bitfield.h" - -namespace { -ModifierFlags g_modifier_state = c_modifierNone; -} - -typedef std::vector WindowObservers; - -inline void WindowObservers_OnModifierDown(WindowObservers &observers, ModifierFlags type) -{ - g_modifier_state = bitfield_enable(g_modifier_state, type); - for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) { - (*i)->onModifierDown(type); - } -} - -inline void WindowObservers_OnModifierUp(WindowObservers &observers, ModifierFlags type) -{ - g_modifier_state = bitfield_disable(g_modifier_state, type); - for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) { - (*i)->onModifierUp(type); - } -} - -#include - -gboolean selection_modifier_key_press(ui::Widget widget, GdkEventKey *event, WindowObservers &observers) -{ - switch (event->keyval) { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierAlt); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierShift); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierControl); - break; - } - return FALSE; -} - -gboolean selection_modifier_key_release(ui::Widget widget, GdkEventKey *event, WindowObservers &observers) -{ - switch (event->keyval) { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierAlt); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierShift); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierControl); - break; - } - return FALSE; -} - -void WindowObservers_UpdateModifier(WindowObservers &observers, ModifierFlags modifiers, ModifierFlags modifier) -{ - if (!bitfield_enabled(g_modifier_state, modifier) && bitfield_enabled(modifiers, modifier)) { - WindowObservers_OnModifierDown(observers, modifier); - } - if (bitfield_enabled(g_modifier_state, modifier) && !bitfield_enabled(modifiers, modifier)) { - WindowObservers_OnModifierUp(observers, modifier); - } -} - -void WindowObservers_UpdateModifiers(WindowObservers &observers, ModifierFlags modifiers) -{ - WindowObservers_UpdateModifier(observers, modifiers, c_modifierAlt); - WindowObservers_UpdateModifier(observers, modifiers, c_modifierShift); - WindowObservers_UpdateModifier(observers, modifiers, c_modifierControl); -} - -gboolean modifiers_button_press(ui::Widget widget, GdkEventButton *event, WindowObservers *observers) -{ - if (event->type == GDK_BUTTON_PRESS) { - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean modifiers_button_release(ui::Widget widget, GdkEventButton *event, WindowObservers *observers) -{ - if (event->type == GDK_BUTTON_RELEASE) { - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean modifiers_motion(ui::Widget widget, GdkEventMotion *event, WindowObservers *observers) -{ - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - return FALSE; -} - - -WindowObservers g_window_observers; - -void GlobalWindowObservers_updateModifiers(ModifierFlags modifiers) -{ - WindowObservers_UpdateModifiers(g_window_observers, modifiers); -} - -void GlobalWindowObservers_add(WindowObserver *observer) -{ - g_window_observers.push_back(observer); -} - -void GlobalWindowObservers_connectTopLevel(ui::Window window) -{ - window.connect("key_press_event", G_CALLBACK(selection_modifier_key_press), &g_window_observers); - window.connect("key_release_event", G_CALLBACK(selection_modifier_key_release), &g_window_observers); -} - -void GlobalWindowObservers_connectWidget(ui::Widget widget) -{ - widget.connect("button_press_event", G_CALLBACK(modifiers_button_press), &g_window_observers); - widget.connect("button_release_event", G_CALLBACK(modifiers_button_release), &g_window_observers); - widget.connect("motion_notify_event", G_CALLBACK(modifiers_motion), &g_window_observers); -} - -int Get_Modifier_State(void); -ModifierFlags modifiers_for_state(unsigned int state) -{ - ModifierFlags modifiers = c_modifierNone; - if (Get_Modifier_State() & 1) { - modifiers |= c_modifierShift; - } - if (Get_Modifier_State() & 2) { - modifiers |= c_modifierControl; - } - if (Get_Modifier_State() & 4) { - modifiers |= c_modifierAlt; - } - return modifiers; -} - -ModifierFlags modifiers_for_key(unsigned int state) -{ - ModifierFlags modifiers = c_modifierNone; - if (state & GDK_CONTROL_MASK) { - modifiers |= c_modifierShift; - } - if (state & GDK_SHIFT_MASK) { - modifiers |= c_modifierControl; - } - if (state & GDK_MOD1_MASK) { - modifiers |= c_modifierAlt; - } - return modifiers; -} diff --git a/src/windowobservers.h b/src/windowobservers.h deleted file mode 100644 index 7daadc2..0000000 --- a/src/windowobservers.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WINDOWOBSERVERS_H ) -#define INCLUDED_WINDOWOBSERVERS_H - -#include "windowobserver.h" - -#include - -#include "math/vector.h" - -class WindowObserver; - -void GlobalWindowObservers_add(WindowObserver *observer); - -void GlobalWindowObservers_connectWidget(ui::Widget widget); - -void GlobalWindowObservers_connectTopLevel(ui::Window window); - -inline ButtonIdentifier button_for_button(unsigned int button) -{ - switch (button) { - case 1: - return c_buttonLeft; - case 2: - return c_buttonMiddle; - case 3: - return c_buttonRight; - } - return c_buttonInvalid; -} - -ModifierFlags modifiers_for_state(unsigned int state); -ModifierFlags modifiers_for_state_cam(unsigned int state); - -inline WindowVector WindowVector_forDouble(double x, double y) -{ - return WindowVector(static_cast( x ), static_cast( y )); -} - -#endif diff --git a/src/worldspawn.ico b/src/worldspawn.ico deleted file mode 100644 index 592a1844e17eb4d77cb14aec01290f332578b27f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5430 zcmbuD2UOHozQ@Oyyd-b4hBSLYO`?e!NS?7ojerGf6j4NqAXbW^0@9HV(uUq~7&_8> zRX`~!3Zfubh+siYBIv4-81(ZlX5E*Z&C5y7-g7Q@_|N_I@2|{XA{ioiMWU!E5vQUg zO+h00SR#=qh;#7&U9URbj$J#XT~ z2;Z@xPji{_@A~1bsef0vEq85h3UjANVCimU0gqeGQSIl({j;ZeRC`Q3E21MijlMId z=q|~lHSI7r$_r`FkkekAOCis5XBx z=KX)e!>tq_zx$P0+^fjpc)&q=8yo0Ijis-tk)N-3(_Ng!wW1vA<&ivUsG+x^n(m@Z zN`!sKp0wr zwpF}ec7(?Q-!}@gU)bE77RT{Wf3B7n)8E-ndwwRjO7rP!ZszfYb9{gLBs~@RT+B-5 zY(hB4q5_Dr-A`_)FD_eFQ7CmM#nlRXt;JMHJ-C&hMy20DB208K)>LEem*W&)>ToMy zuk1!?CVef9lm@$t`wmnD`UsgB-0Qr`<)UnkCd=qO*GylB$hrFuczC^w%XKFxiwGp$ z!Tnq@Qi^c zPq@=`n#*PR$XyO#r@f2qPFqu=cnAPE~QfV&fip@oDd(*XD84YA5EmSDN*~kkZ8M2;8cdys!wrWKMxn} zg{Xb;iQ&DxL|LP|CB4NRc%q;T#|=!WVa6S+ct7OBc1-Mm$@x4RuvIU;z0{yoNVZ5Jj30# z^9($C#H}lrxp(yvJpvC+WyR!q+Ou!@92~c-CE3M-2%9}b3q6b%PQgLrE2<*>u~7XO zzs>46E?44^{!+}fRjY1?T2r}8lL9j>@~n4oT-1-Q%2KjK4kzw5zzr`}7_OrvDwz0v zn}z%janqcK|E9%+7^<^p-9l~#SyQ@o5xI_gC=oku=QsFk%)w^CL~H~fR}B@id_>%n zj}aDJK}BH=hg@9n-nof*$GzBTsbI1EODvX5W9Qt-n0_@Gvjvl}Su!1GJq?jZUSzpi zkg(4H8?}kZ%yh6{@fkrzE7-kuCf|oxaoXCDqoPLF1h{h{Baw#Ka0=}AaJ#&eYh{I` zMC9P$lucyxQBn_Q5EB-T$4)I`M7(U)eTA{A5(n1I#b)*V7rHpEQNu-d6|qj{xNlTP zx^+EX>%Yclqbl)&CfH~-hqT4rb+fqZV?wRKbBCyt=X2A9-^lrAFYdKq|$_ zAp&oYG~!}%@j4iS(e`clT3O;D_&9G=W2^cCc5d5(!OZdO65Dvzhc99lEo!dy5+xi( zPI|4IC$PLq$W_5@-E1OE*I}l)h@M!Fs!I``oC$U2PGdc%jwDeTEk*8ZP4JHO#Ck;& z;^t3LR0?HDIW%RLkSOeT-)l_ZHVtA#ZdtBZ!PR;%ChA`h?_f^c{>}Jp*TQDyJZzRK z;k9ugwrl6&Yq*lAJp$uaM#%T*vVHB+ss}~!vP%I@oELSpMAVm*JqF|*+()bEGx581 zX(~O+$(&4%CdjEuNECJF4iA3lr79zX3=cb;1(pI#4Dq$Mr#3a7Qt2VGh2Qq6OvPK+ zYPV_@u_Et+_HM^cV>TxR7SG0p;BB}B?NxJR{n@^T*ADwp=emy*0{hYW%gM7dA;WSz z?%JwU$H!2cm&4Jh2u^2bbMMA&PL);Cb@~h`UI&Twb|Y2P-f~}8>N3*s(OZMB!5Yk# z&&5t%8K<@L$oIBEF8Xi0s70+w(G+_+;4boT>B5-;cmWFE$$bYdin>;2VL-a+deZjj zktpuA5oEGC3t3uDYwr{bxh zij&YidZ!K%yEJgsT}GJE8XCd_IVpTB7r9`st3EJh#>f|a_+G4|>|#t14W4#X+wY`W z^p6LkzkGN06pa~4RLdf0tvxRMAH}h(G_JO^a81kr7pp5d66{O3*=E{L)l-v}Kvklg zD2D?$ubzj)vQH@xIht&1Mq^|E<=zfN?$#pKcn#Y&%zx2;276F{NtojGAX{qe_EPD2 zQ1pK{YQm(nWTuN=V9zZvf80FPh_{Hznc^aDU2LNwC!4O5wN#|1kSA(Ywdf6HK|W-8 zI8dJyPm;GY89uJuZ#qv?Toe^jPg3?7lD1zD&+Y42{>>c4LD?@?Uv_}s)hH1gTYCx} zY^V;Y2>#k`d2 zVo$!HEee-%rLt1gZz~e_>WjSACU)0atn}CYX8st|fzvSx5Aw^JThr<|>K9Lzg9nlO zEs1lqBgVp%XiHOaeBA}sH^1O}T$V^#oSgEQIC6Y^@YrF%AuUxrw3pzmw_MaFZKMXP zM6XpNdAB|tNpgw>u48ttYhJbF^M9MaUg%I8uhf%O+Shudk%pui%3>Mx)`C-aEStWhvQyQsHzeIKZEh{O z4Rmy-GDz_C4#eL|D&{*qfPbG zEJVIV4f*ypWSAL|Z*JI}XuA0i?S3iy<;kfSg~vw{1Ny4#`A1Vb*D5U;Tn#{lv3s!OkIdCXT$s{a}+(z-XfsFV&Ct^`=zWuI-k~O zDfSnK%kF1{KfjTYLuY0gZIRJ51VxEiyMSYnB{YO3b0sT_mc#_Qj>zduj(OgBI9OKd zVy^f{y#LB~90^qDZ_F_4Kb|l9E?ZW0CnbpMNfF#W63fH#WPV7Ethz3j$}R;t7(Pw( z{?qnSJ#_F_Is+2P!hVTl!hMP4?JkMr^=gS^=-_r1uMY;d>l!8V#k{bYJe^LVYbaJFl?%%U9VXnI_pf`yIhiEQeo? zU;kY+<4qpk`+?i-wLIwUCBj^rhfi*!J$n@MrVK-4mNH*|GW3_129Cd`lt^ss{aChi z18b)Koe%?cd^N{nr2HnIT9hzFWfwp8eoyy>(`;F$jN;fKNG$%3US;-h&bC}dbH)cO z`{X^AO@15w&xdi`bSxhkS2AfsA|E-)?vmZC+INik(_dri`$HN1?hsZB z+jZuTL2J$!LUt&#OLZd4J{!U2c@t>AbQjn9M*f!Q&*(5)-gDlZ&GbjC> z+2h_saoA7{mXBo1($T^n3f%8*6TTRask$Oxnb;upT)~i4D;W~9lht33X0h@JEQGIS zjT^?7V}~*QGbIePMsnlZCQR3k!NW|A$jmiZme$}<5{d4DvFNLeM|0+AWty2 zP8-hGAAZ36Y2%nW;lE$Rz+vx9tn|jwdAW=K@-h?t7=@wA7#6H~AKiIlS@rn{*3KEl z%Fjo#aQgcwO;BKphUUNGueW+QoA$2Yb@#Ij5AWmkaxdPCn2XNWqu8c04kNMG2@D%8 zoPhGgxA|z~TYT}+JO82|M3G0DlnJT#dDUJA^QHpc$lHZt%sxVE3WV$t=*=BNVO0a` z)n_op$on_6|Ae8$VB<)#YKq7?*T}0@s%V7T(IfK7FWCz-S6@!GbueevZ{@zE{q^bR zHyNj#6s+@Q*yS~Gspl>`cZ~X7nf((alCIY!lIo!niL - -class ISAXHandler; - -// a 'user data' structure we pass along in the SAX callbacks to represent the current state -// the recurse value tracks the current depth in the tree -// message_info also stores information to exit the stream listening cleanly with an error: -// if msg_level == SYS_ERR, then we will reset the listening at the end of the current node -// the level for stopping the feed is stored in stop_depth -// unkown nodes are ignored, we use ignore_depth to track the level we start ignoring from -struct message_info_t { - int msg_level; // current message level (SYS_MSG, SYS_WRN, SYS_ERR) - int recurse; // current recursion depth (used to track various things) - int ignore_depth; // the ignore depth limit when we are jumping over unknown nodes (0 means we are not ignoring) - int stop_depth; // the depth we need to stop at the end - int geometry_depth; // are we parsing some geometry information (i.e. do we forward the SAX calls?) - ISAXHandler *pGeometry; // the handler - - enum unnamed0 { bufsize = 1024 }; - char m_buffer[bufsize]; - std::size_t m_length; -}; - -class IGL2DWindow; - -class ISAXHandler { -public: -virtual ~ISAXHandler() = default; - -virtual void Release() -{ -} - -virtual void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) = 0; - -virtual void saxEndElement(message_info_t *ctx, const xmlChar *name) = 0; - -virtual void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) = 0; - -virtual const char *getName() -{ - return NULL; -} - -virtual IGL2DWindow *Highlight() -{ - return 0; -} - -virtual void DropHighlight() -{ -} -}; - -#endif diff --git a/src/xywindow.cpp b/src/xywindow.cpp deleted file mode 100644 index ba2d7c5..0000000 --- a/src/xywindow.cpp +++ /dev/null @@ -1,2998 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// XY Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "xywindow.h" - -#include - -#include "debugging/debugging.h" - -#include "ientity.h" -#include "igl.h" -#include "ibrush.h" -#include "iundo.h" -#include "iimage.h" -#include "ifilesystem.h" -#include "os/path.h" -#include "image.h" -#include "gtkutil/messagebox.h" - -#include -#include - -#include "generic/callback.h" -#include "string/string.h" -#include "stream/stringstream.h" - -#include "scenelib.h" -#include "eclasslib.h" -#include "renderer.h" -#include "moduleobserver.h" - -#include "gtkutil/menu.h" -#include "gtkutil/container.h" -#include "gtkutil/widget.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/filechooser.h" -#include "gtkmisc.h" -#include "select.h" -#include "csg.h" -#include "brushmanip.h" -#include "selection.h" -#include "entity.h" -#include "camwindow.h" -#include "texwindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "commands.h" -#include "feedback.h" -#include "grid.h" -#include "windowobservers.h" - -void LoadTextureRGBA(qtexture_t *q, unsigned char *pPixels, int nWidth, int nHeight); - -// d1223m -extern bool g_brush_always_caulk; - -//!\todo Rewrite. -class ClipPoint { -public: -Vector3 m_ptClip; // the 3d point -bool m_bSet; - -ClipPoint() -{ - Reset(); -}; - -void Reset() -{ - m_ptClip[0] = m_ptClip[1] = m_ptClip[2] = 0.0; - m_bSet = false; -} - -bool Set() -{ - return m_bSet; -} - -void Set(bool b) -{ - m_bSet = b; -} - -operator Vector3 &() -{ - return m_ptClip; -}; - -/*! Draw clip/path point with rasterized number label */ -void Draw(int num, float scale); - -/*! Draw clip/path point with rasterized string label */ -void Draw(const char *label, float scale); -}; - -VIEWTYPE g_clip_viewtype; -bool g_bSwitch = true; -bool g_clip_useCaulk = true; -ClipPoint g_Clip1; -ClipPoint g_Clip2; -ClipPoint g_Clip3; -ClipPoint *g_pMovingClip = 0; - -/* Drawing clip points */ -void ClipPoint::Draw(int num, float scale) -{ - StringOutputStream label(4); - label << num; - Draw(label.c_str(), scale); -} - -void ClipPoint::Draw(const char *label, float scale) -{ - // draw point - glPointSize(4); - glColor3fv(vector3_to_array(g_xywindow_globals.color_clipper)); - glBegin(GL_POINTS); - glVertex3fv(vector3_to_array(m_ptClip)); - glEnd(); - glPointSize(1); - - float offset = 2.0f / scale; - - // draw label - glRasterPos3f(m_ptClip[0] + offset, m_ptClip[1] + offset, m_ptClip[2] + offset); - glCallLists(GLsizei(strlen(label)), GL_UNSIGNED_BYTE, label); -} - -float fDiff(float f1, float f2) -{ - if (f1 > f2) { - return f1 - f2; - } else { - return f2 - f1; - } -} - -inline double ClipPoint_Intersect(const ClipPoint &clip, const Vector3 &point, VIEWTYPE viewtype, float scale) -{ - int nDim1 = (viewtype == YZ) ? 1 : 0; - int nDim2 = (viewtype == XY) ? 1 : 2; - double screenDistanceSquared(vector2_length_squared(Vector2(fDiff(clip.m_ptClip[nDim1], point[nDim1]) * scale, - fDiff(clip.m_ptClip[nDim2], point[nDim2]) * scale))); - if (screenDistanceSquared < 8 * 8) { - return screenDistanceSquared; - } - return FLT_MAX; -} - -inline void -ClipPoint_testSelect(ClipPoint &clip, const Vector3 &point, VIEWTYPE viewtype, float scale, double &bestDistance, - ClipPoint *&bestClip) -{ - if (clip.Set()) { - double distance = ClipPoint_Intersect(clip, point, viewtype, scale); - if (distance < bestDistance) { - bestDistance = distance; - bestClip = &clip; - } - } -} - -inline ClipPoint *GlobalClipPoints_Find(const Vector3 &point, VIEWTYPE viewtype, float scale) -{ - double bestDistance = FLT_MAX; - ClipPoint *bestClip = 0; - ClipPoint_testSelect(g_Clip1, point, viewtype, scale, bestDistance, bestClip); - ClipPoint_testSelect(g_Clip2, point, viewtype, scale, bestDistance, bestClip); - ClipPoint_testSelect(g_Clip3, point, viewtype, scale, bestDistance, bestClip); - return bestClip; -} - -inline void GlobalClipPoints_Draw(float scale) -{ - // Draw clip points - if (g_Clip1.Set()) { - g_Clip1.Draw(1, scale); - } - if (g_Clip2.Set()) { - g_Clip2.Draw(2, scale); - } - if (g_Clip3.Set()) { - g_Clip3.Draw(3, scale); - } -} - -inline bool GlobalClipPoints_valid() -{ - return g_Clip1.Set() && g_Clip2.Set(); -} - -void PlanePointsFromClipPoints(Vector3 planepts[3], const AABB &bounds, int viewtype) -{ - ASSERT_MESSAGE(GlobalClipPoints_valid(), "clipper points not initialised"); - planepts[0] = g_Clip1.m_ptClip; - planepts[1] = g_Clip2.m_ptClip; - planepts[2] = g_Clip3.m_ptClip; - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - if (!g_Clip3.Set()) { - int n = (viewtype == XY) ? 2 : (viewtype == YZ) ? 0 : 1; - int x = (n == 0) ? 1 : 0; - int y = (n == 2) ? 1 : 2; - - if (n == 1) { // on viewtype XZ, flip clip points - planepts[0][n] = maxs[n]; - planepts[1][n] = maxs[n]; - planepts[2][x] = g_Clip1.m_ptClip[x]; - planepts[2][y] = g_Clip1.m_ptClip[y]; - planepts[2][n] = mins[n]; - } else { - planepts[0][n] = mins[n]; - planepts[1][n] = mins[n]; - planepts[2][x] = g_Clip1.m_ptClip[x]; - planepts[2][y] = g_Clip1.m_ptClip[y]; - planepts[2][n] = maxs[n]; - } - } -} - -void Clip_Update() -{ - Vector3 planepts[3]; - if (!GlobalClipPoints_valid()) { - planepts[0] = Vector3(0, 0, 0); - planepts[1] = Vector3(0, 0, 0); - planepts[2] = Vector3(0, 0, 0); - Scene_BrushSetClipPlane(GlobalSceneGraph(), Plane3(0, 0, 0, 0)); - } else { - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - if (g_bSwitch) { - std::swap(planepts[0], planepts[1]); - } - Scene_BrushSetClipPlane(GlobalSceneGraph(), plane3_for_points(planepts[0], planepts[1], planepts[2])); - } - ClipperChangeNotify(); -} - -const char *Clip_getShader() -{ - return g_clip_useCaulk ? "textures/common/caulk" : TextureBrowser_GetSelectedShader(GlobalTextureBrowser()); -} - -void Clip() -{ - if (ClipMode() && GlobalClipPoints_valid()) { - Vector3 planepts[3]; - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - Scene_BrushSplitByPlane(GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), - (!g_bSwitch) ? eFront : eBack); - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void SplitClip() -{ - if (ClipMode() && GlobalClipPoints_valid()) { - Vector3 planepts[3]; - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - Scene_BrushSplitByPlane(GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), - eFrontAndBack); - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void FlipClip() -{ - g_bSwitch = !g_bSwitch; - Clip_Update(); - ClipperChangeNotify(); -} - -void OnClipMode(bool enabled) -{ - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - - if (!enabled && g_pMovingClip) { - g_pMovingClip = 0; - } - - Clip_Update(); - ClipperChangeNotify(); -} - -bool ClipMode() -{ - return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip; -} - -void NewClipPoint(const Vector3 &point) -{ - if (g_Clip1.Set() == false) { - g_Clip1.m_ptClip = point; - g_Clip1.Set(true); - } else if (g_Clip2.Set() == false) { - g_Clip2.m_ptClip = point; - g_Clip2.Set(true); - } else if (g_Clip3.Set() == false) { - g_Clip3.m_ptClip = point; - g_Clip3.Set(true); - } else { - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - g_Clip1.m_ptClip = point; - g_Clip1.Set(true); - } - - Clip_Update(); - ClipperChangeNotify(); -} - - -struct xywindow_globals_private_t { - bool d_showgrid; - - // these are in the View > Show menu with Show coordinates - bool show_names; - bool show_coordinates; - bool show_angles; - bool show_outline; - bool show_axis; - - bool d_show_work; - - bool show_blocks; - int blockSize; - - bool m_bCamXYUpdate; - bool m_bChaseMouse; - bool m_bSizePaint; - - xywindow_globals_private_t() : - d_showgrid(true), - /* all very performance intensive */ - show_names(false), - show_coordinates(false), - show_angles(false), - show_outline(false), - show_axis(false), - d_show_work(false), - - show_blocks(true), - - m_bCamXYUpdate(true), - m_bChaseMouse(true), - m_bSizePaint(true) - { - } -}; - -xywindow_globals_t g_xywindow_globals; -xywindow_globals_private_t g_xywindow_globals_private; - -const unsigned int RAD_NONE = 0x00; -const unsigned int RAD_SHIFT = 0x01; -const unsigned int RAD_ALT = 0x02; -const unsigned int RAD_CONTROL = 0x04; -const unsigned int RAD_PRESS = 0x08; -const unsigned int RAD_LBUTTON = 0x10; -const unsigned int RAD_MBUTTON = 0x20; -const unsigned int RAD_RBUTTON = 0x40; - -inline ButtonIdentifier button_for_flags(unsigned int flags) -{ - if (flags & RAD_LBUTTON) { - return c_buttonLeft; - } - if (flags & RAD_RBUTTON) { - return c_buttonRight; - } - if (flags & RAD_MBUTTON) { - return c_buttonMiddle; - } - return c_buttonInvalid; -} - -inline ModifierFlags modifiers_for_flags(unsigned int flags) -{ - ModifierFlags modifiers = c_modifierNone; - if (flags & RAD_SHIFT) { - modifiers |= c_modifierShift; - } - if (flags & RAD_CONTROL) { - modifiers |= c_modifierControl; - } - if (flags & RAD_ALT) { - modifiers |= c_modifierAlt; - } - return modifiers; -} - -inline unsigned int buttons_for_button_and_modifiers(ButtonIdentifier button, ModifierFlags flags) -{ - unsigned int buttons = 0; - - switch (button.get()) { - case ButtonEnumeration::INVALID: - break; - case ButtonEnumeration::LEFT: - buttons |= RAD_LBUTTON; - break; - case ButtonEnumeration::MIDDLE: - buttons |= RAD_MBUTTON; - break; - case ButtonEnumeration::RIGHT: - buttons |= RAD_RBUTTON; - break; - } - - if (bitfield_enabled(flags, c_modifierControl)) { - buttons |= RAD_CONTROL; - } - - if (bitfield_enabled(flags, c_modifierShift)) { - buttons |= RAD_SHIFT; - } - - if (bitfield_enabled(flags, c_modifierAlt)) { - buttons |= RAD_ALT; - } - - return buttons; -} - -inline unsigned int buttons_for_event_button(GdkEventButton *event) -{ - unsigned int flags = 0; - - switch (event->button) { - case 1: - flags |= RAD_LBUTTON; - break; - case 2: - flags |= RAD_MBUTTON; - break; - case 3: - flags |= RAD_RBUTTON; - break; - } - - if ((event->state & GDK_CONTROL_MASK) != 0) { - flags |= RAD_CONTROL; - } - - if ((event->state & GDK_SHIFT_MASK) != 0) { - flags |= RAD_SHIFT; - } - - if ((event->state & GDK_MOD1_MASK) != 0) { - flags |= RAD_ALT; - } - - return flags; -} - -inline unsigned int buttons_for_state(guint state) -{ - unsigned int flags = 0; - - if ((state & GDK_BUTTON1_MASK) != 0) { - flags |= RAD_LBUTTON; - } - - if ((state & GDK_BUTTON2_MASK) != 0) { - flags |= RAD_MBUTTON; - } - - if ((state & GDK_BUTTON3_MASK) != 0) { - flags |= RAD_RBUTTON; - } - - if ((state & GDK_CONTROL_MASK) != 0) { - flags |= RAD_CONTROL; - } - - if ((state & GDK_SHIFT_MASK) != 0) { - flags |= RAD_SHIFT; - } - - if ((state & GDK_MOD1_MASK) != 0) { - flags |= RAD_ALT; - } - - return flags; -} - - -void XYWnd::SetScale(float f) -{ - m_fScale = f; - updateProjection(); - updateModelview(); - XYWnd_Update(*this); -} - -void XYWnd_ZoomIn(XYWnd *xy) -{ - float max_scale = 64; - float scale = xy->Scale() * 5.0f / 4.0f; - if (scale > max_scale) { - if (xy->Scale() != max_scale) { - xy->SetScale(max_scale); - } - } else { - xy->SetScale(scale); - } -} - - -// NOTE: the zoom out factor is 4/5, we could think about customizing it -// we don't go below a zoom factor corresponding to 10% of the max world size -// (this has to be computed against the window size) -void XYWnd_ZoomOut(XYWnd *xy) -{ - float min_scale = MIN(xy->Width(), xy->Height()) / (1.1f * (g_MaxWorldCoord - g_MinWorldCoord)); - float scale = xy->Scale() * 4.0f / 5.0f; - if (scale < min_scale) { - if (xy->Scale() != min_scale) { - xy->SetScale(min_scale); - } - } else { - xy->SetScale(scale); - } -} - -VIEWTYPE GlobalXYWnd_getCurrentViewType() -{ - ASSERT_NOTNULL(g_pParentWnd); - ASSERT_NOTNULL(g_pParentWnd->ActiveXY()); - return g_pParentWnd->ActiveXY()->GetViewType(); -} - -// ============================================================================= -// variables - -bool g_bCrossHairs = false; - -ui::Menu XYWnd::m_mnuDrop(ui::null); -ui::Menu XYWnd::m_mnuDropSingle(ui::null); -ui::Menu XYWnd::m_mnuDropMultiple(ui::null); - -// this is disabled, and broken -// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394 -#if 0 -void WXY_Print(){ - long width, height; - width = g_pParentWnd->ActiveXY()->Width(); - height = g_pParentWnd->ActiveXY()->Height(); - unsigned char* img; - const char* filename; - - filename = ui::file_dialog( MainFrame_getWindow( ), FALSE, "Save Image", 0, FILTER_BMP ); - if ( !filename ) { - return; - } - - g_pParentWnd->ActiveXY()->MakeCurrent(); - img = (unsigned char*)malloc( width * height * 3 ); - glReadPixels( 0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,img ); - - FILE *fp; - fp = fopen( filename, "wb" ); - if ( fp ) { - unsigned short bits; - unsigned long cmap, bfSize; - - bits = 24; - cmap = 0; - bfSize = 54 + width * height * 3; - - long byteswritten = 0; - long pixoff = 54 + cmap * 4; - short res = 0; - char m1 = 'B', m2 = 'M'; - fwrite( &m1, 1, 1, fp ); byteswritten++; // B - fwrite( &m2, 1, 1, fp ); byteswritten++; // M - fwrite( &bfSize, 4, 1, fp ); byteswritten += 4; // bfSize - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved1 - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved2 - fwrite( &pixoff, 4, 1, fp ); byteswritten += 4; // bfOffBits - - unsigned long biSize = 40, compress = 0, size = 0; - long pixels = 0; - unsigned short planes = 1; - fwrite( &biSize, 4, 1, fp ); byteswritten += 4; // biSize - fwrite( &width, 4, 1, fp ); byteswritten += 4; // biWidth - fwrite( &height, 4, 1, fp ); byteswritten += 4; // biHeight - fwrite( &planes, 2, 1, fp ); byteswritten += 2; // biPlanes - fwrite( &bits, 2, 1, fp ); byteswritten += 2; // biBitCount - fwrite( &compress, 4, 1, fp ); byteswritten += 4; // biCompression - fwrite( &size, 4, 1, fp ); byteswritten += 4; // biSizeImage - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biXPelsPerMeter - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biYPelsPerMeter - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrUsed - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrImportant - - unsigned long widthDW = ( ( ( width * 24 ) + 31 ) / 32 * 4 ); - long row, row_size = width * 3; - for ( row = 0; row < height; row++ ) - { - unsigned char* buf = img + row * row_size; - - // write a row - int col; - for ( col = 0; col < row_size; col += 3 ) - { - putc( buf[col + 2], fp ); - putc( buf[col + 1], fp ); - putc( buf[col], fp ); - } - byteswritten += row_size; - - unsigned long count; - for ( count = row_size; count < widthDW; count++ ) - { - putc( 0, fp ); // dummy - byteswritten++; - } - } - - fclose( fp ); - } - - free( img ); -} -#endif - - -#include "timer.h" - -Timer g_chasemouse_timer; - -void XYWnd::ChaseMouse() -{ - float multiplier = g_chasemouse_timer.elapsed_msec() / 10.0f; - Scroll(float_to_integer(multiplier * m_chasemouse_delta_x), float_to_integer(multiplier * -m_chasemouse_delta_y)); - - //globalOutputStream() << "chasemouse: multiplier=" << multiplier << " x=" << m_chasemouse_delta_x << " y=" << m_chasemouse_delta_y << '\n'; - - XY_MouseMoved(m_chasemouse_current_x, m_chasemouse_current_y, getButtonState()); - g_chasemouse_timer.start(); -} - -gboolean xywnd_chasemouse(gpointer data) -{ - reinterpret_cast( data )->ChaseMouse(); - return TRUE; -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -bool XYWnd::chaseMouseMotion(int pointx, int pointy) -{ - m_chasemouse_delta_x = 0; - m_chasemouse_delta_y = 0; - - if (g_xywindow_globals_private.m_bChaseMouse && getButtonState() == RAD_LBUTTON) { - const int epsilon = 16; - - if (pointx < epsilon) { - m_chasemouse_delta_x = std::max(pointx, 0) - epsilon; - } else if ((pointx - m_nWidth) > -epsilon) { - m_chasemouse_delta_x = min_int((pointx - m_nWidth), 0) + epsilon; - } - - if (pointy < epsilon) { - m_chasemouse_delta_y = std::max(pointy, 0) - epsilon; - } else if ((pointy - m_nHeight) > -epsilon) { - m_chasemouse_delta_y = min_int((pointy - m_nHeight), 0) + epsilon; - } - - if (m_chasemouse_delta_y != 0 || m_chasemouse_delta_x != 0) { - //globalOutputStream() << "chasemouse motion: x=" << pointx << " y=" << pointy << "... "; - m_chasemouse_current_x = pointx; - m_chasemouse_current_y = pointy; - if (m_chasemouse_handler == 0) { - //globalOutputStream() << "chasemouse timer start... "; - g_chasemouse_timer.start(); - m_chasemouse_handler = g_idle_add(xywnd_chasemouse, this); - } - return true; - } else { - if (m_chasemouse_handler != 0) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove(m_chasemouse_handler); - m_chasemouse_handler = 0; - } - } - } else { - if (m_chasemouse_handler != 0) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove(m_chasemouse_handler); - m_chasemouse_handler = 0; - } - } - return false; -} - -// ============================================================================= -// XYWnd class -Shader *XYWnd::m_state_selected = 0; -ModifierFlags modifiers_for_key(unsigned int state); -void xy_update_xor_rectangle(XYWnd &self, rect_t area) -{ - if (self.GetWidget().visible()) { - self.m_XORRectangle.set(rectangle_from_area(area.min, area.max, self.Width(), self.Height())); - } -} - -gboolean xywnd_button_press(ui::Widget widget, GdkEventButton *event, XYWnd *xywnd) -{ - if (event->type == GDK_BUTTON_PRESS) { - g_pParentWnd->SetActiveXY(xywnd); - - xywnd->ButtonState_onMouseDown(buttons_for_event_button(event)); - - xywnd->onMouseDown(WindowVector(event->x, event->y), button_for_button(event->button), - modifiers_for_key(event->state)); - } - return FALSE; -} - -gboolean xywnd_button_release(ui::Widget widget, GdkEventButton *event, XYWnd *xywnd) -{ - if (event->type == GDK_BUTTON_RELEASE) { - xywnd->XY_MouseUp(static_cast( event->x ), static_cast( event->y ), buttons_for_event_button(event)); - - xywnd->ButtonState_onMouseUp(buttons_for_event_button(event)); - } - return FALSE; -} - -gboolean xywnd_focus_in(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - if (event->type == GDK_FOCUS_CHANGE) { - if (event->in) { - g_pParentWnd->SetActiveXY(xywnd); - } - } - return FALSE; -} - -void xywnd_motion(gdouble x, gdouble y, guint state, void *data) -{ - if (reinterpret_cast( data )->chaseMouseMotion(static_cast( x ), static_cast( y ))) { - return; - } - reinterpret_cast( data )->XY_MouseMoved(static_cast( x ), static_cast( y ), - buttons_for_state(state)); -} - -gboolean xywnd_wheel_scroll(ui::Widget widget, GdkEventScroll *event, XYWnd *xywnd) -{ - if (event->direction == GDK_SCROLL_UP) { - XYWnd_ZoomIn(xywnd); - } else if (event->direction == GDK_SCROLL_DOWN) { - XYWnd_ZoomOut(xywnd); - } - return FALSE; -} - -gboolean xywnd_size_allocate(ui::Widget widget, GtkAllocation *allocation, XYWnd *xywnd) -{ - xywnd->m_nWidth = allocation->width; - xywnd->m_nHeight = allocation->height; - xywnd->updateProjection(); - xywnd->m_window_observer->onSizeChanged(xywnd->Width(), xywnd->Height()); - return FALSE; -} - -gboolean xywnd_expose(ui::Widget widget, GdkEventExpose *event, XYWnd *xywnd) -{ - if (glwidget_make_current(xywnd->GetWidget()) != FALSE) { - if (Map_Valid(g_map) && ScreenUpdates_Enabled()) { - GlobalOpenGL_debugAssertNoErrors(); - xywnd->XY_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - - xywnd->m_XORRectangle.set(rectangle_t()); - } - glwidget_swap_buffers(xywnd->GetWidget()); - } - return FALSE; -} - - -void XYWnd_CameraMoved(XYWnd &xywnd) -{ - if (g_xywindow_globals_private.m_bCamXYUpdate) { - XYWnd_Update(xywnd); - } -} - -XYWnd::XYWnd() : - m_gl_widget(glwidget_new(FALSE)), - m_deferredDraw(WidgetQueueDrawCaller(m_gl_widget)), - m_deferred_motion(xywnd_motion, this), - m_parent(ui::null), - m_window_observer(NewWindowObserver()), - m_XORRectangle(m_gl_widget), - m_chasemouse_handler(0) -{ - m_bActive = false; - m_buttonstate = 0; - - m_bNewBrushDrag = false; - m_move_started = false; - m_zoom_started = false; - - m_nWidth = 0; - m_nHeight = 0; - - m_vOrigin[0] = 0; - m_vOrigin[1] = 20; - m_vOrigin[2] = 46; - m_fScale = 1; - m_viewType = XY; - - m_backgroundActivated = false; - m_alpha = 1.0f; - m_xmin = 0.0f; - m_ymin = 0.0f; - m_xmax = 0.0f; - m_ymax = 0.0f; - - m_entityCreate = false; - - m_mnuDrop = ui::Menu(ui::null); - m_mnuDropSingle = ui::Menu(ui::null); - m_mnuDropMultiple = ui::Menu(ui::null); - - GlobalWindowObservers_add(m_window_observer); - GlobalWindowObservers_connectWidget(m_gl_widget); - - m_window_observer->setRectangleDrawCallback(ReferenceCaller(*this)); - m_window_observer->setView(m_view); - - g_object_ref(m_gl_widget._handle); - - gtk_widget_set_events(m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(m_gl_widget, true); - - m_sizeHandler = m_gl_widget.connect("size_allocate", G_CALLBACK(xywnd_size_allocate), this); - m_exposeHandler = m_gl_widget.on_render(G_CALLBACK(xywnd_expose), this); - - m_gl_widget.connect("button_press_event", G_CALLBACK(xywnd_button_press), this); - m_gl_widget.connect("button_release_event", G_CALLBACK(xywnd_button_release), this); - m_gl_widget.connect("focus_in_event", G_CALLBACK(xywnd_focus_in), this); - m_gl_widget.connect("motion_notify_event", G_CALLBACK(DeferredMotion::gtk_motion), &m_deferred_motion); - - m_gl_widget.connect("scroll_event", G_CALLBACK(xywnd_wheel_scroll), this); - - Map_addValidCallback(g_map, DeferredDrawOnMapValidChangedCaller(m_deferredDraw)); - - updateProjection(); - updateModelview(); - - AddSceneChangeCallback(ReferenceCaller(*this)); - AddCameraMovedCallback(ReferenceCaller(*this)); - - PressedButtons_connect(g_pressedButtons, m_gl_widget); - - onMouseDown.connectLast(makeSignalHandler3(MouseDownCaller(), *this)); -} - -XYWnd::~XYWnd() -{ - onDestroyed(); - - if (m_mnuDrop) { - m_mnuDrop.destroy(); - m_mnuDrop = ui::Menu(ui::null); - } - - if (m_mnuDropSingle) { - m_mnuDropSingle.destroy(); - m_mnuDropSingle = ui::Menu(ui::null); - } - - if (m_mnuDropMultiple) { - m_mnuDropMultiple.destroy(); - m_mnuDropMultiple = ui::Menu(ui::null); - } - - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_exposeHandler); - - m_gl_widget.unref(); - - m_window_observer->release(); -} - -void XYWnd::captureStates() -{ - m_state_selected = GlobalShaderCache().capture("$XY_OVERLAY"); -} - -void XYWnd::releaseStates() -{ - GlobalShaderCache().release("$XY_OVERLAY"); -} - -const Vector3 &XYWnd::GetOrigin() -{ - return m_vOrigin; -} - -void XYWnd::SetOrigin(const Vector3 &origin) -{ - m_vOrigin = origin; - updateModelview(); -} - -void XYWnd::Scroll(int x, int y) -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - m_vOrigin[nDim1] += x / m_fScale; - m_vOrigin[nDim2] += y / m_fScale; - updateModelview(); - queueDraw(); -} - -unsigned int Clipper_buttons() -{ - return RAD_LBUTTON; -} - -void XYWnd::DropClipPoint(int pointx, int pointy) -{ - Vector3 point; - - XY_ToPoint(pointx, pointy, point); - - Vector3 mid; - Select_GetMid(mid); - g_clip_viewtype = static_cast( GetViewType()); - const int nDim = (g_clip_viewtype == YZ) ? 0 : ((g_clip_viewtype == XZ) ? 1 : 2); - point[nDim] = mid[nDim]; - vector3_snap(point, GetSnapGridSize()); - NewClipPoint(point); -} - -void XYWnd::Clipper_OnLButtonDown(int x, int y) -{ - Vector3 mousePosition; - XY_ToPoint(x, y, mousePosition); - g_pMovingClip = GlobalClipPoints_Find(mousePosition, (VIEWTYPE) m_viewType, m_fScale); - if (!g_pMovingClip) { - DropClipPoint(x, y); - } -} - -void XYWnd::Clipper_OnLButtonUp(int x, int y) -{ - if (g_pMovingClip) { - g_pMovingClip = 0; - } -} - -void XYWnd::Clipper_OnMouseMoved(int x, int y) -{ - if (g_pMovingClip) { - XY_ToPoint(x, y, g_pMovingClip->m_ptClip); - XY_SnapToGrid(g_pMovingClip->m_ptClip); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void XYWnd::Clipper_Crosshair_OnMouseMoved(int x, int y) -{ - Vector3 mousePosition; - XY_ToPoint(x, y, mousePosition); - if (ClipMode() && GlobalClipPoints_Find(mousePosition, (VIEWTYPE) m_viewType, m_fScale) != 0) { - GdkCursor *cursor; - cursor = gdk_cursor_new(GDK_CROSSHAIR); - gdk_window_set_cursor(gtk_widget_get_window(m_gl_widget), cursor); - gdk_cursor_unref(cursor); - } else { - gdk_window_set_cursor(gtk_widget_get_window(m_gl_widget), 0); - } -} - -unsigned int MoveCamera_buttons() -{ - return RAD_CONTROL | (g_glwindow_globals.m_nMouseType == ETwoButton ? RAD_RBUTTON : RAD_MBUTTON); -} - -void XYWnd_PositionCamera(XYWnd *xywnd, int x, int y, CamWnd &camwnd) -{ - Vector3 origin(Camera_getOrigin(camwnd)); - xywnd->XY_ToPoint(x, y, origin); - xywnd->XY_SnapToGrid(origin); - Camera_setOrigin(camwnd, origin); -} - -unsigned int OrientCamera_buttons() -{ - if (g_glwindow_globals.m_nMouseType == ETwoButton) { - return RAD_RBUTTON | RAD_SHIFT | RAD_CONTROL; - } - return RAD_MBUTTON; -} - -void XYWnd_OrientCamera(XYWnd *xywnd, int x, int y, CamWnd &camwnd) -{ - Vector3 point = g_vector3_identity; - xywnd->XY_ToPoint(x, y, point); - xywnd->XY_SnapToGrid(point); - vector3_subtract(point, Camera_getOrigin(camwnd)); - - int n1 = (xywnd->GetViewType() == XY) ? 1 : 2; - int n2 = (xywnd->GetViewType() == YZ) ? 1 : 0; - int nAngle = (xywnd->GetViewType() == XY) ? CAMERA_YAW : CAMERA_PITCH; - if (point[n1] || point[n2]) { - Vector3 angles(Camera_getAngles(camwnd)); - angles[nAngle] = static_cast( radians_to_degrees(atan2(point[n1], point[n2]))); - Camera_setAngles(camwnd, angles); - } -} - -/* - ============== - NewBrushDrag - ============== - */ -unsigned int NewBrushDrag_buttons() -{ - return RAD_LBUTTON; -} - -void XYWnd::NewBrushDrag_Begin(int x, int y) -{ - m_NewBrushDrag = 0; - m_nNewBrushPressx = x; - m_nNewBrushPressy = y; - - m_bNewBrushDrag = true; - GlobalUndoSystem().start(); -} - -void XYWnd::NewBrushDrag_End(int x, int y) -{ - if (m_NewBrushDrag != 0) { - GlobalUndoSystem().finish("brushDragNew"); - } -} - -void XYWnd::NewBrushDrag(int x, int y) -{ - Vector3 mins, maxs; - XY_ToPoint(m_nNewBrushPressx, m_nNewBrushPressy, mins); - XY_SnapToGrid(mins); - XY_ToPoint(x, y, maxs); - XY_SnapToGrid(maxs); - - int nDim = (m_viewType == XY) ? 2 : (m_viewType == YZ) ? 0 : 1; - - mins[nDim] = float_snapped(Select_getWorkZone().d_work_min[nDim], GetSnapGridSize()); - maxs[nDim] = float_snapped(Select_getWorkZone().d_work_max[nDim], GetSnapGridSize()); - - if (maxs[nDim] <= mins[nDim]) { - maxs[nDim] = mins[nDim] + GetGridSize(); - } - - for (int i = 0; i < 3; i++) { - if (mins[i] == maxs[i]) { - return; // don't create a degenerate brush - } - if (mins[i] > maxs[i]) { - float temp = mins[i]; - mins[i] = maxs[i]; - maxs[i] = temp; - } - } - - if (m_NewBrushDrag == 0) { - NodeSmartReference node(GlobalBrushCreator().createBrush()); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node); - - scene::Path brushpath(makeReference(GlobalSceneGraph().root())); - brushpath.push(makeReference(*Map_GetWorldspawn(g_map))); - brushpath.push(makeReference(node.get())); - selectPath(brushpath, true); - - m_NewBrushDrag = node.get_pointer(); - } - - // d1223m - //Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), - g_brush_always_caulk ? - "textures/common/caulk" : TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -void entitycreate_activated(ui::Widget item) -{ - scene::Node *world_node = Map_FindWorldspawn(g_map); - const char *entity_name = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item)))); - - if (!(world_node && string_equal(entity_name, "worldspawn"))) { - g_pParentWnd->ActiveXY()->OnEntityCreate(entity_name); - } else { - GlobalRadiant().m_pfnMessageBox(MainFrame_getWindow(), "There's already a worldspawn in your map!" - "", - "Info", - eMB_OK, - eMB_ICONDEFAULT); - } -} - -void EntityClassMenu_addItem(ui::Menu menu, const char *name) -{ - auto item = ui::MenuItem(name); - item.connect("activate", G_CALLBACK(entitycreate_activated), item); - item.show(); - menu_add_item(menu, item); -} - -class EntityClassMenuInserter : public EntityClassVisitor { -typedef std::pair MenuPair; -typedef std::vector MenuStack; -MenuStack m_stack; -CopiedString m_previous; -public: -EntityClassMenuInserter(ui::Menu menu) -{ - m_stack.reserve(2); - m_stack.push_back(MenuPair(menu, "")); -} - -~EntityClassMenuInserter() -{ - if (!string_empty(m_previous.c_str())) { - addItem(m_previous.c_str(), ""); - } -} - -void visit(EntityClass *e) -{ - ASSERT_MESSAGE(!string_empty(e->name()), "entity-class has no name"); - if (!string_empty(m_previous.c_str())) { - addItem(m_previous.c_str(), e->name()); - } - m_previous = e->name(); -} - -void pushMenu(const CopiedString &name) -{ - auto item = ui::MenuItem(name.c_str()); - item.show(); - m_stack.back().first.add(item); - - auto submenu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(item, submenu); - - m_stack.push_back(MenuPair(submenu, name)); -} - -void popMenu() -{ - m_stack.pop_back(); -} - -void addItem(const char *name, const char *next) -{ - const char *underscore = strchr(name, '_'); - - if (underscore != 0 && underscore != name) { - bool nextEqual = string_equal_n(name, next, (underscore + 1) - name); - const char *parent = m_stack.back().second.c_str(); - - if (!string_empty(parent) - && string_length(parent) == std::size_t(underscore - name) - && string_equal_n(name, parent, underscore - name)) { // this is a child - } else if (nextEqual) { - if (m_stack.size() == 2) { - popMenu(); - } - pushMenu(CopiedString(StringRange(name, underscore))); - } else if (m_stack.size() == 2) { - popMenu(); - } - } else if (m_stack.size() == 2) { - popMenu(); - } - - EntityClassMenu_addItem(m_stack.back().first, name); -} -}; - -void XYWnd::OnContextMenu() -{ - if (g_xywindow_globals.m_bRightClick == false) { - return; - } - - /* first time, init */ - if (!m_mnuDrop) { - auto menu1 = m_mnuDrop = ui::Menu(ui::New); - EntityClassMenuInserter inserter(menu1); - GlobalEntityClassManager().forEachPoint(inserter); - } - if (!m_mnuDropSingle) { - auto menu2 = m_mnuDropSingle = ui::Menu(ui::New); - create_menu_item_with_mnemonic(menu2, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu2, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu2, "Snap selection to _grid", "SnapToGrid"); - menu_separator(menu2); - create_menu_item_with_mnemonic(menu2, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu2, "Arbitrary scale...", "ArbitraryScale"); - menu_separator(menu2); - create_menu_item_with_mnemonic(menu2, "_To Worldspawn", "UngroupSelection"); - - } - if (!m_mnuDropMultiple) { - auto menu3 = m_mnuDropMultiple = ui::Menu(ui::New); - create_menu_item_with_mnemonic(menu3, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu3, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu3, "Snap selection to _grid", "SnapToGrid"); - menu_separator(menu3); - create_menu_item_with_mnemonic(menu3, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu3, "Arbitrary scale...", "ArbitraryScale"); - menu_separator(menu3); - create_menu_item_with_mnemonic(menu3, "_To Worldspawn", "UngroupSelection"); - create_menu_item_with_mnemonic(menu3, "_Group Structural", "CreateFuncGroup"); - create_menu_item_with_mnemonic(menu3, "_Combine Entities", "GroupSelection"); - create_menu_item_with_mnemonic(menu3, "_Connect", "ConnectSelection"); - create_menu_item_with_mnemonic(menu3, "_KillConnect", "KillConnectSelection"); - create_menu_item_with_mnemonic(menu3, "_Select Color...", "EntityColor"); - create_menu_item_with_mnemonic(menu3, "_Normalize Color...", "NormalizeColor"); - } - - if (GlobalSelectionSystem().countSelected() == 0) { - gtk_menu_popup(m_mnuDrop, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } else if (GlobalSelectionSystem().countSelected() == 1) { - gtk_menu_popup(m_mnuDropSingle, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } else { - gtk_menu_popup(m_mnuDropMultiple, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } -} - -FreezePointer g_xywnd_freezePointer; - -unsigned int Move_buttons() -{ - return RAD_RBUTTON; -} - -void XYWnd_moveDelta(int x, int y, unsigned int state, void *data) -{ - reinterpret_cast( data )->EntityCreate_MouseMove(x, y); - reinterpret_cast( data )->Scroll(-x, y); -} - -gboolean XYWnd_Move_focusOut(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - xywnd->Move_End(); - return FALSE; -} - -void XYWnd::Move_Begin() -{ - if (m_move_started) { - Move_End(); - } - m_move_started = true; - g_xywnd_freezePointer.freeze_pointer(m_parent ? m_parent : MainFrame_getWindow(), XYWnd_moveDelta, this); - m_move_focusOut = m_gl_widget.connect("focus_out_event", G_CALLBACK(XYWnd_Move_focusOut), this); -} - -void XYWnd::Move_End() -{ - m_move_started = false; - g_xywnd_freezePointer.unfreeze_pointer(m_parent ? m_parent : MainFrame_getWindow()); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_move_focusOut); -} - -unsigned int Zoom_buttons() -{ - return RAD_RBUTTON | RAD_SHIFT; -} - -int g_dragZoom = 0; - -void XYWnd_zoomDelta(int x, int y, unsigned int state, void *data) -{ - if (y != 0) { - g_dragZoom += y; - - while (abs(g_dragZoom) > 8) { - if (g_dragZoom > 0) { - XYWnd_ZoomOut(reinterpret_cast( data )); - g_dragZoom -= 8; - } else { - XYWnd_ZoomIn(reinterpret_cast( data )); - g_dragZoom += 8; - } - } - } -} - -gboolean XYWnd_Zoom_focusOut(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - xywnd->Zoom_End(); - return FALSE; -} - -void XYWnd::Zoom_Begin() -{ - if (m_zoom_started) { - Zoom_End(); - } - m_zoom_started = true; - g_dragZoom = 0; - g_xywnd_freezePointer.freeze_pointer(m_parent ? m_parent : MainFrame_getWindow(), XYWnd_zoomDelta, this); - m_zoom_focusOut = m_gl_widget.connect("focus_out_event", G_CALLBACK(XYWnd_Zoom_focusOut), this); -} - -void XYWnd::Zoom_End() -{ - m_zoom_started = false; - g_xywnd_freezePointer.unfreeze_pointer(m_parent ? m_parent : MainFrame_getWindow()); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_zoom_focusOut); -} - -// makes sure the selected brush or camera is in view -void XYWnd::PositionView(const Vector3 &position) -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - m_vOrigin[nDim1] = position[nDim1]; - m_vOrigin[nDim2] = position[nDim2]; - - updateModelview(); - - XYWnd_Update(*this); -} - -void XYWnd::SetViewType(VIEWTYPE viewType) -{ - m_viewType = viewType; - updateModelview(); - - if (m_parent) { - gtk_window_set_title(m_parent, ViewType_getTitle(m_viewType)); - } -} - - -inline WindowVector WindowVector_forInteger(int x, int y) -{ - return WindowVector(static_cast( x ), static_cast( y )); -} - -void XYWnd::mouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - XY_MouseDown(static_cast( position.x()), static_cast( position.y()), - buttons_for_button_and_modifiers(button, modifiers)); -} - -void CamWnd_DisableMovement(); - -void XYWnd::XY_MouseDown(int x, int y, unsigned int buttons) -{ - if (buttons == Move_buttons()) { - Move_Begin(); - EntityCreate_MouseDown(x, y); - } else if (buttons == Zoom_buttons()) { - Zoom_Begin(); - } else if (ClipMode() && buttons == Clipper_buttons()) { - Clipper_OnLButtonDown(x, y); - } else if (buttons == NewBrushDrag_buttons() && GlobalSelectionSystem().countSelected() == 0) { - NewBrushDrag_Begin(x, y); - } - // control mbutton = move camera - else if (buttons == MoveCamera_buttons()) { - XYWnd_PositionCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } - // mbutton = angle camera - else if (buttons == OrientCamera_buttons()) { - XYWnd_OrientCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } else { - m_window_observer->onMouseDown(WindowVector_forInteger(x, y), button_for_flags(buttons), - modifiers_for_flags(buttons)); - } - CamWnd_DisableMovement(); -} - -void XYWnd::XY_MouseUp(int x, int y, unsigned int buttons) -{ - if (m_move_started) { - Move_End(); - EntityCreate_MouseUp(x, y); - } else if (m_zoom_started) { - Zoom_End(); - } else if (ClipMode() && buttons == Clipper_buttons()) { - Clipper_OnLButtonUp(x, y); - } else if (m_bNewBrushDrag) { - m_bNewBrushDrag = false; - NewBrushDrag_End(x, y); - } else { - m_window_observer->onMouseUp(WindowVector_forInteger(x, y), button_for_flags(buttons), - modifiers_for_flags(buttons)); - } -} - -void XYWnd::XY_MouseMoved(int x, int y, unsigned int buttons) -{ - // rbutton = drag xy origin - if (m_move_started) { - } - // zoom in/out - else if (m_zoom_started) { - } else if (ClipMode() && g_pMovingClip != 0) { - Clipper_OnMouseMoved(x, y); - } - // lbutton without selection = drag new brush - else if (m_bNewBrushDrag) { - NewBrushDrag(x, y); - } - - // control mbutton = move camera - else if (getButtonState() == MoveCamera_buttons()) { - XYWnd_PositionCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } - - // mbutton = angle camera - else if (getButtonState() == OrientCamera_buttons()) { - XYWnd_OrientCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } else { - m_window_observer->onMouseMotion(WindowVector_forInteger(x, y), modifiers_for_flags(buttons)); - - m_mousePosition[0] = m_mousePosition[1] = m_mousePosition[2] = 0.0; - XY_ToPoint(x, y, m_mousePosition); - XY_SnapToGrid(m_mousePosition); - - StringOutputStream status(64); - status << "x:: " << FloatFormat(m_mousePosition[0], 6, 1) - << " y:: " << FloatFormat(m_mousePosition[1], 6, 1) - << " z:: " << FloatFormat(m_mousePosition[2], 6, 1); - g_pParentWnd->SetStatusText(g_pParentWnd->m_position_status, status.c_str()); - - if (g_bCrossHairs) { - XYWnd_Update(*this); - } - - Clipper_Crosshair_OnMouseMoved(x, y); - } -} - -void XYWnd::EntityCreate_MouseDown(int x, int y) -{ - m_entityCreate = true; - m_entityCreate_x = x; - m_entityCreate_y = y; -} - -void XYWnd::EntityCreate_MouseMove(int x, int y) -{ - if (m_entityCreate && (m_entityCreate_x != x || m_entityCreate_y != y)) { - m_entityCreate = false; - } -} - -void XYWnd::EntityCreate_MouseUp(int x, int y) -{ - if (m_entityCreate) { - m_entityCreate = false; - OnContextMenu(); - } -} - -inline float screen_normalised(int pos, unsigned int size) -{ - return ((2.0f * pos) / size) - 1.0f; -} - -inline float normalised_to_world(float normalised, float world_origin, float normalised2world_scale) -{ - return world_origin + normalised * normalised2world_scale; -} - - -// TTimo: watch it, this doesn't init one of the 3 coords -void XYWnd::XY_ToPoint(int x, int y, Vector3 &point) -{ - float normalised2world_scale_x = m_nWidth / 2 / m_fScale; - float normalised2world_scale_y = m_nHeight / 2 / m_fScale; - if (m_viewType == XY) { - point[0] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[0], normalised2world_scale_x); - point[1] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[1], normalised2world_scale_y); - } else if (m_viewType == YZ) { - point[1] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[1], normalised2world_scale_x); - point[2] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[2], normalised2world_scale_y); - } else { - point[0] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[0], normalised2world_scale_x); - point[2] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[2], normalised2world_scale_y); - } -} - -void XYWnd::XY_SnapToGrid(Vector3 &point) -{ - if (m_viewType == XY) { - point[0] = float_snapped(point[0], GetSnapGridSize()); - point[1] = float_snapped(point[1], GetSnapGridSize()); - } else if (m_viewType == YZ) { - point[1] = float_snapped(point[1], GetSnapGridSize()); - point[2] = float_snapped(point[2], GetSnapGridSize()); - } else { - point[0] = float_snapped(point[0], GetSnapGridSize()); - point[2] = float_snapped(point[2], GetSnapGridSize()); - } -} - -void XYWnd::XY_LoadBackgroundImage(const char *name) -{ - const char *relative = path_make_relative(name, GlobalFileSystem().findRoot(name)); - if (relative == name) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - - char fileNameWithoutExt[512]; - strncpy(fileNameWithoutExt, relative, sizeof(fileNameWithoutExt) - 1); - fileNameWithoutExt[512 - 1] = '\0'; - fileNameWithoutExt[strlen(fileNameWithoutExt) - 4] = '\0'; - - Image *image = QERApp_LoadImage(0, fileNameWithoutExt); - if (!image) { - globalOutputStream() << "Could not load texture " << fileNameWithoutExt << "\n"; - return; - } - g_pParentWnd->ActiveXY()->m_tex = (qtexture_t *) malloc(sizeof(qtexture_t)); - LoadTextureRGBA(g_pParentWnd->ActiveXY()->XYWnd::m_tex, image->getRGBAPixels(), image->getWidth(), - image->getHeight()); - globalOutputStream() << "Loaded background texture " << relative << "\n"; - g_pParentWnd->ActiveXY()->m_backgroundActivated = true; - - int m_ix, m_iy; - switch (g_pParentWnd->ActiveXY()->m_viewType) { - case XY: - m_ix = 0; - m_iy = 1; - break; - case XZ: - m_ix = 0; - m_iy = 2; - break; - case YZ: - m_ix = 1; - m_iy = 2; - break; - } - - Vector3 min, max; - Select_GetBounds(min, max); - g_pParentWnd->ActiveXY()->m_xmin = min[m_ix]; - g_pParentWnd->ActiveXY()->m_ymin = min[m_iy]; - g_pParentWnd->ActiveXY()->m_xmax = max[m_ix]; - g_pParentWnd->ActiveXY()->m_ymax = max[m_iy]; -} - -void XYWnd::XY_DisableBackground(void) -{ - g_pParentWnd->ActiveXY()->m_backgroundActivated = false; - if (g_pParentWnd->ActiveXY()->m_tex) { - free(g_pParentWnd->ActiveXY()->m_tex); - } - g_pParentWnd->ActiveXY()->m_tex = NULL; -} - -void WXY_BackgroundSelect(void) -{ - bool brushesSelected = Scene_countSelectedBrushes(GlobalSceneGraph()) != 0; - if (!brushesSelected) { - ui::alert(ui::root, "You have to select some brushes to get the bounding box for.\n", - "No selection", ui::alert_type::OK, ui::alert_icon::Error); - return; - } - - const char *filename = MainFrame_getWindow().file_dialog(TRUE, "Background Image", NULL, NULL); - g_pParentWnd->ActiveXY()->XY_DisableBackground(); - if (filename) { - g_pParentWnd->ActiveXY()->XY_LoadBackgroundImage(filename); - } -} - -/* - ============================================================================ - - DRAWING - - ============================================================================ - */ - -/* - ============== - XY_DrawGrid - ============== - */ - -double two_to_the_power(int power) -{ - return pow(2.0f, power); -} - -void XYWnd::XY_DrawAxis(void) -{ - if (g_xywindow_globals_private.show_axis) { - const char g_AxisName[3] = {'X', 'Y', 'Z'}; - const int nDim1 = (m_viewType == YZ) ? 1 : 0; - const int nDim2 = (m_viewType == XY) ? 1 : 2; - const int w = (m_nWidth / 2 / m_fScale); - const int h = (m_nHeight / 2 / m_fScale); - - const Vector3 &colourX = (m_viewType == YZ) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorX; - const Vector3 &colourY = (m_viewType == XY) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorZ; - - // draw two lines with corresponding axis colors to highlight current view - // horizontal line: nDim1 color - glLineWidth(2); - glBegin(GL_LINES); - glColor3fv(vector3_to_array(colourX)); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(m_vOrigin[nDim1] - w + 65 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(0, 0); - glVertex2f(32 / m_fScale, 0); - glColor3fv(vector3_to_array(colourY)); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); - glVertex2f(0, 0); - glVertex2f(0, 32 / m_fScale); - glEnd(); - glLineWidth(1); - // now print axis symbols - glColor3fv(vector3_to_array(colourX)); - glRasterPos2f(m_vOrigin[nDim1] - w + 55 / m_fScale, m_vOrigin[nDim2] + h - 55 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim1]); - glRasterPos2f(28 / m_fScale, -10 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim1]); - glColor3fv(vector3_to_array(colourY)); - glRasterPos2f(m_vOrigin[nDim1] - w + 25 / m_fScale, m_vOrigin[nDim2] + h - 30 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim2]); - glRasterPos2f(-10 / m_fScale, 28 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim2]); - } -} - -void XYWnd::XY_DrawBackground(void) -{ - glPushAttrib(GL_ALL_ATTRIB_BITS); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - glPolygonMode(GL_FRONT, GL_FILL); - - glBindTexture(GL_TEXTURE_2D, m_tex->texture_number); - glBegin(GL_QUADS); - - glColor4f(1.0, 1.0, 1.0, m_alpha); - glTexCoord2f(0.0, 1.0); - glVertex2f(m_xmin, m_ymin); - - glTexCoord2f(1.0, 1.0); - glVertex2f(m_xmax, m_ymin); - - glTexCoord2f(1.0, 0.0); - glVertex2f(m_xmax, m_ymax); - - glTexCoord2f(0.0, 0.0); - glVertex2f(m_xmin, m_ymax); - - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); - - glPopAttrib(); -} - -void XYWnd::XY_DrawGrid(void) -{ - float x, y, xb, xe, yb, ye; - float w, h, a; - char text[32]; - float step, minor_step, stepx, stepy; - step = minor_step = stepx = stepy = GetGridSize(); - - int minor_power = Grid_getPower(); - int mask; - - while ((minor_step * m_fScale) <= 4.0f) { // make sure minor grid spacing is at least 4 pixels on the screen - ++minor_power; - minor_step *= 2; - } - int power = minor_power; - while ((power % 3) != 0 || - (step * m_fScale) <= 32.0f) { // make sure major grid spacing is at least 32 pixels on the screen - ++power; - step = float(two_to_the_power(power)); - } - mask = (1 << (power - minor_power)) - 1; - while ((stepx * m_fScale) <= 32.0f) { // text step x must be at least 32 - stepx *= 2; - } - while ((stepy * m_fScale) <= 32.0f) { // text step y must be at least 32 - stepy *= 2; - } - - a = ((GetSnapGridSize() > 0.0f) ? 1.0f : 0.3f); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_1D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glLineWidth(1); - - w = (m_nWidth / 2 / m_fScale); - h = (m_nHeight / 2 / m_fScale); - - const int nDim1 = (m_viewType == YZ) ? 1 : 0; - const int nDim2 = (m_viewType == XY) ? 1 : 2; - - xb = m_vOrigin[nDim1] - w; - if (xb < region_mins[nDim1]) { - xb = region_mins[nDim1]; - } - xb = step * floor(xb / step); - - xe = m_vOrigin[nDim1] + w; - if (xe > region_maxs[nDim1]) { - xe = region_maxs[nDim1]; - } - xe = step * ceil(xe / step); - - yb = m_vOrigin[nDim2] - h; - if (yb < region_mins[nDim2]) { - yb = region_mins[nDim2]; - } - yb = step * floor(yb / step); - - ye = m_vOrigin[nDim2] + h; - if (ye > region_maxs[nDim2]) { - ye = region_maxs[nDim2]; - } - ye = step * ceil(ye / step); - - #define COLORS_DIFFER(a, b) \ - ( ( a )[0] != ( b )[0] || \ - ( a )[1] != ( b )[1] || \ - ( a )[2] != ( b )[2] ) - - // djbob - // draw minor blocks - if (g_xywindow_globals_private.d_showgrid || a < 1.0f) { - if (a < 1.0f) { - glEnable(GL_BLEND); - } - - if (COLORS_DIFFER(g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback)) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridminor, a))); - - glBegin(GL_LINES); - int i = 0; - for (x = xb; x < xe; x += minor_step, ++i) { - if ((i & mask) != 0) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - } - i = 0; - for (y = yb; y < ye; y += minor_step, ++i) { - if ((i & mask) != 0) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - } - glEnd(); - } - - // draw major blocks - if (COLORS_DIFFER(g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridminor)) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridmajor, a))); - - glBegin(GL_LINES); - for (x = xb; x <= xe; x += step) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - for (y = yb; y <= ye; y += step) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - glEnd(); - } - - if (a < 1.0f) { - glDisable(GL_BLEND); - } - } - - // draw coordinate text if needed - if (g_xywindow_globals_private.show_coordinates) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridtext, 1.0f))); - float offx = m_vOrigin[nDim2] + h - (4 + GlobalOpenGL().m_font->getPixelAscent()) / m_fScale; - float offy = m_vOrigin[nDim1] - w + 4 / m_fScale; - for (x = xb - fmod(xb, stepx); x <= xe; x += stepx) { - glRasterPos2f(x, offx); - sprintf(text, "%g", x); - GlobalOpenGL().drawString(text); - } - for (y = yb - fmod(yb, stepy); y <= ye; y += stepy) { - glRasterPos2f(offy, y); - sprintf(text, "%g", y); - GlobalOpenGL().drawString(text); - } - - if (Active()) { - glColor3fv(vector3_to_array(g_xywindow_globals.color_viewname)); - } - - // we do this part (the old way) only if show_axis is disabled - if (!g_xywindow_globals_private.show_axis) { - glRasterPos2f(m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); - - GlobalOpenGL().drawString(ViewType_getTitle(m_viewType)); - } - } - - XYWnd::XY_DrawAxis(); - - // show current work zone? - // the work zone is used to place dropped points and brushes - if (g_xywindow_globals_private.d_show_work) { - glColor4f(1.0f, 0.0f, 0.0f, 1.0f); - glBegin(GL_LINES); - glVertex2f(xb, Select_getWorkZone().d_work_min[nDim2]); - glVertex2f(xe, Select_getWorkZone().d_work_min[nDim2]); - glVertex2f(xb, Select_getWorkZone().d_work_max[nDim2]); - glVertex2f(xe, Select_getWorkZone().d_work_max[nDim2]); - glVertex2f(Select_getWorkZone().d_work_min[nDim1], yb); - glVertex2f(Select_getWorkZone().d_work_min[nDim1], ye); - glVertex2f(Select_getWorkZone().d_work_max[nDim1], yb); - glVertex2f(Select_getWorkZone().d_work_max[nDim1], ye); - glEnd(); - } -} - -/* - ============== - XY_DrawBlockGrid - ============== - */ -void XYWnd::XY_DrawBlockGrid() -{ - if (Map_FindWorldspawn(g_map) == 0) { - return; - } - const char *value = Node_getEntity(*Map_GetWorldspawn(g_map))->getKeyValue("_blocksize"); - if (strlen(value)) { - sscanf(value, "%i", &g_xywindow_globals_private.blockSize); - } - - if (!g_xywindow_globals_private.blockSize || g_xywindow_globals_private.blockSize > 65536 || - g_xywindow_globals_private.blockSize < 1024) { - // don't use custom blocksize if it is less than the default, or greater than the maximum world coordinate - g_xywindow_globals_private.blockSize = 1024; - } - - float x, y, xb, xe, yb, ye; - float w, h; - char text[32]; - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_1D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - - w = (m_nWidth / 2 / m_fScale); - h = (m_nHeight / 2 / m_fScale); - - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - xb = m_vOrigin[nDim1] - w; - if (xb < region_mins[nDim1]) { - xb = region_mins[nDim1]; - } - xb = static_cast( g_xywindow_globals_private.blockSize * floor(xb / g_xywindow_globals_private.blockSize)); - - xe = m_vOrigin[nDim1] + w; - if (xe > region_maxs[nDim1]) { - xe = region_maxs[nDim1]; - } - xe = static_cast( g_xywindow_globals_private.blockSize * ceil(xe / g_xywindow_globals_private.blockSize)); - - yb = m_vOrigin[nDim2] - h; - if (yb < region_mins[nDim2]) { - yb = region_mins[nDim2]; - } - yb = static_cast( g_xywindow_globals_private.blockSize * floor(yb / g_xywindow_globals_private.blockSize)); - - ye = m_vOrigin[nDim2] + h; - if (ye > region_maxs[nDim2]) { - ye = region_maxs[nDim2]; - } - ye = static_cast( g_xywindow_globals_private.blockSize * ceil(ye / g_xywindow_globals_private.blockSize)); - - // draw major blocks - - glColor3fv(vector3_to_array(g_xywindow_globals.color_gridblock)); - glLineWidth(2); - - glBegin(GL_LINES); - - for (x = xb; x <= xe; x += g_xywindow_globals_private.blockSize) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - - if (m_viewType == XY) { - for (y = yb; y <= ye; y += g_xywindow_globals_private.blockSize) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - } - - glEnd(); - glLineWidth(1); - - // draw coordinate text if needed - - if (m_viewType == XY && m_fScale > .1) { - for (x = xb; x < xe; x += g_xywindow_globals_private.blockSize) { - for (y = yb; y < ye; y += g_xywindow_globals_private.blockSize) { - glRasterPos2f(x + (g_xywindow_globals_private.blockSize / 2), - y + (g_xywindow_globals_private.blockSize / 2)); - sprintf(text, "%i,%i", (int) floor(x / g_xywindow_globals_private.blockSize), - (int) floor(y / g_xywindow_globals_private.blockSize)); - GlobalOpenGL().drawString(text); - } - } - } - - glColor4f(0, 0, 0, 0); -} - -void XYWnd::DrawCameraIcon(const Vector3 &origin, const Vector3 &angles) -{ - float x, y, fov, box; - double a; - - fov = 48 / m_fScale; - box = 16 / m_fScale; - - if (m_viewType == XY) { - x = origin[0]; - y = origin[1]; - a = degrees_to_radians(angles[CAMERA_YAW]); - } else if (m_viewType == YZ) { - x = origin[1]; - y = origin[2]; - a = degrees_to_radians(angles[CAMERA_PITCH]); - } else { - x = origin[0]; - y = origin[2]; - a = degrees_to_radians(angles[CAMERA_PITCH]); - } - - glColor3f(0.0, 0.0, 1.0); - glBegin(GL_LINE_STRIP); - glVertex3f(x - box, y, 0); - glVertex3f(x, y + (box / 2), 0); - glVertex3f(x + box, y, 0); - glVertex3f(x, y - (box / 2), 0); - glVertex3f(x - box, y, 0); - glVertex3f(x + box, y, 0); - glEnd(); - - glBegin(GL_LINE_STRIP); - glVertex3f(x + static_cast( fov * cos(a + c_pi / 4)), y + static_cast( fov * sin(a + c_pi / 4)), 0); - glVertex3f(x, y, 0); - glVertex3f(x + static_cast( fov * cos(a - c_pi / 4)), y + static_cast( fov * sin(a - c_pi / 4)), 0); - glEnd(); - -} - - -float Betwixt(float f1, float f2) -{ - if (f1 > f2) { - return f2 + ((f1 - f2) / 2); - } else { - return f1 + ((f2 - f1) / 2); - } -} - - -// can be greatly simplified but per usual i am in a hurry -// which is not an excuse, just a fact -void XYWnd::PaintSizeInfo(int nDim1, int nDim2, Vector3 &vMinBounds, Vector3 &vMaxBounds) -{ - if (vector3_equal(vMinBounds, vMaxBounds)) { - return; - } - const char *g_pDimStrings[] = {"x:", "y:", "z:"}; - typedef const char *OrgStrings[2]; - const OrgStrings g_pOrgStrings[] = {{"x:", "y:",}, - {"x:", "z:",}, - {"y:", "z:",}}; - - Vector3 vSize(vector3_subtracted(vMaxBounds, vMinBounds)); - - glColor3f(g_xywindow_globals.color_selbrushes[0] * .65f, - g_xywindow_globals.color_selbrushes[1] * .65f, - g_xywindow_globals.color_selbrushes[2] * .65f); - - StringOutputStream dimensions(16); - - if (m_viewType == XY) { - glBegin(GL_LINES); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glEnd(); - - glRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0f / m_fScale, 0.0f); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMaxBounds[nDim1] + 16.0f / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f); - dimensions << "(" << g_pOrgStrings[0][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[0][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } else if (m_viewType == XZ) { - glBegin(GL_LINES); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); - glEnd(); - - glRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0f / m_fScale); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMaxBounds[nDim1] + 16.0f / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale); - dimensions << "(" << g_pOrgStrings[1][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[1][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } else { - glBegin(GL_LINES); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); - glEnd(); - - glRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0f / m_fScale); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(0, vMaxBounds[nDim1] + 16.0f / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(0, vMinBounds[nDim1] + 4.0f, vMaxBounds[nDim2] + 8 / m_fScale); - dimensions << "(" << g_pOrgStrings[2][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[2][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } -} - -class XYRenderer : public Renderer { -struct state_type { - state_type() : - m_highlight(0), - m_state(0) - { - } - - unsigned int m_highlight; - Shader *m_state; -}; - -public: -XYRenderer(RenderStateFlags globalstate, Shader *selected) : - m_globalstate(globalstate), - m_state_selected(selected) -{ - ASSERT_NOTNULL(selected); - m_state_stack.push_back(state_type()); -} - -void SetState(Shader *state, EStyle style) -{ - ASSERT_NOTNULL(state); - if (style == eWireframeOnly) { - m_state_stack.back().m_state = state; - } -} - -EStyle getStyle() const -{ - return eWireframeOnly; -} - -void PushState() -{ - m_state_stack.push_back(m_state_stack.back()); -} - -void PopState() -{ - ASSERT_MESSAGE(!m_state_stack.empty(), "popping empty stack"); - m_state_stack.pop_back(); -} - -void Highlight(EHighlightMode mode, bool bEnable = true) -{ - (bEnable) - ? m_state_stack.back().m_highlight |= mode - : m_state_stack.back().m_highlight &= ~mode; -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &localToWorld) -{ - if (m_state_stack.back().m_highlight & ePrimitive) { - m_state_selected->addRenderable(renderable, localToWorld); - } else { - m_state_stack.back().m_state->addRenderable(renderable, localToWorld); - } -} - -void render(const Matrix4 &modelview, const Matrix4 &projection) -{ - GlobalShaderCache().render(m_globalstate, modelview, projection); -} - -private: -std::vector m_state_stack; -RenderStateFlags m_globalstate; -Shader *m_state_selected; -}; - -void XYWnd::updateProjection() -{ - m_projection[0] = 1.0f / static_cast( m_nWidth / 2 ); - m_projection[5] = 1.0f / static_cast( m_nHeight / 2 ); - m_projection[10] = 1.0f / (g_MaxWorldCoord * m_fScale); - - m_projection[12] = 0.0f; - m_projection[13] = 0.0f; - m_projection[14] = -1.0f; - - m_projection[1] = - m_projection[2] = - m_projection[3] = - - m_projection[4] = - m_projection[6] = - m_projection[7] = - - m_projection[8] = - m_projection[9] = - m_projection[11] = 0.0f; - - m_projection[15] = 1.0f; - - m_view.Construct(m_projection, m_modelview, m_nWidth, m_nHeight); -} - -// note: modelview matrix must have a uniform scale, otherwise strange things happen when rendering the rotation manipulator. -void XYWnd::updateModelview() -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - // translation - m_modelview[12] = -m_vOrigin[nDim1] * m_fScale; - m_modelview[13] = -m_vOrigin[nDim2] * m_fScale; - m_modelview[14] = g_MaxWorldCoord * m_fScale; - - // axis base - switch (m_viewType) { - case XY: - m_modelview[0] = m_fScale; - m_modelview[1] = 0; - m_modelview[2] = 0; - - m_modelview[4] = 0; - m_modelview[5] = m_fScale; - m_modelview[6] = 0; - - m_modelview[8] = 0; - m_modelview[9] = 0; - m_modelview[10] = -m_fScale; - break; - case XZ: - m_modelview[0] = m_fScale; - m_modelview[1] = 0; - m_modelview[2] = 0; - - m_modelview[4] = 0; - m_modelview[5] = 0; - m_modelview[6] = m_fScale; - - m_modelview[8] = 0; - m_modelview[9] = m_fScale; - m_modelview[10] = 0; - break; - case YZ: - m_modelview[0] = 0; - m_modelview[1] = 0; - m_modelview[2] = -m_fScale; - - m_modelview[4] = m_fScale; - m_modelview[5] = 0; - m_modelview[6] = 0; - - m_modelview[8] = 0; - m_modelview[9] = m_fScale; - m_modelview[10] = 0; - break; - } - - m_modelview[3] = m_modelview[7] = m_modelview[11] = 0; - m_modelview[15] = 1; - - m_view.Construct(m_projection, m_modelview, m_nWidth, m_nHeight); -} - -/* - ============== - XY_Draw - ============== - */ - -//#define DBG_SCENEDUMP - -void XYWnd::XY_Draw() -{ - // - // clear - // - glViewport(0, 0, m_nWidth, m_nHeight); - glClearColor(g_xywindow_globals.color_gridback[0], - g_xywindow_globals.color_gridback[1], - g_xywindow_globals.color_gridback[2], 0); - - glClear(GL_COLOR_BUFFER_BIT); - - // - // set up viewpoint - // - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &m_projection )); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(m_fScale, m_fScale, 1); - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - glTranslatef(-m_vOrigin[nDim1], -m_vOrigin[nDim2], 0); - - glDisable(GL_LINE_STIPPLE); - glLineWidth(1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_DEPTH_TEST); - - if (m_backgroundActivated) { - XY_DrawBackground(); - } - XY_DrawGrid(); - - if (g_xywindow_globals_private.show_blocks) { - XY_DrawBlockGrid(); - } - - glLoadMatrixf(reinterpret_cast( &m_modelview )); - - unsigned int globalstate = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH; - if (!g_xywindow_globals.m_bNoStipple) { - globalstate |= RENDER_LINESTIPPLE; - } - - { - XYRenderer renderer(globalstate, m_state_selected); - Scene_Render(renderer, m_view); - GlobalOpenGL_debugAssertNoErrors(); - renderer.render(m_modelview, m_projection); - GlobalOpenGL_debugAssertNoErrors(); - } - - glDepthMask(GL_FALSE); - GlobalOpenGL_debugAssertNoErrors(); - glLoadMatrixf(reinterpret_cast( &m_modelview )); - - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_LINE_STIPPLE); - GlobalOpenGL_debugAssertNoErrors(); - glLineWidth(1); - GlobalOpenGL_debugAssertNoErrors(); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState(GL_COLOR_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_TEXTURE_2D); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_LIGHTING); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_COLOR_MATERIAL); - GlobalOpenGL_debugAssertNoErrors(); - GlobalOpenGL_debugAssertNoErrors(); - - - // size info - if (g_xywindow_globals_private.m_bSizePaint && GlobalSelectionSystem().countSelected() != 0) { - Vector3 min, max; - Select_GetBounds(min, max); - PaintSizeInfo(nDim1, nDim2, min, max); - } - - if (g_bCrossHairs) { - glColor4f(0.2f, 0.9f, 0.2f, 0.8f); - glBegin(GL_LINES); - if (m_viewType == XY) { - glVertex2f(2.0f * g_MinWorldCoord, m_mousePosition[1]); - glVertex2f(2.0f * g_MaxWorldCoord, m_mousePosition[1]); - glVertex2f(m_mousePosition[0], 2.0f * g_MinWorldCoord); - glVertex2f(m_mousePosition[0], 2.0f * g_MaxWorldCoord); - } else if (m_viewType == YZ) { - glVertex3f(m_mousePosition[0], 2.0f * g_MinWorldCoord, m_mousePosition[2]); - glVertex3f(m_mousePosition[0], 2.0f * g_MaxWorldCoord, m_mousePosition[2]); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MinWorldCoord); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MaxWorldCoord); - } else { - glVertex3f(2.0f * g_MinWorldCoord, m_mousePosition[1], m_mousePosition[2]); - glVertex3f(2.0f * g_MaxWorldCoord, m_mousePosition[1], m_mousePosition[2]); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MinWorldCoord); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MaxWorldCoord); - } - glEnd(); - } - - if (ClipMode()) { - GlobalClipPoints_Draw(m_fScale); - } - - GlobalOpenGL_debugAssertNoErrors(); - - // reset modelview - glLoadIdentity(); - glScalef(m_fScale, m_fScale, 1); - glTranslatef(-m_vOrigin[nDim1], -m_vOrigin[nDim2], 0); - DrawCameraIcon(Camera_getOrigin(*g_pParentWnd->GetCamWnd()), Camera_getAngles(*g_pParentWnd->GetCamWnd())); - Feedback_draw2D(m_viewType); - - if (g_xywindow_globals_private.show_outline) { - if (Active()) { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, m_nWidth, 0, m_nHeight, 0, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - switch (m_viewType) { - case YZ: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorX)); - break; - case XZ: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorY)); - break; - case XY: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorZ)); - break; - } - - glBegin(GL_LINE_LOOP); - glVertex2f(0.5, 0.5); - glVertex2f(m_nWidth - 0.5, 1); - glVertex2f(m_nWidth - 0.5, m_nHeight - 0.5); - glVertex2f(0.5, m_nHeight - 0.5); - glEnd(); - } - } - - GlobalOpenGL_debugAssertNoErrors(); - glFinish(); -} - -void XYWnd_MouseToPoint(XYWnd *xywnd, int x, int y, Vector3 &point) -{ - xywnd->XY_ToPoint(x, y, point); - xywnd->XY_SnapToGrid(point); - - int nDim = (xywnd->GetViewType() == XY) ? 2 : (xywnd->GetViewType() == YZ) ? 0 : 1; - float fWorkMid = float_mid(Select_getWorkZone().d_work_min[nDim], Select_getWorkZone().d_work_max[nDim]); - point[nDim] = float_snapped(fWorkMid, GetGridSize()); -} - -void XYWnd::OnEntityCreate(const char *item) -{ - StringOutputStream command; - command << "entityCreate -class " << item; - UndoableCommand undo(command.c_str()); - Vector3 point; - XYWnd_MouseToPoint(this, m_entityCreate_x, m_entityCreate_y, point); - Entity_createFromSelection(item, point); -} - - -void GetFocusPosition(Vector3 &position) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - Select_GetMid(position); - } else { - position = Camera_getOrigin(*g_pParentWnd->GetCamWnd()); - } -} - -void XYWnd_Focus(XYWnd *xywnd) -{ - Vector3 position; - GetFocusPosition(position); - xywnd->PositionView(position); -} - -void XY_Split_Focus() -{ - Vector3 position; - GetFocusPosition(position); - if (g_pParentWnd->GetXYWnd()) { - g_pParentWnd->GetXYWnd()->PositionView(position); - } - if (g_pParentWnd->GetXZWnd()) { - g_pParentWnd->GetXZWnd()->PositionView(position); - } - if (g_pParentWnd->GetYZWnd()) { - g_pParentWnd->GetYZWnd()->PositionView(position); - } -} - -void XY_Focus() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Top() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(XY); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Side() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(XZ); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Front() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(YZ); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Next() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - if (xywnd->GetViewType() == XY) { - xywnd->SetViewType(XZ); - } else if (xywnd->GetViewType() == XZ) { - xywnd->SetViewType(YZ); - } else { - xywnd->SetViewType(XY); - } - XYWnd_Focus(xywnd); -#endif -} - -void XY_Zoom100() -{ - if (g_pParentWnd->GetXYWnd()) { - g_pParentWnd->GetXYWnd()->SetScale(1); - } - if (g_pParentWnd->GetXZWnd()) { - g_pParentWnd->GetXZWnd()->SetScale(1); - } - if (g_pParentWnd->GetYZWnd()) { - g_pParentWnd->GetYZWnd()->SetScale(1); - } -} - -void XY_ZoomIn() -{ - XYWnd_ZoomIn(g_pParentWnd->ActiveXY()); -} - -// NOTE: the zoom out factor is 4/5, we could think about customizing it -// we don't go below a zoom factor corresponding to 10% of the max world size -// (this has to be computed against the window size) -void XY_ZoomOut() -{ - XYWnd_ZoomOut(g_pParentWnd->ActiveXY()); -} - - -void ToggleShowCrosshair() -{ - g_bCrossHairs ^= 1; - XY_UpdateAllWindows(); -} - -void ToggleShowSizeInfo() -{ - g_xywindow_globals_private.m_bSizePaint = !g_xywindow_globals_private.m_bSizePaint; - XY_UpdateAllWindows(); -} - -void ToggleShowGrid() -{ - g_xywindow_globals_private.d_showgrid = !g_xywindow_globals_private.d_showgrid; - XY_UpdateAllWindows(); -} - -ToggleShown g_xy_top_shown(true); - -void XY_Top_Shown_Construct(ui::Window parent) -{ - g_xy_top_shown.connect(parent); -} - -ToggleShown g_yz_side_shown(false); - -void YZ_Side_Shown_Construct(ui::Window parent) -{ - g_yz_side_shown.connect(parent); -} - -ToggleShown g_xz_front_shown(false); - -void XZ_Front_Shown_Construct(ui::Window parent) -{ - g_xz_front_shown.connect(parent); -} - - -class EntityClassMenu : public ModuleObserver { -std::size_t m_unrealised; -public: -EntityClassMenu() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (XYWnd::m_mnuDrop) { - XYWnd::m_mnuDrop.destroy(); - XYWnd::m_mnuDrop = ui::Menu(ui::null); - } - if (XYWnd::m_mnuDropSingle) { - XYWnd::m_mnuDropSingle.destroy(); - XYWnd::m_mnuDropSingle = ui::Menu(ui::null); - } - if (XYWnd::m_mnuDropMultiple) { - XYWnd::m_mnuDropMultiple.destroy(); - XYWnd::m_mnuDropMultiple = ui::Menu(ui::null); - } - } -} -}; - -EntityClassMenu g_EntityClassMenu; - - -void ShowNamesToggle() -{ - GlobalEntityCreator().setShowNames(!GlobalEntityCreator().getShowNames()); - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowNamesToggleCaller; - -void ShowNamesExport(const Callback &importer) -{ - importer(GlobalEntityCreator().getShowNames()); -} - -typedef FreeCaller &), ShowNamesExport> ShowNamesExportCaller; - -void ShowAnglesToggle() -{ - GlobalEntityCreator().setShowAngles(!GlobalEntityCreator().getShowAngles()); - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowAnglesToggleCaller; - -void ShowAnglesExport(const Callback &importer) -{ - importer(GlobalEntityCreator().getShowAngles()); -} - -typedef FreeCaller &), ShowAnglesExport> ShowAnglesExportCaller; - -void ShowBlocksToggle() -{ - g_xywindow_globals_private.show_blocks ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowBlocksToggleCaller; - -void ShowBlocksExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_blocks); -} - -typedef FreeCaller &), ShowBlocksExport> ShowBlocksExportCaller; - -void ShowCoordinatesToggle() -{ - g_xywindow_globals_private.show_coordinates ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowCoordinatesToggleCaller; - -void ShowCoordinatesExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_coordinates); -} - -typedef FreeCaller &), ShowCoordinatesExport> ShowCoordinatesExportCaller; - -void ShowOutlineToggle() -{ - g_xywindow_globals_private.show_outline ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowOutlineToggleCaller; - -void ShowOutlineExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_outline); -} - -typedef FreeCaller &), ShowOutlineExport> ShowOutlineExportCaller; - -void ShowAxesToggle() -{ - g_xywindow_globals_private.show_axis ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowAxesToggleCaller; - -void ShowAxesExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_axis); -} - -typedef FreeCaller &), ShowAxesExport> ShowAxesExportCaller; - -void ShowWorkzoneToggle() -{ - g_xywindow_globals_private.d_show_work ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowWorkzoneToggleCaller; - -void ShowWorkzoneExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.d_show_work); -} - -typedef FreeCaller &), ShowWorkzoneExport> ShowWorkzoneExportCaller; - -ShowNamesExportCaller g_show_names_caller; -Callback &)> g_show_names_callback(g_show_names_caller); -ToggleItem g_show_names(g_show_names_callback); - -ShowAnglesExportCaller g_show_angles_caller; -Callback &)> g_show_angles_callback(g_show_angles_caller); -ToggleItem g_show_angles(g_show_angles_callback); - -ShowBlocksExportCaller g_show_blocks_caller; -Callback &)> g_show_blocks_callback(g_show_blocks_caller); -ToggleItem g_show_blocks(g_show_blocks_callback); - -ShowCoordinatesExportCaller g_show_coordinates_caller; -Callback &)> g_show_coordinates_callback(g_show_coordinates_caller); -ToggleItem g_show_coordinates(g_show_coordinates_callback); - -ShowOutlineExportCaller g_show_outline_caller; -Callback &)> g_show_outline_callback(g_show_outline_caller); -ToggleItem g_show_outline(g_show_outline_callback); - -ShowAxesExportCaller g_show_axes_caller; -Callback &)> g_show_axes_callback(g_show_axes_caller); -ToggleItem g_show_axes(g_show_axes_callback); - -ShowWorkzoneExportCaller g_show_workzone_caller; -Callback &)> g_show_workzone_callback(g_show_workzone_caller); -ToggleItem g_show_workzone(g_show_workzone_callback); - -void XYShow_registerCommands() -{ - GlobalToggles_insert("ShowAngles", ShowAnglesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_angles)); - GlobalToggles_insert("ShowNames", ShowNamesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_names)); - GlobalToggles_insert("ShowBlocks", ShowBlocksToggleCaller(), ToggleItem::AddCallbackCaller(g_show_blocks)); - GlobalToggles_insert("ShowCoordinates", ShowCoordinatesToggleCaller(), - ToggleItem::AddCallbackCaller(g_show_coordinates)); - GlobalToggles_insert("ShowWindowOutline", ShowOutlineToggleCaller(), ToggleItem::AddCallbackCaller(g_show_outline)); - GlobalToggles_insert("ShowAxes", ShowAxesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_axes)); - GlobalToggles_insert("ShowWorkzone", ShowWorkzoneToggleCaller(), ToggleItem::AddCallbackCaller(g_show_workzone)); -} - -void XYWnd_registerShortcuts() -{ - command_connect_accelerator("ToggleCrosshairs"); - command_connect_accelerator("ToggleSizePaint"); -} - - -void Orthographic_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Solid selection boxes", g_xywindow_globals.m_bNoStipple); - page.appendCheckBox("", "Display size info", g_xywindow_globals_private.m_bSizePaint); - page.appendCheckBox("", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse); - page.appendCheckBox("", "Update views on camera move", g_xywindow_globals_private.m_bCamXYUpdate); -} - -void Orthographic_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Orthographic", "Orthographic View Preferences")); - Orthographic_constructPreferences(page); -} - -void Orthographic_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Orthographic_constructPage)); -} - -void Clipper_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Clipper tool uses caulk", g_clip_useCaulk); -} - -void Clipper_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Clipper", "Clipper Tool Settings")); - Clipper_constructPreferences(page); -} - -void Clipper_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Clipper_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - - -struct ToggleShown_Bool { - static void Export(const ToggleShown &self, const Callback &returnz) - { - returnz(self.active()); - } - - static void Import(ToggleShown &self, bool value) - { - self.set(value); - } -}; - - -void XYWindow_Construct() -{ - GlobalCommands_insert("ToggleCrosshairs", makeCallbackF(ToggleShowCrosshair), - Accelerator('X', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("ToggleSizePaint", makeCallbackF(ToggleShowSizeInfo), Accelerator('J')); - GlobalCommands_insert("ToggleGrid", makeCallbackF(ToggleShowGrid), Accelerator('0')); - - GlobalToggles_insert("ToggleView", ToggleShown::ToggleCaller(g_xy_top_shown), - ToggleItem::AddCallbackCaller(g_xy_top_shown.m_item), - Accelerator('V', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalToggles_insert("ToggleSideView", ToggleShown::ToggleCaller(g_yz_side_shown), - ToggleItem::AddCallbackCaller(g_yz_side_shown.m_item)); - GlobalToggles_insert("ToggleFrontView", ToggleShown::ToggleCaller(g_xz_front_shown), - ToggleItem::AddCallbackCaller(g_xz_front_shown.m_item)); - GlobalCommands_insert("NextView", makeCallbackF(XY_Next), Accelerator(GDK_KEY_Tab, - (GdkModifierType) GDK_CONTROL_MASK)); // fixme: doesn't show its shortcut - GlobalCommands_insert("ZoomIn", makeCallbackF(XY_ZoomIn), Accelerator(GDK_KEY_Delete)); - GlobalCommands_insert("ZoomOut", makeCallbackF(XY_ZoomOut), Accelerator(GDK_KEY_Insert)); - GlobalCommands_insert("ViewTop", makeCallbackF(XY_Top), Accelerator(GDK_KEY_KP_Home)); - GlobalCommands_insert("ViewSide", makeCallbackF(XY_Side), Accelerator(GDK_KEY_KP_Page_Down)); - GlobalCommands_insert("ViewFront", makeCallbackF(XY_Front), Accelerator(GDK_KEY_KP_End)); - GlobalCommands_insert("Zoom100", makeCallbackF(XY_Zoom100)); - GlobalCommands_insert("CenterXYView", makeCallbackF(XY_Focus), - Accelerator(GDK_KEY_Tab, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - - GlobalPreferenceSystem().registerPreference("ClipCaulk", make_property_string(g_clip_useCaulk)); - - GlobalPreferenceSystem().registerPreference("NewRightClick", - make_property_string(g_xywindow_globals.m_bRightClick)); - GlobalPreferenceSystem().registerPreference("ChaseMouse", - make_property_string(g_xywindow_globals_private.m_bChaseMouse)); - GlobalPreferenceSystem().registerPreference("SizePainting", - make_property_string(g_xywindow_globals_private.m_bSizePaint)); - GlobalPreferenceSystem().registerPreference("NoStipple", make_property_string(g_xywindow_globals.m_bNoStipple)); - GlobalPreferenceSystem().registerPreference("SI_ShowCoords", - make_property_string(g_xywindow_globals_private.show_coordinates)); - GlobalPreferenceSystem().registerPreference("SI_ShowOutlines", - make_property_string(g_xywindow_globals_private.show_outline)); - GlobalPreferenceSystem().registerPreference("SI_ShowAxis", - make_property_string(g_xywindow_globals_private.show_axis)); - GlobalPreferenceSystem().registerPreference("CamXYUpdate", - make_property_string(g_xywindow_globals_private.m_bCamXYUpdate)); - GlobalPreferenceSystem().registerPreference("ShowWorkzone", - make_property_string(g_xywindow_globals_private.d_show_work)); - - GlobalPreferenceSystem().registerPreference("SI_AxisColors0", make_property_string(g_xywindow_globals.AxisColorX)); - GlobalPreferenceSystem().registerPreference("SI_AxisColors1", make_property_string(g_xywindow_globals.AxisColorY)); - GlobalPreferenceSystem().registerPreference("SI_AxisColors2", make_property_string(g_xywindow_globals.AxisColorZ)); - GlobalPreferenceSystem().registerPreference("SI_Colors1", make_property_string(g_xywindow_globals.color_gridback)); - GlobalPreferenceSystem().registerPreference("SI_Colors2", make_property_string(g_xywindow_globals.color_gridminor)); - GlobalPreferenceSystem().registerPreference("SI_Colors3", make_property_string(g_xywindow_globals.color_gridmajor)); - GlobalPreferenceSystem().registerPreference("SI_Colors6", make_property_string(g_xywindow_globals.color_gridblock)); - GlobalPreferenceSystem().registerPreference("SI_Colors7", make_property_string(g_xywindow_globals.color_gridtext)); - GlobalPreferenceSystem().registerPreference("SI_Colors8", make_property_string(g_xywindow_globals.color_brushes)); - GlobalPreferenceSystem().registerPreference("SI_Colors14", - make_property_string(g_xywindow_globals.color_gridmajor_alt)); - - - GlobalPreferenceSystem().registerPreference("XZVIS", make_property_string(g_xz_front_shown)); - GlobalPreferenceSystem().registerPreference("YZVIS", make_property_string(g_yz_side_shown)); - - Orthographic_registerPreferencesPage(); - Clipper_registerPreferencesPage(); - - XYWnd::captureStates(); - GlobalEntityClassManager().attach(g_EntityClassMenu); -} - -void XYWindow_Destroy() -{ - GlobalEntityClassManager().detach(g_EntityClassMenu); - XYWnd::releaseStates(); -} diff --git a/src/xywindow.h b/src/xywindow.h deleted file mode 100644 index 3878148..0000000 --- a/src/xywindow.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XYWINDOW_H ) -#define INCLUDED_XYWINDOW_H - -#include "math/matrix.h" -#include "signal/signal.h" - -#include "gtkutil/cursor.h" -#include "gtkutil/window.h" -#include "gtkutil/xorrectangle.h" -#include "view.h" -#include "map.h" -#include "texturelib.h" - -#include "qerplugin.h" - -class Shader; - -class SelectionSystemWindowObserver; -namespace scene { -class Node; -} - - -void FlipClip(); - -void SplitClip(); - -void Clip(); - -void OnClipMode(bool enabled); - -bool ClipMode(); - -inline const char *ViewType_getTitle(VIEWTYPE viewtype) -{ - if (viewtype == XY) { - return "XY Top"; - } - if (viewtype == XZ) { - return "XZ Front"; - } - if (viewtype == YZ) { - return "YZ Side"; - } - return ""; -} - -class XYWnd { -ui::GLArea m_gl_widget; -guint m_sizeHandler; -guint m_exposeHandler; - -DeferredDraw m_deferredDraw; -DeferredMotion m_deferred_motion; -public: -ui::Window m_parent; - -XYWnd(); - -~XYWnd(); - -void queueDraw() -{ - m_deferredDraw.draw(); -} - -ui::GLArea GetWidget() -{ - return m_gl_widget; -} - -public: -SelectionSystemWindowObserver *m_window_observer; -XORRectangle m_XORRectangle; -WindowPositionTracker m_positionTracker; - -static void captureStates(); - -static void releaseStates(); - -void PositionView(const Vector3 &position); - -const Vector3 &GetOrigin(); - -void SetOrigin(const Vector3 &origin); - -void Scroll(int x, int y); - -void XY_Draw(); - -void DrawCameraIcon(const Vector3 &origin, const Vector3 &angles); - -void XY_DrawBlockGrid(); - -void XY_DrawAxis(); - -void XY_DrawGrid(); - -void XY_DrawBackground(); - -void XY_LoadBackgroundImage(const char *name); - -void XY_DisableBackground(); - -void XY_MouseUp(int x, int y, unsigned int buttons); - -void XY_MouseDown(int x, int y, unsigned int buttons); - -void XY_MouseMoved(int x, int y, unsigned int buttons); - -void NewBrushDrag_Begin(int x, int y); - -void NewBrushDrag(int x, int y); - -void NewBrushDrag_End(int x, int y); - -void XY_ToPoint(int x, int y, Vector3 &point); - -void XY_SnapToGrid(Vector3 &point); - -void Move_Begin(); - -void Move_End(); - -bool m_move_started; -guint m_move_focusOut; - -void Zoom_Begin(); - -void Zoom_End(); - -bool m_zoom_started; -guint m_zoom_focusOut; - -void SetActive(bool b) -{ - m_bActive = b; -}; - -bool Active() -{ - return m_bActive; -}; - -void Clipper_OnLButtonDown(int x, int y); - -void Clipper_OnLButtonUp(int x, int y); - -void Clipper_OnMouseMoved(int x, int y); - -void Clipper_Crosshair_OnMouseMoved(int x, int y); - -void DropClipPoint(int pointx, int pointy); - -void SetViewType(VIEWTYPE n); - -bool m_bActive; - -static ui::Menu m_mnuDrop; -static ui::Menu m_mnuDropSingle; -static ui::Menu m_mnuDropMultiple; - -int m_chasemouse_current_x, m_chasemouse_current_y; -int m_chasemouse_delta_x, m_chasemouse_delta_y; - - -guint m_chasemouse_handler; - -void ChaseMouse(); - -bool chaseMouseMotion(int pointx, int pointy); - -void updateModelview(); - -void updateProjection(); - -Matrix4 m_projection; -Matrix4 m_modelview; - -int m_nWidth; -int m_nHeight; -// background image stuff -qtexture_t *m_tex; -bool m_backgroundActivated; -float m_alpha; // vertex alpha -float m_xmin, m_ymin, m_xmax, m_ymax; -private: -float m_fScale; -Vector3 m_vOrigin; - - -View m_view; -static Shader *m_state_selected; - -int m_ptCursorX, m_ptCursorY; - -unsigned int m_buttonstate; - -int m_nNewBrushPressx; -int m_nNewBrushPressy; -scene::Node *m_NewBrushDrag; -bool m_bNewBrushDrag; - -Vector3 m_mousePosition; - -VIEWTYPE m_viewType; - -void OriginalButtonUp(guint32 nFlags, int point, int pointy); - -void OriginalButtonDown(guint32 nFlags, int point, int pointy); - -void OnContextMenu(); - -void PaintSizeInfo(int nDim1, int nDim2, Vector3 &vMinBounds, Vector3 &vMaxBounds); - -int m_entityCreate_x, m_entityCreate_y; -bool m_entityCreate; - -public: -void ButtonState_onMouseDown(unsigned int buttons) -{ - m_buttonstate |= buttons; -} - -void ButtonState_onMouseUp(unsigned int buttons) -{ - m_buttonstate &= ~buttons; -} - -unsigned int getButtonState() const -{ - return m_buttonstate; -} - -void EntityCreate_MouseDown(int x, int y); - -void EntityCreate_MouseMove(int x, int y); - -void EntityCreate_MouseUp(int x, int y); - -void OnEntityCreate(const char *item); - -VIEWTYPE GetViewType() -{ - return m_viewType; -} - -void SetScale(float f); - -float Scale() -{ - return m_fScale; -} - -int Width() -{ - return m_nWidth; -} - -int Height() -{ - return m_nHeight; -} - -Signal0 onDestroyed; -Signal3 onMouseDown; - -void mouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers); - -typedef Member MouseDownCaller; -}; - -inline void XYWnd_Update(XYWnd &xywnd) -{ - xywnd.queueDraw(); -} - - -struct xywindow_globals_t { - Vector3 color_gridback; - Vector3 color_gridminor; - Vector3 color_gridmajor; - Vector3 color_gridblock; - Vector3 color_gridtext; - Vector3 color_brushes; - Vector3 color_selbrushes; - Vector3 color_clipper; - Vector3 color_viewname; - Vector3 color_gridminor_alt; - Vector3 color_gridmajor_alt; - Vector3 AxisColorX; - Vector3 AxisColorY; - Vector3 AxisColorZ; - - bool m_bRightClick; - bool m_bNoStipple; - - xywindow_globals_t() : - color_gridback(0.0f, 0.0f, 0.0f), - color_gridmajor(0.45f, 0.45f, 0.45f), - color_gridminor(0.2f, 0.2f, 0.2f), - color_gridblock(0.39f, 0.18f, 0.0f), - color_gridtext(0.0f, 0.0f, 0.0f), - color_brushes(0.55f, 0.55f, 0.55f), - color_selbrushes(1.0f, 0.0f, 0.0f), - color_clipper(0.0f, 0.0f, 1.0f), - color_viewname(0.7f, 0.7f, 0.0f), - color_gridminor_alt(0.f, 0.f, 0.f), - color_gridmajor_alt(0.f, 0.f, 0.f), - - AxisColorX(1.f, 0.f, 0.f), - AxisColorY(0.f, 1.f, 0.f), - AxisColorZ(0.f, 0.f, 1.f), - m_bRightClick(true), - m_bNoStipple(false) - { - } - -}; - -extern xywindow_globals_t g_xywindow_globals; - - -VIEWTYPE GlobalXYWnd_getCurrentViewType(); - -void XY_Top_Shown_Construct(ui::Window parent); - -void YZ_Side_Shown_Construct(ui::Window parent); - -void XZ_Front_Shown_Construct(ui::Window parent); - -void XYWindow_Construct(); - -void XYWindow_Destroy(); - -void WXY_Print(); - -void WXY_BackgroundSelect(); - -void XYShow_registerCommands(); - -void XYWnd_registerShortcuts(); - -#endif diff --git a/tools/Makefile b/tools/Makefile deleted file mode 100644 index 70fa52b..0000000 --- a/tools/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -# vmap Makefile - -# ws libs vmap uses -LIBOBJS=../libs/libddslib.a \ - ../libs/libetclib.a \ - ../libs/libfilematch.a \ - ../libs/libl_net.a \ - ../libs/libmathlib.a \ - ../libs/libpicomodel.a - -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -GLIB_LDFLAGS=$(shell pkg-config --libs glib-2.0) - -XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) -XML_LDFLAGS=$(shell pkg-config --libs libxml-2.0) - -MINIZIP_CFLAGS=$(shell pkg-config --cflags minizip) -MINIZIP_LDFLAGS=$(shell pkg-config --libs minizip) - -JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) -JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) - -PNG_CFLAGS=$(shell pkg-config --cflags libpng) -PNG_LDFLAGS=$(shell pkg-config --libs libpng) - -VMAP_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(MINIZIP_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) -I../include -I./common -I../libs -VMAP_LDFLAGS=$(LDFLAGS) -lm -lpthread -L../lib $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(MINIZIP_LDFLAGS) $(JPEG_LDFLAGS) $(PNG_LDFLAGS) - -DO_CC=$(CC) $(VMAP_CFLAGS) -o $@ -c $< - -.c.o: - $(DO_CC) - -VMAP_OBJS = \ - common/cmdlib.o \ - common/imagelib.o \ - common/inout.o \ - common/jpeg.o \ - common/md4.o \ - common/mutex.o \ - common/polylib.o \ - common/scriplib.o \ - common/matlib.o \ - common/threads.o \ - common/vfs.o \ - vmap/brush.o \ - vmap/brush_primit.o \ - vmap/bsp.o \ - vmap/bsp_analyze.o \ - vmap/bsp_info.o \ - vmap/bsp_scale.o \ - vmap/bspfile_abstract.o \ - vmap/bspfile_ibsp.o \ - vmap/bspfile_rbsp.o \ - vmap/convert_ase.o \ - vmap/convert_bsp.o \ - vmap/convert_map.o \ - vmap/convert_obj.o \ - vmap/decals.o \ - vmap/exportents.o \ - vmap/facebsp.o \ - vmap/fixaas.o \ - vmap/fog.o \ - vmap/help.o \ - vmap/image.o \ - vmap/leakfile.o \ - vmap/light.o \ - vmap/light_bounce.o \ - vmap/light_trace.o \ - vmap/light_ydnar.o \ - vmap/lightmaps_ydnar.o \ - vmap/main.o \ - vmap/map.o \ - vmap/mesh.o \ - vmap/model.o \ - vmap/patch.o \ - vmap/path_init.o \ - vmap/portals.o \ - vmap/prtfile.o \ - vmap/shaders.o \ - vmap/surface.o \ - vmap/surface_extra.o \ - vmap/surface_foliage.o \ - vmap/surface_fur.o \ - vmap/surface_meta.o \ - vmap/tjunction.o \ - vmap/tree.o \ - vmap/vis.o \ - vmap/visflow.o \ - vmap/writebsp.o - -# binary target -../build/vmap: $(VMAP_OBJS) - $(CXX) -o $@ $(VMAP_OBJS) $(LIBOBJS) $(VMAP_LDFLAGS) - -clean: - -rm -f ./common/*.o - -rm -f ./vmap/*.o - -rm -f ../build/vmap - -# object files -common/cmdlib.o: common/cmdlib.c common/cmdlib.h -common/imagelib.o: common/imagelib.c common/imagelib.h -common/inout.o: common/inout.c common/inout.h -common/jpeg.o: common/jpeg.c -common/md4.o: common/md4.c common/md4.h -common/mutex.o: common/mutex.c common/mutex.h -common/polylib.o: common/polylib.c common/polylib.h -common/scriplib.o: common/scriplib.c common/scriplib.h -common/matlib.o: common/matlib.c common/matlib.h -common/threads.o: common/threads.c -common/vfs.o: common/vfs.c common/vfs.h -vmap/brush.o: vmap/brush.c -vmap/brush_primit.o: vmap/brush_primit.c -vmap/bsp.o: vmap/bsp.c -vmap/bsp_analyze.o: vmap/bsp_analyze.c -vmap/bsp_info.o: vmap/bsp_info.c -vmap/bsp_scale.o: vmap/bsp_scale.c -vmap/bspfile_abstract.o: vmap/bspfile_abstract.c -vmap/bspfile_ibsp.o: vmap/bspfile_ibsp.c -vmap/bspfile_rbsp.o: vmap/bspfile_rbsp.c -vmap/convert_ase.o: vmap/convert_ase.c -vmap/convert_bsp.o: vmap/convert_bsp.c -vmap/convert_map.o: vmap/convert_map.c -vmap/convert_obj.o: vmap/convert_obj.c -vmap/decals.o: vmap/decals.c -vmap/exportents.o: vmap/exportents.c -vmap/facebsp.o: vmap/facebsp.c -vmap/fixaas.o: vmap/fixaas.c -vmap/fog.o: vmap/fog.c -vmap/help.o: vmap/help.c -vmap/image.o: vmap/image.c -vmap/leakfile.o: vmap/leakfile.c -vmap/light.o: vmap/light.c -vmap/light_bounce.o: vmap/light_bounce.c -vmap/light_trace.o: vmap/light_trace.c -vmap/light_ydnar.o: vmap/light_ydnar.c -vmap/lightmaps_ydnar.o: vmap/lightmaps_ydnar.c -vmap/main.o: vmap/main.c -vmap/map.o: vmap/map.c -vmap/mesh.o: vmap/mesh.c -vmap/model.o: vmap/model.c -vmap/patch.o: vmap/patch.c -vmap/path_init.o: vmap/path_init.c -vmap/portals.o: vmap/portals.c -vmap/prtfile.o: vmap/prtfile.c -vmap/shaders.o: vmap/shaders.c -vmap/surface.o: vmap/surface.c -vmap/surface_extra.o: vmap/surface_extra.c -vmap/surface_foliage.o: vmap/surface_foliage.c -vmap/surface_fur.o: vmap/surface_fur.c -vmap/surface_meta.o: vmap/surface_meta.c -vmap/tjunction.o: vmap/tjunction.c -vmap/tree.o: vmap/tree.c -vmap/vis.o: vmap/vis.c -vmap/visflow.o: vmap/visflow.c -vmap/writebsp.o: vmap/writebsp.c diff --git a/worldspawn.desktop b/worldspawn.desktop deleted file mode 100755 index f272035..0000000 --- a/worldspawn.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=WorldSpawn -Comment=idTech BSP Level Editor -Exec=worldspawn %f -Icon=worldspawn -Terminal=true -Type=Application -Categories=Development;