Pārlūkot izejas kodu

Merge pull request #339 from GarageGames/development

Torque 2D 3.3!
Peter Robinson 9 gadi atpakaļ
vecāks
revīzija
4571f96732
92 mainītis faili ar 5116 papildinājumiem un 1277 dzēšanām
  1. 3 3
      README.md
  2. 2 0
      engine/compilers/Make/Makefile
  3. 9 3
      engine/compilers/Make/Torque2D
  4. 64 0
      engine/compilers/Make/ogg
  5. 89 0
      engine/compilers/Make/vorbis
  6. 0 71
      engine/compilers/Project1/Project1.vcxproj
  7. 0 17
      engine/compilers/Project1/Project1.vcxproj.filters
  8. 18 8
      engine/compilers/VisualStudio 2013/Torque 2D.vcxproj
  9. 48 15
      engine/compilers/VisualStudio 2013/Torque 2D.vcxproj.filters
  10. 17 8
      engine/compilers/VisualStudio 2015/Torque 2D.vcxproj
  11. 45 15
      engine/compilers/VisualStudio 2015/Torque 2D.vcxproj.filters
  12. 49 18
      engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj
  13. 47 14
      engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj
  14. 9 6
      engine/compilers/android-studio/app/build.gradle
  15. 10 4
      engine/compilers/android-studio/app/src/main/jni/Android.mk
  16. 275 0
      engine/source/2d/assets/FontAsset.cc
  17. 93 0
      engine/source/2d/assets/FontAsset.h
  18. 47 0
      engine/source/2d/assets/FontAsset_ScriptBinding.h
  19. 30 2
      engine/source/2d/gui/SceneWindow.cc
  20. 9 0
      engine/source/2d/gui/SceneWindow.h
  21. 12 0
      engine/source/2d/gui/SceneWindow_ScriptBinding.h
  22. 3 3
      engine/source/2d/scene/ContactFilter.cc
  23. 1 0
      engine/source/2d/scene/Scene.cc
  24. 1 0
      engine/source/2d/scene/Scene.h
  25. 0 400
      engine/source/2d/sceneobject/ImageFont.cc
  26. 0 133
      engine/source/2d/sceneobject/ImageFont.h
  27. 0 161
      engine/source/2d/sceneobject/ImageFont_ScriptBinding.h
  28. 221 88
      engine/source/2d/sceneobject/SceneObject.cc
  29. 23 6
      engine/source/2d/sceneobject/SceneObject.h
  30. 171 12
      engine/source/2d/sceneobject/SceneObject_ScriptBinding.h
  31. 2 2
      engine/source/2d/sceneobject/ShapeVector.cc
  32. 915 0
      engine/source/2d/sceneobject/TextSprite.cc
  33. 241 0
      engine/source/2d/sceneobject/TextSprite.h
  34. 437 0
      engine/source/2d/sceneobject/TextSprite_ScriptBinding.h
  35. 40 1
      engine/source/audio/audio.cc
  36. 10 1
      engine/source/audio/audioBuffer.cc
  37. 2 0
      engine/source/audio/audioBuffer.h
  38. 57 0
      engine/source/audio/audioDescriptions.cc
  39. 72 0
      engine/source/audio/audioDescriptions.h
  40. 5 0
      engine/source/audio/audioStreamSourceFactory.cc
  41. 3 3
      engine/source/audio/audio_ScriptBinding.cc
  42. 1 1
      engine/source/audio/vorbisStreamSource.cc
  43. 2 1
      engine/source/audio/vorbisStreamSource.h
  44. 1 1
      engine/source/audio/wavStreamSource.cc
  45. 255 0
      engine/source/bitmapFont/BitmapFont.cc
  46. 75 0
      engine/source/bitmapFont/BitmapFont.h
  47. 46 0
      engine/source/bitmapFont/BitmapFontCharacter.cc
  48. 57 0
      engine/source/bitmapFont/BitmapFontCharacter.h
  49. 61 0
      engine/source/bitmapFont/BitmapFontCharacterInfo.h
  50. 51 0
      engine/source/bitmapFont/BitmapFontLineInfo.h
  51. 1 1
      engine/source/collection/nameTags_ScriptBinding.h
  52. 1 1
      engine/source/delegates/delegateSignal.h
  53. 1 1
      engine/source/gui/guiCanvas_ScriptBinding.h
  54. 1 1
      engine/source/persistence/taml/json/tamlJSONReader.cc
  55. 1 0
      engine/source/platform/platformAudio.h
  56. 9 0
      engine/source/platform/platformVideo.cc
  57. 3 1
      engine/source/platform/platformVideo.h
  58. 8 0
      engine/source/platform/platformVideo_ScriptBinding.h
  59. 0 80
      engine/source/platform/typesLinux.h
  60. 0 80
      engine/source/platform/typesX86UNIX.h
  61. 3 3
      engine/source/platformAndroid/AndroidEvents.h
  62. 6 0
      engine/source/platformAndroid/AndroidOGLVideo.cpp
  63. 1 0
      engine/source/platformAndroid/AndroidOGLVideo.h
  64. 1 1
      engine/source/platformAndroid/AndroidProcessControl.cpp
  65. 2 0
      engine/source/platformOSX/osxOpenGLDevice.h
  66. 14 0
      engine/source/platformOSX/osxOpenGLDevice.mm
  67. 15 0
      engine/source/platformOSX/osxTorqueView.mm
  68. 11 0
      engine/source/platformWin32/winOGLVideo.cc
  69. 1 0
      engine/source/platformWin32/winOGLVideo.h
  70. 0 26
      engine/source/platformWin32/winWindow.cc
  71. 13 0
      engine/source/platformX86UNIX/x86UNIXOGLVideo.cc
  72. 2 1
      engine/source/platformX86UNIX/x86UNIXOGLVideo.h
  73. 1 0
      engine/source/platformiOS/iOSOGLVideo.h
  74. 6 0
      engine/source/platformiOS/iOSOGLVideo.mm
  75. 1 4
      engine/source/sim/simObject.cc
  76. 1 1
      engine/source/string/stringBuffer.cc
  77. 0 77
      modules/ImageFontToy/1/main.cs
  78. 251 0
      modules/TextSpriteToy/1/main.cs
  79. 2 2
      modules/TextSpriteToy/1/module.taml
  80. 3 0
      modules/ToyAssets/1/assets/fonts/Arial.asset.taml
  81. 195 0
      modules/ToyAssets/1/assets/fonts/Arial.fnt
  82. BIN
      modules/ToyAssets/1/assets/fonts/Arial_0.png
  83. BIN
      modules/ToyAssets/1/assets/fonts/Arial_1.png
  84. 55 0
      modules/ToyAssets/1/assets/fonts/Bitmap Font Config.bmfc
  85. 3 0
      modules/ToyAssets/1/assets/fonts/Orator Bold.asset.taml
  86. 102 0
      modules/ToyAssets/1/assets/fonts/Orator Bold.fnt
  87. BIN
      modules/ToyAssets/1/assets/fonts/Orator Bold_0.png
  88. BIN
      modules/ToyAssets/1/assets/fonts/Orator Bold_1.png
  89. 3 0
      modules/ToyAssets/1/assets/fonts/Trajan Pro.asset.taml
  90. 770 0
      modules/ToyAssets/1/assets/fonts/Trajan Pro.fnt
  91. BIN
      modules/ToyAssets/1/assets/fonts/Trajan Pro_0.png
  92. BIN
      unicows.dll

+ 3 - 3
README.md

@@ -1,5 +1,5 @@
 ![Torque Logo](http://static.garagegames.com/static/pg/logokits/Torque-Logo_H.png)
-## Torque 2D 3.2
+## Torque 2D 3.3
 
 MIT Licensed Open Source version of Torque 2D from GarageGames. Maintained by the T2D Steering Committee and contributions from the community.
 
@@ -21,11 +21,11 @@ If you do not wish to compile the source code yourself, precompiled binary files
 
 After downloading a copy of the source code, the following project files for each platform are provided for you and can be found in the `engine/compilers` folder.
 
-* **Windows:** Visual Studio 2010, 2012, or 2013 (works with the free, "Express for Windows Desktop" version)
+* **Windows:** Visual Studio 2013 or 2015 (works with the free, "Express for Windows Desktop" version)
 * **OSX:** Xcode
 * **Linux:** Make
 * **iOS:** Xcode_iOS
-* **Android:** Eclipse
+* **Android:** Eclipse or Android Studio
 * **Web:** Emscripten/Cmake
 
 See the [wiki](https://github.com/GarageGames/Torque2D/wiki) for available guides on platform setup and development.

+ 2 - 0
engine/compilers/Make/Makefile

@@ -19,6 +19,8 @@ clean:
 -include x zlib
 -include x lpng
 -include x ljpeg
+-include x vorbis
+-include x ogg
 
 release: $(LIB_TARGETS) $(SHARED_LIB_TARGETS) $(APP_TARGETS)
 	@echo Built libraries: $(LIB_TARGETS)

+ 9 - 3
engine/compilers/Make/Torque2D

@@ -1,6 +1,7 @@
 APPNAME := ../../../Torque2D
 
 SOURCES := ../../source/2d/assets/AnimationAsset.cc \
+	../../source/2d/assets/FontAsset.cc \
 	../../source/2d/assets/ImageAsset.cc \
 	../../source/2d/assets/ParticleAsset.cc \
 	../../source/2d/assets/ParticleAssetEmitter.cc \
@@ -30,7 +31,6 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/2d/gui/guiSpriteCtrl.cc \
 	../../source/2d/gui/SceneWindow.cc \
 	../../source/2d/sceneobject/CompositeSprite.cc \
-	../../source/2d/sceneobject/ImageFont.cc \
 	../../source/2d/sceneobject/ParticlePlayer.cc \
 	../../source/2d/sceneobject/SceneObject.cc \
 	../../source/2d/sceneobject/SceneObjectList.cc \
@@ -39,6 +39,7 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/2d/sceneobject/ShapeVector.cc \
 	../../source/2d/sceneobject/SkeletonObject.cc \
 	../../source/2d/sceneobject/Sprite.cc \
+	../../source/2d/sceneobject/TextSprite.cc \
 	../../source/2d/sceneobject/Trigger.cc \
 	../../source/2d/scene/ContactFilter.cc \
 	../../source/2d/scene/DebugDraw.cc \
@@ -56,6 +57,8 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/assets/declaredAssets.cc \
 	../../source/assets/referencedAssets.cc \
 	../../source/audio/AudioAsset.cc \
+	../../source/bitmapFont/BitmapFont.cc \
+	../../source/bitmapFont/BitmapFontCharacter.cc \
 	../../source/Box2D/Collision/b2BroadPhase.cpp \
 	../../source/Box2D/Collision/b2CollideCircle.cpp \
 	../../source/Box2D/Collision/b2CollideEdge.cpp \
@@ -238,6 +241,7 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/persistence/tinyXML/tinyxml.cpp \
 	../../source/persistence/tinyXML/tinyxmlerror.cpp \
 	../../source/persistence/tinyXML/tinyxmlparser.cpp \
+	../../source/audio/vorbisStreamSource.cc \
 	../../source/audio/audio.cc \
 	../../source/audio/audioBuffer.cc \
 	../../source/audio/audioDataBlock.cc \
@@ -398,12 +402,12 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/gui/editor/guiInspector.cc \
 	../../source/gui/editor/guiInspectorTypes.cc \
 	../../source/gui/editor/guiMenuBar.cc \
-	../../source/gui/editor/guiSeparatorCtrl.cc 
+	../../source/gui/editor/guiSeparatorCtrl.cc
 
 LDFLAGS := -g -m32
 LDLIBS := -lstdc++ -lm -ldl -lpthread -lrt -lX11 -lXft -lSDL -lopenal
 
-CFLAGS := -MMD -I. -Wfatal-errors -Wunused -m32 -msse -march=i686 -pipe
+CFLAGS := -std=gnu++11 -MMD -I. -Wfatal-errors -Wunused -m32 -msse -march=i686 -pipe
 
 CFLAGS += -I/usr/include
 CFLAGS += -I/usr/include/freetype2
@@ -413,6 +417,8 @@ CFLAGS += -I../../lib/ljpeg
 CFLAGS += -I../../lib/zlib
 CFLAGS += -I../../lib/lpng
 CFLAGS += -I../../lib/freetype
+CFLAGS += -I../../lib/libvorbis/include
+CFLAGS += -I../../lib/libogg/include
 
 CFLAGS += -DLINUX
 

+ 64 - 0
engine/compilers/Make/ogg

@@ -0,0 +1,64 @@
+# I release this sample under the MIT license: free for any use, provided
+# you hold me harmless from any such use you make, and you retain my
+# copyright on the actual sources.
+# Copyright 2005 Jon Watte.
+
+LIBNAME := ogg
+SOURCES := \
+../../lib/libogg/src/bitwise.c \
+../../lib/libogg/src/framing.c \
+
+LDFLAGS_ogg := -g -m32
+
+CFLAGS_ogg := -MMD -I. -m32 -msse -mmmx -march=i686
+
+CFLAGS_ogg += -I../../lib/libogg/include
+
+CFLAGS_ogg += -DUNICODE
+CFLAGS_ogg += -DLINUX
+
+CFLAGS_DEBUG_ogg := $(CFLAGS_ogg) -ggdb
+CFLAGS_DEBUG_ogg += -DTORQUE_DEBUG
+CFLAGS_DEBUG_ogg += -DTORQUE_DEBUG_GUARD
+CFLAGS_DEBUG_ogg += -DTORQUE_NET_STATS
+
+CFLAGS_ogg += -O3
+
+CC := gcc
+LD := gcc
+
+TARGET_ogg := lib/libogg.a
+TARGET_ogg_DEBUG := lib/libogg_DEBUG.a
+
+LIB_TARGETS += $(TARGET_ogg)
+LIB_TARGETS_DEBUG += $(TARGET_ogg_DEBUG)
+
+OBJS_ogg := $(patsubst ../../lib/libogg/%,Release/ogg/%.o,$(SOURCES))
+OBJS_ogg_DEBUG := $(patsubst ../../lib/libogg/%,Debug/ogg/%.o,$(SOURCES))
+
+# Deriving the variable name from the target name is the secret sauce
+# of the build system.
+#
+$(TARGET_ogg):	$(OBJS_ogg)
+	@mkdir -p $(dir $@)
+	ar cr $@ $(OBJS_ogg)
+
+$(TARGET_ogg_DEBUG):	$(OBJS_ogg_DEBUG)
+	@mkdir -p $(dir $@)
+	ar cr $@ $(OBJS_ogg_DEBUG)
+
+Release/ogg/%.o:	../../lib/libogg/%
+	@mkdir -p $(dir $@)
+	$(CC) -c $(CFLAGS_ogg) $< -o $@
+
+Debug/ogg/%.o:	../../lib/libogg/%
+	@mkdir -p $(dir $@)
+	$(CC) -c $(CFLAGS_DEBUG_ogg) $< -o $@
+
+release_ogg: $(TARGET_ogg)
+debug_ogg: $(TARGET_ogg_DEBUG)
+
+.PHONY: debug_ogg release_ogg
+
+DEPS += $(patsubst %.o,%.d,$(OBJS_ogg))
+DEPS += $(patsubst %.o,%.d,$(OBJS_ogg_DEBUG))

+ 89 - 0
engine/compilers/Make/vorbis

@@ -0,0 +1,89 @@
+# I release this sample under the MIT license: free for any use, provided
+# you hold me harmless from any such use you make, and you retain my
+# copyright on the actual sources.
+# Copyright 2005 Jon Watte.
+
+LIBNAME := vorbis
+SOURCES := \
+../../lib/libvorbis/analysis.c \
+../../lib/libvorbis/barkmel.c \
+../../lib/libvorbis/bitrate.c \
+../../lib/libvorbis/block.c \
+../../lib/libvorbis/codebook.c \
+../../lib/libvorbis/envelope.c \
+../../lib/libvorbis/floor0.c \
+../../lib/libvorbis/floor1.c \
+../../lib/libvorbis/info.c \
+../../lib/libvorbis/lookup.c \
+../../lib/libvorbis/lpc.c \
+../../lib/libvorbis/lsp.c \
+../../lib/libvorbis/mapping0.c \
+../../lib/libvorbis/mdct.c \
+../../lib/libvorbis/psy.c \
+../../lib/libvorbis/registry.c \
+../../lib/libvorbis/res0.c \
+../../lib/libvorbis/sharedbook.c \
+../../lib/libvorbis/smallft.c \
+../../lib/libvorbis/synthesis.c \
+../../lib/libvorbis/tone.c \
+../../lib/libvorbis/vorbisenc.c \
+../../lib/libvorbis/vorbisfile.c \
+../../lib/libvorbis/window.c \
+
+LDFLAGS_vorbis := -g -m32
+
+CFLAGS_vorbis := -MMD -I. -m32 -msse -mmmx -march=i686
+
+CFLAGS_vorbis += -I../../lib/libvorbis
+CFLAGS_vorbis += -I../../lib/libvorbis/lib
+CFLAGS_vorbis += -I../../lib/libvorbis/include
+CFLAGS_vorbis += -I../../lib/libogg/include
+
+CFLAGS_vorbis += -DUNICODE
+CFLAGS_vorbis += -DLINUX
+
+CFLAGS_DEBUG_vorbis := $(CFLAGS_vorbis) -ggdb
+CFLAGS_DEBUG_vorbis += -DTORQUE_DEBUG
+CFLAGS_DEBUG_vorbis += -DTORQUE_DEBUG_GUARD
+CFLAGS_DEBUG_vorbis += -DTORQUE_NET_STATS
+
+CFLAGS_vorbis += -O3
+
+CC := gcc
+LD := gcc
+
+TARGET_vorbis := lib/libvorbis.a
+TARGET_vorbis_DEBUG := lib/libvorbis_DEBUG.a
+
+LIB_TARGETS += $(TARGET_vorbis)
+LIB_TARGETS_DEBUG += $(TARGET_vorbis_DEBUG)
+
+OBJS_vorbis := $(patsubst ../../lib/libvorbis/%,Release/vorbis/%.o,$(SOURCES))
+OBJS_vorbis_DEBUG := $(patsubst ../../lib/libvorbis/%,Debug/vorbis/%.o,$(SOURCES))
+
+# Deriving the variable name from the target name is the secret sauce
+# of the build system.
+#
+$(TARGET_vorbis):	$(OBJS_vorbis)
+	@mkdir -p $(dir $@)
+	ar cr $@ $(OBJS_vorbis)
+
+$(TARGET_vorbis_DEBUG):	$(OBJS_vorbis_DEBUG)
+	@mkdir -p $(dir $@)
+	ar cr $@ $(OBJS_vorbis_DEBUG)
+
+Release/vorbis/%.o:	../../lib/libvorbis/%
+	@mkdir -p $(dir $@)
+	$(CC) -c $(CFLAGS_vorbis) $< -o $@
+
+Debug/vorbis/%.o:	../../lib/libvorbis/%
+	@mkdir -p $(dir $@)
+	$(CC) -c $(CFLAGS_DEBUG_vorbis) $< -o $@
+
+release_vorbis: $(TARGET_vorbis)
+debug_vorbis: $(TARGET_vorbis_DEBUG)
+
+.PHONY: debug_vorbis release_vorbis
+
+DEPS += $(patsubst %.o,%.d,$(OBJS_vorbis))
+DEPS += $(patsubst %.o,%.d,$(OBJS_vorbis_DEBUG))

+ 0 - 71
engine/compilers/Project1/Project1.vcxproj

@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{0E947C0D-AB66-4F43-B453-91B7DF61A133}</ProjectGuid>
-    <RootNamespace>Project1</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup />
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>

+ 0 - 17
engine/compilers/Project1/Project1.vcxproj.filters

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-</Project>

+ 18 - 8
engine/compilers/VisualStudio 2013/Torque 2D.vcxproj

@@ -100,7 +100,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -149,7 +149,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -209,7 +209,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -240,6 +240,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\2d\assets\AnimationAsset.cc" />
+    <ClCompile Include="..\..\source\2d\assets\FontAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ImageAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAssetEmitter.cc" />
@@ -269,7 +270,6 @@
     <ClCompile Include="..\..\source\2d\gui\guiSpriteCtrl.cc" />
     <ClCompile Include="..\..\source\2d\gui\SceneWindow.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
-    <ClCompile Include="..\..\source\2d\sceneobject\ImageFont.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ParticlePlayer.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
@@ -278,6 +278,7 @@
     <ClCompile Include="..\..\source\2d\sceneobject\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Trigger.cc" />
     <ClCompile Include="..\..\source\2d\scene\ContactFilter.cc" />
     <ClCompile Include="..\..\source\2d\scene\DebugDraw.cc" />
@@ -295,8 +296,11 @@
     <ClCompile Include="..\..\source\assets\declaredAssets.cc" />
     <ClCompile Include="..\..\source\assets\referencedAssets.cc" />
     <ClCompile Include="..\..\source\audio\AudioAsset.cc" />
+    <ClCompile Include="..\..\source\audio\audioDescriptions.cc" />
     <ClCompile Include="..\..\source\audio\audio_ScriptBinding.cc" />
     <ClCompile Include="..\..\source\audio\vorbisStreamSource.cc" />
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc" />
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2BroadPhase.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideCircle.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideEdge.cpp" />
@@ -652,6 +656,8 @@
   <ItemGroup>
     <ClInclude Include="..\..\source\2d\assets\AnimationAsset.h" />
     <ClInclude Include="..\..\source\2d\assets\AnimationAsset_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\assets\FontAsset.h" />
+    <ClInclude Include="..\..\source\2d\assets\FontAsset_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\assets\ImageAsset.h" />
     <ClInclude Include="..\..\source\2d\assets\ImageAsset_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\assets\ParticleAsset.h" />
@@ -701,12 +707,11 @@
     <ClInclude Include="..\..\source\2d\gui\SceneWindow_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont.h" />
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectList.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectMoveToEvent.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectRotateToEvent.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectSet.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectSet_ScriptBinding.h" />
@@ -719,6 +724,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\scene\ContactFilter.h" />
@@ -757,7 +764,12 @@
     <ClInclude Include="..\..\source\assets\tamlAssetReferencedUpdateVisitor.h" />
     <ClInclude Include="..\..\source\assets\tamlAssetReferencedVisitor.h" />
     <ClInclude Include="..\..\source\audio\AudioAsset.h" />
+    <ClInclude Include="..\..\source\audio\audioDescriptions.h" />
     <ClInclude Include="..\..\source\audio\vorbisStreamSource.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFont.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacter.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacterInfo.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontLineInfo.h" />
     <ClInclude Include="..\..\source\Box2D\Box2D.h" />
     <ClInclude Include="..\..\source\Box2D\Collision\b2BroadPhase.h" />
     <ClInclude Include="..\..\source\Box2D\Collision\b2Collision.h" />
@@ -1120,10 +1132,8 @@
     <ClInclude Include="..\..\source\platform\types.ppc.h" />
     <ClInclude Include="..\..\source\platform\types.visualc.h" />
     <ClInclude Include="..\..\source\platform\types.win32.h" />
-    <ClInclude Include="..\..\source\platform\typesLinux.h" />
     <ClInclude Include="..\..\source\platform\typesPPC.h" />
     <ClInclude Include="..\..\source\platform\typesWin32.h" />
-    <ClInclude Include="..\..\source\platform\typesX86UNIX.h" />
     <ClInclude Include="..\..\source\platform\menus\popupMenu.h" />
     <ClInclude Include="..\..\source\platform\nativeDialogs\fileDialog.h" />
     <ClInclude Include="..\..\source\platform\nativeDialogs\msgBox.h" />

+ 48 - 15
engine/compilers/VisualStudio 2013/Torque 2D.vcxproj.filters

@@ -199,6 +199,9 @@
     <Filter Include="spine">
       <UniqueIdentifier>{bb776838-ed6f-477c-b366-dd0c5c60ae5f}</UniqueIdentifier>
     </Filter>
+    <Filter Include="bitmapFont">
+      <UniqueIdentifier>{f2c8da8c-5c32-48ef-b5ab-0b27a9fe28d3}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1251,9 +1254,6 @@
     <ClCompile Include="..\..\source\2d\core\ParticleSystem.cc">
       <Filter>2d\core</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\source\2d\sceneobject\ImageFont.cc">
-      <Filter>2d\sceneobject</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\source\assets\declaredAssets.cc">
       <Filter>assets</Filter>
     </ClCompile>
@@ -1428,6 +1428,21 @@
     <ClCompile Include="..\..\source\audio\vorbisStreamSource.cc">
       <Filter>audio</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\source\2d\assets\FontAsset.cc">
+      <Filter>2d\assets</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc">
+      <Filter>bitmapFont</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc">
+      <Filter>bitmapFont</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\audio\audioDescriptions.cc">
+      <Filter>audio</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -1625,18 +1640,12 @@
     <ClInclude Include="..\..\source\platform\types.win32.h">
       <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\platform\typesLinux.h">
-      <Filter>platform</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\platform\typesPPC.h">
       <Filter>platform</Filter>
     </ClInclude>
     <ClInclude Include="..\..\source\platform\typesWin32.h">
       <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\platform\typesX86UNIX.h">
-      <Filter>platform</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\platform\menus\popupMenu.h">
       <Filter>platform\menus</Filter>
     </ClInclude>
@@ -2471,6 +2480,9 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject_ScriptBinding.h">
       <Filter>2d\sceneobject</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectMoveToEvent.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectRotateToEvent.h">
       <Filter>2d\sceneobject</Filter>
     </ClInclude>
@@ -2690,12 +2702,6 @@
     <ClInclude Include="..\..\source\2d\core\ParticleSystem.h">
       <Filter>2d\core</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont.h">
-      <Filter>2d\sceneobject</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont_ScriptBinding.h">
-      <Filter>2d\sceneobject</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\assets\declaredAssets.h">
       <Filter>assets</Filter>
     </ClInclude>
@@ -3165,6 +3171,33 @@
     <ClInclude Include="..\..\source\platformWin32\winVersion.h">
       <Filter>platformWin32</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\2d\assets\FontAsset.h">
+      <Filter>2d\assets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\assets\FontAsset_ScriptBinding.h">
+      <Filter>2d\assets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFont.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacter.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacterInfo.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontLineInfo.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\audio\audioDescriptions.h">
+      <Filter>audio</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">

+ 17 - 8
engine/compilers/VisualStudio 2015/Torque 2D.vcxproj

@@ -100,7 +100,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -149,7 +149,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -209,7 +209,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;unicows.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -240,6 +240,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\2d\assets\AnimationAsset.cc" />
+    <ClCompile Include="..\..\source\2d\assets\FontAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ImageAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAsset.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAssetEmitter.cc" />
@@ -269,7 +270,6 @@
     <ClCompile Include="..\..\source\2d\gui\guiSpriteCtrl.cc" />
     <ClCompile Include="..\..\source\2d\gui\SceneWindow.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
-    <ClCompile Include="..\..\source\2d\sceneobject\ImageFont.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ParticlePlayer.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
@@ -278,6 +278,7 @@
     <ClCompile Include="..\..\source\2d\sceneobject\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Trigger.cc" />
     <ClCompile Include="..\..\source\2d\scene\ContactFilter.cc" />
     <ClCompile Include="..\..\source\2d\scene\DebugDraw.cc" />
@@ -295,8 +296,11 @@
     <ClCompile Include="..\..\source\assets\declaredAssets.cc" />
     <ClCompile Include="..\..\source\assets\referencedAssets.cc" />
     <ClCompile Include="..\..\source\audio\AudioAsset.cc" />
+    <ClCompile Include="..\..\source\audio\audioDescriptions.cc" />
     <ClCompile Include="..\..\source\audio\audio_ScriptBinding.cc" />
     <ClCompile Include="..\..\source\audio\vorbisStreamSource.cc" />
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc" />
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2BroadPhase.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideCircle.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideEdge.cpp" />
@@ -652,6 +656,8 @@
   <ItemGroup>
     <ClInclude Include="..\..\source\2d\assets\AnimationAsset.h" />
     <ClInclude Include="..\..\source\2d\assets\AnimationAsset_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\assets\FontAsset.h" />
+    <ClInclude Include="..\..\source\2d\assets\FontAsset_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\assets\ImageAsset.h" />
     <ClInclude Include="..\..\source\2d\assets\ImageAsset_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\assets\ParticleAsset.h" />
@@ -701,8 +707,6 @@
     <ClInclude Include="..\..\source\2d\gui\SceneWindow_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont.h" />
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject.h" />
@@ -720,6 +724,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\scene\ContactFilter.h" />
@@ -758,7 +764,12 @@
     <ClInclude Include="..\..\source\assets\tamlAssetReferencedUpdateVisitor.h" />
     <ClInclude Include="..\..\source\assets\tamlAssetReferencedVisitor.h" />
     <ClInclude Include="..\..\source\audio\AudioAsset.h" />
+    <ClInclude Include="..\..\source\audio\audioDescriptions.h" />
     <ClInclude Include="..\..\source\audio\vorbisStreamSource.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFont.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacter.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacterInfo.h" />
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontLineInfo.h" />
     <ClInclude Include="..\..\source\Box2D\Box2D.h" />
     <ClInclude Include="..\..\source\Box2D\Collision\b2BroadPhase.h" />
     <ClInclude Include="..\..\source\Box2D\Collision\b2Collision.h" />
@@ -1121,10 +1132,8 @@
     <ClInclude Include="..\..\source\platform\types.ppc.h" />
     <ClInclude Include="..\..\source\platform\types.visualc.h" />
     <ClInclude Include="..\..\source\platform\types.win32.h" />
-    <ClInclude Include="..\..\source\platform\typesLinux.h" />
     <ClInclude Include="..\..\source\platform\typesPPC.h" />
     <ClInclude Include="..\..\source\platform\typesWin32.h" />
-    <ClInclude Include="..\..\source\platform\typesX86UNIX.h" />
     <ClInclude Include="..\..\source\platform\menus\popupMenu.h" />
     <ClInclude Include="..\..\source\platform\nativeDialogs\fileDialog.h" />
     <ClInclude Include="..\..\source\platform\nativeDialogs\msgBox.h" />

+ 45 - 15
engine/compilers/VisualStudio 2015/Torque 2D.vcxproj.filters

@@ -199,6 +199,9 @@
     <Filter Include="spine">
       <UniqueIdentifier>{bb776838-ed6f-477c-b366-dd0c5c60ae5f}</UniqueIdentifier>
     </Filter>
+    <Filter Include="bitmapFont">
+      <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1251,9 +1254,6 @@
     <ClCompile Include="..\..\source\2d\core\ParticleSystem.cc">
       <Filter>2d\core</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\source\2d\sceneobject\ImageFont.cc">
-      <Filter>2d\sceneobject</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\source\assets\declaredAssets.cc">
       <Filter>assets</Filter>
     </ClCompile>
@@ -1428,6 +1428,21 @@
     <ClCompile Include="..\..\source\audio\vorbisStreamSource.cc">
       <Filter>audio</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\source\2d\assets\FontAsset.cc">
+      <Filter>2d\assets</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc">
+      <Filter>bitmapFont</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc">
+      <Filter>bitmapFont</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\audio\audioDescriptions.cc">
+      <Filter>audio</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -1625,18 +1640,12 @@
     <ClInclude Include="..\..\source\platform\types.win32.h">
       <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\platform\typesLinux.h">
-      <Filter>platform</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\platform\typesPPC.h">
       <Filter>platform</Filter>
     </ClInclude>
     <ClInclude Include="..\..\source\platform\typesWin32.h">
       <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\platform\typesX86UNIX.h">
-      <Filter>platform</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\platform\menus\popupMenu.h">
       <Filter>platform\menus</Filter>
     </ClInclude>
@@ -2693,12 +2702,6 @@
     <ClInclude Include="..\..\source\2d\core\ParticleSystem.h">
       <Filter>2d\core</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont.h">
-      <Filter>2d\sceneobject</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\source\2d\sceneobject\ImageFont_ScriptBinding.h">
-      <Filter>2d\sceneobject</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\assets\declaredAssets.h">
       <Filter>assets</Filter>
     </ClInclude>
@@ -3168,6 +3171,33 @@
     <ClInclude Include="..\..\source\platformWin32\winVersion.h">
       <Filter>platformWin32</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\2d\assets\FontAsset.h">
+      <Filter>2d\assets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\assets\FontAsset_ScriptBinding.h">
+      <Filter>2d\assets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFont.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacter.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacterInfo.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\bitmapFont\BitmapFontLineInfo.h">
+      <Filter>bitmapFont</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\audio\audioDescriptions.h">
+      <Filter>audio</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">

+ 49 - 18
engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj

@@ -50,7 +50,6 @@
 		2AB4C1A316DE9F1100B02479 /* AmbientForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1A116DE9F1100B02479 /* AmbientForceController.cc */; };
 		2AB97A1D16B66BC70080F940 /* tamlCustom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB97A1B16B66BC70080F940 /* tamlCustom.cc */; };
 		2ABF5C8F16569A0C00BBBF1D /* osxMutex.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */; };
-		2AC4404516B0142B00FC4091 /* ImageFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AC4404316B0142B00FC4091 /* ImageFont.cc */; };
 		2AC5C7E81667C85700A0D046 /* platformStringTests.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AC5C7E71667C85700A0D046 /* platformStringTests.cc */; };
 		2ACAFD4A1705CF4A0022601C /* tamlJSONParser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ACAFD481705CF4A0022601C /* tamlJSONParser.cc */; };
 		2ACF5A2816E52D4B00F838D9 /* SpriteBatchQuery.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF5A2516E52D4B00F838D9 /* SpriteBatchQuery.cc */; };
@@ -485,6 +484,11 @@
 		B350D158174EF62400033EBB /* fileSystem_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D156174EF62400033EBB /* fileSystem_ScriptBinding.cc */; };
 		B350D164174EF71B00033EBB /* metaScripting_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D161174EF71B00033EBB /* metaScripting_ScriptBinding.cc */; };
 		B350D172174EF91900033EBB /* audio_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D171174EF91900033EBB /* audio_ScriptBinding.cc */; };
+		D000F9731CB0CF4800C4D097 /* audioDescriptions.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9711CB0CF4800C4D097 /* audioDescriptions.cc */; };
+		D000F97B1CB0D16A00C4D097 /* BitmapFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9751CB0D16A00C4D097 /* BitmapFont.cc */; };
+		D000F97C1CB0D16A00C4D097 /* BitmapFontCharacter.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9771CB0D16A00C4D097 /* BitmapFontCharacter.cc */; };
+		D000F9801CB0D1B300C4D097 /* FontAsset.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F97E1CB0D1B300C4D097 /* FontAsset.cc */; };
+		D000F9841CB0D25A00C4D097 /* TextSprite.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9821CB0D25A00C4D097 /* TextSprite.cc */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -594,9 +598,6 @@
 		2AB97A1B16B66BC70080F940 /* tamlCustom.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tamlCustom.cc; sourceTree = "<group>"; };
 		2AB97A1C16B66BC70080F940 /* tamlCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tamlCustom.h; sourceTree = "<group>"; };
 		2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxMutex.mm; sourceTree = "<group>"; };
-		2AC4404216B0142B00FC4091 /* ImageFont_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont_ScriptBinding.h; sourceTree = "<group>"; };
-		2AC4404316B0142B00FC4091 /* ImageFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFont.cc; sourceTree = "<group>"; };
-		2AC4404416B0142B00FC4091 /* ImageFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont.h; sourceTree = "<group>"; };
 		2AC5C7E71667C85700A0D046 /* platformStringTests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = platformStringTests.cc; path = ../../../source/testing/tests/platformStringTests.cc; sourceTree = "<group>"; };
 		2ACAFD481705CF4A0022601C /* tamlJSONParser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tamlJSONParser.cc; path = json/tamlJSONParser.cc; sourceTree = "<group>"; };
 		2ACAFD491705CF4A0022601C /* tamlJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tamlJSONParser.h; path = json/tamlJSONParser.h; sourceTree = "<group>"; };
@@ -928,7 +929,6 @@
 		86BC7EC316518D4600D96ADF /* SceneObject.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneObject.cc; sourceTree = "<group>"; };
 		86BC7EC416518D4600D96ADF /* SceneObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObject.h; sourceTree = "<group>"; };
 		86BC7EC516518D4600D96ADF /* SceneObject_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObject_ScriptBinding.h; sourceTree = "<group>"; };
-		86BC7EC816518D4600D96ADF /* SceneObjectMoveToEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectMoveToEvent.h; sourceTree = "<group>"; };
 		86BC7EC916518D4600D96ADF /* SceneObjectRotateToEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectRotateToEvent.h; sourceTree = "<group>"; };
 		86BC7ECE16518D4600D96ADF /* Scroller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scroller.cc; sourceTree = "<group>"; };
 		86BC7ECF16518D4600D96ADF /* Scroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scroller.h; sourceTree = "<group>"; };
@@ -1540,6 +1540,20 @@
 		B350D171174EF91900033EBB /* audio_ScriptBinding.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio_ScriptBinding.cc; sourceTree = "<group>"; };
 		B350D173174EF93900033EBB /* undo_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = undo_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D174174EFA6100033EBB /* Utility_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utility_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F9711CB0CF4800C4D097 /* audioDescriptions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioDescriptions.cc; sourceTree = "<group>"; };
+		D000F9721CB0CF4800C4D097 /* audioDescriptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioDescriptions.h; sourceTree = "<group>"; };
+		D000F9751CB0D16A00C4D097 /* BitmapFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapFont.cc; sourceTree = "<group>"; };
+		D000F9761CB0D16A00C4D097 /* BitmapFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFont.h; sourceTree = "<group>"; };
+		D000F9771CB0D16A00C4D097 /* BitmapFontCharacter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapFontCharacter.cc; sourceTree = "<group>"; };
+		D000F9781CB0D16A00C4D097 /* BitmapFontCharacter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontCharacter.h; sourceTree = "<group>"; };
+		D000F9791CB0D16A00C4D097 /* BitmapFontCharacterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontCharacterInfo.h; sourceTree = "<group>"; };
+		D000F97A1CB0D16A00C4D097 /* BitmapFontLineInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontLineInfo.h; sourceTree = "<group>"; };
+		D000F97D1CB0D1B300C4D097 /* FontAsset_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontAsset_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F97E1CB0D1B300C4D097 /* FontAsset.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontAsset.cc; sourceTree = "<group>"; };
+		D000F97F1CB0D1B300C4D097 /* FontAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontAsset.h; sourceTree = "<group>"; };
+		D000F9811CB0D25A00C4D097 /* TextSprite_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextSprite_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F9821CB0D25A00C4D097 /* TextSprite.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextSprite.cc; sourceTree = "<group>"; };
+		D000F9831CB0D25A00C4D097 /* TextSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextSprite.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -2122,6 +2136,7 @@
 		869FF8C21651518C002FE082 /* Torque2D */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9741CB0D16A00C4D097 /* bitmapFont */,
 				86BC7E7516518D4600D96ADF /* 2d */,
 				86BC7EE016518D4600D96ADF /* algorithm */,
 				86BC7EE716518D4600D96ADF /* assets */,
