diff --git a/doc/doc_files/nav_bottom.html b/doc/doc_files/nav_bottom.html
index bd64910..f703cf3 100644
--- a/doc/doc_files/nav_bottom.html
+++ b/doc/doc_files/nav_bottom.html
@@ -299,6 +299,10 @@ ul, #myUL {
Stack_Size_S
+Stack_N_Exists
+
+Stack_S_Exists
+
@@ -569,6 +573,18 @@ ul, #myUL {
GetSpriteCanvasRenderPriority
+SetPostEffect
+
+ClearPostEffect
+
+SetPostEffectProperty
+
+GetPostEffectProperty
+
+SetPostEffectActive
+
+PostEffectIsActive
+
@@ -1173,6 +1189,8 @@ ul, #myUL {
GetMatrixScale
+MatrixExists
+
@@ -1451,6 +1469,8 @@ ul, #myUL {
GetSpriteShapeOffset
+GetSpriteWorldCenter
+
@@ -1691,6 +1711,16 @@ ul, #myUL {
FlipMeshSurfaces
+SetMeshBuffer
+
+GetMeshBufferCount
+
+GetMeshBufferVertexCount
+
+GetMeshBufferIndexCount
+
+GetMeshBuffer
+
@@ -2233,6 +2263,12 @@ ul, #myUL {
GetSceneAmbientColor
+Pipeline_Begin
+
+Pipeline_End
+
+Pipeline_Render
+
diff --git a/rcbasic_build/rcbasic4_changes.ods b/rcbasic_build/rcbasic4_changes.ods
index 4a19efc..ecabd31 100644
Binary files a/rcbasic_build/rcbasic4_changes.ods and b/rcbasic_build/rcbasic4_changes.ods differ
diff --git a/rcbasic_runtime/Android.mk b/rcbasic_runtime/Android.mk
old mode 100755
new mode 100644
index 81ef9e5..3c07759
--- a/rcbasic_runtime/Android.mk
+++ b/rcbasic_runtime/Android.mk
@@ -1,151 +1,85 @@
LOCAL_PATH := $(call my-dir)
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := Bullet-prebuilt
-LOCAL_SRC_FILES := ../bullet3/build3/Android/obj/local/$(TARGET_ARCH_ABI)/libBullet.a
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := freetype-prebuilt
-LOCAL_SRC_FILES := ../freetype/Android/libs/$(TARGET_ARCH_ABI)/libfreetype.so
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
-include $(PREBUILT_SHARED_LIBRARY)
-
include $(CLEAR_VARS)
LOCAL_MODULE := main
SDL_PATH := ../SDL
-SDL_IMAGE_PATH := ../SDL2_image
-SDL_MIXER_PATH := ../SDL2_mixer
-SDL_NET_PATH := ../SDL2_net
+IRRLICHT_PATH := ../RCIrrlicht
+
+SDL_MIXER_PATH := ../SDL_mixer
+SDL_NET_PATH := ../SDL_net
THEORA_PATH := ../theora
-IRR_PATH := ../RCIrrlicht
-BULLET_PATH := ../bullet3
-IRRBULLET_PATH := ../irrBullet
-IRRTHEORA_PATH := ../irrTheora
-FREETYPE_PATH := ../freetype
-BOX2D_PATH := ../box2d-2.4.2
+IRR_THEORA_PATH := ../irrTheora
+
AN8_PATH := ../an8-parser
+BOX2D_PATH := ../box2d-2.4.2
+BULLET_PATH := ../bullet3
+IRR_BULLET_PATH := ../irrBullet
+
VORBIS_LIBRARY_PATH := ../libvorbis64
THEORAPLAY_PATH := ../src/theoraplay
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
-VORBIS_LIBRARY_PATH := ../libvorbisidec-1.2.1
-THEORAPLAY_PATH := ../src/theoraplay_tremor
-endif
+FREETYPE_PATH := ../freetype-2.9.1
-LOCAL_CFLAGS := -I$(LOCAL_PATH)/$(THEORAPLAY_PATH) -I$(LOCAL_PATH)/$(IRR_PATH)/include -DRC_ANDROID_BUILD
-LOCAL_CPP_FEATURES += exceptions
+LOCAL_CFLAGS := -I$(LOCAL_PATH)/$(THEORAPLAY_PATH) -DRC_ANDROID_BUILD
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
- $(LOCAL_PATH)/$(SDL_IMAGE_PATH) \
- $(LOCAL_PATH)/$(SDL_MIXER_PATH) \
- $(LOCAL_PATH)/$(SDL_NET_PATH) \
- $(LOCAL_PATH)/$(THEORA_PATH) \
+ $(LOCAL_PATH)/$(SDL_MIXER_PATH)/include \
+ $(LOCAL_PATH)/$(SDL_NET_PATH)/include \
+ $(LOCAL_PATH)/$(THEORA_PATH)/include \
$(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)/include \
$(LOCAL_PATH)/$(THEORAPLAY_PATH) \
- $(LOCAL_PATH)/$(IRR_PATH)/include \
- $(LOCAL_PATH)/$(BULLET_PATH)/src \
- $(LOCAL_PATH)/$(IRRBULLET_PATH)/include \
- $(LOCAL_PATH)/$(IRRTHEORA_PATH) \
+ $(LOCAL_PATH)/$(IRR_THEORA_PATH) \
$(LOCAL_PATH)/$(FREETYPE_PATH)/include \
$(LOCAL_PATH)/$(AN8_PATH) \
- $(LOCAL_PATH)/$(BOX2D_PATH)/include
+ $(LOCAL_PATH)/$(BOX2D_PATH)/include \
+ $(LOCAL_PATH)/$(BULLET_PATH)/src \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/include
+
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(IRRLICHT_PATH)/include
# Add your application source files here...
-LOCAL_SRC_FILES := main.cpp $(LOCAL_PATH)/$(THEORAPLAY_PATH)/theoraplay.c gui_freetype_font.cpp
+LOCAL_SRC_FILES := main.cpp \
+ CShader.cpp \
+ gui_freetype_font.cpp \
+ ProjectiveTextures.cpp \
+ theoraplay.c
-LOCAL_SRC_FILES += \
- $(BOX2D_PATH)/src/collision/b2_broad_phase.cpp \
- $(BOX2D_PATH)/src/collision/b2_chain_shape.cpp \
- $(BOX2D_PATH)/src/collision/b2_circle_shape.cpp \
- $(BOX2D_PATH)/src/collision/b2_collide_circle.cpp \
- $(BOX2D_PATH)/src/collision/b2_collide_edge.cpp \
- $(BOX2D_PATH)/src/collision/b2_collide_polygon.cpp \
- $(BOX2D_PATH)/src/collision/b2_collision.cpp \
- $(BOX2D_PATH)/src/collision/b2_distance.cpp \
- $(BOX2D_PATH)/src/collision/b2_dynamic_tree.cpp \
- $(BOX2D_PATH)/src/collision/b2_edge_shape.cpp \
- $(BOX2D_PATH)/src/collision/b2_polygon_shape.cpp \
- $(BOX2D_PATH)/src/collision/b2_time_of_impact.cpp \
- $(BOX2D_PATH)/src/common/b2_block_allocator.cpp \
- $(BOX2D_PATH)/src/common/b2_draw.cpp \
- $(BOX2D_PATH)/src/common/b2_math.cpp \
- $(BOX2D_PATH)/src/common/b2_settings.cpp \
- $(BOX2D_PATH)/src/common/b2_stack_allocator.cpp \
- $(BOX2D_PATH)/src/common/b2_timer.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_body.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_chain_circle_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_chain_polygon_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_circle_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_contact_manager.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_contact_solver.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_distance_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_edge_circle_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_edge_polygon_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_fixture.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_friction_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_gear_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_island.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_motor_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_mouse_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_polygon_circle_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_polygon_contact.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_prismatic_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_pulley_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_revolute_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_weld_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_wheel_joint.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_world_callbacks.cpp \
- $(BOX2D_PATH)/src/dynamics/b2_world.cpp \
- $(BOX2D_PATH)/src/rope/b2_rope.cpp \
- $(IRRBULLET_PATH)/src/irrBulletBoxShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletBvhTriangleMeshShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCapsuleShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionCallBackInformation.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffectorAttract.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffector.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffectorDelete.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionObject.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCollisionShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletcommon.cpp \
- $(IRRBULLET_PATH)/src/irrBulletConeShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletConvexHullShape.cpp \
- $(IRRBULLET_PATH)/src/irrBullet.cpp \
- $(IRRBULLET_PATH)/src/irrBulletCylinderShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletGhostObject.cpp \
- $(IRRBULLET_PATH)/src/irrBulletGImpactMeshShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletLiquidBody.cpp \
- $(IRRBULLET_PATH)/src/irrBulletMotionState.cpp \
- $(IRRBULLET_PATH)/src/irrBulletPhysicsDebug.cpp \
- $(IRRBULLET_PATH)/src/irrBulletRayCastVehicle.cpp \
- $(IRRBULLET_PATH)/src/irrBulletRigidBody.cpp \
- $(IRRBULLET_PATH)/src/irrBulletSoftBody.cpp \
- $(IRRBULLET_PATH)/src/irrBulletSphereShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletTriangleMeshShape.cpp \
- $(IRRBULLET_PATH)/src/irrBulletWorld.cpp
+# Add irrBullet source files
+LOCAL_SRC_FILES += $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletBoxShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletBvhTriangleMeshShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCapsuleShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionCallBackInformation.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffectorAttract.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffector.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffectorDelete.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObject.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletcommon.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletConeShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletConvexHullShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBullet.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCylinderShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletGhostObject.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletGImpactMeshShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletLiquidBody.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletMotionState.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletPhysicsDebug.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletRayCastVehicle.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletRigidBody.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletSoftBody.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletSphereShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletTriangleMeshShape.cpp \
+ $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletWorld.cpp
+# LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_net ogg_shared vorbis64 theora
+LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_net SDL2_ttf ogg_shared vorbis64 theora
+LOCAL_STATIC_LIBRARIES := Irrlicht Box2d Bullet freetype
-
-LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_mixer SDL2_net Irrlicht freetype-prebuilt
-LOCAL_STATIC_LIBRARIES := Bullet-prebuilt android_native_app_glue
-
-RC_TH_LOCAL_SHARED_LIBRARIES := ogg_shared vorbis64 theora
-
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
-RC_TH_LOCAL_SHARED_LIBRARIES := ogg_shared tremor theora
-LOCAL_CFLAGS += -DRC_USE_TREMOR -O2
-endif
-
-LOCAL_SHARED_LIBRARIES += $(RC_TH_LOCAL_SHARED_LIBRARIES)
-
-LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
+LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
include $(BUILD_SHARED_LIBRARY)
diff --git a/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp b/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp
new file mode 100755
index 0000000..e2707b6
--- /dev/null
+++ b/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp
@@ -0,0 +1,616 @@
+#include "gui_freetype_font.h"
+
+#include
+
+#if COMPILE_WITH_FREETYPE
+
+#include
+
+#include
+
+#define LOGE(TAG, ...) __android_log_print(ANDROID_LOG_ERROR , TAG,__VA_ARGS__)
+
+using namespace irr;
+using namespace gui;
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4996)
+#endif
+
+
+// --------------------------------------------------------
+CGUITTGlyph::CGUITTGlyph()
+: IReferenceCounted()
+ ,cached(false)
+ ,size(0)
+ ,top(0)
+ ,left(0)
+ ,texw(0)
+ ,texh(0)
+ ,imgw(0)
+ ,imgh(0)
+ ,tex(NULL)
+ ,top16(0)
+ ,left16(0)
+ ,texw16(0)
+ ,texh16(0)
+ ,imgw16(0)
+ ,imgh16(0)
+ ,tex16(NULL)
+ ,image(NULL)
+{
+}
+
+CGUITTGlyph::~CGUITTGlyph()
+{
+ delete[] image;
+}
+
+//void CGUITTGlyph::cache(u32 idx_, CGUITTFace& ttFace_, video::IVideoDriver* driver_, irr::core::dimension2d &largestSize)
+void CGUITTGlyph::cache(u32 idx_, const CGUIFreetypeFont * freetypeFont)
+{
+ assert(freetypeFont);
+
+ FT_Face face = freetypeFont->TrueTypeFace->face;
+
+ FT_Set_Pixel_Sizes(face, 0, size);
+ if ( size > freetypeFont->LargestGlyph.Height )
+ freetypeFont->LargestGlyph.Height = size;
+
+ if ( !FT_Load_Glyph(face, idx_, FT_LOAD_NO_HINTING|FT_LOAD_NO_BITMAP) )
+ {
+ FT_GlyphSlot glyph = face->glyph;
+ FT_Bitmap bits;
+
+ if (glyph->format == ft_glyph_format_outline )
+ {
+ if (!FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL))
+ {
+ bits = glyph->bitmap;
+ u8 *pt = bits.buffer;
+ delete[] image;
+ image = new u8[bits.width * bits.rows];
+ memcpy(image,pt,bits.width * bits.rows);
+ top = glyph->bitmap_top;
+ left = glyph->bitmap_left;
+ imgw = 1;
+ imgh = 1;
+ texw = bits.width;
+ texh = bits.rows;
+ for(;;)
+ {
+ if (imgw > texw)
+ {
+ break;
+ }
+ else
+ {
+ imgw <<= 1;
+ }
+ }
+ for(;;)
+ {
+ if (imgh > texh)
+ {
+ break;
+ }
+ else
+ {
+ imgh <<= 1;
+ }
+ }
+ if (imgw > imgh)
+ {
+ imgh = imgw;
+ }
+ else
+ {
+ imgw = imgh;
+ }
+
+ s32 offx = left;
+ s32 offy = size - top;
+ if ( offx+texw > freetypeFont->LargestGlyph.Width )
+ freetypeFont->LargestGlyph.Width = offx+texw;
+ if ( offy+texh > freetypeFont->LargestGlyph.Height )
+ freetypeFont->LargestGlyph.Height = offy+texh;
+
+ u32 *texd = new u32[imgw*imgh];
+ memset(texd,0,imgw*imgh*sizeof(u32));
+ u32 *texp = texd;
+ bool cflag = (freetypeFont->Driver->getDriverType() == video::EDT_DIRECT3D9);
+ for (int i = 0;i < bits.rows;i++)
+ {
+ u32 *rowp = texp;
+ for (int j = 0;j < bits.width;j++)
+ {
+ if (*pt)
+ {
+ if (cflag)
+ {
+ *rowp = *pt;
+ *rowp *= 0x01010101;
+ }
+ else
+ {
+ *rowp = *pt << 24;
+ *rowp |= 0xffffff;
+ }
+ }
+ else
+ {
+ *rowp = 0;
+ }
+ pt++;
+ rowp++;
+ }
+ texp += imgw;
+ }
+
+ c8 name[128];
+ sprintf(name,"ttf%d_%d_%p",idx_, size, freetypeFont );
+ video::IImage *img = freetypeFont->Driver->createImageFromData(video::ECF_A8R8G8B8,core::dimension2d(imgw,imgh),texd);
+ setGlyphTextureFlags(freetypeFont->Driver);
+ tex = freetypeFont->Driver->addTexture(name,img);
+ img->drop();
+ restoreTextureFlags(freetypeFont->Driver);
+ delete[] texd;
+ cached = true;
+ }
+ }
+ }
+
+ if (!FT_Load_Glyph(face,idx_,FT_LOAD_NO_HINTING|FT_LOAD_RENDER|FT_LOAD_MONOCHROME))
+ {
+ FT_GlyphSlot glyph = face->glyph;
+ FT_Bitmap bits = glyph->bitmap;
+ u8 *pt = bits.buffer;
+ top16 = glyph->bitmap_top;
+ left16 = glyph->bitmap_left;
+ imgw16 = 1;
+ imgh16 = 1;
+ texw16 = bits.width;
+ texh16 = bits.rows;
+ for(;;)
+ {
+ if (imgw16 >= texw16)
+ {
+ break;
+ }
+ else
+ {
+ imgw16 <<= 1;
+ }
+ }
+ for(;;)
+ {
+ if (imgh16 >= texh16)
+ {
+ break;
+ }
+ else
+ {
+ imgh16 <<= 1;
+ }
+ }
+ if (imgw16 > imgh16)
+ {
+ imgh16 = imgw16;
+ }
+ else
+ {
+ imgw16 = imgh16;
+ }
+
+ s32 offx = left;
+ s32 offy = size - top;
+ if ( offx+texw > freetypeFont->LargestGlyph.Width )
+ freetypeFont->LargestGlyph.Width = offx+texw;
+ if ( offy+texh > freetypeFont->LargestGlyph.Height )
+ freetypeFont->LargestGlyph.Height = offy+texh;
+
+
+ u16 *texd16 = new u16[imgw16*imgh16];
+ memset(texd16,0,imgw16*imgh16*sizeof(u16));
+ u16 *texp16 = texd16;
+ for (int y = 0;y < bits.rows;y++)
+ {
+ u16 *rowp = texp16;
+ for (int x = 0;x < bits.width;x++)
+ {
+ if (pt[y * bits.pitch + (x / 8)] & (0x80 >> (x % 8)))
+ {
+ *rowp = 0xffff;
+ }
+ rowp++;
+ }
+ texp16 += imgw16;
+ }
+ c8 name[128];
+ sprintf(name,"ttf%d_%d_%p_16",idx_, size, freetypeFont );
+ video::IImage *img = freetypeFont->Driver->createImageFromData(video::ECF_A1R5G5B5,core::dimension2d(imgw16,imgh16),texd16);
+ setGlyphTextureFlags(freetypeFont->Driver);
+ tex16 = freetypeFont->Driver->addTexture(name,img);
+ img->drop();
+ restoreTextureFlags(freetypeFont->Driver);
+// freetypeFont->Driver->makeColorKeyTexture(tex16,video::SColor(0,0,0,0));
+ delete[] texd16;
+ }
+}
+
+bool CGUITTGlyph::mTexFlag16 = false;
+bool CGUITTGlyph::mTexFlag32 = true;
+bool CGUITTGlyph::mTexFlagMip = false;
+
+void CGUITTGlyph::setGlyphTextureFlags(video::IVideoDriver* driver_)
+{
+ mTexFlag16 = driver_->getTextureCreationFlag(video::ETCF_ALWAYS_16_BIT);
+ mTexFlag32 = driver_->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT);
+ mTexFlagMip = driver_->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
+ driver_->setTextureCreationFlag(video::ETCF_ALWAYS_16_BIT,false);
+ driver_->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true);
+ driver_->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
+}
+
+void CGUITTGlyph::restoreTextureFlags(video::IVideoDriver* driver_)
+{
+ driver_->setTextureCreationFlag(video::ETCF_ALWAYS_16_BIT, mTexFlag16);
+ driver_->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, mTexFlag32);
+ driver_->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mTexFlagMip);
+}
+
+// --------------------------------------------------------
+FT_Library CGUITTFace::library = 0;
+int CGUITTFace::countClassObjects = 0;
+bool CGUITTFace::ttf_init = false;
+
+CGUITTFace::CGUITTFace()
+: face(0)
+{
+ ++countClassObjects;
+ is_sdl = false;
+
+ if(!ttf_init)
+ {
+ TTF_Init();
+ ttf_init = true;
+ }
+}
+
+CGUITTFace::~CGUITTFace()
+{
+ if( is_sdl )
+ {
+ TTF_CloseFont(sdl_font);
+ face = NULL;
+ sdl_font = NULL;
+ }
+
+ if ( face )
+ FT_Done_Face( face );
+
+ --countClassObjects;
+ assert(countClassObjects >= 0 );
+ if ( !countClassObjects && library )
+ {
+ FT_Done_FreeType( library );
+ library = 0;
+ }
+}
+
+//! loads a font file
+bool CGUITTFace::load(const irr::io::path& filename)
+{
+ //TTF_Font* sdl_font = TTF_Open
+ if ( !library )
+ {
+ if (FT_Init_FreeType( &library ))
+ {
+ return false;
+ }
+ }
+ core::stringc ansiFilename(filename); // path can be anything but freetype can only work with ansi-filenames
+ if (FT_New_Face( library,ansiFilename.c_str(),0,&face ))
+ {
+ return false;
+ }
+ return true;
+}
+
+// --------------------------------------------------------
+//! constructor
+CGUIFreetypeFont::CGUIFreetypeFont(video::IVideoDriver* driver)
+: Driver(driver)
+, TrueTypeFace(0)
+{
+ #ifdef _DEBUG
+ setDebugName("CGUIFreetypeFont");
+ #endif
+
+ if (Driver)
+ Driver->grab();
+ AntiAlias = false;
+ Transparency = false;
+}
+
+
+
+//! destructor
+CGUIFreetypeFont::~CGUIFreetypeFont()
+{
+ if ( TrueTypeFace )
+ TrueTypeFace->drop();
+ if (Driver)
+ Driver->drop();
+ clearGlyphs();
+}
+
+bool CGUIFreetypeFont::attach(CGUITTFace *Face,u32 size)
+{
+ if (!Driver || !Face)
+ return false;
+
+ Face->grab();
+ if ( TrueTypeFace )
+ TrueTypeFace->drop();
+ TrueTypeFace = Face;
+ if ( !TrueTypeFace )
+ return false;
+
+ clearGlyphs();
+ Glyphs.reallocate(TrueTypeFace->face->num_glyphs);
+ Glyphs.set_used(TrueTypeFace->face->num_glyphs);
+ for (int i = 0;i < TrueTypeFace->face->num_glyphs;i++)
+ {
+ CGUITTGlyph * glyph = new CGUITTGlyph();
+
+ glyph->size = size;
+// glyph->cache((wchar_t)i + 1);
+
+ Glyphs[i] = glyph;
+ }
+
+ // TODO: this is a workaround to get a probably ok height for getDimensions. So we check a few extreme characters which usually make trouble.
+ getGlyphByChar(L'A');
+ getGlyphByChar(L'g');
+ getGlyphByChar(L'.');
+ getGlyphByChar(L'(');
+
+ return true;
+}
+
+bool CGUIFreetypeFont::sdl_loadfont(irr::io::path font_file,irr::u32 size)
+{
+ if (!Driver)
+ return false;
+
+ CGUITTFace *Face = new CGUITTFace();
+
+ if(!Face)
+ return false;
+
+ TTF_Font* sdl_font = TTF_OpenFont(font_file.c_str(), size);
+
+ if(!sdl_font)
+ {
+ LOGE("RCTEST", "TTF_OpenFont(%s) FAILED -> error: %s", font_file.c_str(), TTF_GetError());
+ delete Face;
+ return false;
+ }
+
+ Face->face = (FT_Face)TTF_GetFreeTypeFace(sdl_font);
+ Face->is_sdl = true;
+
+ Face->grab();
+ if ( TrueTypeFace )
+ TrueTypeFace->drop();
+ TrueTypeFace = Face;
+ if ( !TrueTypeFace )
+ return false;
+
+ clearGlyphs();
+ Glyphs.reallocate(TrueTypeFace->face->num_glyphs);
+ Glyphs.set_used(TrueTypeFace->face->num_glyphs);
+ for (int i = 0;i < TrueTypeFace->face->num_glyphs;i++)
+ {
+ CGUITTGlyph * glyph = new CGUITTGlyph();
+
+ glyph->size = size;
+// glyph->cache((wchar_t)i + 1);
+
+ Glyphs[i] = glyph;
+ }
+
+ // TODO: this is a workaround to get a probably ok height for getDimensions. So we check a few extreme characters which usually make trouble.
+ getGlyphByChar(L'A');
+ getGlyphByChar(L'g');
+ getGlyphByChar(L'.');
+ getGlyphByChar(L'(');
+
+ return true;
+}
+
+CGUITTFace* CGUIFreetypeFont::getFace()
+{
+ return TrueTypeFace;
+}
+
+void CGUIFreetypeFont::clearGlyphs()
+{
+ for ( unsigned int i=0; i < Glyphs.size(); ++i )
+ {
+ if ( Glyphs[i] )
+ {
+ Glyphs[i]->drop();
+ }
+ Glyphs[i] = 0;
+ }
+}
+
+u32 CGUIFreetypeFont::getGlyphByChar(wchar_t c) const
+{
+ u32 idx = FT_Get_Char_Index( TrueTypeFace->face, c );
+ if ( idx && !Glyphs[idx - 1]->cached )
+ Glyphs[idx - 1]->cache(idx, this);
+ return idx;
+}
+
+//! returns the dimension of a text
+core::dimension2d CGUIFreetypeFont::getDimension(const wchar_t* text) const
+{
+ core::dimension2d dim(0, Glyphs[0]->size);
+
+ for(const wchar_t* p = text; *p; ++p)
+ {
+ dim.Width += getWidthFromCharacter(*p);
+ }
+
+ // TODO: The correct solution might be working with TrueTypeFace->height but I can't figure out how to use units_per_EM
+ // even if I know which FT_Render_Mode I used. I'm sure there is some way to figure that out, but I have to give up for now.
+ if ( TrueTypeFace && LargestGlyph.Height > dim.Height)
+ dim.Height = LargestGlyph.Height;
+
+ return dim;
+}
+
+
+inline u32 CGUIFreetypeFont::getWidthFromCharacter(wchar_t c) const
+{
+ u32 n = getGlyphByChar(c);
+ if ( n > 0)
+ {
+ int w = Glyphs[n - 1]->texw;
+ s32 left = Glyphs[n - 1]->left;
+ if (w + left > 0)
+ return w + left;
+ }
+ if (c >= 0x2000)
+ {
+ return Glyphs[0]->size;
+ }
+ else
+ {
+ return Glyphs[0]->size / 2;
+ }
+}
+
+
+//! draws an text and clips it to the specified rectangle if wanted
+void CGUIFreetypeFont::draw(const irr::core::stringw& textstring, const irr::core::rect& position, video::SColor color, bool hcenter, bool vcenter, const core::rect* clip)
+{
+ if (!Driver)
+ return;
+
+ core::dimension2d textDimension;
+ core::position2d offset = position.UpperLeftCorner;
+ video::SColor colors[4];
+ for (int i = 0;i < 4;i++)
+ {
+ colors[i] = color;
+ }
+
+ const wchar_t * text = textstring.c_str();
+ if (hcenter || vcenter)
+ {
+ textDimension = getDimension(text);
+
+ if (hcenter)
+ offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X;
+
+ if (vcenter)
+ offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y;
+ }
+
+ u32 n;
+
+ while(*text)
+ {
+ n = getGlyphByChar(*text);
+ if ( n > 0)
+ {
+ if (AntiAlias)
+ {
+// s32 imgw = Glyphs[n-1]->imgw;
+// s32 imgh = Glyphs[n-1]->imgh;
+ s32 texw = Glyphs[n-1]->texw;
+ s32 texh = Glyphs[n-1]->texh;
+ s32 offx = Glyphs[n-1]->left;
+ s32 offy = Glyphs[n-1]->size - Glyphs[n-1]->top;
+ if (Driver->getDriverType() != video::EDT_SOFTWARE)
+ {
+ if (!Transparency)
+ color.color |= 0xff000000;
+ Driver->draw2DImage(Glyphs[n-1]->tex,core::position2d(offset.X+offx,offset.Y+offy),core::rect(0,0,texw,texh),clip,color,true);
+ }
+ else
+ {
+ s32 a = color.getAlpha();
+ s32 r = color.getRed();
+ s32 g = color.getGreen();
+ s32 b = color.getBlue();
+ u8 *pt = Glyphs[n-1]->image;
+ if (!Transparency) a = 255;
+ for (int y = 0;y < texh;y++)
+ {
+ for (int x = 0;x < texw;x++)
+ {
+ if (!clip || clip->isPointInside(core::position2d(offset.X+x+offx,offset.Y+y+offy)))
+ {
+ if (*pt)
+ {
+ Driver->draw2DRectangle(video::SColor((a * *pt)/255,r,g,b),core::rect(offset.X+x+offx,offset.Y+y+offy,offset.X+x+offx+1,offset.Y+y+offy+1));
+ }
+ pt++;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+// s32 imgw = Glyphs[n-1]->imgw16;
+// s32 imgh = Glyphs[n-1]->imgh16;
+ s32 texw = Glyphs[n-1]->texw16;
+ s32 texh = Glyphs[n-1]->texh16;
+ s32 offx = Glyphs[n-1]->left16;
+ s32 offy = Glyphs[n-1]->size - Glyphs[n-1]->top16;
+ if (!Transparency)
+ {
+ color.color |= 0xff000000;
+ }
+ Driver->draw2DImage(Glyphs[n-1]->tex16,
+ core::position2d(offset.X+offx,offset.Y+offy),
+ core::rect(0,0,texw,texh),
+ clip, color, true);
+ }
+ offset.X += getWidthFromCharacter(*text);
+ }
+ else
+ {
+ offset.X += getWidthFromCharacter(*text);
+ }
+
+ ++text;
+ }
+}
+
+//! Calculates the index of the character in the text which is on a specific position.
+s32 CGUIFreetypeFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
+{
+ s32 x = 0;
+ s32 idx = 0;
+
+ while (text[idx])
+ {
+ x += getWidthFromCharacter(text[idx]);
+
+ if (x >= pixel_x)
+ return idx;
+
+ ++idx;
+ }
+
+ return -1;
+}
+
+#endif // #if COMPILE_WITH_FREETYPE
diff --git a/rcbasic_runtime/android_alt_src/gui_freetype_font.h b/rcbasic_runtime/android_alt_src/gui_freetype_font.h
new file mode 100755
index 0000000..2e6a65e
--- /dev/null
+++ b/rcbasic_runtime/android_alt_src/gui_freetype_font.h
@@ -0,0 +1,141 @@
+#include "rc_os_defines.h"
+
+#ifndef _GUI_FREETYPE_FONT_H
+#define _GUI_FREETYPE_FONT_H
+
+//! freetype support enabled with 1 and disabled with 0
+#define COMPILE_WITH_FREETYPE 1
+
+
+#if COMPILE_WITH_FREETYPE
+
+#ifdef RC_ANDROID
+ #include "ft2build.h"
+ #include "freetype/freetype.h"
+ #include
+#else
+ #include
+ #include
+#endif // RC_ANDROID
+#include
+
+class CGUITTFace : public irr::IReferenceCounted
+{
+public:
+ CGUITTFace();
+ virtual ~CGUITTFace();
+
+ bool load(const irr::io::path& filename);
+
+ FT_Face face; // handle to face
+ bool is_sdl;
+
+private:
+ static bool ttf_init;
+ static int countClassObjects;
+ static FT_Library library; // handle to library
+
+ TTF_Font* sdl_font;
+};
+
+class CGUIFreetypeFont;
+
+class CGUITTGlyph : public irr::IReferenceCounted
+{
+public:
+ CGUITTGlyph();
+ virtual ~CGUITTGlyph();
+
+ bool cached;
+ void cache(irr::u32 idx_, const CGUIFreetypeFont * freetypeFont);
+
+ irr::u32 size;
+ irr::u32 top;
+ irr::u32 left;
+ irr::u32 texw;
+ irr::u32 texh;
+ irr::u32 imgw;
+ irr::u32 imgh;
+ irr::video::ITexture *tex;
+ irr::u32 top16;
+ irr::u32 left16;
+ irr::u32 texw16;
+ irr::u32 texh16;
+ irr::u32 imgw16;
+ irr::u32 imgh16;
+ irr::video::ITexture *tex16;
+ irr::u8 *image;
+
+private:
+ void setGlyphTextureFlags(irr::video::IVideoDriver* driver_);
+ void restoreTextureFlags(irr::video::IVideoDriver* driver_);
+
+ static bool mTexFlag16;
+ static bool mTexFlag32;
+ static bool mTexFlagMip;
+};
+
+class CGUIFreetypeFont : public irr::gui::IGUIFont
+{
+ friend class CGUITTGlyph;
+
+public:
+
+ //! constructor
+ CGUIFreetypeFont(irr::video::IVideoDriver* Driver);
+
+ //! destructor
+ virtual ~CGUIFreetypeFont();
+
+ //! loads a truetype font file
+ bool attach(CGUITTFace *Face,irr::u32 size);
+
+ //! loads a truetype font file using SDL2
+ bool sdl_loadfont(irr::io::path font_file,irr::u32 size);
+
+ CGUITTFace* getFace();
+
+ //! draws an text and clips it to the specified rectangle if wanted
+ virtual void draw(const irr::core::stringw& text, const irr::core::rect& position, irr::video::SColor color, bool hcenter=false, bool vcenter=false, const irr::core::rect* clip=0);
+
+ //! returns the dimension of a text
+ virtual irr::core::dimension2d getDimension(const wchar_t* text) const;
+
+ //! Calculates the index of the character in the text which is on a specific position.
+ virtual irr::s32 getCharacterFromPos(const wchar_t* text, irr::s32 pixel_x) const;
+
+ //! Not yet supported
+ virtual void setKerningWidth (irr::s32 kerning) {}
+
+ //! Not yet supported
+ virtual void setKerningHeight (irr::s32 kerning) {}
+
+ //! Not yet supported
+ virtual irr::s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const { return 0; }
+
+ //! Not yet supported
+ virtual irr::s32 getKerningHeight() const { return 0; }
+
+ //! Not yet supported
+ virtual void setInvisibleCharacters( const wchar_t *s ) {}
+
+
+ bool AntiAlias;
+ bool Transparency;
+
+protected:
+ void clearGlyphs();
+
+private:
+ irr::u32 getWidthFromCharacter(wchar_t c) const;
+ irr::u32 getGlyphByChar(wchar_t c) const;
+ irr::video::IVideoDriver* Driver;
+ irr::core::array< CGUITTGlyph* > Glyphs;
+ CGUITTFace * TrueTypeFace;
+ mutable irr::core::dimension2d LargestGlyph;
+};
+
+#endif // #if COMPILE_WITH_FREETYPE
+
+#endif // _GUI_FREETYPE_FONT_H
+