@@ -2182,6 +2197,9 @@
 		86BC7E7616518D4600D96ADF /* assets */ = {
 			isa = PBXGroup;
 			children = (
+				D000F97E1CB0D1B300C4D097 /* FontAsset.cc */,
+				D000F97F1CB0D1B300C4D097 /* FontAsset.h */,
+				D000F97D1CB0D1B300C4D097 /* FontAsset_ScriptBinding.h */,
 				27908E1018A3F904002D41BD /* SkeletonAsset_ScriptBinding.h */,
 				27908E1118A3F904002D41BD /* SkeletonAsset.cc */,
 				27908E1218A3F904002D41BD /* SkeletonAsset.h */,
@@ -2289,12 +2307,12 @@
 		86BC7EB716518D4600D96ADF /* sceneobject */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9811CB0D25A00C4D097 /* TextSprite_ScriptBinding.h */,
+				D000F9821CB0D25A00C4D097 /* TextSprite.cc */,
+				D000F9831CB0D25A00C4D097 /* TextSprite.h */,
 				86BC7EBB16518D4600D96ADF /* CompositeSprite.cc */,
 				86BC7EBC16518D4600D96ADF /* CompositeSprite.h */,
 				86BC7EBD16518D4600D96ADF /* CompositeSprite_ScriptBinding.h */,
-				2AC4404316B0142B00FC4091 /* ImageFont.cc */,
-				2AC4404416B0142B00FC4091 /* ImageFont.h */,
-				2AC4404216B0142B00FC4091 /* ImageFont_ScriptBinding.h */,
 				2A25738E16A48DAC00363C6F /* ParticlePlayer.cc */,
 				2A25738F16A48DAC00363C6F /* ParticlePlayer.h */,
 				2A25738D16A48DAC00363C6F /* ParticlePlayer_ScriptBinding.h */,
@@ -2303,7 +2321,6 @@
 				86BC7EC516518D4600D96ADF /* SceneObject_ScriptBinding.h */,
 				2AA6865A16D69943003CEF0A /* SceneObjectList.cc */,
 				2AA6865B16D69943003CEF0A /* SceneObjectList.h */,
-				86BC7EC816518D4600D96ADF /* SceneObjectMoveToEvent.h */,
 				86BC7EC916518D4600D96ADF /* SceneObjectRotateToEvent.h */,
 				2AA6865D16D69943003CEF0A /* SceneObjectSet.cc */,
 				2AA6865E16D69943003CEF0A /* SceneObjectSet.h */,
@@ -2376,6 +2393,8 @@
 		86BC7F0016518D4600D96ADF /* audio */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9711CB0CF4800C4D097 /* audioDescriptions.cc */,
+				D000F9721CB0CF4800C4D097 /* audioDescriptions.h */,
 				B350D171174EF91900033EBB /* audio_ScriptBinding.cc */,
 				86BC7F0116518D4600D96ADF /* audio.cc */,
 				86BC7F0216518D4600D96ADF /* audio.h */,
@@ -3219,6 +3238,20 @@
 			path = threads;
 			sourceTree = "<group>";
 		};
+		D000F9741CB0D16A00C4D097 /* bitmapFont */ = {
+			isa = PBXGroup;
+			children = (
+				D000F9751CB0D16A00C4D097 /* BitmapFont.cc */,
+				D000F9761CB0D16A00C4D097 /* BitmapFont.h */,
+				D000F9771CB0D16A00C4D097 /* BitmapFontCharacter.cc */,
+				D000F9781CB0D16A00C4D097 /* BitmapFontCharacter.h */,
+				D000F9791CB0D16A00C4D097 /* BitmapFontCharacterInfo.h */,
+				D000F97A1CB0D16A00C4D097 /* BitmapFontLineInfo.h */,
+			);
+			name = bitmapFont;
+			path = ../../../source/bitmapFont;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -3246,7 +3279,7 @@
 		869FF8AF1651518C002FE082 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0500;
+				LastUpgradeCheck = 0510;
 				ORGANIZATIONNAME = "Michael Perry";
 			};
 			buildConfigurationList = 869FF8B21651518C002FE082 /* Build configuration list for PBXProject "Torque2D" */;
@@ -3348,6 +3381,7 @@
 				27908DFB18A3F8CB002D41BD /* AnimationState.c in Sources */,
 				86D770991656873C0046D71F /* msgBox.cpp in Sources */,
 				86D770AA1656873C0046D71F /* scriptGroup.cc in Sources */,
+				D000F9731CB0CF4800C4D097 /* audioDescriptions.cc in Sources */,
 				86D770AB1656873C0046D71F /* scriptObject.cc in Sources */,
 				86D770AC1656873C0046D71F /* simBase.cc in Sources */,
 				86D770AD1656873C0046D71F /* simConsoleEvent.cc in Sources */,
@@ -3385,6 +3419,8 @@
 				86D7704C165687220046D71F /* centralDir.cc in Sources */,
 				86D7704D165687220046D71F /* compressor.cc in Sources */,
 				86D7704E165687220046D71F /* deflate.cc in Sources */,
+				D000F97C1CB0D16A00C4D097 /* BitmapFontCharacter.cc in Sources */,
+				D000F97B1CB0D16A00C4D097 /* BitmapFont.cc in Sources */,
 				86D7704F165687220046D71F /* extraField.cc in Sources */,
 				86D77050165687220046D71F /* fileHeader.cc in Sources */,
 				86D77051165687220046D71F /* stored.cc in Sources */,
@@ -3426,6 +3462,7 @@
 				27908E0A18A3F8CB002D41BD /* SkeletonBounds.c in Sources */,
 				86D76FD2165687060046D71F /* RemoteDebugger1.cc in Sources */,
 				86D76FD3165687060046D71F /* RemoteDebuggerBase.cc in Sources */,
+				D000F9801CB0D1B300C4D097 /* FontAsset.cc in Sources */,
 				86D76FD4165687060046D71F /* RemoteDebuggerBridge.cc in Sources */,
 				86D76FD5165687060046D71F /* telnetDebugger.cc in Sources */,
 				86D76FD6165687060046D71F /* delegateSignal.cpp in Sources */,
@@ -3660,6 +3697,7 @@
 				865A2331165187FF00527C44 /* jquant2.c in Sources */,
 				27908E0218A3F8CB002D41BD /* BoneData.c in Sources */,
 				865A2332165187FF00527C44 /* jutils.c in Sources */,
+				D000F9841CB0D25A00C4D097 /* TextSprite.cc in Sources */,
 				865A23421651881300527C44 /* png.c in Sources */,
 				865A23431651881300527C44 /* pngerror.c in Sources */,
 				27908E0718A3F8CB002D41BD /* Json.c in Sources */,
@@ -3717,7 +3755,6 @@
 				2A25739016A48DAC00363C6F /* ParticlePlayer.cc in Sources */,
 				2AE5B54216A6D860006908D5 /* ParticleAssetFieldCollection.cc in Sources */,
 				2AF3633916A9BBE0004ED7AA /* ParticleSystem.cc in Sources */,
-				2AC4404516B0142B00FC4091 /* ImageFont.cc in Sources */,
 				2AF1C54016B439BB00C1CF3A /* declaredAssets.cc in Sources */,
 				2AF1C54116B439BB00C1CF3A /* referencedAssets.cc in Sources */,
 				2AB97A1D16B66BC70080F940 /* tamlCustom.cc in Sources */,
@@ -3768,7 +3805,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
 				CLANG_CXX_LIBRARY = "libstdc++";
 				CLANG_WARN_EMPTY_BODY = YES;
@@ -3795,7 +3831,6 @@
 		865A20AF165152EA00527C44 /* Shipping */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;
@@ -3837,7 +3872,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
 				CLANG_CXX_LIBRARY = "libstdc++";
 				CLANG_WARN_EMPTY_BODY = YES;
@@ -3862,7 +3896,7 @@
 				HEADER_SEARCH_PATHS = "";
 				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
 				MACOSX_DEPLOYMENT_TARGET = 10.6;
-				ONLY_ACTIVE_ARCH = NO;
+				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = macosx;
 				VALID_ARCHS = i386;
 			};
@@ -3872,7 +3906,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
 				CLANG_CXX_LIBRARY = "libstdc++";
 				CLANG_WARN_EMPTY_BODY = YES;
@@ -3903,7 +3936,6 @@
 		869FF8D71651518C002FE082 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;
@@ -3946,7 +3978,6 @@
 		869FF8D81651518C002FE082 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;

+ 47 - 14
engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj

@@ -40,7 +40,6 @@
 		2AB4C1B016DE9F6700B02479 /* GroupedSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1AA16DE9F6700B02479 /* GroupedSceneController.cc */; };
 		2AB4C1B116DE9F6700B02479 /* PickingSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1AD16DE9F6700B02479 /* PickingSceneController.cc */; };
 		2AB97A2116B66BE50080F940 /* tamlCustom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB97A1F16B66BE50080F940 /* tamlCustom.cc */; };
-		2AC4404E16B0144500FC4091 /* ImageFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AC4404C16B0144500FC4091 /* ImageFont.cc */; };
 		2ACAFD471705CF340022601C /* tamlJSONParser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ACAFD451705CF340022601C /* tamlJSONParser.cc */; };
 		2ACF5A2C16E52D6A00F838D9 /* SpriteBatchQuery.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF5A2916E52D6A00F838D9 /* SpriteBatchQuery.cc */; };
 		2AD42156170434C2005BB8AD /* tamlBinaryReader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AD42152170434C2005BB8AD /* tamlBinaryReader.cc */; };
@@ -508,6 +507,11 @@
 		B350D1A3174F063200033EBB /* math_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D19F174F063200033EBB /* math_ScriptBinding.cc */; };
 		B350D1A5174F064000033EBB /* frameAllocator_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D1A4174F064000033EBB /* frameAllocator_ScriptBinding.cc */; };
 		B350D1BB174F06B700033EBB /* platformNetwork_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D1B8174F06B700033EBB /* platformNetwork_ScriptBinding.cc */; };
+		D000F9881CB0D44600C4D097 /* TextSprite.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9861CB0D44600C4D097 /* TextSprite.cc */; };
+		D000F98C1CB0D46D00C4D097 /* FontAsset.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98A1CB0D46D00C4D097 /* FontAsset.cc */; };
+		D000F9941CB0D48600C4D097 /* BitmapFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98E1CB0D48600C4D097 /* BitmapFont.cc */; };
+		D000F9951CB0D48600C4D097 /* BitmapFontCharacter.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9901CB0D48600C4D097 /* BitmapFontCharacter.cc */; };
+		D000F9981CB0D5DD00C4D097 /* audioDescriptions.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9961CB0D5DD00C4D097 /* audioDescriptions.cc */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -588,9 +592,6 @@
 		2AB4C1AF16DE9F6700B02479 /* SceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController.h; path = controllers/core/SceneController.h; sourceTree = "<group>"; };
 		2AB97A1F16B66BE50080F940 /* tamlCustom.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tamlCustom.cc; sourceTree = "<group>"; };
 		2AB97A2016B66BE50080F940 /* tamlCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tamlCustom.h; sourceTree = "<group>"; };
-		2AC4404B16B0144500FC4091 /* ImageFont_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont_ScriptBinding.h; sourceTree = "<group>"; };
-		2AC4404C16B0144500FC4091 /* ImageFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFont.cc; sourceTree = "<group>"; };
-		2AC4404D16B0144500FC4091 /* ImageFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont.h; sourceTree = "<group>"; };
 		2ACAFD451705CF340022601C /* tamlJSONParser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tamlJSONParser.cc; path = json/tamlJSONParser.cc; sourceTree = "<group>"; };
 		2ACAFD461705CF340022601C /* tamlJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tamlJSONParser.h; path = json/tamlJSONParser.h; sourceTree = "<group>"; };
 		2ACF5A2916E52D6A00F838D9 /* SpriteBatchQuery.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatchQuery.cc; sourceTree = "<group>"; };
@@ -784,7 +785,6 @@
 		867BAD5216AEC9050033868F /* SceneObject.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneObject.cc; sourceTree = "<group>"; };
 		867BAD5316AEC9050033868F /* SceneObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObject.h; sourceTree = "<group>"; };
 		867BAD5416AEC9050033868F /* SceneObject_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObject_ScriptBinding.h; sourceTree = "<group>"; };
-		867BAD5716AEC9050033868F /* SceneObjectMoveToEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectMoveToEvent.h; sourceTree = "<group>"; };
 		867BAD5816AEC9050033868F /* SceneObjectRotateToEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectRotateToEvent.h; sourceTree = "<group>"; };
 		867BAD5D16AEC9050033868F /* Scroller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scroller.cc; sourceTree = "<group>"; };
 		867BAD5E16AEC9050033868F /* Scroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scroller.h; sourceTree = "<group>"; };
@@ -1289,10 +1289,8 @@
 		867BAFAE16AEC9050033868F /* types.ppc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.ppc.h; sourceTree = "<group>"; };
 		867BAFAF16AEC9050033868F /* types.visualc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.visualc.h; sourceTree = "<group>"; };
 		867BAFB016AEC9050033868F /* types.win32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.win32.h; sourceTree = "<group>"; };
-		867BAFB116AEC9050033868F /* typesLinux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typesLinux.h; sourceTree = "<group>"; };
 		867BAFB216AEC9050033868F /* typesPPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typesPPC.h; sourceTree = "<group>"; };
 		867BAFB316AEC9050033868F /* typesWin32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typesWin32.h; sourceTree = "<group>"; };
-		867BAFB416AEC9050033868F /* typesX86UNIX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typesX86UNIX.h; sourceTree = "<group>"; };
 		867BAFB616AEC9050033868F /* scriptGroup.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptGroup.cc; sourceTree = "<group>"; };
 		867BAFB716AEC9050033868F /* scriptGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scriptGroup.h; sourceTree = "<group>"; };
 		867BAFB816AEC9050033868F /* scriptObject.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptObject.cc; sourceTree = "<group>"; };
@@ -1586,6 +1584,20 @@
 		B350D1C2174F06DE00033EBB /* simSet_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simSet_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1C3174F06ED00033EBB /* stringBuffer_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringBuffer_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1C4174F06ED00033EBB /* stringUnit_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringUnit_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F9851CB0D44600C4D097 /* TextSprite_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextSprite_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F9861CB0D44600C4D097 /* TextSprite.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextSprite.cc; sourceTree = "<group>"; };
+		D000F9871CB0D44600C4D097 /* TextSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextSprite.h; sourceTree = "<group>"; };
+		D000F9891CB0D46D00C4D097 /* FontAsset_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontAsset_ScriptBinding.h; sourceTree = "<group>"; };
+		D000F98A1CB0D46D00C4D097 /* FontAsset.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontAsset.cc; sourceTree = "<group>"; };
+		D000F98B1CB0D46D00C4D097 /* FontAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontAsset.h; sourceTree = "<group>"; };
+		D000F98E1CB0D48600C4D097 /* BitmapFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapFont.cc; sourceTree = "<group>"; };
+		D000F98F1CB0D48600C4D097 /* BitmapFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFont.h; sourceTree = "<group>"; };
+		D000F9901CB0D48600C4D097 /* BitmapFontCharacter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapFontCharacter.cc; sourceTree = "<group>"; };
+		D000F9911CB0D48600C4D097 /* BitmapFontCharacter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontCharacter.h; sourceTree = "<group>"; };
+		D000F9921CB0D48600C4D097 /* BitmapFontCharacterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontCharacterInfo.h; sourceTree = "<group>"; };
+		D000F9931CB0D48600C4D097 /* BitmapFontLineInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapFontLineInfo.h; sourceTree = "<group>"; };
+		D000F9961CB0D5DD00C4D097 /* audioDescriptions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioDescriptions.cc; sourceTree = "<group>"; };
+		D000F9971CB0D5DD00C4D097 /* audioDescriptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioDescriptions.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1879,6 +1891,9 @@
 		867BACF916AEC9050033868F /* assets */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9891CB0D46D00C4D097 /* FontAsset_ScriptBinding.h */,
+				D000F98A1CB0D46D00C4D097 /* FontAsset.cc */,
+				D000F98B1CB0D46D00C4D097 /* FontAsset.h */,
 				27908E1818A3FA9C002D41BD /* SkeletonAsset_ScriptBinding.h */,
 				27908E1918A3FA9C002D41BD /* SkeletonAsset.cc */,
 				27908E1A18A3FA9C002D41BD /* SkeletonAsset.h */,
@@ -1986,6 +2001,9 @@
 		867BAD4516AEC9050033868F /* sceneobject */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9851CB0D44600C4D097 /* TextSprite_ScriptBinding.h */,
+				D000F9861CB0D44600C4D097 /* TextSprite.cc */,
+				D000F9871CB0D44600C4D097 /* TextSprite.h */,
 				27908E1C18A3FAB1002D41BD /* SkeletonObject_ScriptBinding.h */,
 				27908E1D18A3FAB1002D41BD /* SkeletonObject.cc */,
 				27908E1E18A3FAB1002D41BD /* SkeletonObject.h */,
@@ -1994,9 +2012,6 @@
 				2AA6866716D69968003CEF0A /* SceneObjectSet_ScriptBinding.h */,
 				2AA6866816D69968003CEF0A /* SceneObjectSet.cc */,
 				2AA6866916D69968003CEF0A /* SceneObjectSet.h */,
-				2AC4404B16B0144500FC4091 /* ImageFont_ScriptBinding.h */,
-				2AC4404C16B0144500FC4091 /* ImageFont.cc */,
-				2AC4404D16B0144500FC4091 /* ImageFont.h */,
 				867BAD4916AEC9050033868F /* CompositeSprite.cc */,
 				867BAD4A16AEC9050033868F /* CompositeSprite.h */,
 				867BAD4B16AEC9050033868F /* CompositeSprite_ScriptBinding.h */,
@@ -2006,7 +2021,6 @@
 				867BAD5216AEC9050033868F /* SceneObject.cc */,
 				867BAD5316AEC9050033868F /* SceneObject.h */,
 				867BAD5416AEC9050033868F /* SceneObject_ScriptBinding.h */,
-				867BAD5716AEC9050033868F /* SceneObjectMoveToEvent.h */,
 				867BAD5816AEC9050033868F /* SceneObjectRotateToEvent.h */,
 				867BAD5D16AEC9050033868F /* Scroller.cc */,
 				867BAD5E16AEC9050033868F /* Scroller.h */,
@@ -2073,6 +2087,8 @@
 		867BAD8916AEC9050033868F /* audio */ = {
 			isa = PBXGroup;
 			children = (
+				D000F9961CB0D5DD00C4D097 /* audioDescriptions.cc */,
+				D000F9971CB0D5DD00C4D097 /* audioDescriptions.h */,
 				B350D17B174F053800033EBB /* audio_ScriptBinding.cc */,
 				867BAD8A16AEC9050033868F /* audio.cc */,
 				867BAD8B16AEC9050033868F /* audio.h */,
@@ -2819,10 +2835,8 @@
 				867BAFAE16AEC9050033868F /* types.ppc.h */,
 				867BAFAF16AEC9050033868F /* types.visualc.h */,
 				867BAFB016AEC9050033868F /* types.win32.h */,
-				867BAFB116AEC9050033868F /* typesLinux.h */,
 				867BAFB216AEC9050033868F /* typesPPC.h */,
 				867BAFB316AEC9050033868F /* typesWin32.h */,
-				867BAFB416AEC9050033868F /* typesX86UNIX.h */,
 			);
 			name = platform;
 			path = ../../../source/platform;
@@ -3224,6 +3238,7 @@
 		86A9A3BA16AEC786003F01E6 /* Torque2D */ = {
 			isa = PBXGroup;
 			children = (
+				D000F98D1CB0D48600C4D097 /* bitmapFont */,
 				867BACF816AEC9050033868F /* 2d */,
 				867BAD6916AEC9050033868F /* algorithm */,
 				867BAD7016AEC9050033868F /* assets */,
@@ -3276,6 +3291,20 @@
 			path = Torque2D;
 			sourceTree = "<group>";
 		};
+		D000F98D1CB0D48600C4D097 /* bitmapFont */ = {
+			isa = PBXGroup;
+			children = (
+				D000F98E1CB0D48600C4D097 /* BitmapFont.cc */,
+				D000F98F1CB0D48600C4D097 /* BitmapFont.h */,
+				D000F9901CB0D48600C4D097 /* BitmapFontCharacter.cc */,
+				D000F9911CB0D48600C4D097 /* BitmapFontCharacter.h */,
+				D000F9921CB0D48600C4D097 /* BitmapFontCharacterInfo.h */,
+				D000F9931CB0D48600C4D097 /* BitmapFontLineInfo.h */,
+			);
+			name = bitmapFont;
+			path = ../../../source/bitmapFont;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -3429,6 +3458,7 @@
 				867BB00B16AEC9050033868F /* assetQuery.cc in Sources */,
 				867BB00D16AEC9050033868F /* assetTagsManifest.cc in Sources */,
 				867BB00E16AEC9050033868F /* audio.cc in Sources */,
+				D000F9981CB0D5DD00C4D097 /* audioDescriptions.cc in Sources */,
 				27908E5418A3FAE1002D41BD /* AttachmentLoader.c in Sources */,
 				867BB00F16AEC9050033868F /* AudioAsset.cc in Sources */,
 				867BB01016AEC9050033868F /* audioBuffer.cc in Sources */,
@@ -3534,6 +3564,7 @@
 				867BB07D16AEC9050033868F /* guiCanvas.cc in Sources */,
 				867BB07F16AEC9050033868F /* guiConsole.cc in Sources */,
 				867BB08016AEC9050033868F /* guiConsoleEditCtrl.cc in Sources */,
+				D000F9951CB0D48600C4D097 /* BitmapFontCharacter.cc in Sources */,
 				867BB08116AEC9050033868F /* guiConsoleTextCtrl.cc in Sources */,
 				867BB08216AEC9050033868F /* guiControl.cc in Sources */,
 				867BB08316AEC9050033868F /* guiDefaultControlRender.cc in Sources */,
@@ -3576,6 +3607,7 @@
 				867BB0A816AEC9050033868F /* centralDir.cc in Sources */,
 				27908E5118A3FAE1002D41BD /* Atlas.c in Sources */,
 				867BB0A916AEC9050033868F /* compressor.cc in Sources */,
+				D000F98C1CB0D46D00C4D097 /* FontAsset.cc in Sources */,
 				867BB0AA16AEC9050033868F /* deflate.cc in Sources */,
 				867BB0AB16AEC9050033868F /* extraField.cc in Sources */,
 				867BB0AC16AEC9050033868F /* fileHeader.cc in Sources */,
@@ -3729,6 +3761,7 @@
 				867BB21D16AECA070033868F /* pngread.c in Sources */,
 				867BB21E16AECA070033868F /* pngrio.c in Sources */,
 				867BB21F16AECA070033868F /* pngrtran.c in Sources */,
+				D000F9881CB0D44600C4D097 /* TextSprite.cc in Sources */,
 				867BB22016AECA070033868F /* pngrutil.c in Sources */,
 				867BB22116AECA070033868F /* pngset.c in Sources */,
 				867BB22216AECA070033868F /* pngtrans.c in Sources */,
@@ -3762,6 +3795,7 @@
 				27908E4F18A3FAE1002D41BD /* AnimationState.c in Sources */,
 				867BB26B16AECA110033868F /* jddctmgr.c in Sources */,
 				867BB26C16AECA110033868F /* jdhuff.c in Sources */,
+				D000F9941CB0D48600C4D097 /* BitmapFont.cc in Sources */,
 				867BB26D16AECA110033868F /* jdinput.c in Sources */,
 				867BB26E16AECA110033868F /* jdmainct.c in Sources */,
 				867BB26F16AECA110033868F /* jdmarker.c in Sources */,
@@ -3785,7 +3819,6 @@
 				867BB28116AECA110033868F /* jquant2.c in Sources */,
 				867BB28216AECA110033868F /* jutils.c in Sources */,
 				867BB44416AED2850033868F /* iOSGL2ES.mm in Sources */,
-				2AC4404E16B0144500FC4091 /* ImageFont.cc in Sources */,
 				86555D3716B2C2B400881446 /* T2DAppDelegate.mm in Sources */,
 				86555D3816B2C2B400881446 /* T2DView.mm in Sources */,
 				86555D3916B2C2B400881446 /* T2DViewController.mm in Sources */,

+ 9 - 6
engine/compilers/android-studio/app/build.gradle

@@ -1,14 +1,15 @@
 apply plugin: 'com.android.application'
 
+import org.apache.tools.ant.taskdefs.condition.Os
 
 android {
-    compileSdkVersion 19
-    buildToolsVersion "22.0.1"
+    compileSdkVersion 22
+    buildToolsVersion "23.0.2"
 
     defaultConfig {
         applicationId "com.garagegames.torque2d"
-        minSdkVersion 19
-        targetSdkVersion 19
+        minSdkVersion 22
+        targetSdkVersion 22
 
         sourceSets.main {
             assets.srcDirs=[
@@ -21,7 +22,8 @@ android {
         }
         task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
             def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()
-            commandLine "$ndkDir/ndk-build",
+            def extension = (Os.isFamily(Os.FAMILY_WINDOWS))? '.cmd' : ''
+            commandLine "$ndkDir/ndk-build" + extension,
                     '-C', file('src/main/jni').absolutePath,
                     '-j', Runtime.runtime.availableProcessors(),
                     'all',
@@ -30,7 +32,8 @@ android {
 
         task cleanNative(type: Exec, description: 'Clean JNI object files') {
             def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()
-            commandLine "$ndkDir/ndk-build",
+            def extension = (Os.isFamily(Os.FAMILY_WINDOWS))? '.cmd' : ''
+            commandLine "$ndkDir/ndk-build" + extension,
                     '-C', file('src/main/jni').absolutePath,
                     'clean'
         }

+ 10 - 4
engine/compilers/android-studio/app/src/main/jni/Android.mk

@@ -198,6 +198,7 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
                     ../../../../../../lib/libvorbis/vorbisfile.c \
                     ../../../../../../lib/libvorbis/window.c \
 					../../../../../../source/2d/assets/AnimationAsset.cc \
+					../../../../../../source/2d/assets/FontAsset.cc \
 					../../../../../../source/2d/assets/ImageAsset.cc \
 					../../../../../../source/2d/assets/ParticleAsset.cc \
 					../../../../../../source/2d/assets/ParticleAssetEmitter.cc \
@@ -227,7 +228,6 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/2d/gui/guiSpriteCtrl.cc \
 					../../../../../../source/2d/gui/SceneWindow.cc \
 					../../../../../../source/2d/sceneobject/CompositeSprite.cc \
-					../../../../../../source/2d/sceneobject/ImageFont.cc \
 					../../../../../../source/2d/sceneobject/ParticlePlayer.cc \
 					../../../../../../source/2d/sceneobject/SceneObject.cc \
 					../../../../../../source/2d/sceneobject/SceneObjectList.cc \
@@ -236,6 +236,7 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/2d/sceneobject/ShapeVector.cc \
 					../../../../../../source/2d/sceneobject/SkeletonObject.cc \
 					../../../../../../source/2d/sceneobject/Sprite.cc \
+					../../../../../../source/2d/sceneobject/TextSprite.cc \
 					../../../../../../source/2d/sceneobject/Trigger.cc \
 					../../../../../../source/2d/scene/ContactFilter.cc \
 					../../../../../../source/2d/scene/DebugDraw.cc \
@@ -254,12 +255,15 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/assets/referencedAssets.cc \
                     ../../../../../../source/audio/audio.cc \
                     ../../../../../../source/audio/audioDataBlock.cc \
+					../../../../../../source/audio/audioDescriptions.cc \
                     ../../../../../../source/audio/audio_ScriptBinding.cc \
                     ../../../../../../source/audio/audioStreamSourceFactory.cc \
                     ../../../../../../source/audio/wavStreamSource.cc \
 					../../../../../../source/audio/AudioAsset.cc \
 					../../../../../../source/audio/audioBuffer.cc \
 					../../../../../../source/audio/vorbisStreamSource.cc \
+					../../../../../../source/bitmapFont/BitmapFont.cc \
+					../../../../../../source/bitmapFont/BitmapFontCharacter.cc \
 					../../../../../../source/Box2D/Collision/b2BroadPhase.cpp \
 					../../../../../../source/Box2D/Collision/b2CollideCircle.cpp \
 					../../../../../../source/Box2D/Collision/b2CollideEdge.cpp \
@@ -603,10 +607,12 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 #					../../../../../../source/testing/unitTesting.cc
  
 ifeq ($(APP_OPTIM),debug)
-	LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_DEBUG -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O0 -fsigned-char   
+	LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_DEBUG -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O0 -fsigned-char
+	LOCAL_CPPFLAGS := -std=gnu++11 $(LOCAL_CFLAGS)
 else
-	LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O3 -fsigned-char   
-endif				   
+	LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O3 -fsigned-char
+	LOCAL_CPPFLAGS := -std=gnu++11 $(LOCAL_CFLAGS)
+endif
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM -lz -lOpenSLES -L../../../../../../lib/openal/Android/$(TARGET_ARCH_ABI)
 LOCAL_STATIC_LIBRARIES := android_native_app_glue freetype-prebuilt
 LOCAL_SHARED_LIBRARIES := libopenal-prebuilt

+ 275 - 0
engine/source/2d/assets/FontAsset.cc

@@ -0,0 +1,275 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _CONSOLE_H_
+#include "console/console.h"
+#endif
+
+#ifndef _CONSOLEINTERNAL_H_
+#include "console/consoleInternal.h"
+#endif
+
+#ifndef _GBITMAP_H_
+#include "graphics/gBitmap.h"
+#endif
+
+#ifndef _UTILITY_H_
+#include "2d/core/Utility.h"
+#endif
+
+#ifndef _SCENE_OBJECT_H_
+#include "2d/sceneobject/SceneObject.h"
+#endif
+
+#ifndef _FONT_ASSET_H_
+#include "2d/assets/FontAsset.h"
+#endif
+
+// Script bindings.
+#include "FontAsset_ScriptBinding.h"
+
+//------------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(FontAsset);
+
+//------------------------------------------------------------------------------
+
+ConsoleType( FontAssetPtr, TypeFontAssetPtr, sizeof(AssetPtr<FontAsset>), ASSET_ID_FIELD_PREFIX )
+
+//-----------------------------------------------------------------------------
+
+ConsoleGetType( TypeFontAssetPtr )
+{
+    // Fetch asset Id.
+    return (*((AssetPtr<FontAsset>*)dptr)).getAssetId();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleSetType( TypeFontAssetPtr )
+{
+    // Was a single argument specified?
+    if( argc == 1 )
+    {
+        // Yes, so fetch field value.
+        const char* pFieldValue = argv[0];
+
+        // Fetch asset pointer.
+        AssetPtr<FontAsset>* pAssetPtr = dynamic_cast<AssetPtr<FontAsset>*>((AssetPtrBase*)(dptr));
+
+        // Is the asset pointer the correct type?
+        if (pAssetPtr == NULL )
+        {
+            // No, so fail.
+            Con::warnf( "(TypeFontAssetPtr) - Failed to set asset Id '%d'.", pFieldValue );
+            return;
+        }
+
+        // Set asset.
+        pAssetPtr->setAssetId( pFieldValue );
+
+        return;
+   }
+
+    // Warn.
+    Con::warnf( "(TypeFontAssetPtr) - Cannot set multiple args to a single asset." );
+}
+
+
+//------------------------------------------------------------------------------
+
+FontAsset::FontAsset() :    mFontFile(StringTable->EmptyString),
+                                    mBitmapFont()
+{
+}
+
+//------------------------------------------------------------------------------
+
+FontAsset::~FontAsset()
+{
+    
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::initPersistFields()
+{
+    // Call parent.
+    Parent::initPersistFields();
+
+    // Fields.
+    addProtectedField("FontFile", TypeAssetLooseFilePath, Offset(mFontFile, FontAsset), &setFontFile, &defaultProtectedGetFn, &writeFontFile, "The loose file pointing to a .fnt file");
+}
+
+//------------------------------------------------------------------------------
+
+bool FontAsset::onAdd()
+{
+    // Call Parent.
+    if (!Parent::onAdd())
+       return false;
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::onRemove()
+{
+    // Call Parent.
+    Parent::onRemove();
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::setFontFile( const char* pFontFile )
+{
+    // Sanity!
+    AssertFatal( pFontFile != NULL, "Cannot use a NULL Font file." );
+
+    // Fetch Font file.
+    pFontFile = StringTable->insert( pFontFile );
+
+    // Ignore no change.
+    if (pFontFile == mFontFile )
+        return;
+
+    // Update.
+    mFontFile = getOwned() ? expandAssetFilePath( pFontFile ) : StringTable->insert( pFontFile );
+
+    // Refresh the asset.
+    refreshAsset();
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::copyTo(SimObject* object)
+{
+    // Call to parent.
+    Parent::copyTo(object);
+
+    // Cast to asset.
+    FontAsset* pAsset = static_cast<FontAsset*>(object);
+
+    // Sanity!
+    AssertFatal(pAsset != NULL, "FontAsset::copyTo() - Object is not the correct type.");
+
+    // Copy state.
+    pAsset->setFontFile( getFontFile() );
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::initializeAsset( void )
+{
+    // Call parent.
+    Parent::initializeAsset();
+
+    // Ensure the Font file is expanded.
+    mFontFile = expandAssetFilePath( mFontFile );
+
+    // Build the Font data
+    buildFontData();
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::onAssetRefresh( void )
+{
+    // Ignore if not yet added to the sim.
+    if (!isProperlyAdded() )
+        return;
+
+    // Call parent.
+    Parent::onAssetRefresh();
+
+    buildFontData();
+}
+
+//-----------------------------------------------------------------------------
+
+void FontAsset::buildFontData( void )
+{
+   FileStream fStream;
+
+   if (!fStream.open(mFontFile, FileStream::Read))
+   {
+      Con::printf("Failed to open file '%s'.", expandAssetFilePath(mFontFile));
+      return;
+   }
+
+   mBitmapFont.mPageName.clear();
+   mBitmapFont.parseFont(fStream);
+
+   fStream.close();
+
+   //load the images
+   mBitmapFont.mTexture.clear();
+   for (auto iter = mBitmapFont.mPageName.begin(); iter != mBitmapFont.mPageName.end(); iter++)
+   {
+      mBitmapFont.mTexture.push_back(mBitmapFont.LoadTexture(expandAssetFilePath(*iter)));
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void FontAsset::onTamlPreWrite( void )
+{
+    // Call parent.
+    Parent::onTamlPreWrite();
+
+    // Ensure the Font file is collapsed.
+    mFontFile = collapseAssetFilePath( mFontFile );
+}
+
+//-----------------------------------------------------------------------------
+
+void FontAsset::onTamlPostWrite( void )
+{
+    // Call parent.
+    Parent::onTamlPostWrite();
+
+    // Ensure the Font file is expanded.
+    mFontFile = expandAssetFilePath( mFontFile );
+}
+
+//------------------------------------------------------------------------------
+
+void FontAsset::onTamlCustomWrite( TamlCustomNodes& customNodes )
+{
+    // Debug Profiling.
+    PROFILE_SCOPE(FontAsset_OnTamlCustomWrite);
+
+    // Call parent.
+    Parent::onTamlCustomWrite( customNodes );
+}
+
+//-----------------------------------------------------------------------------
+
+void FontAsset::onTamlCustomRead( const TamlCustomNodes& customNodes )
+{
+    // Debug Profiling.
+    PROFILE_SCOPE(FontAsset_OnTamlCustomRead);
+
+    // Call parent.
+    Parent::onTamlCustomRead( customNodes );
+}

+ 93 - 0
engine/source/2d/assets/FontAsset.h

@@ -0,0 +1,93 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _FONT_ASSET_H_
+#define _FONT_ASSET_H_
+
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
+#ifndef _IMAGE_ASSET_H_
+#include "2d/assets/ImageAsset.h"
+#endif
+
+#ifndef _BITMAP_FONT_H_
+#include "bitmapFont/BitmapFont.h"
+#endif
+
+//-----------------------------------------------------------------------------
+
+DefineConsoleType(TypeFontAssetPtr)
+
+//-----------------------------------------------------------------------------
+
+using namespace font;
+
+class FontAsset : public AssetBase
+{
+private:
+    typedef AssetBase Parent;
+
+public:
+    StringTableEntry                mFontFile;
+    AssetPtr<ImageAsset>            mImageAsset;
+    BitmapFont                      mBitmapFont;
+
+public:
+    FontAsset();
+    virtual ~FontAsset();
+
+    /// Core.
+    static void initPersistFields();
+    virtual bool onAdd();
+    virtual void onRemove();
+    virtual void copyTo(SimObject* object);
+
+    void                    setFontFile( const char* pFontFile );
+    inline StringTableEntry getFontFile( void ) const                   { return mFontFile; }
+
+    inline TextureHandle&   getImageTexture(U16 pageID)                         { return mBitmapFont.mTexture[pageID]; }
+
+    /// Declare Console Object.
+    DECLARE_CONOBJECT(FontAsset);
+
+private:
+    void buildFontData( void );
+
+protected:
+    virtual void initializeAsset( void );
+    virtual void onAssetRefresh( void );
+
+    /// Taml callbacks.
+    virtual void onTamlPreWrite( void );
+    virtual void onTamlPostWrite( void );
+    virtual void onTamlCustomWrite( TamlCustomNodes& customNodes );
+    virtual void onTamlCustomRead( const TamlCustomNodes& customNodes );
+
+
+protected:
+    static bool setFontFile( void* obj, const char* data )              { static_cast<FontAsset*>(obj)->setFontFile(data); return false; }
+    static bool writeFontFile( void* obj, StringTableEntry pFieldName ) { return static_cast<FontAsset*>(obj)->getFontFile() != StringTable->EmptyString; }
+};
+
+#endif // _FONT_ASSET_H_

+ 47 - 0
engine/source/2d/assets/FontAsset_ScriptBinding.h

@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+ConsoleMethodGroupBeginWithDocs(FontAsset, AssetBase)
+
+//------------------------------------------------------------------------------
+
+/*! Sets the Font file.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(FontAsset, setFontFile, ConsoleVoid, 3, 3, (FontFile))
+{
+    object->setFontFile( argv[2] );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the Font file.
+    @return Returns the Font file.
+*/
+ConsoleMethodWithDocs(FontAsset, getFontFile, ConsoleString, 2, 2, ())
+{
+    return object->getFontFile();
+}
+
+//------------------------------------------------------------------------------
+
+ConsoleMethodGroupEndWithDocs(FontAsset)

+ 30 - 2
engine/source/2d/gui/SceneWindow.cc

@@ -113,7 +113,8 @@ SceneWindow::SceneWindow() :    mpScene(NULL),
                                 mUseObjectInputEvents(false),
                                 mInputEventGroupMaskFilter(MASK_ALL),
                                 mInputEventLayerMaskFilter(MASK_ALL),
-                                mInputEventInvisibleFilter( true )
+                                mInputEventInvisibleFilter( true ),
+                                mProcessAudioListener(false)
 {
     // Set Vector Associations.
     VECTOR_SET_ASSOCIATION( mCameraQueue );
@@ -419,6 +420,13 @@ void SceneWindow::setCameraInterpolationMode( const CameraInterpolationMode inte
 
 //-----------------------------------------------------------------------------
 
+void SceneWindow::setProcessAudioListener(bool mval)
+{
+    mProcessAudioListener = mval;
+}
+
+//-----------------------------------------------------------------------------
+
 void SceneWindow::startCameraMove( const F32 interpolationTime )
 {
     // Are we mounted to an object and trying to move?
@@ -1462,6 +1470,8 @@ void SceneWindow::processTick( void )
     // Debug Profiling.
     PROFILE_SCOPE(SceneWindow_ProcessTick);
 
+    Point2F PreMove_CameraPos = mCameraCurrent.mSourceArea.centre();
+    F32 PreMove_CameraZoom = mCameraCurrent.mCameraZoom;
     // Are we moving the camera.
     if ( mMovingCamera )
     {
@@ -1505,7 +1515,25 @@ void SceneWindow::processTick( void )
             // No, so stop shake.
             stopCameraShake();
         }
-    }    
+    }
+    if (mProcessAudioListener)
+    {
+        F32 listenervelocity[] = { 0.f, 0.f, 0.f };
+
+        Point2F campos = mCameraCurrent.mSourceArea.centre();
+
+        if (campos != PreMove_CameraPos)
+        {
+            listenervelocity[0] = (campos.x - PreMove_CameraPos.x) * Tickable::smTickSec;
+            listenervelocity[1] = (campos.y - PreMove_CameraPos.y) * Tickable::smTickSec;
+            listenervelocity[2] = (mCameraCurrent.mCameraZoom - PreMove_CameraZoom) * Tickable::smTickSec;
+        }
+
+        F32 listenerpos[] = { campos.x, campos.y, 5.f };
+
+        alListenerfv(AL_POSITION, listenerpos);
+        alListenerfv(AL_VELOCITY, listenervelocity);
+    }
 }
 
 //-----------------------------------------------------------------------------

+ 9 - 0
engine/source/2d/gui/SceneWindow.h

@@ -141,6 +141,9 @@ private:
     U32                 mRenderLayerMask;
     U32                 mRenderGroupMask;
 
+    //Audio Listener
+    bool                mProcessAudioListener;
+
     char                mDebugText[256];
 
     /// Handling Input Events.
@@ -264,6 +267,9 @@ public:
     void setCameraInterpolationTime( const F32 interpolationTime );
     void setCameraInterpolationMode( const CameraInterpolationMode interpolationMode );
 
+    /// Audio Listener
+    void setProcessAudioListener(bool mval);
+
     /// Camera Movement.
     void startCameraMove( const F32 interpolationTime );
     void stopCameraMove( void );
@@ -281,6 +287,9 @@ public:
     inline bool isCameraMounted( void ) const                           { return mCameraMounted; }
     inline bool isCameraMoving( void ) const                            { return mMovingCamera; }
 
+    /// Audio Listener
+    inline bool isProcessAudioListener(void) const { return mProcessAudioListener; }
+
     /// Camera Shake.
     void startCameraShake( const F32 magnitude, const F32 time );
     void stopCameraShake( void );

+ 12 - 0
engine/source/2d/gui/SceneWindow_ScriptBinding.h

@@ -1545,4 +1545,16 @@ ConsoleMethodWithDocs(SceneWindow, getIsWindowPoint, ConsoleBool, 3, 4, (X / Y))
     return object->mBounds.pointInRect( Point2I( S32(mFloor(dstPoint.x)+object->mBounds.point.x), S32(mFloor(dstPoint.y)+object->mBounds.point.y )) );
 }
 
+/*! Sets this Scenewindow to process the AudioListener's position and velocity
+    WARNING : The code does not verify if multiple SceneWindows have this function enabled.
+              User must make sure to manage this manually. Multiple listeners may lead to crashes/bugs/unexpected behaviors.
+    @param status - Whether to enable or disable AudioListener processing (optional, default to true)
+*/
+ConsoleMethodWithDocs(SceneWindow, setAudioListener, ConsoleVoid, 2, 3, ())
+{
+    bool onoff = true;
+    if ((argc > 2) && !dAtob(argv[2])) onoff = false;
+    object->setProcessAudioListener(onoff);
+}
+
 ConsoleMethodGroupEndWithDocs(SceneWindow)

+ 3 - 3
engine/source/2d/scene/ContactFilter.cc

@@ -75,8 +75,8 @@ bool ContactFilter::ShouldCollide(b2Fixture* pFixtureA, b2Fixture* pFixtureB)
 bool ContactFilter::FilterOneWay(SceneObject* pSceneObjectA, SceneObject* pSceneObjectB, b2Fixture* pFixtureA, b2Fixture* pFixtureB)
 {
     // One way collisions only apply to edge or chain shapes.
-    if ((pFixtureA->GetType() == b2Shape::Type::e_chain || pFixtureA->GetType() == b2Shape::Type::e_edge) ||
-        (pFixtureB->GetType() == b2Shape::Type::e_chain || pFixtureB->GetType() == b2Shape::Type::e_edge))
+    if ((pFixtureA->GetType() == b2Shape::e_chain || pFixtureA->GetType() == b2Shape::e_edge) ||
+        (pFixtureB->GetType() == b2Shape::e_chain || pFixtureB->GetType() == b2Shape::e_edge))
     {
         // Convenience renaming.
         SceneObject* pPlatformObject = NULL;
@@ -103,7 +103,7 @@ bool ContactFilter::FilterOneWay(SceneObject* pSceneObjectA, SceneObject* pScene
         b2Vec2 shapeCentroid;
         b2AABB* box = new b2AABB();
 
-        if (pFixturePlatform->GetType() == b2Shape::Type::e_chain)
+        if (pFixturePlatform->GetType() == b2Shape::e_chain)
         {
             const b2ChainShape* shape = pPlatformObject->getCollisionChainShape(0);
             shape->ComputeAABB(box, pPlatformObject->getTransform(), 0);

+ 1 - 0
engine/source/2d/scene/Scene.cc

@@ -5272,6 +5272,7 @@ static EnumTable::Enums DebugOptionsLookup[] =
                 { Scene::SCENE_DEBUG_CONTROLLERS,       "controllers" },
                 { Scene::SCENE_DEBUG_JOINTS,            "joints" },
                 { Scene::SCENE_DEBUG_WIREFRAME_RENDER,  "wireframe" },
+                { Scene::SCENE_DEBUG_AUDIO_SOURCES,     "audio"},
                 ///
                 { Scene::SCENE_DEBUG_AABB,              "aabb" },
                 { Scene::SCENE_DEBUG_OOBB,              "oobb" },

+ 1 - 0
engine/source/2d/scene/Scene.h

@@ -183,6 +183,7 @@ public:
         SCENE_DEBUG_CONTROLLERS        = BIT(2), 
         SCENE_DEBUG_JOINTS             = BIT(3),
         SCENE_DEBUG_WIREFRAME_RENDER   = BIT(4),
+        SCENE_DEBUG_AUDIO_SOURCES      = BIT(5),
         ///
         SCENE_DEBUG_AABB               = BIT(16),
         SCENE_DEBUG_OOBB               = BIT(17),

+ 0 - 400
engine/source/2d/sceneobject/ImageFont.cc

@@ -1,400 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _DGL_H_
-#include "graphics/dgl.h"
-#endif
-
-#include "console/consoleTypes.h"
-
-#include "io/bitStream.h"
-
-#include "string/stringBuffer.h"
-
-#include "ImageFont.h"
-
-// Script bindings.
-#include "ImageFont_ScriptBinding.h"
-
-//------------------------------------------------------------------------------
-
-static EnumTable::Enums textAlignmentEnums[] = 
-{
-    { ImageFont::ALIGN_LEFT,      "Left" },
-    { ImageFont::ALIGN_CENTER,    "Center" },
-    { ImageFont::ALIGN_RIGHT,     "Right" },
-};
-
-static EnumTable gTextAlignmentTable(3, &textAlignmentEnums[0]); 
-
-//-----------------------------------------------------------------------------
-
-ImageFont::TextAlignment ImageFont::getTextAlignmentEnum(const char* label)
-{
-    // Search for Mnemonic.
-    for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
-    {
-        if( dStricmp(textAlignmentEnums[i].label, label) == 0)
-            return (TextAlignment)textAlignmentEnums[i].index;
-    }
-
-    // Warn.
-    Con::warnf("ImageFont::getTextAlignmentEnum() - Invalid text alignment of '%s'", label );
-
-    return ImageFont::INVALID_ALIGN;
-}
-
-//-----------------------------------------------------------------------------
-
-const char* ImageFont::getTextAlignmentDescription(const ImageFont::TextAlignment alignment)
-{
-    // Search for Mnemonic.
-    for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
-    {
-        if( textAlignmentEnums[i].index == alignment )
-            return textAlignmentEnums[i].label;
-    }
-
-    // Warn.
-    Con::warnf( "ImageFont::getTextAlignmentDescription() - Invalid text alignment.");
-
-    return StringTable->EmptyString;
-}
-
-//------------------------------------------------------------------------------
-
-IMPLEMENT_CONOBJECT(ImageFont);
-
-//-----------------------------------------------------------------------------
-
-ImageFont::ImageFont() :
-    mTextAlignment( ImageFont::ALIGN_CENTER ),
-    mFontSize( 1.0f, 1.0f ),
-    mFontPadding( 0 )
-{
-   // Use a static body by default.
-   mBodyDefinition.type = b2_staticBody;
-
-    // Set as auto-sizing.
-    mAutoSizing = true;
-}
-
-//-----------------------------------------------------------------------------
-
-ImageFont::~ImageFont()
-{
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::initPersistFields()
-{    
-    // Call parent.
-    Parent::initPersistFields();
-
-    addProtectedField("image", TypeImageAssetPtr, Offset(mImageAsset, ImageFont), &setImage, &getImage, &writeImage, "");
-    addProtectedField("text", TypeString, 0, setText, getText, &writeText, "The text to be displayed." );  
-    addProtectedField("textAlignment", TypeEnum, Offset(mTextAlignment, ImageFont), &setTextAlignment, &defaultProtectedGetFn, &writeTextAlignment, 1, &gTextAlignmentTable, "");
-    addProtectedField("fontSize", TypeVector2, Offset(mFontSize, ImageFont), &setFontSize, &defaultProtectedGetFn,&writeFontSize, "" );
-    addProtectedField("fontPadding", TypeF32, Offset(mFontPadding, ImageFont), &setFontPadding, &defaultProtectedGetFn, &writeFontPadding, "" );
-}
-
-//-----------------------------------------------------------------------------
-
-bool ImageFont::onAdd()
-{
-    // Call Parent.
-    if(!Parent::onAdd())
-        return false;
-    
-    // Return Okay.
-    return true;
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::onRemove()
-{
-    // Call Parent.
-    Parent::onRemove();
-}
-
-//------------------------------------------------------------------------------
-
-void ImageFont::copyTo(SimObject* object)
-{
-    // Fetch font object.
-    ImageFont* pFontObject = dynamic_cast<ImageFont*>(object);
-
-    // Sanity.
-    AssertFatal(pFontObject != NULL, "ImageFont::copyTo() - Object is not the correct type.");
-
-    // Call parent.
-    Parent::copyTo(object);
-
-    // Copy.
-    pFontObject->setImage( getImage() );
-    pFontObject->setText( getText() );
-    pFontObject->setTextAlignment( getTextAlignment() );
-    pFontObject->setFontSize( getFontSize() );
-    pFontObject->setFontPadding( getFontPadding() );
-}
-
-//------------------------------------------------------------------------------
-
-void ImageFont::scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue )
-{
-    // Create a default render request.
-    Scene::createDefaultRenderRequest( pSceneRenderQueue, this );
-}
-
-//------------------------------------------------------------------------------
-
-void ImageFont::sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer )
-{
-    // Finish if no image asset.
-    if ( mImageAsset.isNull() )
-        return;
-
-    // Fetch number of characters to render.
-    const U32 renderCharacters = mText.length();
-
-    // Ignore if no text to render.
-    if( renderCharacters == 0 )
-        return;
-
-    // Fetch render OOBB.
-    const Vector2& renderOOBB0 = mRenderOOBB[0];
-    const Vector2& renderOOBB1 = mRenderOOBB[1];
-    const Vector2& renderOOBB3 = mRenderOOBB[3];
-
-    Vector2 characterOOBB0;
-    Vector2 characterOOBB1;
-    Vector2 characterOOBB2;
-    Vector2 characterOOBB3;
-
-    // Calculate the starting render position based upon text alignment.
-    switch( mTextAlignment )
-    {
-        case ALIGN_LEFT:
-            {
-                // Size is twice the padded text width as we're aligning to the left from the position expanding rightwards.
-                characterOOBB0.Set( (renderOOBB0.x + renderOOBB1.x)*0.5f, renderOOBB0.y );
-            }
-            break;
-
-        case ALIGN_RIGHT:
-            {
-                // Size is twice the padded text width as we're aligning to the right from the position expanding leftwards.
-                characterOOBB0 = renderOOBB0;
-            }
-            break;
-
-        default:
-            {
-                // Warn.
-                Con::warnf("ImageFont() - Unknown text alignment!");
-            }
-        case ALIGN_CENTER:
-            {
-                // Size is the total padded text size as we're simply centered on the position.
-                characterOOBB0 = renderOOBB0;
-            }
-            break;
-    }
-
-    // Calculate character width stride.
-    Vector2 characterWidthStride = (renderOOBB1 - renderOOBB0);
-    characterWidthStride.Normalize( mFontSize.x + mFontPadding );
-
-    // Calculate character height stride.
-    Vector2 characterHeightStride = (renderOOBB3 - renderOOBB0);
-    characterHeightStride.Normalize( mFontSize.y );
-
-    // Complete character OOBB.
-    characterOOBB1 = characterOOBB0 + characterWidthStride;
-    characterOOBB2 = characterOOBB1 + characterHeightStride;
-    characterOOBB3 = characterOOBB2 - characterWidthStride;
-
-    // Render all the characters.    
-    for( U32 characterIndex = 0; characterIndex < renderCharacters; ++characterIndex )
-    {
-        // Fetch character.
-        U32 character = mText.getChar( characterIndex );
-
-        // Set character to "space" if it's out of bounds.
-        if ( character < 32 || character > 128 )
-            character = 32;
-
-        // Calculate character frame index.
-        const U32 characterFrameIndex = character - 32;
-
-        // Fetch current frame area.
-        const ImageAsset::FrameArea::TexelArea& texelFrameArea = mImageAsset->getImageFrameArea( characterFrameIndex ).mTexelArea;
-
-        // Fetch lower/upper texture coordinates.
-        const Vector2& texLower = texelFrameArea.mTexelLower;
-        const Vector2& texUpper = texelFrameArea.mTexelUpper;
-
-        // Submit batched quad.
-        pBatchRenderer->SubmitQuad(
-            characterOOBB0,
-            characterOOBB1,
-            characterOOBB2,
-            characterOOBB3,
-            Vector2( texLower.x, texUpper.y ),
-            Vector2( texUpper.x, texUpper.y ),
-            Vector2( texUpper.x, texLower.y ),
-            Vector2( texLower.x, texLower.y ),
-            mImageAsset->getImageTexture() );
-
-        // Translate character OOBB.
-        characterOOBB0 += characterWidthStride;
-        characterOOBB1 += characterWidthStride;
-        characterOOBB2 += characterWidthStride;
-        characterOOBB3 += characterWidthStride;
-    }
-}
-
-
-//-----------------------------------------------------------------------------
-
-bool ImageFont::setImage( const char* pImageAssetId )
-{
-    // Set asset.
-    mImageAsset = pImageAssetId;
-
-    // Finish if no image asset.
-    if ( mImageAsset.isNull() )
-        return false;
-
-    // We need a minimum of 96 frames here.
-    if ( mImageAsset->getFrameCount() < 96 )
-    {
-        // Warn.
-        Con::warnf("ImageFont::setImage() - The image needs to have at least 96 frames to be used as a font! (%s)", mImageAsset.getAssetId() );
-        mImageAsset.clear();
-        return false;
-    }
-    
-    // Return Okay.
-    return true;
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::setText( const StringBuffer& text )
-{
-    // Set text.
-    mText.set( &text );
-    calculateSpatials();   
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::setTextAlignment( const TextAlignment alignment )
-{
-    mTextAlignment = alignment;
-    calculateSpatials();
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::setFontSize( const Vector2& size )
-{
-    mFontSize = size;
-    mFontSize.clampZero();
-    calculateSpatials();
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::setFontPadding( const F32 padding )
-{
-    mFontPadding = padding;
-    calculateSpatials();
-}
-
-//-----------------------------------------------------------------------------
-
-void ImageFont::calculateSpatials( void )
-{
-    // Fetch number of characters to render.
-    const U32 renderCharacters = mText.length();
-
-    // Set size as a single character if no text.
-    if ( renderCharacters == 0 )
-    {
-        setSize( mFontSize );
-        return;
-    }
-
-    // Calculate total font padding.
-    const F32 totalFontPadding = (renderCharacters * mFontPadding) - mFontPadding;
-
-    // Calculate total character size.
-    const Vector2 totalFontSize( renderCharacters * mFontSize.x, mFontSize.y );
-
-    // Calculate total padded text size.
-    const Vector2 totalPaddedTextSize( totalFontSize.x + totalFontPadding, totalFontSize.y );
-
-    // Calculate size (AABB) including alignment relative to position.
-    // NOTE:    For left/right alignment we have to double the size width as clipping is based upon size and
-    //          we're aligning to the position here.  We cannot align to the size AABB itself as that changes
-    //          as the text length changes therefore it is not a stable point from which to align from.
-    switch( mTextAlignment )
-    {
-        case ALIGN_LEFT:
-            {
-                // Size is twice the padded text width as we're aligning to the left from the position expanding rightwards.
-                setSize( totalPaddedTextSize.x * 2.0f, totalPaddedTextSize.y );
-            }
-            break;
-
-        case ALIGN_RIGHT:
-            {
-                // Size is twice the padded text width as we're aligning to the right from the position expanding leftwards.
-                setSize( totalPaddedTextSize.x * 2.0f, totalPaddedTextSize.y );
-            }
-            break;
-
-        case ALIGN_CENTER:
-            {
-                // Size is the total padded text size as we're simply centered on the position.
-                setSize( totalPaddedTextSize );
-            }
-            break;
-
-        default:
-            {
-                // Warn.
-                Con::warnf("ImageFont() - Unknown text alignment!");
-            }
-    }
-}
-
-//-----------------------------------------------------------------------------
-
-bool ImageFont::setTextAlignment( void* obj, const char* data )
-{
-    static_cast<ImageFont*>( obj )->setTextAlignment( getTextAlignmentEnum(data) ); return false;
-}

+ 0 - 133
engine/source/2d/sceneobject/ImageFont.h

@@ -1,133 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _BITMAP_FONT_OBJECT_H_
-#define _BITMAP_FONT_OBJECT_H_
-
-#ifndef _STRINGBUFFER_H_
-#include "string/stringBuffer.h"
-#endif
-
-#ifndef _IMAGE_ASSET_H_
-#include "2d/assets/ImageAsset.h"
-#endif
-
-#ifndef _SCENE_OBJECT_H_
-#include "2d/sceneobject/SceneObject.h"
-#endif
-
-#ifndef _ASSET_PTR_H_
-#include "assets/assetPtr.h"
-#endif
-
-#ifndef _UTILITY_H_
-#include "2d/core/utility.h"
-#endif
-
-//-----------------------------------------------------------------------------
-
-class ImageFont : public SceneObject
-{
-    typedef SceneObject          Parent;
-
-public:
-    enum TextAlignment
-    {
-        INVALID_ALIGN,
-
-        ALIGN_LEFT,
-        ALIGN_CENTER,
-        ALIGN_RIGHT
-    };
-
-private:
-    struct TextCell
-    {
-        char CharValue;
-        U32 FrameCell;
-
-        TextCell(char charValue, U32 frameCell)
-        {
-            CharValue = charValue;
-            FrameCell = frameCell;
-        }
-    };
-
-private:
-    AssetPtr<ImageAsset>    mImageAsset;
-    StringBuffer            mText;
-    F32                     mFontPadding;
-    Vector2                 mFontSize;
-    TextAlignment           mTextAlignment;
-
-private:
-    void calculateSpatials( void );
-
-public:
-    ImageFont();
-    ~ImageFont();
-
-    static void initPersistFields();
-
-    bool onAdd();
-    void onRemove();
-    void copyTo(SimObject* object);
-
-    virtual bool canPrepareRender( void ) const                             { return true; }
-    virtual bool validRender( void ) const                                  { return mImageAsset.notNull() && mText.length() > 0; }
-    virtual bool shouldRender( void ) const                                 { return true; }
-    virtual void scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue );
-    virtual void sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer );
-
-    bool setImage( const char* pImageAssetId );
-    const char* getImage( void ) const                                      { return mImageAsset.getAssetId(); };
-    void setText( const StringBuffer& text );
-    inline StringBuffer& getText( void )                                    { return mText; }
-    void setTextAlignment( const TextAlignment alignment );
-    inline TextAlignment getTextAlignment( void ) const                     { return mTextAlignment; }
-    void setFontSize( const Vector2& size );
-    inline Vector2 getFontSize( void ) const                                { return mFontSize; }
-    void setFontPadding( const F32 padding );
-    inline F32 getFontPadding( void ) const                                 { return mFontPadding; }
-
-    static TextAlignment getTextAlignmentEnum(const char* label);
-    static const char* getTextAlignmentDescription(const TextAlignment alignment);
-
-    // Declare Console Object.
-    DECLARE_CONOBJECT(ImageFont);
-
-protected:
-    static bool setImage(void* obj, const char* data)                       { static_cast<ImageFont*>(obj)->setImage( data ); return false; }
-    static const char* getImage(void* obj, const char* data)                { return static_cast<ImageFont*>(obj)->getImage(); }
-    static bool writeImage( void* obj, StringTableEntry pFieldName )        { return static_cast<ImageFont*>(obj)->mImageAsset.notNull(); }
-    static bool setText( void* obj, const char* data )                      { static_cast<ImageFont*>( obj )->setText( data ); return false; }
-    static const char* getText( void* obj, const char* data )               { return static_cast<ImageFont*>( obj )->getText().getPtr8(); }
-    static bool writeText( void* obj, StringTableEntry pFieldName )         { return static_cast<ImageFont*>(obj)->mText.length() != 0; }
-    static bool setTextAlignment( void* obj, const char* data );
-    static bool writeTextAlignment( void* obj, StringTableEntry pFieldName ){return static_cast<ImageFont*>(obj)->getTextAlignment() != ImageFont::ALIGN_CENTER; }
-    static bool setFontSize( void* obj, const char* data )                  { static_cast<ImageFont*>( obj )->setFontSize( Utility::mGetStringElementVector(data) ); return false; }
-	static bool writeFontSize( void* obj, StringTableEntry pFieldName )     { return static_cast<ImageFont*>(obj)->getFontSize().notEqual(Vector2::getOne()); }	
-    static bool setFontPadding( void* obj, const char* data )               { static_cast<ImageFont*>( obj )->setFontPadding( dAtof(data) ); return false; }
-    static bool writeFontPadding( void* obj, StringTableEntry pFieldName )  { return static_cast<ImageFont*>(obj)->getFontPadding() != 0; }
-};
-
-#endif // _BITMAP_FONT_OBJECT_H_

+ 0 - 161
engine/source/2d/sceneobject/ImageFont_ScriptBinding.h

@@ -1,161 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-ConsoleMethodGroupBeginWithDocs(ImageFont, SceneObject)
-
-/*! Sets the image asset to use..
-    @param imageName The image asset to use.
-    @return Returns true on success.
-*/
-ConsoleMethodWithDocs(ImageFont, setImage, ConsoleBool, 3, 3, (imageAssetId))
-{
-    // Set Image.
-    return object->setImage( argv[2] );
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets current image asset..
-    @return The current image asset.
-*/
-ConsoleMethodWithDocs(ImageFont, getImage, ConsoleString, 2, 2, ())
-{
-    // Get Image.
-    return object->getImage();
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Set the text to render.
-*/
-ConsoleMethodWithDocs(ImageFont, setText, ConsoleVoid, 3, 3, (text))
-{
-    object->setText(argv[2]);
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets the text being rendered.
-*/
-ConsoleMethodWithDocs(ImageFont, getText, ConsoleString, 2, 2, ())
-{
-    return object->getText().getPtr8();
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Set the text alignment to 'left', 'center' or 'right'.
-    @param alignment The text alignment of 'left', 'center' or 'right'.
-    @return No return value.
-*/
-ConsoleMethodWithDocs(ImageFont, setTextAlignment, ConsoleVoid, 3, 3, (alignment))
-{
-
-    object->setTextAlignment( ImageFont::getTextAlignmentEnum(argv[2]) );
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets the text alignment.
-    @return The text alignment of 'left', 'center' or 'right'.
-*/
-ConsoleMethodWithDocs(ImageFont, getTextAlignment, ConsoleString, 2, 2, ())
-{
-    return ImageFont::getTextAlignmentDescription(object->getTextAlignment());
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Set the size of the font characters.
-    @param width The width of a font character.
-    @param height The height of a font character.
-    @return No return value.
-*/
-ConsoleMethodWithDocs(ImageFont, setFontSize, ConsoleVoid, 3, 4, (width, height))
-{
-    F32 width, height;
-
-    U32 elementCount = Utility::mGetStringElementCount(argv[2]);
-
-    // ("width height")
-    if ((elementCount == 2) && (argc == 3))
-    {
-        width = dAtof(Utility::mGetStringElement(argv[2], 0));
-        height = dAtof(Utility::mGetStringElement(argv[2], 1));
-    }
-
-    // (width, [height])
-    else if (elementCount == 1)
-    {
-        width = dAtof(argv[2]);
-
-        if (argc > 3)
-            height = dAtof(argv[3]);
-        else
-            height = width;
-    }
-    // Invalid
-    else
-    {
-        Con::warnf("ImageFont::setFontSize() - Invalid number of parameters!");
-        return;
-    }
-
-    // Set character size.
-    object->setFontSize(Vector2(width, height));
-
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets the size of the font characters.
-    @return The size of the font characters.
-*/
-ConsoleMethodWithDocs(ImageFont, getFontSize, ConsoleString, 2, 2, ())
-{
-    return object->getFontSize().scriptThis();
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Set the font padding.
-    @param padding The space added in-between font characters.
-    @return No return value.
-*/
-ConsoleMethodWithDocs(ImageFont, setFontPadding, ConsoleVoid, 3, 3, (padding))
-{
-   // Set character padding.
-   object->setFontPadding( dAtof(argv[2]) );
-
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets the font padding.
-    @return The font padding.
-*/
-ConsoleMethodWithDocs(ImageFont, getFontPadding, ConsoleFloat, 2, 2, ())
-{
-    return object->getFontPadding();
-}
-
-ConsoleMethodGroupEndWithDocs(ImageFont)

+ 221 - 88
engine/source/2d/sceneobject/SceneObject.cc

@@ -183,11 +183,6 @@ SceneObject::SceneObject() :
     /// Camera mounting.
     mpAttachedCamera(NULL),
 
-    /// GUI attachment.
-    mAttachedGuiSizeControl(false),
-    mpAttachedGui(NULL),
-    mpAttachedGuiSceneWindow(NULL),
-
     /// Safe deletion.
     mBeingSafeDeleted(false),
     mSafeDeleteReady(true),
@@ -206,6 +201,9 @@ SceneObject::SceneObject() :
     VECTOR_SET_ASSOCIATION( mDestroyNotifyList );
     VECTOR_SET_ASSOCIATION( mCollisionFixtureDefs );
     VECTOR_SET_ASSOCIATION( mCollisionFixtures );
+    VECTOR_SET_ASSOCIATION( mAttachedCtrls );
+    VECTOR_SET_ASSOCIATION( mAudioHandles );
+    VECTOR_SET_ASSOCIATION( mHandleDeletionList );
 
     // Assign scene-object index.
     mSerialId = ++sSceneObjectMasterSerialId;
@@ -260,6 +258,16 @@ SceneObject::~SceneObject()
         mpScene->removeFromScene( this );
     }
 
+    if (mAudioHandles.size())
+    {
+       for (typeAudioHandleVector::iterator itr = mAudioHandles.begin(); itr != mAudioHandles.end(); ++itr)
+       {
+       U32 handle = *itr;
+       alxStop(handle);
+       }
+       mAudioHandles.clear();
+    }
+
     // Decrease scene-object count.
     --sGlobalSceneObjectCount;
 }
@@ -368,8 +376,8 @@ bool SceneObject::onAdd()
 
 void SceneObject::onRemove()
 {
-    // Detach Any GUI Control.
-    detachGui();
+    // Detach all GUI Control.
+    detachAllGuiControls();
 
     // Remove from Scene.
     if ( getScene() )
@@ -567,6 +575,9 @@ void SceneObject::preIntegrate( const F32 totalTime, const F32 elapsedTime, Debu
 		updateSize(elapsedTime);
 	}
 
+    if (mAudioHandles.size())
+        refreshsources();
+
    // Finish if nothing is dirty.
     if ( !mSpatialDirty )
         return;
@@ -627,7 +638,7 @@ void SceneObject::integrateObject( const F32 totalTime, const F32 elapsedTime, D
     }
 
     // Update Any Attached GUI.
-    if ( mpAttachedGui && mpAttachedGuiSceneWindow )
+    if ( mAttachedCtrls.size() )
     {
         updateAttachedGui();
     }
@@ -644,6 +655,17 @@ void SceneObject::integrateObject( const F32 totalTime, const F32 elapsedTime, D
 	{
 		updateBlendColor( elapsedTime );
 	}
+
+    if (mAudioHandles.size())
+    {
+        for (typeAudioHandleVector::iterator itr = mAudioHandles.begin(); itr != mAudioHandles.end(); ++itr)
+        {
+            U32 handle = *itr;
+            Point2F vel = getLinearVelocity();
+            alxSource3f(handle, AL_POSITION, position.x, position.y, 0.f);
+            alxSource3f(handle, AL_VELOCITY, vel.x, vel.y, 0.f);
+        }
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -761,7 +783,7 @@ void SceneObject::interpolateObject( const F32 timeDelta )
     }
 
     // Update Any Attached GUI.
-    if ( mpAttachedGui && mpAttachedGuiSceneWindow )
+    if ( mAttachedCtrls.size() )
     {
         updateAttachedGui();
     }
@@ -865,6 +887,24 @@ void SceneObject::sceneRenderOverlay( const SceneRenderState* sceneRenderState )
     {
         pScene->mDebugDraw.DrawSortPoint( getRenderPosition(), getSize(), mSortPoint );
     }
+
+    if (debugMask & Scene::SCENE_DEBUG_AUDIO_SOURCES)
+    {
+        if (mAudioHandles.size())
+        {
+            for (typeAudioHandleVector::iterator itr = mAudioHandles.begin(); itr != mAudioHandles.end(); ++itr)
+            {
+                U32 handle = *itr;
+                ALfloat MaxDistance = 0.f;
+                ALfloat RefDistance = 0.f;
+                alxGetSourcef(handle, AL_MAX_DISTANCE, &MaxDistance);
+                alxGetSourcef(handle, AL_REFERENCE_DISTANCE, &RefDistance);
+                pScene->mDebugDraw.DrawCircle(getRenderPosition(), MaxDistance, ColorF(1.f, 0.2f, 0.2f));
+                pScene->mDebugDraw.DrawCircle(getRenderPosition(), RefDistance, ColorF(1.f, 0.0f, 0.0f));
+            }
+        }
+        
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -2776,119 +2816,162 @@ void SceneObject::onInputEvent( StringTableEntry name, const GuiEvent& event, co
 
 //-----------------------------------------------------------------------------
 
-void SceneObject::attachGui( GuiControl* pGuiControl, SceneWindow* pSceneWindow, const bool sizeControl )
+void SceneObject::attachGui(GuiControl* pGuiControl, SceneWindow* pSceneWindow, const bool sizeControl, const Vector2 offset)
 {
-    // Attach Gui Control.
-    mpAttachedGui = pGuiControl;
+    // Attach GUI control.
+    SceneObjectAttachedGUI attachedGui;
+    attachedGui.mpAttachedCtrl = pGuiControl;
+    attachedGui.mpAttachedSceneWindow = pSceneWindow;
+    attachedGui.mAutoSize = sizeControl;
+    attachedGui.mAttachedOffset = offset;
 
-    // Attach SceneWindow.
-    mpAttachedGuiSceneWindow = pSceneWindow;
+    // Register GUI control & window references.
+    attachedGui.mpAttachedCtrl->registerReference((SimObject**)&attachedGui.mpAttachedCtrl);
+    attachedGui.mpAttachedSceneWindow->registerReference((SimObject**)&attachedGui.mpAttachedSceneWindow);
 
-    // Set Size Gui Flag.
-    mAttachedGuiSizeControl = sizeControl;
-
-    // Register Gui Control/Window References.
-    mpAttachedGui->registerReference( (SimObject**)&mpAttachedGui );
-    mpAttachedGuiSceneWindow->registerReference( (SimObject**)&mpAttachedGuiSceneWindow );
-
-    // Check/Adjust Parentage.
-    if ( mpAttachedGui->getParent() != mpAttachedGuiSceneWindow )
+    // Check & adjust GUI parentage.
+    if (attachedGui.mpAttachedCtrl->getParent() != attachedGui.mpAttachedSceneWindow)
     {
-        // Warn.
-        // Remove GuiControl from existing parent (if it has one).
-        if ( mpAttachedGui->getParent() )
+        // Warn user & remove the GuiControl from the existing parent (if it has one).
+        if (attachedGui.mpAttachedCtrl->getParent())
         {
-            mpAttachedGui->getParent()->removeObject( mpAttachedGui );
+            Con::warnf("Warning: SceneObject::attachGui - GuiControl already has a parent GuiWindow!");
+            attachedGui.mpAttachedCtrl->getParent()->removeObject(attachedGui.mpAttachedCtrl);
         }
 
-        // Add it to the scene-window.
-        mpAttachedGuiSceneWindow->addObject( mpAttachedGui );
+        // Add the GuiControl to the scene window.
+        attachedGui.mpAttachedSceneWindow->addObject(attachedGui.mpAttachedCtrl);
     }
-    
-}
 
+    mAttachedCtrls.push_back(attachedGui);
+}
 //-----------------------------------------------------------------------------
 
-void SceneObject::detachGui( void )
+void SceneObject::detachGui(void)
 {
-    // Unregister Gui Control Reference.
-    if ( mpAttachedGui )
+    // Remove the last attached GUI.
+    if (mAttachedCtrls.size() > 0)
     {
-       // [neo, 5/7/2007 - #2997]
-       // Changed to UNregisterReference was registerReference which would crash later
-       mpAttachedGui->unregisterReference( (SimObject**)&mpAttachedGui );
-        mpAttachedGui = NULL;
+        mAttachedCtrls.last().mpAttachedCtrl->unregisterReference((SimObject**)&mAttachedCtrls.last().mpAttachedCtrl);
+        mAttachedCtrls.last().mpAttachedSceneWindow->unregisterReference((SimObject**)&mAttachedCtrls.last().mpAttachedSceneWindow);
+
+        mAttachedCtrls.pop_back();
     }
+}
 
-    // Unregister Gui Control Reference.
-    if ( mpAttachedGuiSceneWindow )
+void SceneObject::detachGui(GuiControl* pGuiControl)
+{
+    Vector<SceneObjectAttachedGUI>::iterator i;
+    for (i = mAttachedCtrls.begin(); i != mAttachedCtrls.end(); i++)
     {
-        mpAttachedGuiSceneWindow->registerReference( (SimObject**)&mpAttachedGuiSceneWindow );
-        mpAttachedGuiSceneWindow = NULL;
+        if (i->mpAttachedCtrl == pGuiControl)
+        {
+            // Remove the attached GuiControl.
+            i->mpAttachedCtrl->unregisterReference((SimObject**)&i->mpAttachedCtrl);
+            i->mpAttachedSceneWindow->unregisterReference((SimObject**)&i->mpAttachedSceneWindow);
+
+            mAttachedCtrls.pop_back();
+
+            return;
+        }
     }
+
+    // Warn user that no GuiControls were found.
+    Con::warnf("Warning: SceneObject::detachGui() - The GuiControl was not found!");
 }
 
 //-----------------------------------------------------------------------------
 
-void SceneObject::updateAttachedGui( void )
+void SceneObject::detachAllGuiControls(void)
+{
+    Vector<SceneObjectAttachedGUI>::iterator i;
+    for (i = mAttachedCtrls.begin(); i != mAttachedCtrls.end(); i++)
+    {
+        // Remove the attached GuiControl.
+        i->mpAttachedCtrl->unregisterReference((SimObject**)&i->mpAttachedCtrl);
+        i->mpAttachedSceneWindow->unregisterReference((SimObject**)&i->mpAttachedSceneWindow);
+    }
+
+    // Clear all references to the attached GuiControls.
+    mAttachedCtrls.clear();
+}
+
+//-----------------------------------------------------------------------------
+void SceneObject::updateAttachedGui(void)
 {
     // Debug Profiling.
     PROFILE_SCOPE(SceneObject_updateAttachedGui);
 
-    // Finish if either Gui Control or Window is invalid.
-    if ( !mpAttachedGui || !mpAttachedGuiSceneWindow )
+    // Early-out if no GUIs are attached.
+    if (mAttachedCtrls.size() == 0)
         return;
 
-    // Ignore if we're not in the scene that the scene-window is attached to.
-    if ( getScene() != mpAttachedGuiSceneWindow->getScene() )
+    Vector<SceneObjectAttachedGUI>::iterator i;
+    for (i = mAttachedCtrls.begin(); i != mAttachedCtrls.end(); i++)
     {
-        // Warn.
-        Con::warnf("SceneObject::updateAttachedGui() - SceneWindow is not attached to my Scene!");
-        // Detach from GUI Control.
-        detachGui();
-        // Finish Here.
-        return;
-    }
+        // Ignore if we're not in the scene that the GUI is attached to.
+        if (getScene() != i->mpAttachedSceneWindow->getScene())
+        {
+            // Warn.
+            Con::warnf("Warning: SceneObject::updateAttachedGui() - SceneWindow is not attached to the Scene!");
 
-    // Calculate the GUI Controls' dimensions.
-    Point2I topLeftI, extentI;
+            // Detach the control.
+            detachGui(i->mpAttachedCtrl);
 
-    // Size Control?
-    if ( mAttachedGuiSizeControl )
-    {
-        // Yes, so fetch Clip Rectangle; this forms the area we want to fix the Gui-Control to.
-        const RectF objAABB = getAABBRectangle();
-        // Fetch Top-Left.
-        Vector2 upperLeft = Vector2( objAABB.point.x, objAABB.point.y + objAABB.extent.y );
-        Vector2 lowerRight = Vector2( objAABB.point.x + objAABB.extent.x, objAABB.point.y );
+            return;
+        }
 
-        // Convert Scene to Window Coordinates.
-        mpAttachedGuiSceneWindow->sceneToWindowPoint( upperLeft, upperLeft );
-        mpAttachedGuiSceneWindow->sceneToWindowPoint( lowerRight, lowerRight );
-        // Convert Control Dimensions.
-        topLeftI.set( S32(upperLeft.x), S32(upperLeft.y) );
-        extentI.set( S32(lowerRight.x-upperLeft.x), S32(lowerRight.y-upperLeft.y) );
-    }
-    else
-    {
-        // No, so center GUI-Control on objects position but don't resize it.
+        // Calculate the GUI Controls' dimensions.
+        Point2I topLeftI, extentI;
 
-        // Calculate Position from World Clip.
-        const RectF clipRectangle = getAABBRectangle();
-        // Calculate center position.
-        const Vector2 centerPosition = clipRectangle.point + Vector2(clipRectangle.len_x()*0.5f, clipRectangle.len_y()*0.5f);
+        // Size Control?
+        if (i->mAutoSize)
+        {
+            // Yes, so fetch Clip Rectangle; this forms the area we want to fix the Gui-Control to.
+            const RectF objAABB = getAABBRectangle();
+            // Fetch Top-Left.
+            Vector2 upperLeft = Vector2(objAABB.point.x, objAABB.point.y + objAABB.extent.y);
+            Vector2 lowerRight = Vector2(objAABB.point.x + objAABB.extent.x, objAABB.point.y);
+
+            // Convert Scene to Window Coordinates.
+            i->mpAttachedSceneWindow->sceneToWindowPoint(upperLeft, upperLeft);
+            i->mpAttachedSceneWindow->sceneToWindowPoint(lowerRight, lowerRight);
+
+            // Convert Control Dimensions.
+            topLeftI.set(S32(upperLeft.x), S32(upperLeft.y));
+            extentI.set(S32(lowerRight.x - upperLeft.x), S32(lowerRight.y - upperLeft.y));
+
+            // Add offset
+            topLeftI.x += static_cast<S32>(i->mAttachedOffset.x);
+            topLeftI.y += static_cast<S32>(i->mAttachedOffset.y);
+        }
+        else
+        {
+            // No, so center GUI-Control on objects position but don't resize it.
 
-        // Convert Scene to Window Coordinates.
-        Vector2 positionI;
-        mpAttachedGuiSceneWindow->sceneToWindowPoint( centerPosition, positionI );
-        // Fetch Control Extents (which don't change here).
-        extentI = mpAttachedGui->getExtent();
-        // Calculate new top-left.
-        topLeftI.set( S32(positionI.x-extentI.x/2), S32(positionI.y-extentI.y/2) );
-    }
+            // Calculate Position from World Clip.
+            const RectF clipRectangle = getAABBRectangle();
+            // Calculate center position.
+            const Vector2 centerPosition = clipRectangle.point + Vector2(clipRectangle.len_x()*0.5f, clipRectangle.len_y()*0.5f);
+
+            // Convert Scene to Window Coordinates.
+            Vector2 positionI;
+            i->mpAttachedSceneWindow->sceneToWindowPoint(centerPosition, positionI);
 
-    // Set Control Dimensions.
-    mpAttachedGui->resize( topLeftI, extentI );
+            // Fetch Control Extents (which don't change here).
+            extentI = i->mpAttachedCtrl->getExtent();
+
+            // Calculate new top-left.
+            topLeftI.set(S32(positionI.x - extentI.x / 2), S32(positionI.y - extentI.y / 2));
+
+            // Add offset
+            topLeftI.x += static_cast<S32>(i->mAttachedOffset.x);
+            topLeftI.y += static_cast<S32>(i->mAttachedOffset.y);
+        }
+
+        // Set Control Dimensions.
+        i->mpAttachedCtrl->resize(topLeftI, extentI);
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -3991,6 +4074,56 @@ bool SceneObject::writeField(StringTableEntry fieldname, const char* value)
    return true;
 }
 
+void SceneObject::addAudioHandle(AUDIOHANDLE handle)
+{
+   mAudioHandles.push_back_unique(handle);
+   Con::printf("New Vector size : %i", mAudioHandles.size());
+}
+
+S32 SceneObject::getSoundsCount(void)
+{
+    return mAudioHandles.size();
+}
+
+U32 SceneObject::getSound(S32 index)
+{
+    if (mAudioHandles.size() - 1 < index)
+        return NULL_AUDIOHANDLE;
+    U32 handle = mAudioHandles[index];
+    return handle;
+}
+
+void SceneObject::refreshsources()
+{
+if (mAudioHandles.size())
+{
+    S32 index = 0;
+    for (typeAudioHandleVector::iterator itr = mAudioHandles.begin(); itr != mAudioHandles.end(); ++itr)
+    {
+        U32 handle = *itr;
+
+        if (handle)
+        {
+            if (!alxIsValidHandle(handle))
+            mHandleDeletionList.push_back(index);
+
+            index++;
+        }
+    }
+        
+    if (mHandleDeletionList.size())
+    {
+
+        for (Vector<S32>::iterator delitr = mHandleDeletionList.begin(); delitr != mHandleDeletionList.end(); ++delitr)
+        {
+            mAudioHandles.erase(*delitr);
+        }
+            mHandleDeletionList.clear();
+    }
+}
+}
+
+
 //------------------------------------------------------------------------------
 
 S32 QSORT_CALLBACK SceneObject::sceneObjectLayerDepthSort(const void* a, const void* b)

+ 23 - 6
engine/source/2d/sceneobject/SceneObject.h

@@ -80,6 +80,7 @@ struct tDestroyNotification
 typedef VectorPtr<b2FixtureDef*> typeCollisionFixtureDefVector;
 typedef VectorPtr<b2Fixture*> typeCollisionFixtureVector;
 typedef Vector<tDestroyNotification> typeDestroyNotificationVector;
+typedef Vector<U32> typeAudioHandleVector;
 
 //-----------------------------------------------------------------------------
 
@@ -94,6 +95,14 @@ extern EnumTable dstBlendFactorTable;
 
 //-----------------------------------------------------------------------------
 
+struct SceneObjectAttachedGUI
+{
+    bool mAutoSize;
+    GuiControl* mpAttachedCtrl;
+    SceneWindow* mpAttachedSceneWindow;
+    Vector2 mAttachedOffset;
+};
+
 class SceneObject :
     public BehaviorComponent,
     public SceneRenderObject,
@@ -181,6 +190,8 @@ protected:
     /// General collision shape access.
     typeCollisionFixtureDefVector mCollisionFixtureDefs;
     typeCollisionFixtureVector mCollisionFixtures;
+    typeAudioHandleVector mAudioHandles;
+    Vector<S32> mHandleDeletionList; //Used for Audio source maintenance & deletion
 
     /// Render visibility.
     bool                    mVisible;
@@ -219,9 +230,7 @@ protected:
     SceneWindow*            mpAttachedCamera;
 
     /// GUI attachment.
-    bool                    mAttachedGuiSizeControl;
-    GuiControl*             mpAttachedGui;
-    SceneWindow*            mpAttachedGuiSceneWindow;
+    Vector<SceneObjectAttachedGUI> mAttachedCtrls;
 
     /// Safe deletion.
     bool                    mBeingSafeDeleted;
@@ -562,9 +571,11 @@ public:
     inline void             dismountCamera( void )                      { if ( mpAttachedCamera ) mpAttachedCamera->dismountMe( this ); }
 
     // GUI attachment.
-    void                    attachGui( GuiControl* pGuiControl, SceneWindow* pSceneWindow, const bool sizeControl );
-    void                    detachGui( void );
-    inline void             updateAttachedGui( void );
+    void attachGui(GuiControl* pGuiControl, SceneWindow* pSceneWindow, const bool sizeControl, const Vector2 offset);
+    void detachGui(void);
+    void detachGui(GuiControl* pGuiControl);
+    void detachAllGuiControls(void);
+    inline void updateAttachedGui(void);
 
     // Picking.
     inline void             setPickingAllowed( const bool pickingAllowed ) { mPickingAllowed = pickingAllowed; }
@@ -599,6 +610,12 @@ public:
     static U32              getGlobalSceneObjectCount( void );
     inline U32              getSerialId( void ) const                   { return mSerialId; }
 
+    // Audio
+    void addAudioHandle(AUDIOHANDLE handle);
+    U32                 getSound(S32 index);
+    S32                 getSoundsCount();
+    void                refreshsources();
+
     // Read / Write fields.
     virtual bool            writeField(StringTableEntry fieldname, const char* value);
 

+ 171 - 12
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -20,6 +20,9 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+#ifndef _AUDIODESCRIPTION_H_
+#include "audio/audioDescriptions.h"
+#endif
 /*! Gets the system-wide scene-object count.
     @return The system-wide scene-object count.
 */
@@ -4315,18 +4318,19 @@ ConsoleMethodWithDocs(SceneObject, setDebugOff, ConsoleVoid, 3, 2 + DEBUG_MODE_C
 //-----------------------------------------------------------------------------
 
 /*! Attach a GUI Control to the object.
-    @param guiObject The GuiControl to attach.
-    @param window The SceneWindow to bind the GuiControl to.
-    @param sizeControl Whether or not to size the GuiControl to the size of this object.
-    @return No return Value.
+@param guiObject The GuiControl to attach.
+@param window The SceneWindow to bind the GuiControl to.
+@param sizeControl Whether or not to size the GuiControl to the size of this object.
+@param offset The position offset to apply to the GuiControl.
+@return No return Value.
 */
-ConsoleMethodWithDocs(SceneObject, attachGui, ConsoleVoid, 4, 5, (guiControl guiObject, SceneWindow window, [sizeControl? = false]))
+ConsoleMethodWithDocs(SceneObject, attachGui, ConsoleVoid, 4, 7, (guiControl guiObject, SceneWindow window, [sizeControl ? = false], [offset ? = Vector2(0, 0)]))
 {
     // Find GuiControl Object.
     GuiControl* pGuiControl = dynamic_cast<GuiControl*>(Sim::findObject(argv[2]));
 
     // Check for invalid Gui Control.
-    if ( !pGuiControl )
+    if (!pGuiControl)
     {
         Con::warnf("SceneObject::attachGui() - Couldn't find GuiControl %s!", argv[2]);
         return;
@@ -4336,28 +4340,71 @@ ConsoleMethodWithDocs(SceneObject, attachGui, ConsoleVoid, 4, 5, (guiControl gui
     SceneWindow* pSceneWindow = dynamic_cast<SceneWindow*>(Sim::findObject(argv[3]));
 
     // Check for invalid SceneWindow Object.
-    if ( !pSceneWindow )
+    if (!pSceneWindow)
     {
         Con::warnf("SceneObject::attachGui() - Couldn't find SceneWindow %s!", argv[3]);
         return;
     }
 
-    // Calculate Send to Mount.
+    // Auto-size control?.
     const bool sizeControl = argc >= 5 ? dAtob(argv[4]) : false;
 
+    // GuiControl position offset.
+    Vector2 offset(0, 0);
+
+    // Elements in the first argument.
+    U32 elementCount = Utility::mGetStringElementCount(argv[5]);
+
+    // ("x y")
+    if ((elementCount == 2) && (argc == 6))
+        offset = Utility::mGetStringElementVector(argv[5]);
+
+    // (x, y)
+    else if ((elementCount == 1) && (argc == 7))
+        offset = Vector2(dAtof(argv[5]), dAtof(argv[6]));
+
     // Attach GUI Control.
-    object->attachGui( pGuiControl, pSceneWindow, sizeControl );
+    object->attachGui(pGuiControl, pSceneWindow, sizeControl, offset);
 }
 
 //-----------------------------------------------------------------------------
 
 /*! Detach any GUI Control.
+@param ctrl The SimObjectId of the GuiControl to detach.
     @return No return Value.
 */
-ConsoleMethodWithDocs(SceneObject, detachGui, ConsoleVoid, 2, 2, ())
+ConsoleMethodWithDocs(SceneObject, detachGui, ConsoleVoid, 2, 3, ())
+{
+    if (argc >= 3)
+    {
+        GuiControl* pGuiControl = dynamic_cast<GuiControl*>(Sim::findObject(argv[3]));
+
+        if (!pGuiControl)
+        {
+            // Detach the last attached control.
+            object->detachGui();
+        }
+        else
+        {
+            // Detach the attached control.
+            object->detachGui(pGuiControl);
+        }
+    }
+    else
+    {
+        // Detach the last attached control.
+        object->detachGui();
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Detach all GUI Controls.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(SceneObject, detachAllGuiControls, ConsoleVoid, 2, 2, ())
 {
-    // Detach GUI Control.
-    object->detachGui();
+    object->detachAllGuiControls();
 }
 
 //-----------------------------------------------------------------------------
@@ -4425,4 +4472,116 @@ ConsoleMethodWithDocs(SceneObject, safeDelete, ConsoleVoid, 2, 2, ())
     object->safeDelete();
 }
 
+/*! Plays a sound at the object's location
+@param AudioAsset - The Audio Asset to play
+@param AudioDescription - Sets the audio Description. If omitted,  (optional)
+@return returns the audio handle
+*/
+ConsoleMethodWithDocs(SceneObject, playSound, ConsoleInt, 3, 4, ())
+{
+    // Fetch asset Id.    
+    const char* pAssetId = argv[2];
+
+    // Acquire audio asset.
+    AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>(pAssetId);
+
+    // Did we get the audio asset?
+    if (pAudioAsset == NULL)
+    {
+        // No, so warn.
+        Con::warnf("alxPlay() - Could not find audio asset '%s'.", pAssetId);
+        return NULL_AUDIOHANDLE;
+    }
+    AudioDescription* AD;
+
+    if (argc > 3)
+    {
+        AD = static_cast<AudioDescription*>(Sim::findObject(argv[3]));
+    }
+    else
+    {
+        AD = new AudioDescription();
+    }
+
+    Vector2 pos = object->getPosition();
+    Vector2 vel = object->getLinearVelocity();
+    Point3F realpos;
+    Point3F velocity;
+
+    realpos.x = pos.x;
+    realpos.y = pos.y;
+    realpos.z = 0.f;
+
+    MatrixF transform(false);
+    transform.setColumn(3, realpos);
+
+    //If the source is not looping and outside of listener range, it is not created, handle = 0
+    AUDIOHANDLE handle = alxCreateSource_AD(pAudioAsset, AD, &transform);
+    if (!handle) return (0);
+    //alxplay returns the same handle as alxCreateSource
+    alxPlay(handle);
+    alxSource3f(handle, AL_POSITION, realpos.x, realpos.y, 0.f);
+
+    // Release asset.
+    AssetDatabase.releaseAsset(pAssetId);
+    object->addAudioHandle(handle);
+    return handle;
+}
+
+/*! Stops a sound attached to a SceneObject
+@param Index - The Index of the sound (obtained via getSoundatIndex)
+*/
+ConsoleMethodWithDocs(SceneObject, stopSound, ConsoleVoid, 3, 3, (S32 index))
+{
+    const S32 index = dAtoi(argv[2]);
+    
+    if (!object->getSoundsCount())
+    {
+        Con::warnf("No sounds on this object. Can't stop. WON't stop.");
+        return;
+    }    
+    
+    U32 handle = object->getSound(index);
+
+
+    if (!handle)
+    {
+        Con::warnf("Unable to find Sound Handle at index %i", index);
+        return;
+    }
+
+    alxStop(handle);
+    object->refreshsources();
+}
+
+/*! gets the amount of sounds currently attached to a SceneObject
+@return returns the Amount of sounds currently attached to the SceneObject
+*/
+ConsoleMethodWithDocs(SceneObject, getSoundsCount, ConsoleInt, 2, 2, ())
+{
+    return object->getSoundsCount();
+}
+
+/*! Gets the handle of a sound at specified index
+@param Index - The Index of the sound (obtained via getSoundatIndex)
+@return returns the handle of a sound
+*/
+ConsoleMethodWithDocs(SceneObject, getSoundatIndex, ConsoleInt, 3, 3, ())
+{
+    U32 size = object->getSoundsCount();
+    if (!size)
+    {
+        Con::printf("No sounds on this object.");
+        return 0;
+    }
+
+    U32 handle = object->getSound(dAtoi(argv[2]));
+    if (!handle)
+    {
+        Con::printf("Not a valid handle at index %i", dAtoi(argv[2]));
+        return 0;
+    }
+
+    return handle;
+}
 ConsoleMethodGroupEndWithDocs(SceneObject)

+ 2 - 2
engine/source/2d/sceneobject/ShapeVector.cc

@@ -142,7 +142,7 @@ void ShapeVector::sceneRender( const SceneRenderState* pSceneRenderState, const
         glRotatef( mRadToDeg(getRenderAngle()), 0.0f, 0.0f, 1.0f );
 
         // Render the shape.
-        bool wireFrame = (pBatchRenderer->getWireframeMode() || this->getDebugMask() & Scene::DebugOption::SCENE_DEBUG_WIREFRAME_RENDER) ? true : false;
+        bool wireFrame = (pBatchRenderer->getWireframeMode() || this->getDebugMask() & Scene::SCENE_DEBUG_WIREFRAME_RENDER) ? true : false;
         renderCircleShape(position, mCircleRadius, wireFrame);
     }
     else
@@ -152,7 +152,7 @@ void ShapeVector::sceneRender( const SceneRenderState* pSceneRenderState, const
         glRotatef( mRadToDeg(getRenderAngle()), 0.0f, 0.0f, 1.0f );
 
         // Render the shape.
-        bool wireFrame = (pBatchRenderer->getWireframeMode() || this->getDebugMask() & Scene::DebugOption::SCENE_DEBUG_WIREFRAME_RENDER) ? true : false;
+        bool wireFrame = (pBatchRenderer->getWireframeMode() || this->getDebugMask() & Scene::SCENE_DEBUG_WIREFRAME_RENDER) ? true : false;
         renderPolygonShape(vertexCount, wireFrame);
     }
 

+ 915 - 0
engine/source/2d/sceneobject/TextSprite.cc

@@ -0,0 +1,915 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _DGL_H_
+#include "graphics/dgl.h"
+#endif
+
+#include "console/consoleTypes.h"
+
+#include "io/bitStream.h"
+
+#include "string/stringBuffer.h"
+
+#include "TextSprite.h"
+
+// Script bindings.
+#include "TextSprite_ScriptBinding.h"
+
+//-----------------------------------------------------------------------------
+// Text Alignment
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setTextAlignment(void* obj, const char* data)
+{
+   static_cast<TextSprite*>(obj)->setTextAlignment(getTextAlignmentEnum(data)); return false;
+}
+
+//------------------------------------------------------------------------------
+
+static EnumTable::Enums textAlignmentEnums[] =
+{
+   { TextSprite::ALIGN_LEFT, "Left" },
+   { TextSprite::ALIGN_CENTER, "Center" },
+   { TextSprite::ALIGN_RIGHT, "Right" },
+   { TextSprite::ALIGN_JUSTIFY, "Justify" },
+};
+
+static EnumTable gTextAlignmentTable(4, &textAlignmentEnums[0]);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::TextAlign TextSprite::getTextAlignmentEnum(const char* label)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (dStricmp(textAlignmentEnums[i].label, label) == 0)
+         return (TextAlign)textAlignmentEnums[i].index;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getTextAlignmentEnum() - Invalid text alignment of '%s'", label);
+
+   return TextSprite::INVALID_ALIGN;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* TextSprite::getTextAlignmentDescription(const TextSprite::TextAlign alignment)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (textAlignmentEnums[i].index == alignment)
+         return textAlignmentEnums[i].label;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getTextAlignmentDescription() - Invalid text alignment.");
+
+   return StringTable->EmptyString;
+}
+
+//-----------------------------------------------------------------------------
+// Verticle Text Alignment
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setTextVAlignment(void* obj, const char* data)
+{
+   static_cast<TextSprite*>(obj)->setTextVAlignment(getTextVAlignmentEnum(data)); return false;
+}
+
+//------------------------------------------------------------------------------
+
+static EnumTable::Enums textVAlignmentEnums[] =
+{
+   { TextSprite::VALIGN_TOP, "Top" },
+   { TextSprite::VALIGN_MIDDLE, "Middle" },
+   { TextSprite::VALIGN_BOTTOM, "Bottom" },
+};
+
+static EnumTable gTextVAlignmentTable(3, &textVAlignmentEnums[0]);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::TextVAlign TextSprite::getTextVAlignmentEnum(const char* label)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(textVAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (dStricmp(textVAlignmentEnums[i].label, label) == 0)
+         return (TextVAlign)textVAlignmentEnums[i].index;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getTextVAlignmentEnum() - Invalid vertical text alignment of '%s'", label);
+
+   return TextSprite::INVALID_VALIGN;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* TextSprite::getTextVAlignmentDescription(const TextSprite::TextVAlign alignment)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(textVAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (textVAlignmentEnums[i].index == alignment)
+         return textVAlignmentEnums[i].label;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getTextVAlignmentDescription() - Invalid vertical text alignment.");
+
+   return StringTable->EmptyString;
+}
+
+//-----------------------------------------------------------------------------
+// Overflow Mode X
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setOverflowModeX(void* obj, const char* data)
+{
+   static_cast<TextSprite*>(obj)->setOverflowModeX(getOverflowModeXEnum(data)); return false;
+}
+
+//------------------------------------------------------------------------------
+
+static EnumTable::Enums overflowModeXEnums[] =
+{
+   { TextSprite::OVERFLOW_X_WRAP, "Wrap" },
+   { TextSprite::OVERFLOW_X_VISIBLE, "Visible" },
+   { TextSprite::OVERFLOW_X_HIDDEN, "Hidden" },
+   { TextSprite::OVERFLOW_X_SHRINK, "Shrink" },
+};
+
+static EnumTable gOverflowModeXTable(4, &overflowModeXEnums[0]);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::OverflowModeX TextSprite::getOverflowModeXEnum(const char* label)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(overflowModeXEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (dStricmp(overflowModeXEnums[i].label, label) == 0)
+         return (OverflowModeX)overflowModeXEnums[i].index;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getOverflowModeXEnum() - Invalid overflow mode X of '%s'", label);
+
+   return TextSprite::INVALID_OVERFLOW_X;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* TextSprite::getOverflowModeXDescription(const TextSprite::OverflowModeX modeX)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(overflowModeXEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (overflowModeXEnums[i].index == modeX)
+         return overflowModeXEnums[i].label;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getOverflowModeXDescription() - Invalid overflow mode X.");
+
+   return StringTable->EmptyString;
+}
+
+//-----------------------------------------------------------------------------
+// Overflow Mode Y
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setOverflowModeY(void* obj, const char* data)
+{
+   static_cast<TextSprite*>(obj)->setOverflowModeY(getOverflowModeYEnum(data)); return false;
+}
+
+//------------------------------------------------------------------------------
+
+static EnumTable::Enums overflowModeYEnums[] =
+{
+   { TextSprite::OVERFLOW_Y_VISIBLE, "Visible" },
+   { TextSprite::OVERFLOW_Y_HIDDEN, "Hidden" },
+   { TextSprite::OVERFLOW_Y_SHRINK, "Shrink" },
+};
+
+static EnumTable gOverflowModeYTable(3, &overflowModeYEnums[0]);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::OverflowModeY TextSprite::getOverflowModeYEnum(const char* label)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(overflowModeYEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (dStricmp(overflowModeYEnums[i].label, label) == 0)
+         return (OverflowModeY)overflowModeYEnums[i].index;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getOverflowModeYEnum() - Invalid overflow mode Y of '%s'", label);
+
+   return TextSprite::INVALID_OVERFLOW_Y;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* TextSprite::getOverflowModeYDescription(const TextSprite::OverflowModeY modeY)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(overflowModeYEnums) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (overflowModeYEnums[i].index == modeY)
+         return overflowModeYEnums[i].label;
+   }
+
+   // Warn.
+   Con::warnf("TextSprite::getOverflowModeYDescription() - Invalid overflow mode Y.");
+
+   return StringTable->EmptyString;
+}
+
+//------------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(TextSprite);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::TextSprite() :
+   mFontSize(1.0f),
+   mFontScaleX(1.0f),
+   mFontScaleY(1.0f),
+   mTextAlign(TextSprite::ALIGN_LEFT),
+   mTextVAlign(TextSprite::VALIGN_TOP),
+   mOverflowX(TextSprite::OVERFLOW_X_WRAP),
+   mOverflowY(TextSprite::OVERFLOW_Y_HIDDEN),
+   mAutoLineHeight(true),
+   mCustomLineHeight(1.0f),
+   mKerning(0.0f),
+   mFontSpatialsDirty(true),
+   mCalculatedSize(1.0f, 1.0f)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+TextSprite::~TextSprite()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::initPersistFields()
+{    
+    // Call parent.
+    Parent::initPersistFields();
+
+    addProtectedField("font", TypeFontAssetPtr, Offset(mFontAsset, TextSprite), &setFont, &getFont, &writeFont, "");
+    addProtectedField("text", TypeString, 0, setText, getText, &writeText, "The text to be displayed.");
+    addProtectedField("fontSize", TypeVector2, Offset(mFontSize, TextSprite), &setFontSize, &defaultProtectedGetFn, &writeFontSize, "");
+    addProtectedField("fontScaleX", TypeF32, Offset(mFontScaleX, TextSprite), &setFontScaleX, &defaultProtectedGetFn, &writeFontScaleX, "");
+    addProtectedField("fontScaleY", TypeF32, Offset(mFontScaleY, TextSprite), &setFontScaleY, &defaultProtectedGetFn, &writeFontScaleY, "");
+    addProtectedField("textAlignment", TypeEnum, Offset(mTextAlign, TextSprite), &setTextAlignment, &defaultProtectedGetFn, &writeTextAlignment, 1, &gTextAlignmentTable, "");
+    addProtectedField("textVAlignment", TypeEnum, Offset(mTextVAlign, TextSprite), &setTextVAlignment, &defaultProtectedGetFn, &writeTextVAlignment, 1, &gTextVAlignmentTable, "");
+    addProtectedField("overflowModeX", TypeEnum, Offset(mOverflowX, TextSprite), &setOverflowModeX, &defaultProtectedGetFn, &writeOverflowModeX, 1, &gOverflowModeXTable, "");
+    addProtectedField("overflowModeY", TypeEnum, Offset(mOverflowY, TextSprite), &setOverflowModeY, &defaultProtectedGetFn, &writeOverflowModeY, 1, &gOverflowModeYTable, "");
+    addField("autoLineHeight", TypeBool, Offset(mAutoLineHeight, TextSprite), &writeAutoLineHeight, "");
+    addProtectedField("customLineHeight", TypeF32, Offset(mCustomLineHeight, TextSprite), &setCustomLineHeight, &defaultProtectedGetFn, &writeCustomLineHeight, "");
+    addProtectedField("kerning", TypeF32, Offset(mKerning, TextSprite), &setKerning, &defaultProtectedGetFn, &writeKerning, "");
+}
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::onAdd()
+{
+    // Call Parent.
+    if(!Parent::onAdd())
+        return false;
+    
+    // Return Okay.
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::onRemove()
+{
+    // Call Parent.
+    Parent::onRemove();
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::copyTo(SimObject* object)
+{
+    // Fetch font object.
+    TextSprite* pFontObject = dynamic_cast<TextSprite*>(object);
+
+    // Sanity.
+    AssertFatal(pFontObject != NULL, "TextSprite::copyTo() - Object is not the correct type.");
+
+    // Call parent.
+    Parent::copyTo(object);
+
+    // Copy.
+    pFontObject->setFont(getFont());
+    pFontObject->setText(getText());
+    pFontObject->setFontSize(getFontSize());
+    pFontObject->setFontScaleX(getFontScaleX());
+    pFontObject->setFontScaleY(getFontScaleY());
+    pFontObject->setTextAlignment(getTextAlignment());
+    pFontObject->setTextVAlignment(getTextVAlignment());
+    pFontObject->setOverflowModeX(getOverflowModeX());
+    pFontObject->setOverflowModeY(getOverflowModeY());
+    pFontObject->setAutoLineHeight(getAutoLineHeight());
+    pFontObject->setCustomLineHeight(getCustomLineHeight());
+    pFontObject->setKerning(getKerning());
+    pFontObject->mCharInfo = mCharInfo;
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue )
+{
+    // Create a default render request.
+    Scene::createDefaultRenderRequest( pSceneRenderQueue, this );
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer )
+{
+    // Finish if no font asset.
+    if ( mFontAsset.isNull() )
+        return;
+
+    // Fetch number of characters to render.
+    const U32 renderCharacters = mText.length();
+
+    // Ignore if no text to render.
+    if( renderCharacters == 0 )
+        return;
+
+    //Make sure none of our settings are invalid
+    if (mTextAlign == INVALID_ALIGN)
+    {
+       mTextAlign = ALIGN_LEFT;
+    }
+
+    if (mTextVAlign == INVALID_VALIGN)
+    {
+       mTextVAlign = VALIGN_TOP;
+    }
+
+    if (mOverflowX == INVALID_OVERFLOW_X)
+    {
+       mOverflowX = OVERFLOW_X_WRAP;
+    }
+
+    if (mOverflowY == INVALID_OVERFLOW_Y)
+    {
+       mOverflowY = OVERFLOW_Y_HIDDEN;
+    }
+
+    // Get a size ratio
+    const F32 ratio = mFontAsset->mBitmapFont.getSizeRatio(mFontSize);
+
+    //get the line height
+    const F32 lineHeight = GetLineHeight();
+
+    //prep for justify
+    if (mTextAlign == ALIGN_JUSTIFY)
+    {
+       mKerning = 0;
+    }
+
+    //determine the rows
+    if (mFontSpatialsDirty || mSize != mCalculatedSize)
+    {
+       CalculateSpatials(ratio);
+    }
+
+    // If we're shrinking the set the scale
+    bool shrinkX = false;
+    bool shrinkY = false;
+    F32 origScaleX, origScaleY;
+    F32 origLengthX;
+    if (mOverflowX == OVERFLOW_X_SHRINK && mLine.front().mLength > mSize.x)
+    {
+       shrinkX = true;
+       origScaleX = mFontScaleX;
+       mFontScaleX = mSize.x / mLine.front().mLength;
+       origLengthX = mLine.front().mLength;
+       mLine.front().mLength = mSize.x;
+    }
+    if (mOverflowY == OVERFLOW_Y_SHRINK && (mLine.size() * lineHeight * mFontScaleY) > mSize.y)
+    {
+       shrinkY = true;
+       origScaleY = mFontScaleY;
+       mFontScaleY = mSize.y / (mLine.size() * lineHeight);
+    }
+
+    // Create a cursor
+    Vector2 cursor(0.0f, 0.0f);
+
+    ApplyAlignment(cursor, mLine.size(), 0, mLine.front().mLength, mLine.front().mEnd - mLine.front().mStart + 1, ratio);
+
+    // Render all the characters.  
+    U32 row = 0;
+    S32 prevCharID = -1;
+    for (U32 characterIndex = mLine.front().mStart; characterIndex < renderCharacters; ++characterIndex)
+    {
+        // Fetch character.
+        U32 charID = mText.getChar( characterIndex );
+
+        if (characterIndex >= mLine[row].mStart)
+        {
+           RenderLetter(pBatchRenderer, cursor, charID, ratio, characterIndex);
+        }
+        
+        if ((row + 1) < mLine.size() && mLine[row + 1].mStart == (characterIndex + 1))
+        {
+           row++;
+           cursor.x = 0;
+           prevCharID = -1;
+           ApplyAlignment(cursor, mLine.size(), row, mLine[row].mLength, mLine[row].mEnd - mLine[row].mStart + 1, ratio);
+        }
+        else
+        {
+           cursor.x += getCursorAdvance(charID, prevCharID, ratio);
+           prevCharID = charID;
+        }
+    }
+
+    //clean up for justify
+    if (mTextAlign == ALIGN_JUSTIFY)
+    {
+       mKerning = 0;
+    }
+
+    //clean up scale
+    if (mOverflowX == OVERFLOW_X_SHRINK && shrinkX)
+    {
+       mFontScaleX = origScaleX;
+       mLine.front().mLength = origLengthX;
+    }
+    if (mOverflowY == OVERFLOW_Y_SHRINK && shrinkY)
+    {
+       mFontScaleY = origScaleY;
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+
+void TextSprite::RenderLetter(BatchRender* pBatchRenderer, Vector2& cursor, U32 charID, F32 ratio, U32 charNum)
+{
+   const BitmapFontCharacter& bmChar = mFontAsset->mBitmapFont.getCharacter(charID);
+
+   Vector2 charScale = getCharacterScale(charNum);
+   Vector2 charOffset = getCharacterOffset(charNum);
+   ColorF charColor = getCharacterBlendColor(charNum);
+
+   F32 fontScaleX = mFontScaleX * charScale.x;
+   F32 fontScaleY = mFontScaleY * charScale.y;
+
+   F32 cursorX = cursor.x + charOffset.x - (bmChar.mWidth * ratio * mFontScaleX * ((charScale.x - 1) / 2));
+   F32 cursorY = cursor.y - charOffset.y;
+
+   //inset, for hiding part of a letter
+   F32 insetLeft, insetRight, insetTop, insetBottom;
+   insetLeft = 0;
+   insetRight = 0;
+   insetTop = 0;
+   insetBottom = 0;
+
+   // Cropping time!
+   if (mOverflowX == OVERFLOW_X_HIDDEN) 
+   {
+      if ((cursorX + (bmChar.mWidth * ratio * fontScaleX) <= 0) || (cursorX >= mSize.x))
+         return;
+
+      if (cursorX < 0 && (cursorX + (bmChar.mWidth * ratio * fontScaleX) > 0))
+      {
+         insetLeft = -(cursorX / (bmChar.mWidth * ratio * fontScaleX));
+      }
+
+      if (cursorX < mSize.x && (cursorX + (bmChar.mWidth * ratio * fontScaleX) > mSize.x))
+      {
+         insetRight = (((cursorX + (bmChar.mWidth * ratio * fontScaleX)) - mSize.x) / (bmChar.mWidth * ratio * fontScaleX));
+      }
+
+      if (insetLeft + insetRight > 1)
+         return;
+   }
+   if (mOverflowY == OVERFLOW_Y_HIDDEN)
+   {
+      F32 tempTop, tempBottom;
+      tempTop = cursorY - (mFontAsset->mBitmapFont.mBaseline * ratio * fontScaleY) + (bmChar.mYOffset * ratio * fontScaleY);
+      tempBottom = tempTop + (bmChar.mHeight * ratio * fontScaleY);
+
+      if ((tempBottom <= 0) || (tempTop >= mSize.y))
+         return;
+
+      if (tempTop < 0 && tempBottom > 0)
+      {
+         insetTop = -(tempTop / (bmChar.mHeight * ratio * fontScaleY));
+      }
+
+      if (tempTop < mSize.y && tempBottom > mSize.y)
+      {
+         insetBottom = (tempBottom - mSize.y) / (bmChar.mHeight * ratio * fontScaleY);
+      }
+
+      if (insetTop + insetBottom > 1)
+         return;
+   }
+
+   //create the source rect
+   Vector2 sourceOOBB[4];
+   sourceOOBB[0].Set(bmChar.mOOBB[0].x + ((insetLeft * (F32)bmChar.mWidth) / (F32)bmChar.mPageWidth), bmChar.mOOBB[0].y - ((insetBottom * (F32)bmChar.mHeight) / (F32)bmChar.mPageHeight));
+   sourceOOBB[1].Set(bmChar.mOOBB[1].x - ((insetRight * (F32)bmChar.mWidth) / (F32)bmChar.mPageWidth), bmChar.mOOBB[1].y - ((insetBottom * (F32)bmChar.mHeight) / (F32)bmChar.mPageHeight));
+   sourceOOBB[2].Set(bmChar.mOOBB[2].x - ((insetRight * (F32)bmChar.mWidth) / (F32)bmChar.mPageWidth), bmChar.mOOBB[2].y + ((insetTop * (F32)bmChar.mHeight) / (F32)bmChar.mPageHeight));
+   sourceOOBB[3].Set(bmChar.mOOBB[3].x + ((insetLeft * (F32)bmChar.mWidth) / (F32)bmChar.mPageWidth), bmChar.mOOBB[3].y + ((insetTop * (F32)bmChar.mHeight) / (F32)bmChar.mPageHeight));
+
+   //create the destination rect
+   Vector2 destLeft = (mRenderOOBB[1] - mRenderOOBB[0]);
+   destLeft.Normalize((F32)cursorX + (insetLeft * bmChar.mWidth * ratio * fontScaleX));
+
+   Vector2 destWidth = (mRenderOOBB[1] - mRenderOOBB[0]);
+   destWidth.Normalize(((bmChar.mWidth * ratio) - (insetLeft * (bmChar.mWidth * ratio)) - (insetRight * (bmChar.mWidth * ratio))) * fontScaleX);
+
+   Vector2 destTop = -(mRenderOOBB[3] - mRenderOOBB[0]);
+   destTop.Normalize((F32)cursorY - (((mFontAsset->mBitmapFont.mBaseline * ratio) - (bmChar.mYOffset * ratio) - (insetTop * bmChar.mHeight * ratio)) * fontScaleY));
+
+   Vector2 destHeight = -(mRenderOOBB[3] - mRenderOOBB[0]);
+   destHeight.Normalize(((bmChar.mHeight * ratio) - (insetBottom * bmChar.mHeight * ratio) - (insetTop * bmChar.mHeight * ratio)) * fontScaleY);
+
+   Vector2 destOOBB[4];
+   destOOBB[0] = (mRenderOOBB[3] + destLeft + destTop + destHeight);
+   destOOBB[1] = (mRenderOOBB[3] + destLeft + destWidth + destTop + destHeight);
+   destOOBB[2] = (mRenderOOBB[3] + destLeft + destWidth + destTop);
+   destOOBB[3] = (mRenderOOBB[3] + destLeft + destTop);
+
+   if (charColor != mBlendColor)
+   {
+      // Submit batched quad.
+      pBatchRenderer->SubmitQuad(
+         destOOBB[0],
+         destOOBB[1],
+         destOOBB[2],
+         destOOBB[3],
+         sourceOOBB[0],
+         sourceOOBB[1],
+         sourceOOBB[2],
+         sourceOOBB[3],
+         mFontAsset->getImageTexture(bmChar.mPage),
+         charColor);
+   }
+   else
+   {
+      // Submit batched quad.
+      pBatchRenderer->SubmitQuad(
+         destOOBB[0],
+         destOOBB[1],
+         destOOBB[2],
+         destOOBB[3],
+         sourceOOBB[0],
+         sourceOOBB[1],
+         sourceOOBB[2],
+         sourceOOBB[3],
+         mFontAsset->getImageTexture(bmChar.mPage));
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::CalculateSpatials(F32 ratio)
+{
+   F32 length = 0;
+   S32 start = -1;
+   S32 wordEnd = 0;
+   F32 wordEndLength = 0;
+   S32 prevCharID = -1;
+   mLine.clear();
+   const U32 renderCharacters = mText.length();
+
+   for (U32 i = 0; i < renderCharacters; i++)
+   {
+      U32 charID = mText.getChar(i);
+      const BitmapFontCharacter& bmChar = mFontAsset->mBitmapFont.getCharacter(charID);
+
+      if (start == -1 && charID != 32)
+      {
+         start = i;
+         length = 0;
+         mLine.push_back(BitmapFontLineInfo(start));
+      }
+
+      if (i == start)
+      {
+         length -= (bmChar.mXOffset * ratio * mFontScaleX);
+      }
+
+      length += getCursorAdvance(bmChar, prevCharID, ratio);
+
+      if (mOverflowX == OVERFLOW_X_WRAP)
+      {
+         if (prevCharID != 32 && prevCharID != -1 && charID == 32)
+         {
+            wordEnd = i - 1;
+            wordEndLength = length - getCursorAdvance(bmChar, prevCharID, ratio);
+         }
+
+         if (length > mSize.x && wordEnd > start)
+         {
+            mLine.back().mEnd = wordEnd;
+            U32 endCharID = mText.getChar(wordEnd);
+            const BitmapFontCharacter& bmCharEnd = mFontAsset->mBitmapFont.getCharacter(endCharID);
+            i = wordEnd;
+
+            start = -1;
+            length = 0;
+
+            S32 prevEndCharID = -1;
+            if (wordEnd != 0)
+            {
+               prevEndCharID = mText.getChar(wordEnd - 1);
+            }
+
+            wordEndLength += -getCursorAdvance(bmCharEnd, prevEndCharID, ratio) + (bmCharEnd.mWidth * ratio * mFontScaleX) + (bmCharEnd.mXOffset * ratio * mFontScaleX);
+            mLine.back().mLength = wordEndLength;
+         }
+      }
+
+      prevCharID = charID;
+
+      if ((i + 1) == renderCharacters)
+      {
+         if (charID != 32)//this is the last character and if it's not a space then it's the end of a word.
+         {
+            wordEndLength = length;
+            wordEnd = i;
+         }
+         mLine.back().mEnd = wordEnd;
+         U32 endCharID = mText.getChar(wordEnd);
+         const BitmapFontCharacter& bmCharEnd = mFontAsset->mBitmapFont.getCharacter(endCharID);
+
+         S32 prevEndCharID = -1;
+         if (wordEnd != 0)
+         {
+            prevEndCharID = mText.getChar(wordEnd - 1);
+         }
+
+         wordEndLength += -getCursorAdvance(bmCharEnd, prevEndCharID, ratio) + (bmCharEnd.mWidth * ratio * mFontScaleX) + (bmCharEnd.mXOffset * ratio * mFontScaleX);
+         mLine.back().mLength = wordEndLength;
+      }
+   }
+
+   mFontSpatialsDirty = false;
+   mCalculatedSize = mSize;
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::ApplyAlignment(Vector2& cursor, U32 totalRows, U32 row, F32 length, U32 charCount, F32 ratio)
+{
+   //Horizontal Align
+   if (mTextAlign == ALIGN_CENTER)
+   {
+      cursor.x += ((mSize.x - length) / 2.0f);
+   }
+   else if (mTextAlign == ALIGN_RIGHT)
+   {
+      cursor.x += (mSize.x - length);
+   }
+   else if (mTextAlign == ALIGN_JUSTIFY)
+   {
+      U32 gapCount = charCount - 1;
+      mKerning = (-(mSize.x - length) / gapCount) / mFontScaleX;
+   }
+
+   //Vertical Align
+   const F32 lineHeight = GetLineHeight();
+   if (mTextVAlign == VALIGN_TOP)
+   {
+      cursor.y = ((mFontAsset->mBitmapFont.mBaseline * ratio) + (lineHeight * row)) * mFontScaleY;
+   }
+   else if (mTextVAlign == VALIGN_MIDDLE)
+   {
+      cursor.y = (mSize.y / 2.0f) - ((((lineHeight / 2.0f) * totalRows) - (lineHeight * row) - (mFontAsset->mBitmapFont.mBaseline * ratio)) * mFontScaleY);
+   }
+   else if (mTextVAlign == VALIGN_BOTTOM)
+   {
+      cursor.y = mSize.y - (((lineHeight * totalRows) - (lineHeight * row) - (mFontAsset->mBitmapFont.mBaseline * ratio)) * mFontScaleY);
+   }
+}
+
+
+//-----------------------------------------------------------------------------
+
+F32 TextSprite::getCursorAdvance(U32 charID, S32 prevCharID, F32 ratio)
+{
+   const BitmapFontCharacter& bmChar = mFontAsset->mBitmapFont.getCharacter(charID);
+   return getCursorAdvance(bmChar, prevCharID, ratio);
+}
+
+F32 TextSprite::getCursorAdvance(const BitmapFontCharacter& bmChar, S32 prevCharID, F32 ratio)
+{
+   if (prevCharID != -1)
+   {
+      S16 kerning = mFontAsset->mBitmapFont.getKerning(prevCharID, bmChar.mCharID);
+      return (((bmChar.mXAdvance - kerning) * ratio) - mKerning) * mFontScaleX;
+   }
+   else
+   {
+      return ((bmChar.mXAdvance * ratio) - mKerning) * mFontScaleX;
+   }
+}
+
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setFont( const char* pFontAssetId )
+{
+    // Set asset.
+    mFontAsset = pFontAssetId;
+
+    // Finish if no font asset.
+    if ( mFontAsset.isNull() )
+        return false;
+
+    mFontSpatialsDirty = true;
+    
+    // Return Okay.
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::setCharacterBlendColor(const U32 charNum, const ColorF color)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      mCharInfo[charNum].mColor = color;
+      mCharInfo[charNum].mUseColor = true;
+   }
+   else
+   {
+      mCharInfo[charNum] = BitmapFontCharacterInfo(color);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+ColorF TextSprite::getCharacterBlendColor(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      return mCharInfo[charNum].mColor;
+   }
+   else
+   {
+      return mBlendColor;
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::getCharacterHasBlendColor(const U32 charNum)
+{
+   return (mCharInfo.find(charNum) != mCharInfo.end() && mCharInfo[charNum].mUseColor);
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::resetCharacterBlendColor(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      mCharInfo[charNum].mUseColor = false;
+
+      if (mCharInfo[charNum].isDefault())
+      {
+         mCharInfo.erase(charNum);
+      }
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::setCharacterScale(const U32 charNum, const F32 scaleX, const F32 scaleY)
+{
+   if (mCharInfo.find(charNum) == mCharInfo.end())
+   {
+      mCharInfo[charNum] = BitmapFontCharacterInfo();
+   }
+   mCharInfo[charNum].mScaleX = scaleX;
+   mCharInfo[charNum].mScaleY = scaleY;
+
+   if (mCharInfo[charNum].isDefault())
+   {
+      mCharInfo.erase(charNum);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+Vector2 TextSprite::getCharacterScale(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      return Vector2(mCharInfo[charNum].mScaleX, mCharInfo[charNum].mScaleY);
+   }
+   else
+   {
+      return Vector2(1.0f, 1.0f);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::resetCharacterScale(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      mCharInfo[charNum].mScaleX = 1.0f;
+      mCharInfo[charNum].mScaleY = 1.0f;
+
+      if (mCharInfo[charNum].isDefault())
+      {
+         mCharInfo.erase(charNum);
+      }
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::setCharacterOffset(const U32 charNum, const F32 offsetX, const F32 offsetY)
+{
+   if (mCharInfo.find(charNum) == mCharInfo.end())
+   {
+      mCharInfo[charNum] = BitmapFontCharacterInfo();
+   }
+   mCharInfo[charNum].mOffsetX = offsetX;
+   mCharInfo[charNum].mOffsetY = offsetY;
+
+   if (mCharInfo[charNum].isDefault())
+   {
+      mCharInfo.erase(charNum);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+Vector2 TextSprite::getCharacterOffset(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      return Vector2(mCharInfo[charNum].mOffsetX, mCharInfo[charNum].mOffsetY);
+   }
+   else
+   {
+      return Vector2(0.0f, 0.0f);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::resetCharacterOffset(const U32 charNum)
+{
+   if (mCharInfo.find(charNum) != mCharInfo.end())
+   {
+      mCharInfo[charNum].mOffsetX = 0.0f;
+      mCharInfo[charNum].mOffsetY = 0.0f;
+
+      if (mCharInfo[charNum].isDefault())
+      {
+         mCharInfo.erase(charNum);
+      }
+   }
+}

+ 241 - 0
engine/source/2d/sceneobject/TextSprite.h

@@ -0,0 +1,241 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _TEXT_SPRITE_H_
+#define _TEXT_SPRITE_H_
+
+#ifndef _STRINGBUFFER_H_
+#include "string/stringBuffer.h"
+#endif
+
+#ifndef _FONT_ASSET_H_
+#include "2d/assets/FontAsset.h"
+#endif
+
+#ifndef _SCENE_OBJECT_H_
+#include "2d/sceneobject/SceneObject.h"
+#endif
+
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
+#ifndef _UTILITY_H_
+#include "2d/core/utility.h"
+#endif
+
+#ifndef _BITMAP_FONT_LINE_INFO_H_
+#include "bitmapFont/BitmapFontLineInfo.h"
+#endif
+
+#ifndef _BITMAP_FONT_CHARACTER_INFO_H_
+#include "bitmapFont/BitmapFontCharacterInfo.h"
+#endif
+
+using CharInfoMap = std::map<U32, BitmapFontCharacterInfo>;
+
+//-----------------------------------------------------------------------------
+
+class TextSprite : public SceneObject
+{
+    typedef SceneObject          Parent;
+
+public:
+    enum TextAlign
+    {
+        INVALID_ALIGN,
+
+        ALIGN_LEFT,
+        ALIGN_CENTER,
+        ALIGN_RIGHT,
+        ALIGN_JUSTIFY,
+    };
+
+    enum TextVAlign
+    {
+       INVALID_VALIGN,
+
+       VALIGN_TOP,
+       VALIGN_MIDDLE,
+       VALIGN_BOTTOM,
+    };
+
+    enum OverflowModeX
+    {
+       INVALID_OVERFLOW_X,
+
+       OVERFLOW_X_WRAP,
+       OVERFLOW_X_VISIBLE,
+       OVERFLOW_X_HIDDEN,
+       OVERFLOW_X_SHRINK,
+    };
+
+    enum OverflowModeY
+    {
+       INVALID_OVERFLOW_Y,
+
+       OVERFLOW_Y_VISIBLE,
+       OVERFLOW_Y_HIDDEN,
+       OVERFLOW_Y_SHRINK,
+    };
+
+private:
+    AssetPtr<FontAsset>     mFontAsset;
+    StringBuffer            mText;
+    F32                     mFontSize;
+    F32                     mFontScaleX;
+    F32                     mFontScaleY;
+    TextAlign               mTextAlign;
+    TextVAlign              mTextVAlign;
+    OverflowModeX           mOverflowX;
+    OverflowModeY           mOverflowY;
+    bool                    mAutoLineHeight;
+    F32                     mCustomLineHeight;
+    F32                     mKerning;
+
+    std::vector<BitmapFontLineInfo> mLine;
+    bool                    mFontSpatialsDirty;
+    Vector2                 mCalculatedSize;
+    CharInfoMap             mCharInfo;
+
+
+public:
+    TextSprite();
+    ~TextSprite();
+
+    static void initPersistFields();
+
+    bool onAdd();
+    void onRemove();
+    void copyTo(SimObject* object);
+
+    virtual bool canPrepareRender( void ) const                             { return true; }
+    virtual bool validRender( void ) const                                  { return mFontAsset.notNull() && mText.length() > 0; }
+    virtual bool shouldRender( void ) const                                 { return true; }
+    virtual void scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue );
+    virtual void sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer );
+
+    bool setFont( const char* pFontAssetId );
+    const char* getFont(void) const                                         { return mFontAsset.getAssetId(); }
+    inline void setText(const StringBuffer& text)                           { mText.set(&text); mFontSpatialsDirty = true; mCharInfo.clear(); }
+    inline StringBuffer& getText(void)                                      { return mText; }
+    inline void setFontSize(const F32 size)                                 { mFontSize = size; mFontSpatialsDirty = true; }
+    inline F32 getFontSize(void) const                                      { return mFontSize; }
+    inline void setFontScaleX(const F32 scale)                              { mFontScaleX = scale; mFontSpatialsDirty = true; }
+    inline F32 getFontScaleX(void) const                                    { return mFontScaleX; }
+    inline void setFontScaleY(const F32 scale)                              { mFontScaleY = scale; mFontSpatialsDirty = true; }
+    inline F32 getFontScaleY(void) const                                    { return mFontScaleY; }
+
+    inline void setTextAlignment(const TextAlign alignment)                 { mTextAlign = alignment; mFontSpatialsDirty = true; }
+    inline TextAlign getTextAlignment(void) const                           { return mTextAlign; }
+    static TextAlign getTextAlignmentEnum(const char* label);
+    static const char* getTextAlignmentDescription(const TextAlign alignment);
+
+    inline void setTextVAlignment(const TextVAlign alignment)               { mTextVAlign = alignment; mFontSpatialsDirty = true; }
+    inline TextVAlign getTextVAlignment(void) const                         { return mTextVAlign; }
+    static TextVAlign getTextVAlignmentEnum(const char* label);
+    static const char* getTextVAlignmentDescription(const TextVAlign alignment);
+
+    inline void setOverflowModeX(const OverflowModeX mode)                  { mOverflowX = mode; mFontSpatialsDirty = true; }
+    inline OverflowModeX getOverflowModeX(void) const                       { return mOverflowX; }
+    static OverflowModeX getOverflowModeXEnum(const char* label);
+    static const char* getOverflowModeXDescription(const OverflowModeX mode);
+
+    inline void setOverflowModeY(const OverflowModeY mode)                  { mOverflowY = mode; mFontSpatialsDirty = true; }
+    inline OverflowModeY getOverflowModeY(void) const                       { return mOverflowY; }
+    static OverflowModeY getOverflowModeYEnum(const char* label);
+    static const char* getOverflowModeYDescription(const OverflowModeY mode);
+
+    inline void setAutoLineHeight(const bool isAuto)                        { mAutoLineHeight = isAuto; mFontSpatialsDirty = true; }
+    inline bool getAutoLineHeight(void) const                               { return mAutoLineHeight; }
+    inline void setCustomLineHeight(const F32 lineHeight)                   { mCustomLineHeight = lineHeight; mFontSpatialsDirty = true; }
+    inline F32 getCustomLineHeight(void) const                              { return mCustomLineHeight; }
+
+    inline void setKerning(const F32 kern)                                  { mKerning = kern; mFontSpatialsDirty = true; }
+    inline F32 getKerning(void) const                                       { return mKerning; }
+
+    void resetCharacterSettings(void)                                       { mCharInfo.clear(); }
+
+    void setCharacterBlendColor(const U32 charNum, const ColorF color);
+    ColorF getCharacterBlendColor(const U32 charNum);
+    bool getCharacterHasBlendColor(const U32 charNum);
+    void resetCharacterBlendColor(const U32 charNum);
+
+    void setCharacterScale(const U32 charNum, const F32 scaleX, const F32 scaleY);
+    Vector2 getCharacterScale(const U32 charNum);
+    void resetCharacterScale(const U32 charNum);
+
+    void setCharacterOffset(const U32 charNum, const F32 offsetX, const F32 offsetY);
+    Vector2 getCharacterOffset(const U32 charNum);
+    void resetCharacterOffset(const U32 charNum);
+
+    // Declare Console Object.
+    DECLARE_CONOBJECT(TextSprite);
+
+protected:
+    static bool setFont(void* obj, const char* data)                        { static_cast<TextSprite*>(obj)->setFont( data ); return false; }
+    static const char* getFont(void* obj, const char* data)                 { return static_cast<TextSprite*>(obj)->getFont(); }
+    static bool writeFont( void* obj, StringTableEntry pFieldName )         { return static_cast<TextSprite*>(obj)->mFontAsset.notNull(); }
+
+    static bool setText( void* obj, const char* data )                      { static_cast<TextSprite*>( obj )->setText( data ); return false; }
+    static const char* getText( void* obj, const char* data )               { return static_cast<TextSprite*>( obj )->getText().getPtr8(); }
+    static bool writeText(void* obj, StringTableEntry pFieldName)         { return static_cast<TextSprite*>(obj)->mText.length() != 0; }
+
+    static bool setFontSize(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setFontSize(dAtof(data)); return false; }
+    static bool writeFontSize(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getFontSize() != 1.0f; }
+
+    static bool setFontScaleX(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setFontScaleX(dAtof(data)); return false; }
+    static bool writeFontScaleX(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getFontScaleX() != 1.0f; }
+
+    static bool setFontScaleY(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setFontScaleY(dAtof(data)); return false; }
+    static bool writeFontScaleY(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getFontScaleY() != 1.0f; }
+
+    static bool setTextAlignment(void* obj, const char* data);
+    static bool writeTextAlignment(void* obj, StringTableEntry pFieldName){ return static_cast<TextSprite*>(obj)->getTextAlignment() != TextSprite::ALIGN_LEFT; }
+
+    static bool setTextVAlignment(void* obj, const char* data);
+    static bool writeTextVAlignment(void* obj, StringTableEntry pFieldName){ return static_cast<TextSprite*>(obj)->getTextVAlignment() != TextSprite::VALIGN_TOP; }
+
+    static bool setOverflowModeX(void* obj, const char* data);
+    static bool writeOverflowModeX(void* obj, StringTableEntry pFieldName){ return static_cast<TextSprite*>(obj)->getOverflowModeX() != TextSprite::OVERFLOW_X_WRAP; }
+
+    static bool setOverflowModeY(void* obj, const char* data);
+    static bool writeOverflowModeY(void* obj, StringTableEntry pFieldName){ return static_cast<TextSprite*>(obj)->getOverflowModeY() != TextSprite::OVERFLOW_Y_HIDDEN; }
+
+    static bool writeAutoLineHeight(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getAutoLineHeight() != true; }
+
+    static bool setCustomLineHeight(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setCustomLineHeight(dAtof(data)); return false; }
+    static bool writeCustomLineHeight(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getCustomLineHeight() != 1.0f; }
+
+    static bool setKerning(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setKerning(dAtof(data)); return false; }
+    static bool writeKerning(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getKerning() != 0.0f; }
+
+private:
+   void RenderLetter(BatchRender* pBatchRenderer, Vector2& cursor, U32 charID, F32 ratio, U32 charNum);
+   void ApplyAlignment(Vector2& cursor, U32 totalRows, U32 row, F32 length, U32 charCount, F32 ratio);
+   F32 getCursorAdvance(U32 charID, S32 prevCharID, F32 ratio);
+   F32 getCursorAdvance(const BitmapFontCharacter& bmChar, S32 prevCharID, F32 ratio);
+   F32 GetLineHeight() { return (mAutoLineHeight) ? mFontSize : mCustomLineHeight; }
+   void CalculateSpatials(F32 ratio);
+};
+
+#endif // _TEXT_SPRITE_H_

+ 437 - 0
engine/source/2d/sceneobject/TextSprite_ScriptBinding.h

@@ -0,0 +1,437 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+ConsoleMethodGroupBeginWithDocs(TextSprite, SceneObject)
+
+/*! Sets the image asset to use..
+    @param fontName The font asset to use.
+    @return Returns true on success.
+*/
+ConsoleMethodWithDocs(TextSprite, setFont, ConsoleBool, 3, 3, (fontAssetId))
+{
+    return object->setFont( argv[2] );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current font asset..
+    @return The current font asset.
+*/
+ConsoleMethodWithDocs(TextSprite, getFont, ConsoleString, 2, 2, ())
+{
+    return object->getFont();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the text to render.
+*/
+ConsoleMethodWithDocs(TextSprite, setText, ConsoleVoid, 3, 3, (text))
+{
+    object->setText(argv[2]);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the text being rendered.
+*/
+ConsoleMethodWithDocs(TextSprite, getText, ConsoleString, 2, 2, ())
+{
+    return object->getText().getPtr8();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the size of the font.
+@param size The distance between the top of a line of text and the bottom.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setFontSize, ConsoleVoid, 3, 3, (size))
+{
+   object->setFontSize(dAtof(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the size of the font.
+@return The size of the font.
+*/
+ConsoleMethodWithDocs(TextSprite, getFontSize, ConsoleFloat, 2, 2, ())
+{
+   return object->getFontSize();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the scale of the font in the X direction.
+@param scale The amount to multiply the width of the text by.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setFontScaleX, ConsoleVoid, 3, 3, (scale))
+{
+   object->setFontScaleX(dAtof(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the scale of the font in the X direction.
+@return The scale of the of the font in the X direction.
+*/
+ConsoleMethodWithDocs(TextSprite, getFontScaleX, ConsoleFloat, 2, 2, ())
+{
+   return object->getFontScaleX();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the scale of the font in the Y direction.
+@param scale The amount to multiply the height of the text by.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setFontScaleY, ConsoleVoid, 3, 3, (scale))
+{
+   object->setFontScaleY(dAtof(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the scale of the font in the Y direction.
+@return The scale of the of the font in the Y direction.
+*/
+ConsoleMethodWithDocs(TextSprite, getFontScaleY, ConsoleFloat, 2, 2, ())
+{
+   return object->getFontScaleY();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the horizontal text alignment to 'left', 'center', 'right', or 'justify'.
+    @param alignment The text alignment of 'left', 'center', 'right', or 'justify'.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setTextAlignment, ConsoleVoid, 3, 3, (alignment))
+{
+    object->setTextAlignment( TextSprite::getTextAlignmentEnum(argv[2]) );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the horizontal text alignment.
+    @return The text alignment of 'left', 'center', 'right', or 'justify'.
+*/
+ConsoleMethodWithDocs(TextSprite, getTextAlignment, ConsoleString, 2, 2, ())
+{
+   return TextSprite::getTextAlignmentDescription(object->getTextAlignment());
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the vertical text alignment to 'top', 'middle', or 'bottom'.
+@param alignment The vertical text alignment of 'top', 'middle', or 'bottom'.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setTextVAlignment, ConsoleVoid, 3, 3, (alignment))
+{
+   object->setTextVAlignment(TextSprite::getTextVAlignmentEnum(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the vertical text alignment.
+@return The vertical text alignment of 'top', 'middle', or 'bottom'.
+*/
+ConsoleMethodWithDocs(TextSprite, getTextVAlignment, ConsoleString, 2, 2, ())
+{
+   return TextSprite::getTextVAlignmentDescription(object->getTextVAlignment());
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the overflow mode X to 'wrap', 'visible', 'hidden', or 'shrink'.
+@param mode The overflow mode X of 'wrap', 'visible', 'hidden', or 'shrink'.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setOverflowModeX, ConsoleVoid, 3, 3, (mode))
+{
+   object->setOverflowModeX(TextSprite::getOverflowModeXEnum(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the overflow mode X.
+@return The overflow mode X of 'wrap', 'visible', 'hidden', or 'shrink'.
+*/
+ConsoleMethodWithDocs(TextSprite, getOverflowModeX, ConsoleString, 2, 2, ())
+{
+   return TextSprite::getOverflowModeXDescription(object->getOverflowModeX());
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the overflow mode Y to 'visible', 'hidden', or 'shrink'.
+@param mode The overflow mode Y of 'visible', 'hidden', or 'shrink'.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setOverflowModeY, ConsoleVoid, 3, 3, (mode))
+{
+   object->setOverflowModeY(TextSprite::getOverflowModeYEnum(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the overflow mode Y.
+@return The overflow mode Y of 'visible', 'hidden', or 'shrink'.
+*/
+ConsoleMethodWithDocs(TextSprite, getOverflowModeY, ConsoleString, 2, 2, ())
+{
+   return TextSprite::getOverflowModeYDescription(object->getOverflowModeY());
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets if the line height should be automatically calculated.
+@param isAuto True if the line height automatically calculated or false to use the custom line height.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setAutoLineHeight, ConsoleVoid, 3, 3, (isAuto))
+{
+   object->setAutoLineHeight(dAtob(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets whether the line height is automatically calculated.
+@return True if the line height is automatically calculated or false if the custom line height is used.
+*/
+ConsoleMethodWithDocs(TextSprite, getAutoLineHeight, ConsoleBool, 2, 2, ())
+{
+   return object->getAutoLineHeight();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the custom line height and disables the auto line height.
+@param lineHeight The distance between the top and the bottom of a line before adjusting by the fontScaleY.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setCustomLineHeight, ConsoleVoid, 3, 3, (lineHeight))
+{
+   object->setCustomLineHeight(dAtof(argv[2]));
+   object->setAutoLineHeight(false);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the custom line height.
+@return The distance between the top and the bottom of a line.
+*/
+ConsoleMethodWithDocs(TextSprite, getCustomLineHeight, ConsoleFloat, 2, 2, ())
+{
+   return object->getCustomLineHeight();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets kerning to be used between each character. Kerning is ignored when using alignment of 'justify'.
+@param kerning The amount to decrease the distance by between each character. Positive valus move the characters closer together and negative values move them apart.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setKerning, ConsoleVoid, 3, 3, (kerning))
+{
+   object->setKerning(dAtof(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the kerning amount.
+@return The amount each character is moved closer together.
+*/
+ConsoleMethodWithDocs(TextSprite, getKerning, ConsoleFloat, 2, 2, ())
+{
+   return object->getKerning();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Resets the blend color, scale, and offset for all characters'.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, resetCharacterSettings, ConsoleVoid, 2, 2, ())
+{
+   object->resetCharacterSettings();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the blend color for an individual character.
+@param index The zero based index for the character.
+@param color The blend color to use for character.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setCharacterBlendColor, ConsoleVoid, 4, 4, (index, color))
+{
+   if (argc < 3)
+   {
+      Con::warnf("TextSprite::setCharacterBlendColor() - Invalid number of parameters!");
+      return;
+   }
+
+   const U32 colorCount = Utility::mGetStringElementCount(argv[3]);
+   if (colorCount != 4)
+   {
+      Con::warnf("TextSprite::setCharacterBlendColor() - Invalid color! Colors require four values (red / green / blue / alpha)!");
+      return;
+   }
+   object->setCharacterBlendColor(dAtoi(argv[2]), ColorF(dAtof(Utility::mGetStringElement(argv[3], 0)),
+                                                         dAtof(Utility::mGetStringElement(argv[3], 1)),
+                                                         dAtof(Utility::mGetStringElement(argv[3], 2)),
+                                                         dAtof(Utility::mGetStringElement(argv[3], 3))));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the blend color for an individual character if set or the blend color for the sprite.
+@param index The zero based index for the character.
+@return The blend color for the character or the sprite.
+*/
+ConsoleMethodWithDocs(TextSprite, getCharacterBlendColor, ConsoleString, 3, 3, (index))
+{
+   U32 charNum = dAtoi(argv[2]);
+   if (object->getCharacterHasBlendColor(charNum))
+   {
+      return object->getCharacterBlendColor(charNum).scriptThis();
+   }
+   else
+   {
+      return object->getBlendColor().scriptThis();
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets if the character is using a custom blend color.
+@param index The zero based index for the character.
+@return True if the character is using a custom blend color or false if the character uses the sprite's blend color.
+*/
+ConsoleMethodWithDocs(TextSprite, getCharacterHasBlendColor, ConsoleBool, 3, 3, (index))
+{
+   return object->getCharacterHasBlendColor(dAtoi(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Resets the blend color for a character so that it uses the sprite's blend color.
+@param index The zero based index for the character.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, resetCharacterBlendColor, ConsoleVoid, 3, 3, (index))
+{
+   object->resetCharacterBlendColor(dAtoi(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the scale of a given character. This is multiplied by the scale of the font to get the total scale.
+@param index The zero based index for the character.
+@param (scaleX / scaleY) The amount to multiply the size of the character by. Default value is 1.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setCharacterScale, ConsoleVoid, 4, 4, (index, scale scaleX / scaleY))
+{
+   U32 charNum = dAtoi(argv[2]);
+
+   const U32 count = Utility::mGetStringElementCount(argv[3]);
+   if (count != 2)
+   {
+      Con::warnf("TextSprite::setCharacterScale() - Invalid number of values (scaleX / scaleY)!");
+      return;
+   }
+
+   object->setCharacterScale(charNum, dAtof(Utility::mGetStringElement(argv[3], 0)), dAtof(Utility::mGetStringElement(argv[3], 1)));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets scale of a given character.
+@param index The zero based index for the character.
+@return (scaleX / scaleY) The scale of the character.
+*/
+ConsoleMethodWithDocs(TextSprite, getCharacterScale, ConsoleString, 3, 3, (index))
+{
+   return object->getCharacterScale(dAtoi(argv[2])).scriptThis();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Resets the scale of a given character.
+@param index The zero based index for the character.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, resetCharacterScale, ConsoleVoid, 3, 3, (index))
+{
+   object->resetCharacterScale(dAtoi(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the offset of a given character.
+@param index The zero based index for the character.
+@param (offsetX / offsetY) The amount to move a character from it's calculated position.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setCharacterOffset, ConsoleVoid, 4, 4, (index, offset offsetX / offsetY))
+{
+   U32 charNum = dAtoi(argv[2]);
+
+   const U32 count = Utility::mGetStringElementCount(argv[3]);
+   if (count != 2)
+   {
+      Con::warnf("TextSprite::setCharacterOffset() - Invalid number of values (offsetX / offsetY)!");
+      return;
+   }
+
+   object->setCharacterOffset(charNum, dAtof(Utility::mGetStringElement(argv[3], 0)), dAtof(Utility::mGetStringElement(argv[3], 1)));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets offset of a given character.
+@param index The zero based index for the character.
+@return (offsetX / offsetY) The offset of the character.
+*/
+ConsoleMethodWithDocs(TextSprite, getCharacterOffset, ConsoleString, 3, 3, (index))
+{
+   return object->getCharacterOffset(dAtoi(argv[2])).scriptThis();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Resets the offset of a given character.
+@param index The zero based index for the character.
+@return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, resetCharacterOffset, ConsoleVoid, 3, 3, (index))
+{
+   object->resetCharacterOffset(dAtoi(argv[2]));
+}
+
+ConsoleMethodGroupEndWithDocs(TextSprite)

+ 40 - 1
engine/source/audio/audio.cc

@@ -22,6 +22,7 @@
 
 #include "audio/audio.h"
 #include "audio/audioDataBlock.h"
+#include "audio/audioDescriptions.h"
 #include "collection/vector.h"
 #include "console/console.h"
 #include "console/consoleTypes.h"
@@ -733,7 +734,7 @@ AUDIOHANDLE alxCreateSource(const Audio::Description& desc,
          if (streamSource)
          {
             streamSource->mHandle = getNewHandle() | AUDIOHANDLE_STREAMING_BIT | AUDIOHANDLE_INACTIVE_BIT;
-            streamSource->mSource = NULL;
+            streamSource->mSource = 0;
             streamSource->mDescription = desc;
             streamSource->mScore = volume;
             streamSource->mEnvironment = sampleEnvironment;
@@ -871,6 +872,30 @@ AUDIOHANDLE alxCreateSource(const AudioAsset *profile, const MatrixF *transform)
    return alxCreateSource(profile->getAudioDescription(), profile->getAudioFile(), transform, NULL );
 }
 
+//--------------------------------------------------------------------------
+AUDIOHANDLE alxCreateSource_AD(const AudioAsset *profile, const AudioDescription* description, const MatrixF *transform)
+{
+    //Since we don't want to modify AudioAssets all the time
+    //here is a version which accepts a script-defined AudioDescription
+    if (profile == NULL)
+        return NULL_AUDIOHANDLE;
+    
+    Audio::Description newAD;
+    newAD.mVolume = description->mVolume;
+    newAD.mVolumeChannel = description->mVolumeChannel;
+    newAD.mConeInsideAngle = description->mConeInsideAngle;
+    newAD.mConeOutsideAngle = description->mConeOutsideAngle;
+    newAD.mConeOutsideVolume = description->mConeOutsideVolume;
+    newAD.mConeVector = description->mConeVector;
+    newAD.mEnvironmentLevel = description->mEnvironmentLevel;
+    newAD.mIs3D = description->mIs3D;
+    newAD.mIsLooping = description->mIsLooping;
+    newAD.mIsStreaming = description->mIsStreaming;
+    newAD.mMaxDistance = description->mMaxDistance;
+    newAD.mReferenceDistance = description->mReferenceDistance;
+    
+    return alxCreateSource(newAD, profile->getAudioFile(), transform, NULL);
+}
 //--------------------------------------------------------------------------
 
 extern void threadPlay(AudioBuffer * buffer, AUDIOHANDLE handle);
@@ -2541,8 +2566,22 @@ bool OpenALInit()
    // Similiar to DSound Model w/o min distance clamping
    alEnable(AL_DISTANCE_MODEL);
    alDistanceModel(AL_INVERSE_DISTANCE);
+   alDopplerFactor(1.f);
    alListenerf(AL_GAIN_LINEAR, 1.f);
 
+   //The audio listener is initialized at position 0,0
+   //Listener orientation
+   //The first three values represent an "at" vector which points towards the screen.
+   //The second set of three values represent the "up" vector (Y+)
+
+   F32 listenerPos[] = { 0.f, 0.f, 0.f };
+   F32 listenerVel[] = { 0.f, 0.f, 0.f };
+   F32 listenerOrientation[] = { 0.f, 0.f, -1.0f, 0.f, 1.f, 0.f };
+
+   alListenerfv(AL_POSITION, listenerPos);
+   alListenerfv(AL_VELOCITY, listenerVel);
+   alListenerfv(AL_ORIENTATION, listenerOrientation);
+
    return true;
 }
 

+ 10 - 1
engine/source/audio/audioBuffer.cc

@@ -25,7 +25,10 @@
 #include "io/stream.h"
 #include "console/console.h"
 #include "memory/frameAllocator.h"
+
+#ifndef TORQUE_OS_IOS
 #include "vorbis/vorbisfile.h"
+#endif
 
 #ifndef _MMATH_H_
 #include "math/mMath.h"
@@ -97,6 +100,7 @@ struct WAVChunkHdr
 
 #define CHUNKSIZE 4096
 
+#ifndef TORQUE_OS_IOS
 // Ogg Vorbis
 static size_t _ov_read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
 {
@@ -135,6 +139,7 @@ static long _ov_tell_func(void *datasource)
 	Stream *stream = reinterpret_cast<Stream*>(datasource);
 	return stream->getPosition();
 }
+#endif
 
 
 //--------------------------------------
@@ -275,6 +280,7 @@ ALuint AudioBuffer::getALBuffer()
            malBuffer = bufferID;
        }
 #endif
+#ifndef TORQUE_OS_IOS
 		else if (len > 3 && !dStricmp(mFilename + len - 4, ".ogg"))
 		{
 #  ifdef LOG_SOUND_LOADS
@@ -282,6 +288,7 @@ ALuint AudioBuffer::getALBuffer()
 #  endif
 		   readSuccess = readOgg(obj);
 	   }
+#endif
 
       if(readSuccess)
          return(malBuffer);
@@ -432,6 +439,7 @@ bool AudioBuffer::readWAV(ResourceObject *obj)
    return false;
 }
 
+#ifndef TORQUE_OS_IOS
 // Read an Ogg Vorbis file from the given ResourceObject and initialize an alBuffer with it.
 // Pulled from: https://www.garagegames.com/community/forums/viewthread/136675
 bool AudioBuffer::readOgg(ResourceObject *obj)
@@ -533,4 +541,5 @@ long AudioBuffer::oggRead(OggVorbis_File* vf, char *buffer, int length, int bige
 	}
 
 	return offset;
-}
+}
+#endif

+ 2 - 0
engine/source/audio/audioBuffer.h

@@ -47,8 +47,10 @@ private:
    bool readRIFFchunk(Stream &s, const char *seekLabel, U32 *size);
    bool readWAV(ResourceObject *obj);
 
+#ifndef TORQUE_OS_IOS
    bool readOgg(ResourceObject *obj);
    long oggRead(struct OggVorbis_File* vf, char *buffer, int length, int bigendianp, int *bitstream);
+#endif
 
 public:
    AudioBuffer(StringTableEntry filename);

+ 57 - 0
engine/source/audio/audioDescriptions.cc

@@ -0,0 +1,57 @@
+#ifndef _AUDIODESCRIPTION_H_
+#include "audio/audioDescriptions.h"
+#endif
+
+#include "audio/audio.h"
+
+#include "console/consoleTypes.h"
+#include "platform/platformAL.h"
+
+IMPLEMENT_CO_DATABLOCK_V1(AudioDescription);
+
+AudioDescription::AudioDescription()
+{
+    mVolume = 1.f;  // 0-1    1=loudest volume
+    mVolumeChannel = 1;
+    mIsLooping = false;
+    mIsStreaming = false;
+
+    mIs3D = true; //The default class is used with SceneObject.Playsound
+
+    mReferenceDistance = 25.f;
+    mRollOffFactor = 5.0f;
+    mMaxDistance = 50.f;
+
+    mConeInsideAngle = 360;
+    mConeOutsideAngle = 360;
+    mConeOutsideVolume = 1.0f;
+    mConeVector = { 0.f, 0.f, 1.f };
+
+    // environment info
+    mEnvironmentLevel = 0.f;
+}
+
+void AudioDescription::initPersistFields()
+{
+    Parent::initPersistFields();
+
+    addField("Volume", TypeF32, Offset(mVolume, AudioDescription));
+    addField("VolumeChannel", TypeS32, Offset(mVolumeChannel, AudioDescription));
+    addField("isLooping", TypeBool, Offset(mIsLooping, AudioDescription));
+    addField("isStreaming", TypeBool, Offset(mIsStreaming, AudioDescription));
+
+    addField("is3D", TypeBool, Offset(mIs3D, AudioDescription));
+    addField("ReferenceDistance", TypeF32, Offset(mReferenceDistance, AudioDescription));
+    addField("RolloffFactor", TypeF32, Offset(mRollOffFactor, AudioDescription));
+    addField("MaxDistance", TypeF32, Offset(mMaxDistance, AudioDescription));
+    addField("ConeInsideAngle", TypeS32, Offset(mConeInsideAngle, AudioDescription));
+    addField("ConeOutsideAngle", TypeS32, Offset(mConeOutsideAngle, AudioDescription));
+    addField("ConeOutsideVolume", TypeF32, Offset(mConeOutsideVolume, AudioDescription));
+    addField("ConeVector", TypeF32Vector, Offset(mConeVector, AudioDescription));
+    addField("EnvironmentLevel", TypeF32, Offset(mEnvironmentLevel, AudioDescription));
+}
+
+//--------------------------------------------------------------------------
+IMPLEMENT_CONSOLETYPE(AudioDescription)
+IMPLEMENT_GETDATATYPE(AudioDescription)
+IMPLEMENT_SETDATATYPE(AudioDescription)

+ 72 - 0
engine/source/audio/audioDescriptions.h

@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _AUDIODESCRIPTION_H_
+#define _AUDIODESCRIPTION_H_
+
+#ifndef _PLATFORMAUDIO_H_
+#include "platform/platformAudio.h"
+#endif
+#ifndef _AUDIOBUFFER_H_
+#include "audio/audioBuffer.h"
+#endif
+#ifndef _BITSTREAM_H_
+#include "io/bitStream.h"
+#endif
+#ifndef _SIMBASE_H_
+#include "sim/simBase.h"
+#endif
+
+//--------------------------------------------------------------------------
+
+class AudioDescription : public SimDataBlock
+{
+    typedef SimDataBlock Parent;
+
+public:
+
+    F32  mVolume;    // 0-1    1=loudest volume
+    S32  mVolumeChannel;
+    bool mIsLooping;
+    bool mIsStreaming;
+
+    bool mIs3D;
+    F32  mReferenceDistance;
+    F32  mRollOffFactor;
+    F32  mMaxDistance;
+    S32  mConeInsideAngle;
+    S32  mConeOutsideAngle;
+    F32  mConeOutsideVolume;
+    Point3F mConeVector;
+
+    // environment info
+    F32 mEnvironmentLevel;
+
+    AudioDescription();
+
+    static void initPersistFields();
+
+    DECLARE_CONOBJECT(AudioDescription);
+};
+DECLARE_CONSOLETYPE(AudioDescription)
+
+#endif  // _H_AUDIODATABLOCK_

+ 5 - 0
engine/source/audio/audioStreamSourceFactory.cc

@@ -30,7 +30,10 @@
 #include "audio/audioStreamSourceFactory.h"
 
 #include "audio/wavStreamSource.h"
+
+#ifndef TORQUE_OS_IOS
 #include "audio/vorbisStreamSource.h"
+#endif
 
 AudioStreamSource* AudioStreamSourceFactory::getNewInstance(const char *filename)
 {
@@ -38,8 +41,10 @@ AudioStreamSource* AudioStreamSourceFactory::getNewInstance(const char *filename
 	if(len > 3 && !dStricmp(filename + len - 4, ".wav"))
 		return new WavStreamSource(filename);
 	
+#ifndef TORQUE_OS_IOS
 	if (len > 3 && !dStricmp(filename + len - 4, ".ogg"))
 		return new VorbisStreamSource(filename);
+#endif
 
 	return NULL;
 }

+ 3 - 3
engine/source/audio/audio_ScriptBinding.cc

@@ -407,7 +407,7 @@ ConsoleFunctionWithDocs(alxGetSourcef, ConsoleFloat, 3, 3, ( handle , ALEnum ))
 */
 ConsoleFunctionWithDocs(alxGetSource3f, ConsoleString, 3, 3, ( handle , ALEnum ))
 {
-   ALenum e = getEnum(argv[2], (Source|Get|Float));
+   ALenum e = getEnum(argv[2], (Source|Get|Float3));
    if(e == AL_INVALID)
    {
       Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSource3f: invalid enum name '%s'", argv[2]);
@@ -630,7 +630,7 @@ ConsoleFunctionWithDocs(alxGetListenerf, ConsoleFloat, 2, 2, ( ALEnum ))
 */
 ConsoleFunctionWithDocs(alGetListener3f, ConsoleString, 2, 2, ( ALEnum ))
 {
-   ALenum e = getEnum(argv[2], (Source|Get|Float));
+   ALenum e = getEnum(argv[1], (Source|Get|Float3));
    if(e == AL_INVALID)
    {
       Con::errorf(ConsoleLogEntry::General, "alGetListener3f: invalid enum name '%s'", argv[1]);
@@ -641,7 +641,7 @@ ConsoleFunctionWithDocs(alGetListener3f, ConsoleString, 2, 2, ( ALEnum ))
    alxGetListenerPoint3F(e, &v);
 
    char * ret = Con::getReturnBuffer(64);
-   dSprintf(ret, 64, "%7.3f %7.3 %7.3", v.x, v.y, v.z);
+   dSprintf(ret, 64, "%7.3f %7.3f %7.3f", v.x, v.y, v.z);
    return(ret);
 }
 

+ 1 - 1
engine/source/audio/vorbisStreamSource.cc

@@ -81,7 +81,7 @@ void VorbisStreamSource::clear()
       freeStream();
 
    mHandle           = NULL_AUDIOHANDLE;
-   mSource           = NULL;
+   mSource           = 0;
 
    if(mBufferList[0] != 0)
       alDeleteBuffers(NUMBUFFERS, mBufferList);

+ 2 - 1
engine/source/audio/vorbisStreamSource.h

@@ -12,9 +12,9 @@
 #include "audio/audioStreamSource.h"
 #endif
 
+#ifndef TORQUE_OS_IOS
 #include "vorbis/vorbisfile.h"
 
-
 class VorbisStreamSource: public AudioStreamSource
 {
 	public:
@@ -55,5 +55,6 @@ class VorbisStreamSource: public AudioStreamSource
 		void resetStream();
       void setNewFile(const char * file);
 };
+#endif
 
 #endif // _VORBISSTREAMSOURCE_H_

+ 1 - 1
engine/source/audio/wavStreamSource.cc

@@ -128,7 +128,7 @@ void WavStreamSource::clear()
         freeStream();
 
     mHandle           = NULL_AUDIOHANDLE;
-    mSource			  = NULL;
+    mSource			  = 0;
 
     if(mBufferList[0] != 0)
         alDeleteBuffers(NUMBUFFERS, mBufferList);

+ 255 - 0
engine/source/bitmapFont/BitmapFont.cc

@@ -0,0 +1,255 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_H_
+#include "bitmapFont/BitmapFont.h"
+#endif
+
+#ifndef _STRING_UNIT_H_
+#include "string/stringUnit.h"
+#endif
+
+#include <string>
+
+namespace font
+{
+   BitmapFont::BitmapFont()
+   {
+
+   }
+
+   bool BitmapFont::parseFont(Stream& io_rStream)
+   {
+      U32 numBytes = io_rStream.getStreamSize() - io_rStream.getPosition();
+      while ((io_rStream.getStatus() != Stream::EOS) && numBytes > 0)
+      {
+         char Read[256];
+         char Token[256];
+         char *buffer = Con::getReturnBuffer(256);
+         io_rStream.readLine((U8 *)buffer, 256);
+
+         char temp[256];
+         U32 tokenCount = StringUnit::getUnitCount(buffer, "\"");
+
+         if (tokenCount > 1)
+         {
+            dSprintf(Token, 256, "%s", StringUnit::getUnit(buffer, 1, "\""));
+            dSprintf(temp, 256, "tok1");
+            dSprintf(buffer, 256, "%s", (char*)StringUnit::setUnit(buffer, 1, temp, "\""));
+         }
+
+         U32 wordCount = StringUnit::getUnitCount(buffer, " \t\n");
+
+         dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, 0, " \t\n"));
+         if (dStrcmp(Read, "info") == 0)
+         {
+            U32 currentWordCount = 1;
+            while (currentWordCount < wordCount)
+            {
+               dSprintf(Read, 256, StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+               char temp[256];
+               char Key[256];
+               char Value[256];
+
+               dSprintf(temp, 256, "%s", Read);
+               dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+               dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+
+               if (dStrcmp(Value, "\"tok1\"") == 0) {
+                  dSprintf(Value, 256, "%s", Token);
+               }
+
+               if (dStrcmp(Key, "size") == 0)
+                  mSize = U16(dAtoi(Value));
+               currentWordCount++;
+            }
+         }
+         if (dStrcmp(Read, "common") == 0)
+         {
+            //this holds common data
+            U32 currentWordCount = 1;
+            while (currentWordCount < wordCount)
+            {
+               dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+               char temp[256];
+               char Key[256];
+               char Value[256];
+
+               dSprintf(temp, 256, "%s", Read);
+               dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+               dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+
+               if (dStrcmp(Value, "\"tok1\"") == 0) {
+                  dSprintf(Value, 256, "%s", Token);
+               }
+
+               if (dStrcmp(Key, "lineHeight") == 0)
+                  mLineHeight = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "base") == 0)
+                  mBaseline = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "scaleW") == 0)
+                  mWidth = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "scaleH") == 0)
+                  mHeight = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "pages") == 0)
+                  mPages = U16(dAtoi(Value));
+               currentWordCount++;
+            }
+         }
+         else if (dStrcmp(Read, "page") == 0)
+         {
+            //this is data for a page
+            U32 currentWordCount = 1;
+            while (currentWordCount < wordCount)
+            {
+               dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+               char temp[256];
+               char Key[256];
+               char Value[256];
+
+               dSprintf(temp, 256, "%s", Read);
+               dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+               dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+
+               if (dStrcmp(Value, "\"tok1\"") == 0) {
+                  dSprintf(Value, 256, "%s", Token);
+               }
+
+               //assign the correct value
+               if (dStrcmp(Key, "file") == 0)
+               {
+                  mPageName.push_back(StringTable->insert(Value));
+               }
+
+               currentWordCount++;
+            }
+         }
+         else if (dStrcmp(Read, "char") == 0 && dStrcmp(Read, "chars") != 0)
+         {
+            //this is data for a character
+            BitmapFontCharacter ci;
+            U16 CharID = 0;
+            U32 currentWordCount = 1;
+            while (currentWordCount < wordCount)
+            {
+               dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+               char temp[256];
+               char Key[256];
+               char Value[256];
+
+
+               dSprintf(temp, 256, "%s", Read);
+               dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+               dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+
+               if (dStrcmp(Value, "\"tok1\"") == 0) {
+                  dSprintf(Value, 256, "%s", Token);
+               }
+
+               //assign the correct value
+               if (dStrcmp(Key, "id") == 0)
+                  CharID = U32(dAtoi(Value));
+               else if (dStrcmp(Key, "x") == 0)
+                  ci.mX = U32(dAtoi(Value));
+               else if (dStrcmp(Key, "y") == 0)
+                  ci.mY = U32(dAtoi(Value));
+               else if (dStrcmp(Key, "width") == 0)
+                  ci.mWidth = U32(dAtoi(Value));
+               else if (dStrcmp(Key, "height") == 0)
+                  ci.mHeight = U32(dAtoi(Value));
+               else if (dStrcmp(Key, "xoffset") == 0)
+                  ci.mXOffset = F32(dAtoi(Value));
+               else if (dStrcmp(Key, "yoffset") == 0)
+                  ci.mYOffset = F32(dAtoi(Value));
+               else if (dStrcmp(Key, "xadvance") == 0)
+                  ci.mXAdvance = F32(dAtoi(Value));
+               else if (dStrcmp(Key, "page") == 0)
+                  ci.mPage = S32(dAtoi(Value));
+               currentWordCount++;
+            }
+            ci.mCharID = CharID;
+            ci.ProcessCharacter(mWidth, mHeight);
+            mChar[CharID] = ci;
+         }
+         else if (dStrcmp(Read, "kerning") == 0 && dStrcmp(Read, "kernings") != 0)
+         {
+            //this is data for a kerning pair
+            U16 first = 0;
+            U16 second = 0;
+            S16 amount = 0;
+            U32 currentWordCount = 1;
+            while (currentWordCount < wordCount)
+            {
+               dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+               char temp[256];
+               char Key[256];
+               char Value[256];
+
+
+               dSprintf(temp, 256, "%s", Read);
+               dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+               dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+
+               if (dStrcmp(Value, "\"tok1\"") == 0) {
+                  dSprintf(Value, 256, "%s", Token);
+               }
+
+               //assign the correct value
+               if (dStrcmp(Key, "first") == 0)
+                  first = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "second") == 0)
+                  second = U16(dAtoi(Value));
+               else if (dStrcmp(Key, "amount") == 0)
+                  amount = S16(dAtoi(Value));
+               
+               currentWordCount++;
+            }
+            AddKerning(first, second, amount);
+         }
+      }
+
+      return (io_rStream.getStatus() == Stream::EOS);
+   }
+
+   TextureHandle BitmapFont::LoadTexture(StringTableEntry fileName)
+   {
+      // Debug Profiling.
+      PROFILE_SCOPE(FontAsset_LoadTexture);
+
+      // Get image texture.
+      TextureHandle mImageTextureHandle;
+      mImageTextureHandle.set(fileName, TextureHandle::BitmapTexture, true, false);
+
+      // Is the texture valid?
+      if (mImageTextureHandle.IsNull())
+      {
+         // No, so warn.
+         Con::warnf("FontAsset could not load texture '%s'.", fileName);
+         return mImageTextureHandle;
+      }
+
+      //Set the filter mode. For now we'll just support bilinear. In the future we should give the user an option.
+      mImageTextureHandle.setFilter(GL_LINEAR);
+
+      return mImageTextureHandle;
+   }
+}

+ 75 - 0
engine/source/bitmapFont/BitmapFont.h

@@ -0,0 +1,75 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_H_
+#define _BITMAP_FONT_H_
+
+#ifndef _BITMAP_FONT_CHARACTER_H_
+#include "bitmapFont/BitmapFontCharacter.h"
+#endif
+
+#ifndef _UTILITY_H_
+#include "2d/core/Utility.h"
+#endif
+
+#ifndef _TEXTURE_MANAGER_H_
+#include "graphics/TextureManager.h"
+#endif
+
+using namespace std;
+#include <map>
+#include <string>
+#include <vector>
+using KerningMap = map<pair<U16, U16>, S16>;
+using CharacterMap = map<U16, font::BitmapFontCharacter>;
+
+namespace font
+{
+   class BitmapFont
+   {
+   private:
+      U16 mWidth, mHeight;
+      U16 mPages;
+
+      CharacterMap mChar;       
+      KerningMap mKerning;
+
+   public:
+      U16 mLineHeight;
+      U16 mBaseline;
+      U16 mSize;
+      std::vector<StringTableEntry> mPageName;
+      std::vector<TextureHandle> mTexture;
+
+      BitmapFont();
+      bool parseFont(Stream& io_rStream);
+      TextureHandle LoadTexture(StringTableEntry fileName);
+      const BitmapFontCharacter& getCharacter(const U16 charID) { return mChar[charID]; }
+      inline const F32 getSizeRatio(const F32 size) { return size / mLineHeight; }
+      inline const S16 getKerning(U16 first, U16 second) { return (S16)mKerning[make_pair(first, second)]; }
+
+   private:
+      inline void AddKerning(U16 first, U16 second, S16 amount) { mKerning[make_pair(first, second)] = amount; }
+   };
+}
+
+#endif // _BITMAP_FONT_H_

+ 46 - 0
engine/source/bitmapFont/BitmapFontCharacter.cc

@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_CHARACTER_H_
+#include "bitmapFont/BitmapFontCharacter.h"
+#endif
+
+namespace font
+{
+   void BitmapFontCharacter::ProcessCharacter(U16 width, U16 height)
+   {
+      F32 top, right, bottom, left;
+
+      bottom = (F32)mY / height;
+      top = (F32)(mY + mHeight) / height;
+
+      left = (F32)mX / width;
+      right = (F32)(mX + mWidth) / width;
+
+      mOOBB[0] = Vector2(left, top);
+      mOOBB[1] = Vector2(right, top);
+      mOOBB[2] = Vector2(right, bottom);
+      mOOBB[3] = Vector2(left, bottom);
+      mPageWidth = width;
+      mPageHeight = height;
+   }
+}

+ 57 - 0
engine/source/bitmapFont/BitmapFontCharacter.h

@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_CHARACTER_H_
+#define _BITMAP_FONT_CHARACTER_H_
+
+#ifndef _UTILITY_H_
+#include "2d/core/Utility.h"
+#endif
+
+#ifndef _VECTOR2_H_
+#include "2d/core/Vector2.h"
+#endif
+
+namespace font
+{
+   class BitmapFontCharacter
+   {
+   public:
+      U16 mCharID;
+      U16 mX, mY;
+      U16 mWidth, mHeight;
+      F32 mXOffset, mYOffset;
+      F32 mXAdvance;
+      U16 mPage;
+      U16 mPageWidth, mPageHeight;
+      Vector2 mOOBB[4];
+
+      BitmapFontCharacter() : mX(0), mY(0), mWidth(0), mHeight(0), mXOffset(0), mYOffset(0), mXAdvance(0), mPage(0)
+      {
+
+      }
+
+      void ProcessCharacter(U16 width, U16 height);
+   };
+}
+
+#endif // _BITMAP_FONT_CHARACTER_H_

+ 61 - 0
engine/source/bitmapFont/BitmapFontCharacterInfo.h

@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_CHARACTER_INFO_H_
+#define _BITMAP_FONT_CHARACTER_INFO_H_
+
+#ifndef _UTILITY_H_
+#include "2d/core/utility.h"
+#endif
+
+#ifndef _COLOR_H_
+#include "graphics/color.h"
+#endif
+
+namespace font
+{
+   struct BitmapFontCharacterInfo
+   {
+   public:
+      bool mUseColor;
+      ColorF mColor;
+      F32 mOffsetX;
+      F32 mOffsetY;
+      F32 mScaleX;
+      F32 mScaleY;
+
+      BitmapFontCharacterInfo() : mUseColor(false), mColor(1.0f, 1.0f, 1.0f, 1.0f), mOffsetX(0.0f), mOffsetY(0.0f), mScaleX(1.0f), mScaleY(1.0f)
+      {
+
+      }
+
+      BitmapFontCharacterInfo(ColorF color) : mOffsetX(0.0f), mOffsetY(0.0f), mScaleX(1.0f), mScaleY(1.0f)
+      {
+         mColor = color;
+         mUseColor = true;
+      }
+
+      inline bool isDefault() { return (!mUseColor && mOffsetX == 0.0f && mOffsetY == 0.0f && mScaleX == 1.0f && mScaleY == 1.0f); }
+   };
+}
+
+#endif // _BITMAP_FONT_CHARACTER_INFO_H_

+ 51 - 0
engine/source/bitmapFont/BitmapFontLineInfo.h

@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_LINE_INFO_H_
+#define _BITMAP_FONT_LINE_INFO_H_
+
+#ifndef _UTILITY_H_
+#include "2d/core/utility.h"
+#endif
+
+namespace font
+{
+   struct BitmapFontLineInfo
+   {
+   public:
+      U32 mStart;
+      U32 mEnd;
+      F32 mLength;
+
+      BitmapFontLineInfo() : mStart(0), mEnd(0), mLength(0.0f)
+      {
+
+      }
+
+      BitmapFontLineInfo(U32 start)
+      {
+         mStart = start;
+      }
+   };
+}
+
+#endif // _BITMAP_FONT_LINE_INFO_H_

+ 1 - 1
engine/source/collection/nameTags_ScriptBinding.h

@@ -80,7 +80,7 @@ ConsoleMethodWithDocs(NameTags, deleteTag, ConsoleInt, 3, 3, (tagId))
     if ( tagId == 0 )
     {
         Con::warnf("Invalid tag Id.\n");
-        return NULL;
+        return 0;
     }
 
     return object->deleteTag( tagId );

+ 1 - 1
engine/source/delegates/delegateSignal.h

@@ -54,7 +54,7 @@ public:
    {
       mList.next = mList.prev = &mList;
       mList.order = 0.5f;
-      mTriggerNext = NULL;
+      //mTriggerNext = NULL;
    }
 
    ~SignalBase();

+ 1 - 1
engine/source/gui/guiCanvas_ScriptBinding.h

@@ -256,7 +256,7 @@ ConsoleMethodWithDocs( GuiCanvas, getMouseControl, ConsoleInt, 2, 2, ())
    if (control)
       return control->getId();
    
-   return NULL;
+   return 0;
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 1
engine/source/persistence/taml/json/tamlJSONReader.cc

@@ -45,7 +45,7 @@ SimObject* TamlJSONReader::read( FileStream& stream )
         Con::warnf("TamlJSONReader::read() -  Could not load Taml JSON file from stream.");
         return NULL;
     }
-    jsonText[streamSize] = NULL;
+    jsonText[streamSize] = '\0';
 
     // Create JSON document.
     rapidjson::Document document;

+ 1 - 0
engine/source/platform/platformAudio.h

@@ -86,6 +86,7 @@ class AudioStreamSource;
 AUDIOHANDLE alxCreateSource(const Audio::Description *desc, const char *filename, const MatrixF *transform=NULL, AudioSampleEnvironment * sampleEnvironment = 0);
 AUDIOHANDLE alxCreateSource(AudioDescription *descObject, const char *filename, const MatrixF *transform=NULL, AudioSampleEnvironment * sampleEnvironment = 0);
 AUDIOHANDLE alxCreateSource(const AudioAsset *profile, const MatrixF *transform=NULL);
+AUDIOHANDLE alxCreateSource_AD(const AudioAsset *profile, const AudioDescription* description, const MatrixF *transform);
 AudioStreamSource* alxFindAudioStreamSource(AUDIOHANDLE handle);
 
 AUDIOHANDLE alxPlay(AUDIOHANDLE handle);

+ 9 - 0
engine/source/platform/platformVideo.cc

@@ -465,6 +465,15 @@ bool Video::setGammaCorrection(F32 g)
    return false;	
 }
 
+//------------------------------------------------------------------------------
+bool Video::getVerticalSync()
+{
+    if (smCurrentDevice)
+        return smCurrentDevice->getVerticalSync();
+    
+    return( false );
+}
+
 //------------------------------------------------------------------------------
 bool Video::setVerticalSync( bool on )
 {

+ 3 - 1
engine/source/platform/platformVideo.h

@@ -76,6 +76,7 @@ public:
    static void swapBuffers();                         // page flip
    static bool getGammaCorrection(F32 &g);            // get gamma correction
    static bool setGammaCorrection(F32 g);             // set gamma correction
+   static bool getVerticalSync();                     // get current state of vertical sync
    static bool setVerticalSync( bool on );            // enable/disable vertical sync
 };
 
@@ -129,9 +130,10 @@ class DisplayDevice
       virtual bool setResolution( U32 width, U32 height, U32 bpp );
       virtual bool toggleFullScreen();
       virtual void swapBuffers() = 0;
-     virtual const char* getDriverInfo() = 0;
+      virtual const char* getDriverInfo() = 0;
       virtual bool getGammaCorrection(F32 &g) = 0;
       virtual bool setGammaCorrection(F32 g) = 0;
+      virtual bool getVerticalSync() = 0;
       virtual bool setVerticalSync( bool on ) = 0;
 
       bool prevRes();

+ 8 - 0
engine/source/platform/platformVideo_ScriptBinding.h

@@ -254,6 +254,14 @@ ConsoleFunctionWithDocs(videoSetGammaCorrection, ConsoleVoid, 2, 2, ( gamma ))
     sgGammaCorrection = d;
 }
 
+/*! Use the getVerticalSync function to determine if the application's framerate is currently synchronized to the vertical refresh rate.
+@return Returns true if Vertical sync is enabled, false otherwise
+*/
+ConsoleFunctionWithDocs(getVerticalSync, ConsoleBool, 1, 1, "")
+{
+    return(Video::getVerticalSync());
+}
+
 /*! Use the setVerticalSync function to force the framerate to sync up with the vertical refresh rate.
     This is used to reduce excessive swapping/rendering. There is generally no purpose in rendering any faster than the monitor will support. Those extra 'ergs' can be used for something else
     @param enable A boolean value. If set to true, the engine will only swap front and back buffers on or before a vertical refresh pass.

+ 0 - 80
engine/source/platform/typesLinux.h

@@ -1,80 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _TYPESLINUX_H_
-#define _TYPESLINUX_H_
-
-/* eek. */
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define PLATFORM_LITTLE_ENDIAN
-
-#define FN_CDECL
-
-typedef signed char     	S8;
-typedef unsigned char   	U8;
-
-typedef signed short    	S16;
-typedef unsigned short  	U16;
-
-typedef signed int      	S32;
-typedef unsigned int    	U32;
-
-typedef signed long long        S64;
-typedef unsigned long long      U64;
-
-typedef float           	F32;
-typedef double          	F64;
-
-typedef unsigned int dsize_t;
-
-typedef const char* StringTableEntry;
-
-typedef S32 FileTime;
-
-#define __EQUAL_CONST_F F32(0.000001)
-
-static const F32 Float_One  = F32(1.0);
-static const F32 Float_Half = F32(0.5);
-static const F32 Float_Zero = F32(0.0);
-static const F32 Float_Pi   = F32(3.14159265358979323846);
-static const F32 Float_2Pi  = F32(2.0 * 3.14159265358979323846);
-
-static const S8  S8_MIN  = S8(-128);
-static const S8  S8_MAX  = S8(127);
-static const U8  U8_MAX  = U8(255);
-
-static const S16 S16_MIN = S16(-32768);
-static const S16 S16_MAX = S16(32767);
-static const U16 U16_MAX = U16(65535);
-
-static const S32 S32_MIN = S32(-2147483647 - 1);
-static const S32 S32_MAX = S32(2147483647);
-static const U32 U32_MAX = U32(0xffffffff);
-
-static const F32 F32_MAX = F32(3.402823466e+38F);
-static const F32 F32_MIN = F32(1.175494351e-38F);
-
-
-#endif

+ 0 - 80
engine/source/platform/typesX86UNIX.h

@@ -1,80 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _TYPESX86UNIX_H_
-#define _TYPESX86UNIX_H_
-
-/* eek. */
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define PLATFORM_LITTLE_ENDIAN
-
-#define FN_CDECL
-
-typedef signed char     	S8;
-typedef unsigned char   	U8;
-
-typedef signed short    	S16;
-typedef unsigned short  	U16;
-
-typedef signed int      	S32;
-typedef unsigned int    	U32;
-
-typedef signed long long        S64;
-typedef unsigned long long      U64;
-
-typedef float           	F32;
-typedef double          	F64;
-
-typedef unsigned int dsize_t;
-
-typedef const char* StringTableEntry;
-
-typedef S32 FileTime;
-
-#define __EQUAL_CONST_F F32(0.000001)
-
-static const F32 Float_One  = F32(1.0);
-static const F32 Float_Half = F32(0.5);
-static const F32 Float_Zero = F32(0.0);
-static const F32 Float_Pi   = F32(3.14159265358979323846);
-static const F32 Float_2Pi  = F32(2.0 * 3.14159265358979323846);
-
-static const S8  S8_MIN  = S8(-128);
-static const S8  S8_MAX  = S8(127);
-static const U8  U8_MAX  = U8(255);
-
-static const S16 S16_MIN = S16(-32768);
-static const S16 S16_MAX = S16(32767);
-static const U16 U16_MAX = U16(65535);
-
-static const S32 S32_MIN = S32(-2147483647 - 1);
-static const S32 S32_MAX = S32(2147483647);
-static const U32 U32_MAX = U32(0xffffffff);
-
-static const F32 F32_MAX = F32(3.402823466e+38F);
-static const F32 F32_MIN = F32(1.175494351e-38F);
-
-
-#endif

+ 3 - 3
engine/source/platformAndroid/AndroidEvents.h

@@ -54,7 +54,7 @@ bool AndroidHandleMenuCommand(void* hiCommand);
 void AndroidSendTorqueEventToMain( U32 eventKind, void* userData = NULL );
 
 /// event type for alerts. The event class is an arbitrary val, it must not collide w/ kEventApp* .
-const U32 kEventClassTorque   = 'TORQ';
+const U32 kEventClassTorque   = ('T' * 0x1000000 + 'O' * 0x10000 + 'R' * 0x100 + 'Q'); //'TORQ';
 const U32 kEventTorqueAlert   = 1;
 const U32 kEventTorqueFadeInWindow = 2;
 const U32 kEventTorqueFadeOutWindow = 3;
@@ -63,7 +63,7 @@ const U32 kEventTorqueShowMenuBar = 5;
 const U32 kEventTorqueModalDialog = 6;
 const U32 kEventTorqueDrawMenuBar = 7;
 
-const U32 kEventParamTorqueData           = 'tDAT'; // typeVoidPtr void*
+const U32 kEventParamTorqueData           = ('t' * 0x1000000 + 'D' * 0x10000 + 'A' * 0x100 + 'T'); //'tDAT'; // typeVoidPtr void*
 //const U32 kEventParamTorqueSemaphorePtr   = 'tSEM'; // typeVoidPtr void*
 //const U32 kEventParamTorqueDialogRef      = 'tDRF'; // typeDialogRef DialogRef
 //const U32 kEventParamTorqueHitPtr         = 'tHIT'; // typeVoidPtr U32*
@@ -71,6 +71,6 @@ const U32 kEventParamTorqueData           = 'tDAT'; // typeVoidPtr void*
 
 
 // this command id is used for all dynamically created menus.
-const U32 kHICommandTorque = 'TORQ';
+const U32 kHICommandTorque = ('T' * 0x1000000 + 'O' * 0x10000 + 'R' * 0x100 + 'Q'); //'TORQ';
 
 #endif

+ 6 - 0
engine/source/platformAndroid/AndroidOGLVideo.cpp

@@ -259,6 +259,12 @@ bool OpenGLDevice::setGammaCorrection(F32 g)
     return true;
 }
 
+//------------------------------------------------------------------------------
+bool OpenGLDevice::getVerticalSync()
+{
+    return true;
+}
+
 //------------------------------------------------------------------------------
 bool OpenGLDevice::setVerticalSync(bool on)
 {

+ 1 - 0
engine/source/platformAndroid/AndroidOGLVideo.h

@@ -51,6 +51,7 @@ public:
     const char* getDriverInfo();
     bool getGammaCorrection(F32 &g);
     bool setGammaCorrection(F32 g);
+    bool getVerticalSync();
     bool setVerticalSync( bool on );
 };
 

+ 1 - 1
engine/source/platformAndroid/AndroidProcessControl.cpp

@@ -38,7 +38,7 @@ void Platform::postQuitMessage(const U32 in_quitVal)
 
 void Platform::debugBreak()
 {
-   Platform::outputDebugString((const char *)"\pDEBUG_BREAK!");
+   Platform::outputDebugString((const char *)"DEBUG_BREAK!");
 }
 
 void Platform::forceShutdown(S32 returnValue)

+ 2 - 0
engine/source/platformOSX/osxOpenGLDevice.h

@@ -73,6 +73,8 @@ public:
     
     bool setGammaCorrection(F32 g);
     
+    bool getVerticalSync();
+    
     bool setVerticalSync( bool sync );
     
 };

+ 14 - 0
engine/source/platformOSX/osxOpenGLDevice.mm

@@ -407,6 +407,20 @@ bool osxOpenGLDevice::setGammaCorrection(F32 g)
 
 //-----------------------------------------------------------------------------
 
+bool osxOpenGLDevice::getVerticalSync()
+{
+    if (!gGLState.suppSwapInterval)
+    {
+        return false;
+    }
+    
+    //Note that this returns the number of frames between Swaps.
+    //The function returns 0 / false if SwapInterval has not been specified.
+    return getVerticalSync();
+}
+
+//-----------------------------------------------------------------------------
+
 bool osxOpenGLDevice::setVerticalSync( bool sync )
 {
     if ([[platState torqueView] contextInitialized])

+ 15 - 0
engine/source/platformOSX/osxTorqueView.mm

@@ -165,6 +165,21 @@
         [_openGLContext flushBuffer];
 }
 
+//-----------------------------------------------------------------------------
+- (int)getVerticalSync
+{
+    if (_openGLContext != nil)
+    {
+        GLint swapInterval = 0;
+        [_openGLContext getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+        return swapInterval;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
 //-----------------------------------------------------------------------------
 - (void)setVerticalSync:(bool)sync
 {

+ 11 - 0
engine/source/platformWin32/winOGLVideo.cc

@@ -646,6 +646,17 @@ bool OpenGLDevice::setGammaCorrection(F32 g)
    return SetDeviceGammaRamp(winState.appDC, ramp);
 }
 
+//------------------------------------------------------------------------------
+bool OpenGLDevice::getVerticalSync()
+{
+    if ( !gGLState.suppSwapInterval )
+        return( false );
+
+    //Note that dwglGetSwapIntervalEXT returns the number of frames between Swaps.
+    //The function returns 0 / false if SwapInterval has not been specified.
+    return (dwglGetSwapIntervalEXT());
+}
+
 //------------------------------------------------------------------------------
 bool OpenGLDevice::setVerticalSync( bool on )
 {

+ 1 - 0
engine/source/platformWin32/winOGLVideo.h

@@ -55,6 +55,7 @@ public:
    const char* getDriverInfo();
    bool getGammaCorrection(F32 &g);
    bool setGammaCorrection(F32 g);
+   bool getVerticalSync();
    bool setVerticalSync( bool on );
 
    static DisplayDevice* create();

+ 0 - 26
engine/source/platformWin32/winWindow.cc

@@ -74,32 +74,6 @@ extern U16  DIK_to_Key( U8 dikCode );
 
 Win32PlatState winState;
 
-
-//-----------------------------------------------------------------------------------------------------------------------------------------------------------
-//
-// Microsoft Layer for Unicode
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mslu/winprog/compiling_your_application_with_the_microsoft_layer_for_unicode.asp
-//
-//-----------------------------------------------------------------------------------------------------------------------------------------------------------
-#ifdef UNICODE
-
-HMODULE LoadUnicowsProc(void)
-{
-   return(LoadLibraryA("unicows.dll"));
-}
-
-#ifdef _cplusplus
-extern "C" {
-#endif
-   extern FARPROC _PfnLoadUnicows = (FARPROC) &LoadUnicowsProc;
-#ifdef _cplusplus
-}
-#endif
-
-#endif
-
-
-
 //--------------------------------------
 Win32PlatState::Win32PlatState()
 {

+ 13 - 0
engine/source/platformX86UNIX/x86UNIXOGLVideo.cc

@@ -488,6 +488,19 @@ bool OpenGLDevice::setGammaCorrection(F32 g)
    return ok != -1;
 }
 
+//------------------------------------------------------------------------------
+bool OpenGLDevice::getVerticalSync()
+{
+   Con::printf("WARNING: OpenGLDevice::getVerticalSync is unimplemented %s %d\n", __FILE__, __LINE__);
+   return false;
+#if 0
+    if ( !gGLState.suppSwapInterval )
+        return( false );
+
+    return (qwglGetSwapIntervalEXT());
+#endif
+}
+
 //------------------------------------------------------------------------------
 bool OpenGLDevice::setVerticalSync( bool on )
 {

+ 2 - 1
engine/source/platformX86UNIX/x86UNIXOGLVideo.h

@@ -42,7 +42,7 @@ class OpenGLDevice : public DisplayDevice
       OpenGLDevice();
       virtual ~OpenGLDevice();
 
-      void initDevice();
+      virtual void initDevice();
       bool activate( U32 width, U32 height, U32 bpp, bool fullScreen );
       void shutdown();
       void destroy();
@@ -51,6 +51,7 @@ class OpenGLDevice : public DisplayDevice
       const char* getDriverInfo();
       bool getGammaCorrection(F32 &g);
       bool setGammaCorrection(F32 g);
+      bool getVerticalSync();
       bool setVerticalSync( bool on );
       void loadResolutions();
 

+ 1 - 0
engine/source/platformiOS/iOSOGLVideo.h

@@ -54,6 +54,7 @@ public:
     const char* getDriverInfo();
     bool getGammaCorrection(F32 &g);
     bool setGammaCorrection(F32 g);
+    bool getVerticalSync( );
     bool setVerticalSync( bool on );
 };
 

+ 6 - 0
engine/source/platformiOS/iOSOGLVideo.mm

@@ -261,6 +261,12 @@ bool OpenGLDevice::setGammaCorrection(F32 g)
     return true;
 }
 
+//------------------------------------------------------------------------------
+bool OpenGLDevice::getVerticalSync()
+{
+    return true;
+}
+
 //------------------------------------------------------------------------------
 bool OpenGLDevice::setVerticalSync(bool on)
 {

+ 1 - 4
engine/source/sim/simObject.cc

@@ -622,11 +622,8 @@ const char *SimObject::getPrefixedDataField(StringTableEntry fieldName, const ch
     // Fetch field value.
     const char* pFieldValue = getDataField( fieldName, array );
 
-    // Sanity.
-    AssertFatal( pFieldValue != NULL, "Field value cannot be NULL." );
-
     // Return without the prefix if there's no value.
-    if ( *pFieldValue == 0 )
+    if ( pFieldValue == NULL || *pFieldValue == 0 )
         return StringTable->EmptyString;
 
     // Fetch the field prefix.

+ 1 - 1
engine/source/string/stringBuffer.cc

@@ -384,7 +384,7 @@ void StringBuffer::getCopy(UTF16 *buff, const U32 buffSize) const
    AssertFatal(mBuffer.last() == 0, "StringBuffer::get UTF8 - not a null terminated string!");
    dMemcpy(buff, mBuffer.address(), sizeof(UTF16) * getMin(buffSize, (U32)mBuffer.size()));
    // ensure null termination.
-   buff[buffSize-1] = NULL;
+   buff[buffSize-1] = '\0';
 }
 
 UTF8* StringBuffer::createCopy8() const

+ 0 - 77
modules/ImageFontToy/1/main.cs

@@ -1,77 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-function ImageFontToy::create( %this )
-{
-    // Reset the toy.    
-    ImageFontToy.reset();
-}
-
-//-----------------------------------------------------------------------------
-
-function ImageFontToy::destroy( %this )
-{
-}
-
-//-----------------------------------------------------------------------------
-
-function ImageFontToy::reset( %this )
-{
-    // Clear the scene.
-    SandboxScene.clear();
-            
-    // Create the image font.
-    %object = new ImageFont();
-    
-    // Always try to configure a scene-object prior to adding it to a scene for best performance.
-    
-    // Set the image font to use the font image asset.
-    %object.Image = "ToyAssets:Font";
-    
-    // We don't really need to do this as the position is set to zero by default.
-    %object.Position = "0 0";
-    
-    // We don't need to size this object as it sizes automatically according to the alignment, font-size and text.
-   
-    // Set the font size in both axis.  This is in world-units and not typicaly font "points".
-    %object.FontSize = "2 2";
-    
-    // We don't really need to do this as the padding is set to zero by default.
-    // Padding is specified in world-units and relates to the space added between each character.
-    %object.FontPadding = 0;
-
-    // Set the text alignment.
-    %object.TextAlignment = "Center";
-
-    // Set the text to display.
-    %object.Text = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`~abcdefghijklmnopqrstuvwxyz";
-
-    // Make the text spin just to make it more interesting!
-    %object.AngularVelocity = 30;
-    
-    // The ImageFont is a type that defaults to a "static" body-type (typically so it's not affected by gravity)
-    // but we want this to spin so we need a "dynamic" body-type/
-    %object.BodyType = "dynamic";
-    
-    // Add the sprite to the scene.
-    SandboxScene.add( %object );    
-}

+ 251 - 0
modules/TextSpriteToy/1/main.cs

@@ -0,0 +1,251 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+function TextSpriteToy::create( %this )
+{
+    // Reset the toy.
+    TextSpriteToy.reset();
+}
+
+//-----------------------------------------------------------------------------
+
+function TextSpriteToy::destroy( %this )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+function TextSpriteToy::reset( %this )
+{
+    // Clear the scene.
+    SandboxScene.clear();
+
+    //Title
+    new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:TrajanProFont";
+        FontSize = 6.5;
+        Text = "Presenting the TextSprite!";
+        Position = "0 30";
+        Size = "90 7";
+        OverflowModeX = "visible";
+        TextAlignment = "center";
+        BlendColor = "0.2 0.5 1 1";
+    };
+
+    //Opening Description
+    new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:ArialFont";
+        FontSize = 3;
+        Text = "The TextSprite takes a FontAsset which directly loads a bitmap font file, so adding a new font is super easy! The TextSprite let's you align the text to the left, right, center or even justified. It can also be vertically aligned to the top, middle, or bottom. There's multiple overflow options including automatically shrinking text fit the box. Finally, you can control the color, offset, and scale of each character individually! Check out these examples!";
+        Position = "0 19";
+        Size = "90 15";
+        OverflowModeY = "visible";
+        BlendColor = "1 1 1 0.8";
+    };
+
+    %example1 = new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:OratorBoldFont";
+        FontSize = 5;
+        Text = "You can make any letter big or small!";
+        Position = "-30 -8";
+        Size = "24 24";
+        BlendColor = "1 1 1 1";
+    };
+
+    for(%i = 24; %i <= 26; %i++)
+    {
+        %example1.setCharacterScale(%i, "1.7 2");
+    }
+
+    for(%i = 31; %i <= 35; %i++)
+    {
+        %example1.setCharacterScale(%i, "0.8 0.6");
+    }
+
+    %example2 = new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:TrajanProFont";
+        FontSize = 4.3;
+        Text = "Don't be boring! Add some COLOR and let it spin!";
+        Position = "0 -5";
+        Size = "24 24";
+        BlendColor = "1 1 1 1";
+        AngularVelocity = 30;
+        TextAlignment = "center";
+        TextVAlignment = "middle";
+        autoLineHeight = false;
+        customLineHeight = 3.8;
+    };
+    %example2.setCharacterBlendColor(26, "1 0 0 1");
+    %example2.setCharacterBlendColor(27, "1 0.5 0 1");
+    %example2.setCharacterBlendColor(28, "1 1 0 1");
+    %example2.setCharacterBlendColor(29, "0.2 1 0.2 1");
+    %example2.setCharacterBlendColor(30, "0 0.2 1 1");
+
+    %example3 = new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:ArialFont";
+        FontSize = 3.5;
+        Text = "With a little work you can get your text to jump out at your readers!";
+        Position = "30 -8";
+        Size = "24 24";
+        BlendColor = "1 1 1 1";
+        TextAlignment = "right";
+        TextVAlignment = "bottom";
+        Class = "JumpingText";
+        start = 44;
+        end = 47;
+        jumpSpeed = 0;
+        letterHeight = 0;
+        UpdateCallback = true;
+        autoLineHeight = false;
+        customLineHeight = 6;
+    };
+
+    %example4 = new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:ArialFont";
+        FontSize = 3.7;
+        Text = "You could build a dialog box that shows one letter at a time!";
+        Position = "-24 -27";
+        Size = "45 10";
+        OverflowModeY = "visible";
+        BlendColor = "1 1 1 0";
+        Class = "DialogText";
+        pen = 0;
+    };
+    %example4.showLetter();
+
+    %example5 = new TextSprite()
+    {
+        Scene = SandboxScene;
+        Font = "ToyAssets:OratorBoldFont";
+        FontSize = 3.4;
+        Text = "AJDIORQNAKMAKENZCBADTWOLFJEI PEPWQFDNWORDFHISUDFBHAKLSBLH RUEBNAJDUIOQPSEARCHUIRDFBUYJ MBPIRATEIDBGVMCODEWHTKEIAVIE";
+        Position = "24 -25.5";
+        Size = "45 10";
+        OverflowModeY = "visible";
+        BlendColor = "1 1 1 1";
+        Class = "WordSearchText";
+    };
+    %example5.setCharacterBlendColor(4, "1 1 1 1");
+    %example5.setCharacterBlendColor(5, "1 1 1 1");
+    for(%i = 10; %i <= 13; %i++)
+    {
+        %example5.setCharacterBlendColor(%i, "1 1 1 1");
+    }
+    %example5.setCharacterBlendColor(18, "1 1 1 1");
+    for(%i = 37; %i <= 40; %i++)
+    {
+        %example5.setCharacterBlendColor(%i, "1 1 1 1");
+    }
+    for(%i = 71; %i <= 76; %i++)
+    {
+        %example5.setCharacterBlendColor(%i, "1 1 1 1");
+    }
+    %example5.schedule(6000, "fadeOut");
+}
+
+//-----------------------------------------------------------------------------
+
+function JumpingText::onUpdate(%this)
+{
+    if(%this.jumpSpeed == 0 && %this.letterHeight == 0)
+    {
+        //jump again!
+        %this.jumpSpeed = 0.7;
+    }
+
+    %this.letterHeight += %this.jumpSpeed;
+    if(%this.jumpSpeed > 0)
+    {
+        %this.jumpSpeed *= 0.8;
+        if(%this.jumpSpeed < 0.1)
+        {
+            %this.jumpSpeed = -0.1;
+        }
+    }
+    else if(%this.jumpSpeed < 0)
+    {
+        %this.jumpSpeed *= 1.2;
+        if(%this.letterHeight < 0)
+        {
+            %this.letterHeight = 0;
+            %this.jumpSpeed = 0;
+            %this.setUpdateCallback(false);
+            %this.schedule(1000, "setUpdateCallback", true);
+        }
+    }
+
+    for(%i = %this.start; %i <= %this.end; %i++)
+    {
+        %this.setCharacterOffset(%i, "0" SPC %this.letterHeight);
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+function DialogText::showLetter(%this)
+{
+    if(%this.pen == 0)
+    {
+        %this.resetCharacterSettings();
+    }
+    %this.setCharacterBlendColor(%this.pen, "1 1 1 1");
+    %this.pen++;
+    if(%this.pen >= strlen(%this.getText()))
+    {
+        %this.pen = 0;
+        %this.schedule(3000, "showLetter");
+    }
+    else
+    {
+        %this.schedule(80, "showLetter");
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+function WordSearchText::fadeOut(%this)
+{
+    %this.fadeTo("1 1 1 0", 0.6);
+
+    %this.schedule(6000, "fadeIn");
+}
+
+//-----------------------------------------------------------------------------
+
+function WordSearchText::fadeIn(%this)
+{
+    %this.fadeTo("1 1 1 1", 0.6);
+
+    %this.schedule(6000, "fadeOut");
+}

+ 2 - 2
modules/ImageFontToy/1/module.taml → modules/TextSpriteToy/1/module.taml

@@ -1,7 +1,7 @@
 <ModuleDefinition
-	ModuleId="ImageFontToy"
+	ModuleId="TextSpriteToy"
 	VersionId="1"
-	Description="Demonstrates creating an sprite that renders text."
+	Description="Demonstrates the amazing TextSprite!"
 	Dependencies="ToyAssets=1"
 	Type="toy"
 	ToyCategoryIndex="3"

+ 3 - 0
modules/ToyAssets/1/assets/fonts/Arial.asset.taml

@@ -0,0 +1,3 @@
+<FontAsset
+    AssetName="ArialFont"
+    FontFile="Arial.fnt" />

+ 195 - 0
modules/ToyAssets/1/assets/fonts/Arial.fnt

@@ -0,0 +1,195 @@
+info face="Arial" size=128 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
+common lineHeight=128 base=103 scaleW=512 scaleH=512 pages=2 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
+page id=0 file="Arial_0.png"
+page id=1 file="Arial_1.png"
+chars count=97
+char id=32   x=507   y=0     width=3     height=1     xoffset=-1    yoffset=127   xadvance=32    page=0  chnl=15
+char id=33   x=491   y=358   width=14    height=82    xoffset=8     yoffset=21    xadvance=29    page=0  chnl=15
+char id=34   x=275   y=227   width=32    height=29    xoffset=4     yoffset=21    xadvance=40    page=1  chnl=15
+char id=35   x=128   y=83    width=62    height=82    xoffset=0     yoffset=21    xadvance=63    page=1  chnl=15
+char id=36   x=321   y=0     width=55    height=97    xoffset=3     yoffset=17    xadvance=63    page=0  chnl=15
+char id=37   x=54    y=108   width=89    height=84    xoffset=6     yoffset=20    xadvance=101   page=0  chnl=15
+char id=38   x=74    y=193   width=70    height=84    xoffset=4     yoffset=20    xadvance=76    page=0  chnl=15
+char id=39   x=308   y=227   width=13    height=29    xoffset=4     yoffset=21    xadvance=22    page=1  chnl=15
+char id=40   x=243   y=0     width=28    height=105   xoffset=6     yoffset=21    xadvance=38    page=0  chnl=15
+char id=41   x=213   y=0     width=29    height=105   xoffset=6     yoffset=21    xadvance=38    page=0  chnl=15
+char id=42   x=471   y=166   width=38    height=35    xoffset=3     yoffset=21    xadvance=44    page=1  chnl=15
+char id=43   x=112   y=248   width=56    height=54    xoffset=6     yoffset=36    xadvance=67    page=1  chnl=15
+char id=44   x=322   y=227   width=13    height=27    xoffset=9     yoffset=93    xadvance=32    page=1  chnl=15
+char id=45   x=399   y=175   width=32    height=10    xoffset=3     yoffset=68    xadvance=38    page=0  chnl=15
+char id=46   x=442   y=259   width=13    height=10    xoffset=10    yoffset=93    xadvance=32    page=0  chnl=15
+char id=47   x=471   y=0     width=34    height=82    xoffset=-1    yoffset=21    xadvance=32    page=1  chnl=15
+char id=48   x=0     y=279   width=55    height=83    xoffset=4     yoffset=21    xadvance=63    page=0  chnl=15
+char id=49   x=50    y=166   width=31    height=82    xoffset=12    yoffset=21    xadvance=63    page=1  chnl=15
+char id=50   x=248   y=83    width=55    height=82    xoffset=3     yoffset=21    xadvance=63    page=1  chnl=15
+char id=51   x=56    y=279   width=55    height=83    xoffset=4     yoffset=21    xadvance=63    page=0  chnl=15
+char id=52   x=94    y=166   width=57    height=81    xoffset=1     yoffset=22    xadvance=63    page=1  chnl=15
+char id=53   x=304   y=83    width=55    height=82    xoffset=4     yoffset=22    xadvance=63    page=1  chnl=15
+char id=54   x=112   y=278   width=55    height=83    xoffset=4     yoffset=21    xadvance=63    page=0  chnl=15
+char id=55   x=152   y=166   width=54    height=81    xoffset=5     yoffset=22    xadvance=63    page=1  chnl=15
+char id=56   x=442   y=175   width=55    height=83    xoffset=4     yoffset=21    xadvance=63    page=0  chnl=15
+char id=57   x=168   y=278   width=55    height=83    xoffset=4     yoffset=21    xadvance=63    page=0  chnl=15
+char id=58   x=495   y=441   width=13    height=60    xoffset=10    yoffset=43    xadvance=32    page=0  chnl=15
+char id=59   x=207   y=166   width=13    height=77    xoffset=9     yoffset=43    xadvance=32    page=1  chnl=15
+char id=60   x=0     y=249   width=55    height=55    xoffset=6     yoffset=35    xadvance=67    page=1  chnl=15
+char id=61   x=219   y=244   width=55    height=35    xoffset=6     yoffset=45    xadvance=67    page=1  chnl=15
+char id=62   x=56    y=249   width=55    height=55    xoffset=6     yoffset=35    xadvance=67    page=1  chnl=15
+char id=63   x=224   y=278   width=54    height=83    xoffset=4     yoffset=20    xadvance=63    page=0  chnl=15
+char id=64   x=0     y=0     width=106   height=107   xoffset=6     yoffset=20    xadvance=116   page=0  chnl=15
+char id=65   x=109   y=363   width=78    height=82    xoffset=-1    yoffset=21    xadvance=76    page=0  chnl=15
+char id=66   x=64    y=83    width=63    height=82    xoffset=8     yoffset=21    xadvance=76    page=1  chnl=15
+char id=67   x=0     y=194   width=73    height=84    xoffset=5     yoffset=20    xadvance=82    page=0  chnl=15
+char id=68   x=0     y=0     width=69    height=82    xoffset=8     yoffset=21    xadvance=82    page=1  chnl=15
+char id=69   x=0     y=83    width=63    height=82    xoffset=8     yoffset=21    xadvance=76    page=1  chnl=15
+char id=70   x=191   y=83    width=56    height=82    xoffset=9     yoffset=21    xadvance=70    page=1  chnl=15
+char id=71   x=399   y=90    width=78    height=84    xoffset=5     yoffset=20    xadvance=89    page=0  chnl=15
+char id=72   x=139   y=0     width=66    height=82    xoffset=8     yoffset=21    xadvance=82    page=1  chnl=15
+char id=73   x=498   y=167   width=12    height=82    xoffset=10    yoffset=21    xadvance=32    page=0  chnl=15
+char id=74   x=460   y=0     width=46    height=83    xoffset=3     yoffset=21    xadvance=57    page=0  chnl=15
+char id=75   x=70    y=0     width=68    height=82    xoffset=8     yoffset=21    xadvance=76    page=1  chnl=15
+char id=76   x=360   y=83    width=52    height=82    xoffset=8     yoffset=21    xadvance=63    page=1  chnl=15
+char id=77   x=424   y=275   width=79    height=82    xoffset=8     yoffset=21    xadvance=95    page=0  chnl=15
+char id=78   x=340   y=0     width=65    height=82    xoffset=8     yoffset=21    xadvance=82    page=1  chnl=15
+char id=79   x=318   y=106   width=80    height=84    xoffset=5     yoffset=20    xadvance=89    page=0  chnl=15
+char id=80   x=406   y=0     width=64    height=82    xoffset=8     yoffset=21    xadvance=76    page=1  chnl=15
+char id=81   x=377   y=0     width=82    height=89    xoffset=4     yoffset=20    xadvance=89    page=0  chnl=15
+char id=82   x=417   y=359   width=73    height=82    xoffset=8     yoffset=21    xadvance=82    page=0  chnl=15
+char id=83   x=145   y=193   width=67    height=84    xoffset=4     yoffset=20    xadvance=76    page=0  chnl=15
+char id=84   x=206   y=0     width=66    height=82    xoffset=3     yoffset=21    xadvance=71    page=1  chnl=15
+char id=85   x=375   y=191   width=66    height=83    xoffset=8     yoffset=21    xadvance=82    page=0  chnl=15
+char id=86   x=265   y=362   width=76    height=82    xoffset=0     yoffset=21    xadvance=76    page=0  chnl=15
+char id=87   x=0     y=363   width=108   height=82    xoffset=1     yoffset=21    xadvance=110   page=0  chnl=15
+char id=88   x=188   y=362   width=76    height=82    xoffset=0     yoffset=21    xadvance=77    page=0  chnl=15
+char id=89   x=342   y=360   width=74    height=82    xoffset=0     yoffset=21    xadvance=75    page=0  chnl=15
+char id=90   x=273   y=0     width=66    height=82    xoffset=2     yoffset=21    xadvance=70    page=1  chnl=15
+char id=91   x=272   y=0     width=24    height=105   xoffset=7     yoffset=21    xadvance=32    page=0  chnl=15
+char id=92   x=464   y=83    width=34    height=82    xoffset=-1    yoffset=21    xadvance=32    page=1  chnl=15
+char id=93   x=297   y=0     width=23    height=105   xoffset=2     yoffset=21    xadvance=32    page=0  chnl=15
+char id=94   x=169   y=248   width=49    height=44    xoffset=2     yoffset=20    xadvance=53    page=1  chnl=15
+char id=95   x=418   y=227   width=68    height=7     xoffset=-3    yoffset=119   xadvance=63    page=1  chnl=15
+char id=96   x=396   y=227   width=21    height=16    xoffset=5     yoffset=21    xadvance=38    page=1  chnl=15
+char id=97   x=58    y=446   width=56    height=62    xoffset=3     yoffset=42    xadvance=63    page=0  chnl=15
+char id=98   x=333   y=276   width=52    height=83    xoffset=7     yoffset=21    xadvance=63    page=0  chnl=15
+char id=99   x=172   y=446   width=53    height=62    xoffset=4     yoffset=42    xadvance=57    page=0  chnl=15
+char id=100  x=279   y=276   width=53    height=83    xoffset=3     yoffset=21    xadvance=63    page=0  chnl=15
+char id=101  x=115   y=446   width=56    height=62    xoffset=3     yoffset=42    xadvance=63    page=0  chnl=15
+char id=102  x=386   y=275   width=37    height=83    xoffset=0     yoffset=20    xadvance=32    page=0  chnl=15
+char id=103  x=0     y=108   width=53    height=85    xoffset=3     yoffset=42    xadvance=63    page=0  chnl=15
+char id=104  x=0     y=166   width=49    height=82    xoffset=7     yoffset=21    xadvance=63    page=1  chnl=15
+char id=105  x=82    y=166   width=11    height=82    xoffset=7     yoffset=21    xadvance=25    page=1  chnl=15
+char id=106  x=188   y=0     width=24    height=106   xoffset=-6    yoffset=21    xadvance=25    page=0  chnl=15
+char id=107  x=413   y=83    width=50    height=82    xoffset=7     yoffset=21    xadvance=57    page=1  chnl=15
+char id=108  x=499   y=83    width=12    height=82    xoffset=6     yoffset=21    xadvance=25    page=1  chnl=15
+char id=109  x=277   y=445   width=82    height=61    xoffset=7     yoffset=42    xadvance=95    page=0  chnl=15
+char id=110  x=411   y=443   width=49    height=61    xoffset=7     yoffset=42    xadvance=63    page=0  chnl=15
+char id=111  x=0     y=446   width=57    height=62    xoffset=3     yoffset=42    xadvance=63    page=0  chnl=15
+char id=112  x=322   y=191   width=52    height=84    xoffset=7     yoffset=42    xadvance=63    page=0  chnl=15
+char id=113  x=268   y=191   width=53    height=84    xoffset=3     yoffset=42    xadvance=63    page=0  chnl=15
+char id=114  x=461   y=442   width=33    height=61    xoffset=7     yoffset=42    xadvance=38    page=0  chnl=15
+char id=115  x=226   y=445   width=50    height=62    xoffset=3     yoffset=42    xadvance=57    page=0  chnl=15
+char id=116  x=478   y=84    width=31    height=82    xoffset=1     yoffset=22    xadvance=32    page=0  chnl=15
+char id=117  x=360   y=443   width=50    height=61    xoffset=6     yoffset=43    xadvance=63    page=0  chnl=15
+char id=118  x=360   y=166   width=55    height=60    xoffset=1     yoffset=43    xadvance=57    page=1  chnl=15
+char id=119  x=221   y=166   width=81    height=60    xoffset=0     yoffset=43    xadvance=81    page=1  chnl=15
+char id=120  x=303   y=166   width=56    height=60    xoffset=0     yoffset=43    xadvance=56    page=1  chnl=15
+char id=121  x=213   y=193   width=54    height=84    xoffset=1     yoffset=43    xadvance=55    page=0  chnl=15
+char id=122  x=416   y=166   width=54    height=60    xoffset=1     yoffset=43    xadvance=57    page=1  chnl=15
+char id=123  x=107   y=0     width=34    height=107   xoffset=2     yoffset=20    xadvance=38    page=0  chnl=15
+char id=124  x=176   y=0     width=11    height=107   xoffset=9     yoffset=21    xadvance=29    page=0  chnl=15
+char id=125  x=142   y=0     width=33    height=107   xoffset=2     yoffset=20    xadvance=38    page=0  chnl=15
+char id=126  x=336   y=227   width=59    height=21    xoffset=4     yoffset=54    xadvance=67    page=1  chnl=15
+char id=169  x=231   y=106   width=86    height=84    xoffset=-1    yoffset=20    xadvance=84    page=0  chnl=15
+char id=174  x=144   y=108   width=86    height=84    xoffset=-1    yoffset=20    xadvance=84    page=0  chnl=15
+kernings count=92
+kerning first=32  second=65  amount=-6  
+kerning first=32  second=84  amount=-2  
+kerning first=32  second=89  amount=-2  
+kerning first=121 second=46  amount=-9  
+kerning first=121 second=44  amount=-9  
+kerning first=119 second=46  amount=-6  
+kerning first=119 second=44  amount=-6  
+kerning first=118 second=46  amount=-9  
+kerning first=118 second=44  amount=-9  
+kerning first=114 second=46  amount=-6  
+kerning first=49  second=49  amount=-9  
+kerning first=65  second=32  amount=-6  
+kerning first=65  second=84  amount=-9  
+kerning first=65  second=86  amount=-9  
+kerning first=65  second=87  amount=-4  
+kerning first=65  second=89  amount=-9  
+kerning first=65  second=118 amount=-2  
+kerning first=65  second=119 amount=-2  
+kerning first=65  second=121 amount=-2  
+kerning first=114 second=44  amount=-6  
+kerning first=70  second=44  amount=-13 
+kerning first=70  second=46  amount=-13 
+kerning first=70  second=65  amount=-6  
+kerning first=76  second=32  amount=-4  
+kerning first=76  second=84  amount=-9  
+kerning first=76  second=86  amount=-9  
+kerning first=76  second=87  amount=-9  
+kerning first=76  second=89  amount=-9  
+kerning first=76  second=121 amount=-4  
+kerning first=102 second=102 amount=-2  
+kerning first=80  second=32  amount=-2  
+kerning first=80  second=44  amount=-15 
+kerning first=80  second=46  amount=-15 
+kerning first=80  second=65  amount=-9  
+kerning first=82  second=84  amount=-2  
+kerning first=82  second=86  amount=-2  
+kerning first=82  second=87  amount=-2  
+kerning first=82  second=89  amount=-2  
+kerning first=84  second=32  amount=-2  
+kerning first=84  second=44  amount=-13 
+kerning first=84  second=45  amount=-6  
+kerning first=84  second=46  amount=-13 
+kerning first=84  second=58  amount=-13 
+kerning first=89  second=118 amount=-6  
+kerning first=84  second=65  amount=-9  
+kerning first=84  second=79  amount=-2  
+kerning first=84  second=97  amount=-13 
+kerning first=84  second=99  amount=-13 
+kerning first=84  second=101 amount=-13 
+kerning first=84  second=105 amount=-4  
+kerning first=84  second=111 amount=-13 
+kerning first=84  second=114 amount=-4  
+kerning first=84  second=115 amount=-13 
+kerning first=84  second=117 amount=-4  
+kerning first=84  second=119 amount=-6  
+kerning first=84  second=121 amount=-6  
+kerning first=86  second=44  amount=-11 
+kerning first=86  second=45  amount=-6  
+kerning first=86  second=46  amount=-11 
+kerning first=86  second=58  amount=-4  
+kerning first=89  second=117 amount=-6  
+kerning first=86  second=65  amount=-9  
+kerning first=86  second=97  amount=-9  
+kerning first=86  second=101 amount=-6  
+kerning first=86  second=105 amount=-2  
+kerning first=86  second=111 amount=-6  
+kerning first=86  second=114 amount=-4  
+kerning first=86  second=117 amount=-4  
+kerning first=86  second=121 amount=-4  
+kerning first=87  second=44  amount=-6  
+kerning first=87  second=45  amount=-2  
+kerning first=87  second=46  amount=-6  
+kerning first=87  second=58  amount=-2  
+kerning first=89  second=113 amount=-11 
+kerning first=87  second=65  amount=-4  
+kerning first=87  second=97  amount=-4  
+kerning first=87  second=101 amount=-2  
+kerning first=89  second=112 amount=-9  
+kerning first=87  second=111 amount=-2  
+kerning first=87  second=114 amount=-2  
+kerning first=87  second=117 amount=-2  
+kerning first=87  second=121 amount=-1  
+kerning first=89  second=32  amount=-2  
+kerning first=89  second=44  amount=-15 
+kerning first=89  second=45  amount=-11 
+kerning first=89  second=46  amount=-15 
+kerning first=89  second=58  amount=-6  
+kerning first=89  second=111 amount=-11 
+kerning first=89  second=65  amount=-9  
+kerning first=89  second=97  amount=-9  
+kerning first=89  second=101 amount=-11 
+kerning first=89  second=105 amount=-4  

BIN
modules/ToyAssets/1/assets/fonts/Arial_0.png


BIN
modules/ToyAssets/1/assets/fonts/Arial_1.png


+ 55 - 0
modules/ToyAssets/1/assets/fonts/Bitmap Font Config.bmfc

@@ -0,0 +1,55 @@
+# AngelCode Bitmap Font Generator configuration file
+fileVersion=1
+
+# font settings
+fontName=Arial
+fontFile=
+charSet=0
+fontSize=128
+aa=1
+scaleH=100
+useSmoothing=1
+isBold=0
+isItalic=0
+useUnicode=1
+disableBoxChars=1
+outputInvalidCharGlyph=0
+dontIncludeKerningPairs=0
+useHinting=1
+renderFromOutline=0
+useClearType=1
+
+# character alignment
+paddingDown=0
+paddingUp=0
+paddingRight=0
+paddingLeft=0
+spacingHoriz=1
+spacingVert=1
+useFixedHeight=0
+forceZero=0
+
+# output file
+outWidth=512
+outHeight=512
+outBitDepth=32
+fontDescFormat=0
+fourChnlPacked=0
+textureFormat=png
+textureCompression=0
+alphaChnl=0
+redChnl=4
+greenChnl=4
+blueChnl=4
+invA=0
+invR=0
+invG=0
+invB=0
+
+# outline
+outlineThickness=0
+
+# selected chars
+chars=32-126,169,174
+
+# imported icon images

+ 3 - 0
modules/ToyAssets/1/assets/fonts/Orator Bold.asset.taml

@@ -0,0 +1,3 @@
+<FontAsset
+    AssetName="OratorBoldFont"
+    FontFile="Orator Bold.fnt" />

+ 102 - 0
modules/ToyAssets/1/assets/fonts/Orator Bold.fnt

@@ -0,0 +1,102 @@
+info face="Orator Std" size=72 bold=1 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
+common lineHeight=72 base=56 scaleW=256 scaleH=256 pages=2 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
+page id=0 file="Orator Bold_0.png"
+page id=1 file="Orator Bold_1.png"
+chars count=97
+char id=32   x=21    y=51    width=3     height=1     xoffset=-1    yoffset=71    xadvance=34    page=0  chnl=15
+char id=33   x=239   y=150   width=8     height=36    xoffset=13    yoffset=20    xadvance=34    page=0  chnl=15
+char id=34   x=52    y=117   width=16    height=14    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=35   x=6     y=0     width=31    height=50    xoffset=2     yoffset=12    xadvance=34    page=0  chnl=15
+char id=36   x=23    y=135   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=37   x=0     y=60    width=26    height=37    xoffset=4     yoffset=19    xadvance=34    page=0  chnl=15
+char id=38   x=0     y=209   width=23    height=30    xoffset=6     yoffset=26    xadvance=34    page=0  chnl=15
+char id=39   x=248   y=150   width=7     height=14    xoffset=14    yoffset=20    xadvance=34    page=0  chnl=15
+char id=40   x=123   y=0     width=13    height=40    xoffset=11    yoffset=20    xadvance=34    page=0  chnl=15
+char id=41   x=137   y=0     width=13    height=40    xoffset=10    yoffset=20    xadvance=34    page=0  chnl=15
+char id=42   x=69    y=154   width=19    height=17    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=43   x=24    y=209   width=31    height=29    xoffset=1     yoffset=23    xadvance=34    page=0  chnl=15
+char id=44   x=90    y=191   width=10    height=12    xoffset=11    yoffset=47    xadvance=34    page=0  chnl=15
+char id=45   x=27    y=89    width=14    height=4     xoffset=10    yoffset=40    xadvance=34    page=0  chnl=15
+char id=46   x=42    y=89    width=7     height=8     xoffset=14    yoffset=48    xadvance=34    page=0  chnl=15
+char id=47   x=38    y=0     width=21    height=42    xoffset=7     yoffset=16    xadvance=34    page=0  chnl=15
+char id=48   x=23    y=172   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=49   x=224   y=76    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=50   x=0     y=172   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=51   x=232   y=39    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=52   x=128   y=78    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=53   x=230   y=113   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=54   x=207   y=114   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=55   x=46    y=135   width=22    height=36    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=56   x=176   y=77    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=57   x=184   y=114   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=58   x=248   y=76    width=7     height=23    xoffset=14    yoffset=33    xadvance=34    page=0  chnl=15
+char id=59   x=0     y=29    width=10    height=26    xoffset=11    yoffset=33    xadvance=34    page=1  chnl=15
+char id=60   x=151   y=0     width=24    height=39    xoffset=5     yoffset=17    xadvance=34    page=0  chnl=15
+char id=61   x=0     y=240   width=31    height=10    xoffset=2     yoffset=32    xadvance=34    page=0  chnl=15
+char id=62   x=176   y=0     width=24    height=39    xoffset=5     yoffset=17    xadvance=34    page=0  chnl=15
+char id=63   x=69    y=117   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=64   x=121   y=41    width=32    height=36    xoffset=1     yoffset=20    xadvance=34    page=0  chnl=15
+char id=65   x=180   y=40    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=66   x=152   y=78    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=67   x=92    y=117   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=68   x=103   y=78    width=24    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=69   x=176   y=152   width=20    height=36    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=70   x=197   y=151   width=20    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=71   x=200   y=77    width=23    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=72   x=46    y=172   width=21    height=36    xoffset=7     yoffset=20    xadvance=34    page=0  chnl=15
+char id=73   x=237   y=0     width=16    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=74   x=218   y=151   width=20    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=75   x=115   y=115   width=22    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=76   x=68    y=172   width=21    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=77   x=206   y=39    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=78   x=90    y=154   width=21    height=36    xoffset=7     yoffset=20    xadvance=34    page=0  chnl=15
+char id=79   x=161   y=115   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=80   x=134   y=152   width=20    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=81   x=27    y=51    width=22    height=37    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=82   x=138   y=115   width=22    height=36    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=83   x=112   y=154   width=21    height=36    xoffset=7     yoffset=20    xadvance=34    page=0  chnl=15
+char id=84   x=0     y=135   width=22    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=85   x=155   y=152   width=20    height=36    xoffset=7     yoffset=20    xadvance=34    page=0  chnl=15
+char id=86   x=52    y=80    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=87   x=26    y=98    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=88   x=0     y=98    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=89   x=154   y=40    width=25    height=36    xoffset=5     yoffset=20    xadvance=34    page=0  chnl=15
+char id=90   x=78    y=80    width=24    height=36    xoffset=6     yoffset=20    xadvance=34    page=0  chnl=15
+char id=91   x=219   y=0     width=17    height=38    xoffset=9     yoffset=20    xadvance=34    page=0  chnl=15
+char id=92   x=60    y=0     width=21    height=42    xoffset=7     yoffset=16    xadvance=34    page=0  chnl=15
+char id=93   x=201   y=0     width=17    height=38    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=94   x=11    y=29    width=23    height=18    xoffset=6     yoffset=20    xadvance=34    page=1  chnl=15
+char id=95   x=65    y=239   width=35    height=2     xoffset=0     yoffset=60    xadvance=34    page=0  chnl=15
+char id=96   x=6     y=51    width=14    height=8     xoffset=10    yoffset=18    xadvance=34    page=0  chnl=15
+char id=97   x=132   y=191   width=25    height=28    xoffset=5     yoffset=28    xadvance=34    page=0  chnl=15
+char id=98   x=180   y=218   width=23    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=99   x=204   y=218   width=22    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=100  x=131   y=220   width=24    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=101  x=217   y=0     width=20    height=28    xoffset=8     yoffset=28    xadvance=34    page=1  chnl=15
+char id=102  x=196   y=0     width=20    height=28    xoffset=9     yoffset=28    xadvance=34    page=1  chnl=15
+char id=103  x=156   y=220   width=23    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=104  x=111   y=0     width=21    height=28    xoffset=7     yoffset=28    xadvance=34    page=1  chnl=15
+char id=105  x=238   y=0     width=14    height=28    xoffset=10    yoffset=28    xadvance=34    page=1  chnl=15
+char id=106  x=175   y=0     width=20    height=28    xoffset=6     yoffset=28    xadvance=34    page=1  chnl=15
+char id=107  x=234   y=188   width=21    height=28    xoffset=9     yoffset=28    xadvance=34    page=0  chnl=15
+char id=108  x=89    y=0     width=21    height=28    xoffset=9     yoffset=28    xadvance=34    page=1  chnl=15
+char id=109  x=80    y=209   width=25    height=28    xoffset=5     yoffset=28    xadvance=34    page=0  chnl=15
+char id=110  x=67    y=0     width=21    height=28    xoffset=7     yoffset=28    xadvance=34    page=1  chnl=15
+char id=111  x=227   y=217   width=22    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=112  x=154   y=0     width=20    height=28    xoffset=9     yoffset=28    xadvance=34    page=1  chnl=15
+char id=113  x=56    y=209   width=23    height=29    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=114  x=45    y=0     width=21    height=28    xoffset=8     yoffset=28    xadvance=34    page=1  chnl=15
+char id=115  x=23    y=0     width=21    height=28    xoffset=7     yoffset=28    xadvance=34    page=1  chnl=15
+char id=116  x=0     y=0     width=22    height=28    xoffset=6     yoffset=28    xadvance=34    page=1  chnl=15
+char id=117  x=133   y=0     width=20    height=28    xoffset=7     yoffset=28    xadvance=34    page=1  chnl=15
+char id=118  x=158   y=189   width=25    height=28    xoffset=5     yoffset=28    xadvance=34    page=0  chnl=15
+char id=119  x=106   y=191   width=25    height=28    xoffset=5     yoffset=28    xadvance=34    page=0  chnl=15
+char id=120  x=184   y=189   width=24    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=121  x=209   y=188   width=24    height=28    xoffset=5     yoffset=28    xadvance=34    page=0  chnl=15
+char id=122  x=106   y=220   width=24    height=28    xoffset=6     yoffset=28    xadvance=34    page=0  chnl=15
+char id=123  x=82    y=0     width=20    height=40    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=124  x=0     y=0     width=5     height=59    xoffset=14    yoffset=12    xadvance=34    page=0  chnl=15
+char id=125  x=103   y=0     width=19    height=40    xoffset=8     yoffset=20    xadvance=34    page=0  chnl=15
+char id=126  x=32    y=239   width=32    height=9     xoffset=2     yoffset=32    xadvance=34    page=0  chnl=15
+char id=169  x=86    y=41    width=34    height=36    xoffset=0     yoffset=20    xadvance=34    page=0  chnl=15
+char id=174  x=50    y=43    width=35    height=36    xoffset=0     yoffset=20    xadvance=34    page=0  chnl=15

BIN
modules/ToyAssets/1/assets/fonts/Orator Bold_0.png


BIN
modules/ToyAssets/1/assets/fonts/Orator Bold_1.png


+ 3 - 0
modules/ToyAssets/1/assets/fonts/Trajan Pro.asset.taml

@@ -0,0 +1,3 @@
+<FontAsset
+    AssetName="TrajanProFont"
+    FontFile="Trajan Pro.fnt" />

+ 770 - 0
modules/ToyAssets/1/assets/fonts/Trajan Pro.fnt

@@ -0,0 +1,770 @@
+info face="Trajan Pro" size=128 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=2
+common lineHeight=128 base=102 scaleW=1024 scaleH=1024 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
+page id=0 file="Trajan Pro_0.png"
+chars count=95
+char id=32   x=1015  y=532   width=7     height=132   xoffset=-3    yoffset=-2    xadvance=33    page=0  chnl=15
+char id=33   x=395   y=665   width=15    height=132   xoffset=9     yoffset=-2    xadvance=33    page=0  chnl=15
+char id=34   x=262   y=665   width=27    height=132   xoffset=3     yoffset=-2    xadvance=33    page=0  chnl=15
+char id=35   x=440   y=399   width=57    height=132   xoffset=1     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=36   x=658   y=532   width=47    height=132   xoffset=6     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=37   x=257   y=133   width=83    height=132   xoffset=3     yoffset=-2    xadvance=89    page=0  chnl=15
+char id=38   x=724   y=0     width=88    height=132   xoffset=3     yoffset=-2    xadvance=79    page=0  chnl=15
+char id=39   x=427   y=665   width=14    height=132   xoffset=3     yoffset=-2    xadvance=20    page=0  chnl=15
+char id=40   x=233   y=665   width=28    height=132   xoffset=4     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=41   x=204   y=665   width=28    height=132   xoffset=5     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=42   x=988   y=0     width=34    height=132   xoffset=1     yoffset=-2    xadvance=36    page=0  chnl=15
+char id=43   x=560   y=532   width=48    height=132   xoffset=2     yoffset=-2    xadvance=52    page=0  chnl=15
+char id=44   x=411   y=665   width=15    height=132   xoffset=5     yoffset=-2    xadvance=25    page=0  chnl=15
+char id=45   x=0     y=665   width=38    height=132   xoffset=1     yoffset=-2    xadvance=40    page=0  chnl=15
+char id=46   x=378   y=665   width=16    height=132   xoffset=5     yoffset=-2    xadvance=25    page=0  chnl=15
+char id=47   x=382   y=399   width=57    height=132   xoffset=0     yoffset=-2    xadvance=56    page=0  chnl=15
+char id=48   x=725   y=399   width=54    height=132   xoffset=2     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=49   x=974   y=532   width=40    height=132   xoffset=9     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=50   x=613   y=399   width=55    height=132   xoffset=1     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=51   x=260   y=532   width=50    height=132   xoffset=4     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=52   x=323   y=399   width=58    height=132   xoffset=-1    yoffset=-2    xadvance=58    page=0  chnl=15
+char id=53   x=609   y=532   width=48    height=132   xoffset=5     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=54   x=889   y=399   width=53    height=132   xoffset=3     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=55   x=53    y=532   width=52    height=132   xoffset=6     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=56   x=0     y=532   width=52    height=132   xoffset=3     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=57   x=971   y=266   width=52    height=132   xoffset=3     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=58   x=361   y=665   width=16    height=132   xoffset=5     yoffset=-2    xadvance=25    page=0  chnl=15
+char id=59   x=344   y=665   width=16    height=132   xoffset=5     yoffset=-2    xadvance=25    page=0  chnl=15
+char id=60   x=362   y=532   width=49    height=132   xoffset=0     yoffset=-2    xadvance=52    page=0  chnl=15
+char id=61   x=462   y=532   width=48    height=132   xoffset=2     yoffset=-2    xadvance=52    page=0  chnl=15
+char id=62   x=511   y=532   width=48    height=132   xoffset=2     yoffset=-2    xadvance=52    page=0  chnl=15
+char id=63   x=932   y=532   width=41    height=132   xoffset=5     yoffset=-2    xadvance=50    page=0  chnl=15
+char id=64   x=172   y=133   width=84    height=132   xoffset=4     yoffset=-2    xadvance=92    page=0  chnl=15
+char id=65   x=425   y=133   width=83    height=132   xoffset=-5    yoffset=-2    xadvance=71    page=0  chnl=15
+char id=66   x=264   y=399   width=58    height=132   xoffset=7     yoffset=-2    xadvance=70    page=0  chnl=15
+char id=67   x=386   y=266   width=74    height=132   xoffset=4     yoffset=-2    xadvance=82    page=0  chnl=15
+char id=68   x=341   y=133   width=83    height=132   xoffset=7     yoffset=-2    xadvance=94    page=0  chnl=15
+char id=69   x=158   y=532   width=50    height=132   xoffset=7     yoffset=-2    xadvance=62    page=0  chnl=15
+char id=70   x=209   y=532   width=50    height=132   xoffset=7     yoffset=-2    xadvance=60    page=0  chnl=15
+char id=71   x=592   y=133   width=81    height=132   xoffset=4     yoffset=-2    xadvance=88    page=0  chnl=15
+char id=72   x=0     y=133   width=85    height=132   xoffset=7     yoffset=-2    xadvance=98    page=0  chnl=15
+char id=73   x=110   y=665   width=31    height=132   xoffset=8     yoffset=-2    xadvance=45    page=0  chnl=15
+char id=74   x=39    y=665   width=36    height=132   xoffset=1     yoffset=-2    xadvance=42    page=0  chnl=15
+char id=75   x=756   y=133   width=80    height=132   xoffset=7     yoffset=-2    xadvance=77    page=0  chnl=15
+char id=76   x=835   y=399   width=53    height=132   xoffset=7     yoffset=-2    xadvance=60    page=0  chnl=15
+char id=77   x=520   y=0     width=107   height=132   xoffset=3     yoffset=-2    xadvance=107   page=0  chnl=15
+char id=78   x=813   y=0     width=87    height=132   xoffset=4     yoffset=-2    xadvance=97    page=0  chnl=15
+char id=79   x=86    y=133   width=85    height=132   xoffset=4     yoffset=-2    xadvance=93    page=0  chnl=15
+char id=80   x=669   y=399   width=55    height=132   xoffset=7     yoffset=-2    xadvance=65    page=0  chnl=15
+char id=81   x=0     y=0     width=153   height=132   xoffset=4     yoffset=-2    xadvance=94    page=0  chnl=15
+char id=82   x=509   y=133   width=82    height=132   xoffset=7     yoffset=-2    xadvance=77    page=0  chnl=15
+char id=83   x=799   y=532   width=44    height=132   xoffset=8     yoffset=-2    xadvance=58    page=0  chnl=15
+char id=84   x=829   y=266   width=70    height=132   xoffset=0     yoffset=-2    xadvance=70    page=0  chnl=15
+char id=85   x=674   y=133   width=81    height=132   xoffset=1     yoffset=-2    xadvance=85    page=0  chnl=15
+char id=86   x=901   y=0     width=86    height=132   xoffset=-5    yoffset=-2    xadvance=76    page=0  chnl=15
+char id=87   x=291   y=0     width=120   height=132   xoffset=-4    yoffset=-2    xadvance=112   page=0  chnl=15
+char id=88   x=917   y=133   width=77    height=132   xoffset=-3    yoffset=-2    xadvance=71    page=0  chnl=15
+char id=89   x=837   y=133   width=79    height=132   xoffset=-6    yoffset=-2    xadvance=67    page=0  chnl=15
+char id=90   x=136   y=399   width=64    height=132   xoffset=5     yoffset=-2    xadvance=71    page=0  chnl=15
+char id=91   x=997   y=399   width=26    height=132   xoffset=7     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=92   x=780   y=399   width=54    height=132   xoffset=0     yoffset=-2    xadvance=53    page=0  chnl=15
+char id=93   x=318   y=665   width=25    height=132   xoffset=4     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=94   x=311   y=532   width=50    height=132   xoffset=1     yoffset=-2    xadvance=52    page=0  chnl=15
+char id=95   x=556   y=399   width=56    height=132   xoffset=-2    yoffset=-2    xadvance=51    page=0  chnl=15
+char id=96   x=290   y=665   width=27    height=132   xoffset=28    yoffset=-2    xadvance=93    page=0  chnl=15
+char id=97   x=310   y=266   width=75    height=132   xoffset=-5    yoffset=-2    xadvance=64    page=0  chnl=15
+char id=98   x=943   y=399   width=53    height=132   xoffset=6     yoffset=-2    xadvance=63    page=0  chnl=15
+char id=99   x=69    y=399   width=66    height=132   xoffset=3     yoffset=-2    xadvance=72    page=0  chnl=15
+char id=100  x=461   y=266   width=73    height=132   xoffset=6     yoffset=-2    xadvance=83    page=0  chnl=15
+char id=101  x=706   y=532   width=46    height=132   xoffset=6     yoffset=-2    xadvance=56    page=0  chnl=15
+char id=102  x=753   y=532   width=45    height=132   xoffset=6     yoffset=-2    xadvance=55    page=0  chnl=15
+char id=103  x=756   y=266   width=72    height=132   xoffset=3     yoffset=-2    xadvance=77    page=0  chnl=15
+char id=104  x=233   y=266   width=76    height=132   xoffset=6     yoffset=-2    xadvance=86    page=0  chnl=15
+char id=105  x=995   y=133   width=28    height=132   xoffset=7     yoffset=-2    xadvance=40    page=0  chnl=15
+char id=106  x=76    y=665   width=33    height=132   xoffset=0     yoffset=-2    xadvance=38    page=0  chnl=15
+char id=107  x=683   y=266   width=72    height=132   xoffset=6     yoffset=-2    xadvance=68    page=0  chnl=15
+char id=108  x=412   y=532   width=49    height=132   xoffset=6     yoffset=-2    xadvance=55    page=0  chnl=15
+char id=109  x=628   y=0     width=95    height=132   xoffset=2     yoffset=-2    xadvance=94    page=0  chnl=15
+char id=110  x=78    y=266   width=77    height=132   xoffset=5     yoffset=-2    xadvance=85    page=0  chnl=15
+char id=111  x=156   y=266   width=76    height=132   xoffset=3     yoffset=-2    xadvance=82    page=0  chnl=15
+char id=112  x=106   y=532   width=51    height=132   xoffset=6     yoffset=-2    xadvance=60    page=0  chnl=15
+char id=113  x=154   y=0     width=136   height=132   xoffset=3     yoffset=-2    xadvance=83    page=0  chnl=15
+char id=114  x=609   y=266   width=73    height=132   xoffset=6     yoffset=-2    xadvance=69    page=0  chnl=15
+char id=115  x=889   y=532   width=42    height=132   xoffset=4     yoffset=-2    xadvance=53    page=0  chnl=15
+char id=116  x=201   y=399   width=62    height=132   xoffset=0     yoffset=-2    xadvance=62    page=0  chnl=15
+char id=117  x=535   y=266   width=73    height=132   xoffset=1     yoffset=-2    xadvance=75    page=0  chnl=15
+char id=118  x=0     y=266   width=77    height=132   xoffset=-5    yoffset=-2    xadvance=67    page=0  chnl=15
+char id=119  x=412   y=0     width=107   height=132   xoffset=-4    yoffset=-2    xadvance=99    page=0  chnl=15
+char id=120  x=0     y=399   width=68    height=132   xoffset=-3    yoffset=-2    xadvance=62    page=0  chnl=15
+char id=121  x=900   y=266   width=70    height=132   xoffset=-5    yoffset=-2    xadvance=59    page=0  chnl=15
+char id=122  x=498   y=399   width=57    height=132   xoffset=4     yoffset=-2    xadvance=62    page=0  chnl=15
+char id=123  x=142   y=665   width=30    height=132   xoffset=3     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=124  x=442   y=665   width=10    height=132   xoffset=21    yoffset=-2    xadvance=52    page=0  chnl=15
+char id=125  x=173   y=665   width=30    height=132   xoffset=4     yoffset=-2    xadvance=37    page=0  chnl=15
+char id=126  x=844   y=532   width=44    height=132   xoffset=4     yoffset=-2    xadvance=52    page=0  chnl=15
+kernings count=670
+kerning first=40  second=118 amount=2   
+kerning first=40  second=119 amount=1   
+kerning first=40  second=121 amount=3   
+kerning first=123 second=121 amount=3   
+kerning first=123 second=119 amount=1   
+kerning first=65  second=77  amount=3   
+kerning first=65  second=83  amount=1   
+kerning first=65  second=84  amount=-7  
+kerning first=65  second=86  amount=-8  
+kerning first=65  second=87  amount=-5  
+kerning first=65  second=88  amount=1   
+kerning first=65  second=89  amount=-5  
+kerning first=65  second=109 amount=2   
+kerning first=65  second=115 amount=1   
+kerning first=65  second=116 amount=-7  
+kerning first=65  second=118 amount=-7  
+kerning first=65  second=119 amount=-4  
+kerning first=65  second=120 amount=1   
+kerning first=65  second=121 amount=-5  
+kerning first=123 second=118 amount=2   
+kerning first=122 second=113 amount=-3  
+kerning first=122 second=111 amount=-3  
+kerning first=122 second=103 amount=-3  
+kerning first=122 second=99  amount=-3  
+kerning first=122 second=97  amount=-1  
+kerning first=121 second=125 amount=3   
+kerning first=121 second=120 amount=1   
+kerning first=66  second=65  amount=-1  
+kerning first=66  second=66  amount=-2  
+kerning first=66  second=68  amount=-2  
+kerning first=66  second=69  amount=-2  
+kerning first=66  second=70  amount=-2  
+kerning first=66  second=72  amount=-2  
+kerning first=66  second=73  amount=-2  
+kerning first=66  second=75  amount=-2  
+kerning first=66  second=76  amount=-2  
+kerning first=66  second=78  amount=-2  
+kerning first=66  second=80  amount=-2  
+kerning first=66  second=82  amount=-2  
+kerning first=66  second=86  amount=-4  
+kerning first=66  second=87  amount=-2  
+kerning first=66  second=89  amount=-3  
+kerning first=66  second=97  amount=-1  
+kerning first=66  second=98  amount=-2  
+kerning first=66  second=100 amount=-2  
+kerning first=66  second=101 amount=-2  
+kerning first=66  second=102 amount=-2  
+kerning first=66  second=104 amount=-2  
+kerning first=66  second=105 amount=-2  
+kerning first=66  second=107 amount=-2  
+kerning first=66  second=108 amount=-2  
+kerning first=66  second=110 amount=-2  
+kerning first=66  second=112 amount=-2  
+kerning first=66  second=114 amount=-2  
+kerning first=66  second=118 amount=-4  
+kerning first=66  second=119 amount=-2  
+kerning first=66  second=121 amount=-3  
+kerning first=121 second=119 amount=3   
+kerning first=121 second=118 amount=2   
+kerning first=121 second=116 amount=1   
+kerning first=121 second=113 amount=-1  
+kerning first=121 second=111 amount=-1  
+kerning first=121 second=109 amount=-1  
+kerning first=121 second=103 amount=-1  
+kerning first=121 second=99  amount=-1  
+kerning first=121 second=97  amount=-4  
+kerning first=121 second=93  amount=3   
+kerning first=121 second=46  amount=-9  
+kerning first=121 second=45  amount=-3  
+kerning first=121 second=44  amount=-9  
+kerning first=121 second=41  amount=3   
+kerning first=120 second=121 amount=1   
+kerning first=120 second=120 amount=1   
+kerning first=120 second=119 amount=1   
+kerning first=120 second=116 amount=-3  
+kerning first=120 second=113 amount=-2  
+kerning first=120 second=111 amount=-2  
+kerning first=120 second=103 amount=-2  
+kerning first=120 second=99  amount=-2  
+kerning first=120 second=97  amount=-2  
+kerning first=119 second=125 amount=1   
+kerning first=119 second=121 amount=1   
+kerning first=119 second=116 amount=-2  
+kerning first=119 second=109 amount=-2  
+kerning first=119 second=97  amount=-5  
+kerning first=119 second=93  amount=1   
+kerning first=119 second=59  amount=1   
+kerning first=119 second=58  amount=1   
+kerning first=119 second=46  amount=-10 
+kerning first=119 second=44  amount=-10 
+kerning first=119 second=41  amount=1   
+kerning first=118 second=125 amount=2   
+kerning first=118 second=121 amount=1   
+kerning first=118 second=113 amount=-1  
+kerning first=118 second=111 amount=-1  
+kerning first=118 second=103 amount=-1  
+kerning first=118 second=99  amount=-1  
+kerning first=118 second=97  amount=-7  
+kerning first=118 second=93  amount=2   
+kerning first=118 second=46  amount=-13 
+kerning first=118 second=45  amount=-2  
+kerning first=118 second=44  amount=-13 
+kerning first=67  second=67  amount=-1  
+kerning first=67  second=79  amount=-1  
+kerning first=67  second=81  amount=-1  
+kerning first=67  second=84  amount=-1  
+kerning first=67  second=89  amount=2   
+kerning first=67  second=99  amount=-1  
+kerning first=67  second=103 amount=-1  
+kerning first=67  second=111 amount=-1  
+kerning first=67  second=113 amount=-1  
+kerning first=67  second=116 amount=-1  
+kerning first=67  second=121 amount=2   
+kerning first=118 second=41  amount=2   
+kerning first=117 second=109 amount=-2  
+kerning first=117 second=97  amount=-2  
+kerning first=116 second=121 amount=2   
+kerning first=116 second=120 amount=2   
+kerning first=116 second=119 amount=1   
+kerning first=116 second=116 amount=1   
+kerning first=116 second=115 amount=-1  
+kerning first=116 second=113 amount=-2  
+kerning first=116 second=111 amount=-2  
+kerning first=116 second=109 amount=-1  
+kerning first=116 second=103 amount=-2  
+kerning first=116 second=99  amount=-2  
+kerning first=116 second=97  amount=-4  
+kerning first=116 second=59  amount=-3  
+kerning first=116 second=58  amount=-3  
+kerning first=116 second=46  amount=-11 
+kerning first=116 second=45  amount=-3  
+kerning first=116 second=44  amount=-11 
+kerning first=68  second=65  amount=-1  
+kerning first=68  second=66  amount=-1  
+kerning first=68  second=68  amount=-1  
+kerning first=68  second=69  amount=-1  
+kerning first=68  second=70  amount=-1  
+kerning first=68  second=72  amount=-1  
+kerning first=68  second=73  amount=-1  
+kerning first=68  second=74  amount=-1  
+kerning first=68  second=75  amount=-1  
+kerning first=68  second=76  amount=-1  
+kerning first=68  second=77  amount=-1  
+kerning first=68  second=78  amount=-1  
+kerning first=68  second=80  amount=-1  
+kerning first=68  second=82  amount=-1  
+kerning first=68  second=97  amount=-1  
+kerning first=68  second=98  amount=-1  
+kerning first=68  second=100 amount=-1  
+kerning first=68  second=101 amount=-1  
+kerning first=68  second=102 amount=-1  
+kerning first=68  second=104 amount=-1  
+kerning first=68  second=105 amount=-1  
+kerning first=68  second=106 amount=-1  
+kerning first=68  second=107 amount=-1  
+kerning first=68  second=108 amount=-1  
+kerning first=68  second=109 amount=-1  
+kerning first=68  second=110 amount=-1  
+kerning first=68  second=112 amount=-1  
+kerning first=68  second=114 amount=-1  
+kerning first=115 second=114 amount=-2  
+kerning first=115 second=112 amount=-2  
+kerning first=115 second=110 amount=-2  
+kerning first=115 second=109 amount=-1  
+kerning first=115 second=108 amount=-2  
+kerning first=115 second=107 amount=-2  
+kerning first=115 second=105 amount=-2  
+kerning first=115 second=104 amount=-2  
+kerning first=115 second=102 amount=-2  
+kerning first=115 second=101 amount=-2  
+kerning first=115 second=100 amount=-2  
+kerning first=115 second=98  amount=-2  
+kerning first=114 second=121 amount=-2  
+kerning first=114 second=120 amount=-1  
+kerning first=114 second=118 amount=-2  
+kerning first=114 second=116 amount=-5  
+kerning first=114 second=115 amount=-1  
+kerning first=114 second=113 amount=1   
+kerning first=114 second=111 amount=1   
+kerning first=114 second=103 amount=1   
+kerning first=114 second=99  amount=1   
+kerning first=114 second=97  amount=1   
+kerning first=113 second=125 amount=3   
+kerning first=113 second=114 amount=-2  
+kerning first=113 second=112 amount=-2  
+kerning first=113 second=110 amount=-2  
+kerning first=113 second=108 amount=-2  
+kerning first=113 second=107 amount=-2  
+kerning first=113 second=105 amount=-2  
+kerning first=113 second=104 amount=-2  
+kerning first=113 second=102 amount=-2  
+kerning first=113 second=101 amount=-2  
+kerning first=113 second=100 amount=-2  
+kerning first=113 second=98  amount=-2  
+kerning first=113 second=93  amount=3   
+kerning first=113 second=41  amount=3   
+kerning first=112 second=115 amount=1   
+kerning first=112 second=114 amount=-1  
+kerning first=112 second=112 amount=-1  
+kerning first=112 second=110 amount=-1  
+kerning first=112 second=108 amount=-1  
+kerning first=69  second=86  amount=3   
+kerning first=69  second=87  amount=3   
+kerning first=69  second=88  amount=4   
+kerning first=69  second=89  amount=3   
+kerning first=69  second=118 amount=3   
+kerning first=69  second=119 amount=3   
+kerning first=69  second=120 amount=4   
+kerning first=69  second=121 amount=3   
+kerning first=112 second=107 amount=-1  
+kerning first=112 second=105 amount=-1  
+kerning first=112 second=104 amount=-1  
+kerning first=112 second=102 amount=-1  
+kerning first=70  second=44  amount=-10 
+kerning first=70  second=46  amount=-10 
+kerning first=70  second=65  amount=-3  
+kerning first=70  second=89  amount=2   
+kerning first=70  second=97  amount=-3  
+kerning first=70  second=121 amount=2   
+kerning first=112 second=101 amount=-1  
+kerning first=112 second=100 amount=-1  
+kerning first=112 second=98  amount=-1  
+kerning first=112 second=97  amount=-4  
+kerning first=112 second=46  amount=-15 
+kerning first=112 second=44  amount=-15 
+kerning first=111 second=121 amount=-1  
+kerning first=111 second=120 amount=-2  
+kerning first=111 second=119 amount=-1  
+kerning first=111 second=118 amount=-1  
+kerning first=111 second=116 amount=-3  
+kerning first=111 second=114 amount=-3  
+kerning first=111 second=112 amount=-3  
+kerning first=111 second=110 amount=-3  
+kerning first=111 second=109 amount=-1  
+kerning first=111 second=108 amount=-3  
+kerning first=111 second=107 amount=-3  
+kerning first=111 second=106 amount=-2  
+kerning first=111 second=105 amount=-3  
+kerning first=72  second=67  amount=-2  
+kerning first=72  second=71  amount=-2  
+kerning first=72  second=79  amount=-3  
+kerning first=72  second=81  amount=-3  
+kerning first=72  second=99  amount=-2  
+kerning first=72  second=103 amount=-2  
+kerning first=72  second=111 amount=-2  
+kerning first=72  second=113 amount=-2  
+kerning first=111 second=104 amount=-3  
+kerning first=111 second=102 amount=-3  
+kerning first=111 second=101 amount=-3  
+kerning first=111 second=100 amount=-3  
+kerning first=111 second=98  amount=-3  
+kerning first=111 second=97  amount=-2  
+kerning first=110 second=114 amount=-2  
+kerning first=110 second=113 amount=-1  
+kerning first=110 second=112 amount=-2  
+kerning first=110 second=111 amount=-1  
+kerning first=110 second=110 amount=-2  
+kerning first=110 second=108 amount=-2  
+kerning first=110 second=107 amount=-2  
+kerning first=110 second=105 amount=-2  
+kerning first=110 second=104 amount=-2  
+kerning first=73  second=67  amount=-2  
+kerning first=73  second=71  amount=-2  
+kerning first=73  second=79  amount=-3  
+kerning first=73  second=81  amount=-3  
+kerning first=73  second=99  amount=-2  
+kerning first=73  second=103 amount=-2  
+kerning first=73  second=111 amount=-2  
+kerning first=73  second=113 amount=-2  
+kerning first=110 second=103 amount=-1  
+kerning first=110 second=102 amount=-2  
+kerning first=110 second=101 amount=-2  
+kerning first=110 second=100 amount=-2  
+kerning first=110 second=99  amount=-1  
+kerning first=110 second=98  amount=-2  
+kerning first=109 second=121 amount=-1  
+kerning first=109 second=119 amount=-1  
+kerning first=109 second=116 amount=-2  
+kerning first=109 second=97  amount=2   
+kerning first=108 second=121 amount=-3  
+kerning first=108 second=119 amount=-2  
+kerning first=108 second=118 amount=-4  
+kerning first=108 second=117 amount=-1  
+kerning first=108 second=116 amount=-6  
+kerning first=74  second=79  amount=-1  
+kerning first=74  second=99  amount=-1  
+kerning first=74  second=103 amount=-1  
+kerning first=74  second=111 amount=-1  
+kerning first=74  second=113 amount=-1  
+kerning first=108 second=113 amount=-2  
+kerning first=108 second=111 amount=-2  
+kerning first=108 second=109 amount=-1  
+kerning first=108 second=103 amount=-2  
+kerning first=108 second=99  amount=-2  
+kerning first=108 second=97  amount=1   
+kerning first=107 second=115 amount=1   
+kerning first=107 second=97  amount=-1  
+kerning first=106 second=113 amount=-1  
+kerning first=106 second=111 amount=-1  
+kerning first=106 second=103 amount=-1  
+kerning first=106 second=99  amount=-1  
+kerning first=105 second=114 amount=-2  
+kerning first=105 second=113 amount=-1  
+kerning first=75  second=65  amount=-1  
+kerning first=105 second=112 amount=-2  
+kerning first=105 second=111 amount=-1  
+kerning first=105 second=110 amount=-2  
+kerning first=105 second=108 amount=-2  
+kerning first=75  second=83  amount=1   
+kerning first=75  second=97  amount=-1  
+kerning first=105 second=107 amount=-2  
+kerning first=105 second=105 amount=-2  
+kerning first=105 second=104 amount=-2  
+kerning first=105 second=103 amount=-1  
+kerning first=75  second=115 amount=1   
+kerning first=105 second=102 amount=-2  
+kerning first=105 second=101 amount=-2  
+kerning first=105 second=100 amount=-2  
+kerning first=105 second=99  amount=-1  
+kerning first=105 second=98  amount=-2  
+kerning first=104 second=114 amount=-2  
+kerning first=104 second=113 amount=-1  
+kerning first=104 second=112 amount=-2  
+kerning first=104 second=111 amount=-1  
+kerning first=104 second=110 amount=-2  
+kerning first=104 second=108 amount=-2  
+kerning first=104 second=107 amount=-2  
+kerning first=104 second=105 amount=-2  
+kerning first=104 second=104 amount=-2  
+kerning first=104 second=103 amount=-1  
+kerning first=104 second=102 amount=-2  
+kerning first=104 second=101 amount=-2  
+kerning first=104 second=100 amount=-2  
+kerning first=104 second=99  amount=-1  
+kerning first=104 second=98  amount=-2  
+kerning first=102 second=121 amount=2   
+kerning first=102 second=97  amount=-3  
+kerning first=102 second=46  amount=-9  
+kerning first=102 second=44  amount=-9  
+kerning first=101 second=121 amount=2   
+kerning first=101 second=120 amount=3   
+kerning first=101 second=119 amount=3   
+kerning first=101 second=118 amount=2   
+kerning first=100 second=114 amount=-1  
+kerning first=100 second=112 amount=-1  
+kerning first=100 second=110 amount=-1  
+kerning first=76  second=65  amount=1   
+kerning first=76  second=67  amount=-2  
+kerning first=76  second=71  amount=-2  
+kerning first=76  second=77  amount=-1  
+kerning first=76  second=79  amount=-2  
+kerning first=76  second=84  amount=-6  
+kerning first=76  second=85  amount=-1  
+kerning first=76  second=86  amount=-5  
+kerning first=76  second=87  amount=-3  
+kerning first=76  second=89  amount=-4  
+kerning first=76  second=97  amount=1   
+kerning first=76  second=99  amount=-3  
+kerning first=76  second=103 amount=-3  
+kerning first=76  second=109 amount=-1  
+kerning first=76  second=111 amount=-3  
+kerning first=76  second=113 amount=-3  
+kerning first=76  second=116 amount=-7  
+kerning first=76  second=117 amount=-1  
+kerning first=76  second=118 amount=-5  
+kerning first=76  second=119 amount=-3  
+kerning first=76  second=121 amount=-4  
+kerning first=100 second=109 amount=-1  
+kerning first=100 second=108 amount=-1  
+kerning first=100 second=107 amount=-1  
+kerning first=100 second=106 amount=-1  
+kerning first=100 second=105 amount=-1  
+kerning first=100 second=104 amount=-1  
+kerning first=100 second=102 amount=-1  
+kerning first=100 second=101 amount=-1  
+kerning first=100 second=100 amount=-1  
+kerning first=100 second=98  amount=-1  
+kerning first=100 second=97  amount=-1  
+kerning first=99  second=121 amount=1   
+kerning first=99  second=116 amount=-1  
+kerning first=99  second=113 amount=-1  
+kerning first=99  second=111 amount=-1  
+kerning first=99  second=103 amount=-1  
+kerning first=99  second=99  amount=-1  
+kerning first=98  second=121 amount=-3  
+kerning first=98  second=119 amount=-1  
+kerning first=98  second=118 amount=-3  
+kerning first=98  second=114 amount=-3  
+kerning first=98  second=112 amount=-3  
+kerning first=98  second=110 amount=-3  
+kerning first=98  second=108 amount=-3  
+kerning first=98  second=107 amount=-3  
+kerning first=98  second=105 amount=-3  
+kerning first=98  second=104 amount=-3  
+kerning first=98  second=102 amount=-3  
+kerning first=98  second=101 amount=-3  
+kerning first=98  second=100 amount=-3  
+kerning first=98  second=98  amount=-3  
+kerning first=98  second=97  amount=-1  
+kerning first=97  second=121 amount=-5  
+kerning first=97  second=120 amount=1   
+kerning first=97  second=119 amount=-4  
+kerning first=97  second=118 amount=-7  
+kerning first=97  second=116 amount=-7  
+kerning first=97  second=115 amount=1   
+kerning first=97  second=109 amount=2   
+kerning first=91  second=121 amount=3   
+kerning first=91  second=119 amount=1   
+kerning first=91  second=118 amount=2   
+kerning first=90  second=113 amount=-3  
+kerning first=77  second=65  amount=2   
+kerning first=77  second=84  amount=-2  
+kerning first=90  second=111 amount=-3  
+kerning first=77  second=87  amount=-2  
+kerning first=77  second=89  amount=-1  
+kerning first=77  second=97  amount=2   
+kerning first=77  second=116 amount=-2  
+kerning first=90  second=103 amount=-3  
+kerning first=77  second=119 amount=-2  
+kerning first=77  second=121 amount=-1  
+kerning first=90  second=99  amount=-3  
+kerning first=90  second=97  amount=-1  
+kerning first=90  second=79  amount=-3  
+kerning first=90  second=65  amount=-1  
+kerning first=89  second=125 amount=4   
+kerning first=89  second=120 amount=1   
+kerning first=89  second=119 amount=3   
+kerning first=89  second=118 amount=2   
+kerning first=89  second=116 amount=1   
+kerning first=89  second=113 amount=-4  
+kerning first=89  second=111 amount=-4  
+kerning first=89  second=109 amount=-1  
+kerning first=89  second=103 amount=-4  
+kerning first=89  second=99  amount=-4  
+kerning first=89  second=97  amount=-5  
+kerning first=89  second=93  amount=4   
+kerning first=89  second=88  amount=1   
+kerning first=89  second=87  amount=3   
+kerning first=89  second=86  amount=2   
+kerning first=89  second=84  amount=1   
+kerning first=89  second=79  amount=-2  
+kerning first=89  second=77  amount=-1  
+kerning first=89  second=71  amount=-1  
+kerning first=89  second=67  amount=-1  
+kerning first=89  second=65  amount=-5  
+kerning first=89  second=46  amount=-10 
+kerning first=78  second=67  amount=-2  
+kerning first=78  second=71  amount=-2  
+kerning first=78  second=79  amount=-3  
+kerning first=78  second=81  amount=-3  
+kerning first=78  second=99  amount=-2  
+kerning first=78  second=103 amount=-2  
+kerning first=78  second=111 amount=-2  
+kerning first=78  second=113 amount=-2  
+kerning first=89  second=45  amount=-3  
+kerning first=89  second=44  amount=-10 
+kerning first=89  second=41  amount=4   
+kerning first=88  second=121 amount=1   
+kerning first=88  second=120 amount=1   
+kerning first=88  second=119 amount=1   
+kerning first=88  second=116 amount=-3  
+kerning first=88  second=113 amount=-2  
+kerning first=88  second=111 amount=-2  
+kerning first=88  second=103 amount=-2  
+kerning first=88  second=99  amount=-2  
+kerning first=88  second=97  amount=-2  
+kerning first=88  second=89  amount=1   
+kerning first=88  second=88  amount=1   
+kerning first=88  second=87  amount=1   
+kerning first=79  second=65  amount=-2  
+kerning first=79  second=66  amount=-3  
+kerning first=79  second=68  amount=-3  
+kerning first=79  second=69  amount=-3  
+kerning first=79  second=70  amount=-3  
+kerning first=79  second=72  amount=-3  
+kerning first=79  second=73  amount=-3  
+kerning first=79  second=74  amount=-2  
+kerning first=79  second=75  amount=-3  
+kerning first=79  second=76  amount=-3  
+kerning first=79  second=77  amount=-1  
+kerning first=79  second=78  amount=-3  
+kerning first=79  second=80  amount=-3  
+kerning first=79  second=82  amount=-3  
+kerning first=79  second=84  amount=-3  
+kerning first=79  second=86  amount=-1  
+kerning first=79  second=87  amount=-1  
+kerning first=79  second=88  amount=-3  
+kerning first=79  second=89  amount=-1  
+kerning first=79  second=97  amount=-2  
+kerning first=79  second=98  amount=-3  
+kerning first=79  second=100 amount=-3  
+kerning first=79  second=101 amount=-3  
+kerning first=79  second=102 amount=-3  
+kerning first=79  second=104 amount=-3  
+kerning first=79  second=105 amount=-3  
+kerning first=79  second=106 amount=-2  
+kerning first=79  second=107 amount=-3  
+kerning first=79  second=108 amount=-3  
+kerning first=79  second=109 amount=-1  
+kerning first=79  second=110 amount=-3  
+kerning first=79  second=112 amount=-3  
+kerning first=79  second=114 amount=-3  
+kerning first=79  second=116 amount=-3  
+kerning first=79  second=118 amount=-1  
+kerning first=79  second=119 amount=-1  
+kerning first=79  second=120 amount=-3  
+kerning first=79  second=121 amount=-1  
+kerning first=88  second=84  amount=-3  
+kerning first=88  second=81  amount=-2  
+kerning first=88  second=79  amount=-2  
+kerning first=88  second=71  amount=-2  
+kerning first=88  second=67  amount=-2  
+kerning first=88  second=65  amount=-2  
+kerning first=87  second=125 amount=1   
+kerning first=87  second=121 amount=1   
+kerning first=87  second=116 amount=-2  
+kerning first=87  second=109 amount=-3  
+kerning first=87  second=97  amount=-6  
+kerning first=87  second=93  amount=1   
+kerning first=87  second=89  amount=1   
+kerning first=87  second=84  amount=-2  
+kerning first=87  second=77  amount=-3  
+kerning first=87  second=65  amount=-6  
+kerning first=87  second=59  amount=2   
+kerning first=87  second=58  amount=2   
+kerning first=87  second=46  amount=-11 
+kerning first=87  second=44  amount=-11 
+kerning first=87  second=41  amount=1   
+kerning first=86  second=125 amount=3   
+kerning first=86  second=121 amount=1   
+kerning first=86  second=113 amount=-1  
+kerning first=86  second=111 amount=-1  
+kerning first=86  second=103 amount=-1  
+kerning first=86  second=99  amount=-1  
+kerning first=86  second=97  amount=-8  
+kerning first=86  second=93  amount=3   
+kerning first=86  second=89  amount=1   
+kerning first=86  second=79  amount=-1  
+kerning first=86  second=65  amount=-8  
+kerning first=86  second=46  amount=-15 
+kerning first=86  second=45  amount=-2  
+kerning first=86  second=44  amount=-15 
+kerning first=86  second=41  amount=3   
+kerning first=85  second=114 amount=-3  
+kerning first=85  second=112 amount=-3  
+kerning first=85  second=110 amount=-3  
+kerning first=85  second=109 amount=-2  
+kerning first=85  second=108 amount=-3  
+kerning first=85  second=107 amount=-3  
+kerning first=85  second=105 amount=-3  
+kerning first=85  second=104 amount=-3  
+kerning first=85  second=102 amount=-3  
+kerning first=80  second=44  amount=-16 
+kerning first=80  second=46  amount=-16 
+kerning first=80  second=65  amount=-5  
+kerning first=80  second=66  amount=-2  
+kerning first=80  second=68  amount=-2  
+kerning first=80  second=69  amount=-2  
+kerning first=80  second=70  amount=-2  
+kerning first=80  second=72  amount=-2  
+kerning first=80  second=73  amount=-2  
+kerning first=80  second=75  amount=-2  
+kerning first=80  second=76  amount=-2  
+kerning first=80  second=78  amount=-2  
+kerning first=80  second=80  amount=-2  
+kerning first=80  second=82  amount=-2  
+kerning first=80  second=83  amount=1   
+kerning first=80  second=97  amount=-5  
+kerning first=80  second=98  amount=-2  
+kerning first=80  second=100 amount=-2  
+kerning first=80  second=101 amount=-2  
+kerning first=80  second=102 amount=-2  
+kerning first=80  second=104 amount=-2  
+kerning first=80  second=105 amount=-2  
+kerning first=80  second=107 amount=-2  
+kerning first=80  second=108 amount=-2  
+kerning first=80  second=110 amount=-2  
+kerning first=80  second=112 amount=-2  
+kerning first=80  second=114 amount=-2  
+kerning first=80  second=115 amount=1   
+kerning first=85  second=101 amount=-3  
+kerning first=85  second=100 amount=-3  
+kerning first=85  second=98  amount=-3  
+kerning first=85  second=97  amount=-2  
+kerning first=85  second=77  amount=-2  
+kerning first=85  second=65  amount=-2  
+kerning first=84  second=121 amount=2   
+kerning first=84  second=120 amount=2   
+kerning first=84  second=119 amount=1   
+kerning first=84  second=116 amount=1   
+kerning first=84  second=115 amount=-4  
+kerning first=84  second=114 amount=-2  
+kerning first=84  second=113 amount=-3  
+kerning first=84  second=112 amount=-2  
+kerning first=84  second=111 amount=-3  
+kerning first=84  second=110 amount=-2  
+kerning first=84  second=109 amount=-2  
+kerning first=84  second=108 amount=-2  
+kerning first=84  second=107 amount=-2  
+kerning first=84  second=105 amount=-2  
+kerning first=84  second=104 amount=-2  
+kerning first=84  second=103 amount=-3  
+kerning first=84  second=102 amount=-2  
+kerning first=84  second=101 amount=-2  
+kerning first=84  second=100 amount=-2  
+kerning first=84  second=99  amount=-3  
+kerning first=84  second=98  amount=-2  
+kerning first=84  second=97  amount=-7  
+kerning first=84  second=89  amount=2   
+kerning first=84  second=88  amount=2   
+kerning first=84  second=87  amount=1   
+kerning first=84  second=84  amount=1   
+kerning first=84  second=83  amount=-1  
+kerning first=84  second=79  amount=-3  
+kerning first=84  second=77  amount=-2  
+kerning first=84  second=71  amount=-3  
+kerning first=84  second=67  amount=-3  
+kerning first=84  second=65  amount=-5  
+kerning first=84  second=59  amount=-3  
+kerning first=84  second=58  amount=-3  
+kerning first=84  second=46  amount=-12 
+kerning first=84  second=45  amount=-3  
+kerning first=84  second=44  amount=-12 
+kerning first=83  second=109 amount=-1  
+kerning first=81  second=41  amount=3   
+kerning first=81  second=66  amount=-3  
+kerning first=81  second=68  amount=-3  
+kerning first=81  second=69  amount=-3  
+kerning first=81  second=70  amount=-3  
+kerning first=81  second=72  amount=-3  
+kerning first=81  second=73  amount=-3  
+kerning first=81  second=75  amount=-3  
+kerning first=81  second=76  amount=-3  
+kerning first=81  second=78  amount=-3  
+kerning first=81  second=80  amount=-3  
+kerning first=81  second=82  amount=-3  
+kerning first=81  second=93  amount=3   
+kerning first=81  second=98  amount=-3  
+kerning first=81  second=100 amount=-3  
+kerning first=81  second=101 amount=-3  
+kerning first=81  second=102 amount=-3  
+kerning first=81  second=104 amount=-3  
+kerning first=81  second=105 amount=-3  
+kerning first=81  second=107 amount=-3  
+kerning first=81  second=108 amount=-3  
+kerning first=81  second=110 amount=-3  
+kerning first=81  second=112 amount=-3  
+kerning first=81  second=114 amount=-3  
+kerning first=81  second=125 amount=3   
+kerning first=83  second=77  amount=-1  
+kerning first=82  second=121 amount=-2  
+kerning first=82  second=120 amount=-1  
+kerning first=82  second=118 amount=-3  
+kerning first=82  second=116 amount=-6  
+kerning first=82  second=115 amount=-1  
+kerning first=82  second=113 amount=2   
+kerning first=82  second=111 amount=2   
+kerning first=82  second=103 amount=2   
+kerning first=82  second=99  amount=2   
+kerning first=82  second=97  amount=1   
+kerning first=82  second=89  amount=-2  
+kerning first=82  second=88  amount=-1  
+kerning first=82  second=86  amount=-3  
+kerning first=82  second=84  amount=-5  
+kerning first=82  second=83  amount=-1  
+kerning first=82  second=81  amount=2   
+kerning first=82  second=79  amount=2   
+kerning first=82  second=71  amount=2   
+kerning first=82  second=67  amount=2   
+kerning first=82  second=65  amount=1   

BIN
modules/ToyAssets/1/assets/fonts/Trajan Pro_0.png


BIN
unicows.dll