Browse Source

Merge branch 'ькп' into tween2script

# Conflicts:
#	oxygine/src/Tween.h
dmuratshin 9 years ago
parent
commit
69b1cfcb90
100 changed files with 762 additions and 464 deletions
  1. 3 0
      .gitignore
  2. BIN
      3rdPartyTools/PVRTexToolCL.exe
  3. BIN
      doc/doc.zip
  4. BIN
      doc/wiki.zip
  5. 0 0
      examples/Demo/build_atlasses.bat
  6. 0 0
      examples/Demo/build_atlasses.sh
  7. 0 0
      examples/Demo/build_atlasses_etc1.bat
  8. 0 0
      examples/Demo/build_atlasses_low.bat
  9. 0 0
      examples/Demo/build_atlasses_pvrtc.bat
  10. 0 0
      examples/Demo/build_atlasses_pvrtc.sh
  11. 0 0
      examples/Demo/build_atlasses_pvrtc_high_quality.sh
  12. 2 0
      examples/Demo/proj.cmake/build_emsc.bat
  13. 2 0
      examples/Demo/proj.cmake/build_emsc_release.bat
  14. 1 0
      examples/Demo/proj.win32/Demo.vcxproj
  15. 1 0
      examples/Demo/proj.win32/Demo.vcxproj.filters
  16. 159 0
      examples/Demo/src/TestCamera.h
  17. 64 4
      examples/Demo/src/TestDrag.h
  18. 1 1
      examples/Demo/src/TestInputText.h
  19. 1 1
      examples/Demo/src/TestManageRes.h
  20. 2 2
      examples/Demo/src/TestMask.h
  21. 2 1
      examples/Demo/src/TestProgressBar.h
  22. 3 3
      examples/Demo/src/TestText.h
  23. 29 14
      examples/Demo/src/TestTouches.h
  24. 3 0
      examples/Demo/src/example.cpp
  25. 2 2
      examples/Demo/src/test.cpp
  26. 2 0
      examples/DemoBox2D/proj.cmake/build_emsc.bat
  27. 2 0
      examples/DemoBox2D/proj.cmake/build_emsc_release.bat
  28. 1 1
      examples/DemoBox2D/src/example.cpp
  29. 2 0
      examples/Game/part1/proj.cmake/build_emsc.bat
  30. 2 0
      examples/Game/part1/proj.cmake/build_emsc_release.bat
  31. 2 0
      examples/Game/part2/proj.cmake/build_emsc.bat
  32. 2 0
      examples/Game/part2/proj.cmake/build_emsc_release.bat
  33. 1 1
      examples/Game/part2/src/Enemy.cpp
  34. 2 2
      examples/Game/part2/src/Rocket.cpp
  35. 2 0
      examples/Game/part3/proj.cmake/build_emsc.bat
  36. 2 0
      examples/Game/part3/proj.cmake/build_emsc_release.bat
  37. 1 1
      examples/Game/part3/src/Enemy.cpp
  38. 2 2
      examples/Game/part3/src/Rocket.cpp
  39. 1 1
      examples/Game/part3/src/Scene.cpp
  40. 2 0
      examples/Game/part4/proj.cmake/build_emsc.bat
  41. 2 0
      examples/Game/part4/proj.cmake/build_emsc_release.bat
  42. 1 1
      examples/Game/part4/src/Enemy.cpp
  43. 1 1
      examples/Game/part4/src/GameMenu.cpp
  44. 1 1
      examples/Game/part4/src/MyButton.cpp
  45. 2 2
      examples/Game/part4/src/Rocket.cpp
  46. 1 1
      examples/Game/part4/src/Scene.cpp
  47. 2 0
      examples/Game/part5/proj.cmake/build_emsc.bat
  48. 2 0
      examples/Game/part5/proj.cmake/build_emsc_release.bat
  49. 1 1
      examples/Game/part5/src/Enemy.cpp
  50. 1 1
      examples/Game/part5/src/GameMenu.cpp
  51. 1 1
      examples/Game/part5/src/MyButton.cpp
  52. 2 2
      examples/Game/part5/src/Rocket.cpp
  53. 1 1
      examples/Game/part5/src/Scene.cpp
  54. 2 0
      examples/HelloWorld/proj.cmake/build_emsc.bat
  55. 2 0
      examples/HelloWorld/proj.cmake/build_emsc_release.bat
  56. 2 8
      examples/HelloWorld/src/example.cpp
  57. 2 0
      examples/Match3/proj.cmake/build_emsc.bat
  58. 2 0
      examples/Match3/proj.cmake/build_emsc_release.bat
  59. BIN
      libs/SDL2.dll
  60. BIN
      libs/SDL2.lib
  61. BIN
      libs/SDL2main.lib
  62. 3 3
      oxygine/SDL/android/extension/build.gradle
  63. 7 7
      oxygine/SDL/android/lib/build.gradle
  64. 39 25
      oxygine/SDL/android/lib/src/org/libsdl/app/SDLActivity.java
  65. 32 2
      oxygine/SDL/android/lib/src/org/oxygine/lib/HttpRequests.java
  66. 7 0
      oxygine/SDL/android/lib/src/org/oxygine/lib/Utils.java
  67. 0 16
      oxygine/SDL/ios/oxygine/oxygine_ios.xcodeproj/project.pbxproj
  68. 0 16
      oxygine/SDL/macosx/oxygine_macosx/oxygine_macosx.xcodeproj/project.pbxproj
  69. 2 4
      oxygine/SDL/win32/oxygine.vcxproj
  70. 6 12
      oxygine/SDL/win32/oxygine.vcxproj.filters
  71. 56 62
      oxygine/src/Actor.cpp
  72. 33 72
      oxygine/src/Actor.h
  73. 4 2
      oxygine/src/AnimationFrame.cpp
  74. 2 5
      oxygine/src/AnimationFrame.h
  75. 6 5
      oxygine/src/AsyncTask.h
  76. 6 11
      oxygine/src/Box9Sprite.cpp
  77. 4 9
      oxygine/src/Box9Sprite.h
  78. 20 11
      oxygine/src/Button.cpp
  79. 4 12
      oxygine/src/Button.h
  80. 5 5
      oxygine/src/ClipRectActor.cpp
  81. 4 7
      oxygine/src/ClipRectActor.h
  82. 1 4
      oxygine/src/Clock.h
  83. 6 1
      oxygine/src/ColorRectSprite.cpp
  84. 8 11
      oxygine/src/ColorRectSprite.h
  85. 67 23
      oxygine/src/DebugActor.cpp
  86. 6 11
      oxygine/src/DebugActor.h
  87. 1 2
      oxygine/src/Draggable.h
  88. 8 11
      oxygine/src/Event.h
  89. 0 1
      oxygine/src/EventDispatcher.cpp
  90. 11 7
      oxygine/src/EventDispatcher.h
  91. 6 13
      oxygine/src/Font.cpp
  92. 12 10
      oxygine/src/Font.h
  93. 6 1
      oxygine/src/HttpRequestTask.cpp
  94. 1 4
      oxygine/src/HttpRequestTask.h
  95. 13 3
      oxygine/src/Image.cpp
  96. 7 1
      oxygine/src/Image.h
  97. 29 7
      oxygine/src/Input.cpp
  98. 9 9
      oxygine/src/Input.h
  99. 1 2
      oxygine/src/InputText.h
  100. 1 1
      oxygine/src/MaskedRenderer.cpp

+ 3 - 0
.gitignore

@@ -62,3 +62,6 @@ build
 /examples/Demo/proj.cmake/mingw
 **/proj.marmalade/build_demo_vc*
 .DS_Store
+*.VC.db
+*.VC.VC.opendb
+oxygine/SDL/win32/oxygine.vcxproj.user

BIN
3rdPartyTools/PVRTexToolCL.exe


BIN
doc/doc.zip


BIN
doc/wiki.zip


+ 0 - 0
examples/Demo/prepare_res.bat → examples/Demo/build_atlasses.bat


+ 0 - 0
examples/Demo/prepare_res.sh → examples/Demo/build_atlasses.sh


+ 0 - 0
examples/Demo/prepare_res_etc1.bat → examples/Demo/build_atlasses_etc1.bat


+ 0 - 0
examples/Demo/prepare_res_low.bat → examples/Demo/build_atlasses_low.bat


+ 0 - 0
examples/Demo/prepare_res_pvrtc.bat → examples/Demo/build_atlasses_pvrtc.bat


+ 0 - 0
examples/Demo/prepare_res_pvrtc.sh → examples/Demo/build_atlasses_pvrtc.sh


+ 0 - 0
examples/Demo/prepare_res_pvrtc_high_quality.sh → examples/Demo/build_atlasses_pvrtc_high_quality.sh


+ 2 - 0
examples/Demo/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Demo/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 0
examples/Demo/proj.win32/Demo.vcxproj

@@ -144,6 +144,7 @@
     <ClInclude Include="../src/TestUserShader2.h" />
     <ClInclude Include="../src/example.h" />
     <ClInclude Include="../src/test.h" />
+    <ClInclude Include="..\src\TestCamera.h" />
     <ClInclude Include="..\src\TestEdges.h" />
     <ClInclude Include="..\src\TestSignedDistanceFont.h" />
     <ClInclude Include="..\src\TestTweenPostProcessing.h" />

+ 1 - 0
examples/Demo/proj.win32/Demo.vcxproj.filters

@@ -37,5 +37,6 @@
     <ClInclude Include="..\src\TestEdges.h" />
     <ClInclude Include="..\src\TestTweenPostProcessing.h" />
     <ClInclude Include="..\src\TestSignedDistanceFont.h" />
+    <ClInclude Include="..\src\TestCamera.h" />
   </ItemGroup>
 </Project>

+ 159 - 0
examples/Demo/src/TestCamera.h

@@ -0,0 +1,159 @@
+#pragma once
+#include "test.h"
+#include <map>
+
+DECLARE_SMART(Camera, spCamera);
+class Camera : public Actor
+{
+public:
+
+    spActor _content;
+
+    Camera()
+    {
+        addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &Camera::onEvent));
+        addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Camera::onEvent));
+        addEventListener(TouchEvent::MOVE, CLOSURE(this, &Camera::onEvent));
+        addEventListener(TouchEvent::WHEEL_DIR, CLOSURE(this, &Camera::onEvent));
+
+        _transform.identity();
+    }
+
+    void setContent(spActor content)
+    {
+        _content = content;
+        addChild(content);
+    }
+
+    struct touch
+    {
+        Vector2 current;
+        Vector2 previous;
+    };
+
+    std::map<int, touch> _touches;
+
+    void onEvent(Event* ev)
+    {
+        TouchEvent* te = safeCast<TouchEvent*>(ev);
+        const Vector2& pos = te->localPosition;
+
+
+
+        if (te->type == TouchEvent::TOUCH_DOWN)
+        {
+            touch& t = _touches[te->index];
+            t.previous = t.current = pos;
+        }
+
+        if (te->type == TouchEvent::TOUCH_UP)
+        {
+            auto it = _touches.find(te->index);
+            if (it != _touches.end())
+                _touches.erase(it);
+        }
+
+        if (te->type == TouchEvent::WHEEL_DIR)
+        {
+            if (te->wheelDirection.y != 0.0f)
+            {
+                float scale = te->wheelDirection.y < 0 ? 0.95f : 1.05f;
+
+                _transform.translate(-Vector3(pos.x, pos.y, 0));
+                _transform.scale(Vector3(scale, scale, 1));
+                _transform.translate(Vector3(pos.x, pos.y, 0));
+            }
+        }
+
+        if (te->type == TouchEvent::MOVE && !_touches.empty())
+        {
+            touch& t = _touches[te->index];
+            t.previous = t.current;
+
+            t.current = pos;
+
+            if (_touches.size() == 1)
+            {
+                Vector2 offset = t.current - t.previous;
+                _transform.translate(Vector3(offset.x, offset.y, 0));
+            }
+            else
+            {
+                touch* p1, *p2;
+                for (auto& t : _touches)
+                {
+                    if (t.first == te->index)
+                        p1 = &t.second;
+                    else
+                        p2 = &t.second;
+                }
+
+                Vector2 center = (p1->current + p2->current) / 2;
+                Vector2 prevCenter = (p1->previous + p2->previous) / 2;
+
+                float dist = p1->current.distance(p2->current);
+                float prevDist = p1->previous.distance(p2->previous);
+                float scale = dist / prevDist;
+
+
+                Vector2 offset = center - prevCenter;
+
+                p1->previous = p1->current;
+                p2->previous = p2->current;
+
+                _transform.translate(Vector3(offset.x, offset.y, 0));
+
+
+                _transform.translate(-Vector3(center.x, center.y, 0));
+                _transform.scale(Vector3(scale, scale, 1));
+                _transform.translate(Vector3(center.x, center.y, 0));
+            }
+        }
+
+        update();
+    }
+
+    void doUpdate(const UpdateState& us)
+    {
+
+    }
+
+    void update()
+    {
+        Transform tr(_transform);
+        _content->setTransform(tr);
+    }
+
+    Matrix _transform;
+};
+
+
+class TestCamera : public Test
+{
+public:
+    TestCamera()
+    {
+        spCamera cam = new Camera;
+        cam->attachTo(content);
+        cam->setSize(content->getSize());
+
+
+        spSprite map = new Sprite();
+        map->setResAnim(resources.getResAnim("map"));
+        cam->setContent(map);
+
+        spButton button = new Button;
+
+        button->setPosition(map->getSize() / 2);
+        button->setResAnim(resourcesUI.getResAnim("button"));
+        button->attachTo(map);
+        button->setAnchor(0.5f, 0.5f);
+        button->addEventListener(TouchEvent::CLICK, CLOSURE(this, &TestCamera::testClick));
+
+    }
+
+    void testClick(Event* event)
+    {
+        notify("clicked");
+    }
+};

+ 64 - 4
examples/Demo/src/TestDrag.h

@@ -7,10 +7,68 @@ class DraggableSprite: public Sprite
 public:
     DraggableSprite()
     {
-        drag.init(this);
+        //drag.init(this);
     }
 
-    Draggable drag;
+    //Draggable drag;
+    void onEvent(Event* ev)
+    {
+        TouchEvent* te = safeCast<TouchEvent*>(ev);
+        if (te->type == TouchEvent::TOUCH_DOWN)
+        {
+            local = te->localPosition;
+            _stage->addEventListener(TouchEvent::MOVE, CLOSURE(this, &DraggableSprite::onEvent));
+            _stage->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &DraggableSprite::onEvent));
+        }
+
+        if (te->type == TouchEvent::MOVE)
+        {
+            move(te->localPosition);
+        }
+
+        if (te->type == TouchEvent::TOUCH_UP)
+        {
+            _stage->removeEventListeners(this);
+        }
+    }
+
+    void move(const Vector2& pos)
+    {
+        Vector2 localPos = stage2local(pos);
+        Vector2 offset = localPos - local;
+
+        Transform tr = getTransform();
+        tr.x = 0;
+        tr.y = 0;
+        Vector2 p = tr.transform(offset);
+        setPosition(getPosition() + p);
+    }
+
+    void doUpdate(const UpdateState& us)
+    {
+        pointer_index ind = getPressed();
+        if (!ind)
+            return;
+        PointerState* st = Input::instance.getTouchByIndex(ind);
+        move(_stage->parent2local(st->getPosition()));
+    }
+
+
+
+
+
+    void onAdded2Stage()
+    {
+        addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DraggableSprite::onEvent));
+    }
+
+    void onRemovedFromStage()
+    {
+        _stage->removeEventListeners(this);
+    }
+
+
+    Vector2 local;
 };
 
 class DragTest: public Test
@@ -30,6 +88,7 @@ public:
         pos[1] = Vector2(600, 225);
         pos[2] = Vector2(305, 170);
 
+
         for (int i = 0; i < 3; ++i)
         {
             spSprite sprite = new DraggableSprite;
@@ -37,6 +96,7 @@ public:
             sprite->setResAnim(resources.getResAnim("batterfly"));
             sprite->attachTo(content);
 
+
             float angle = scalar::randFloat(0, (float)MATH_PI * 2);
             sprite->setRotation(angle);
             sprite->addTween(Actor::TweenRotation(MATH_PI * 2 + angle), 30000, -1);
@@ -77,7 +137,7 @@ public:
                     spSprite c = new Sprite;
                     c->setAnchor(0.5f, 0.5f);
                     c->setResAnim(resources.getResAnim("snow"));
-                    c->addTween(Actor::TweenAlpha(0), 300)->setDetachActor(true);
+                    c->addTween(Actor::TweenAlpha(0), 300)->detachWhenDone();
                     Vector2 pos = a->local2stage(contact, content);
                     c->setPosition(pos);
                     c->attachTo(contacts);
@@ -169,7 +229,7 @@ public:
             t = dragging->addTween(Actor::TweenPosition(basket->getPosition() - basket->getSize() / 2), 500);
         else
             t = dragging->addTween(Actor::TweenPosition(ball->getPosition() - ball->getSize() / 2), 500);
-        t->setDetachActor(true);
+        t->detachWhenDone();
         dragging = 0;
     }
 

+ 1 - 1
examples/Demo/src/TestInputText.h

@@ -17,7 +17,7 @@ public:
 
         TextStyle style;
         style.color = Color::Black;
-        style.hAlign = TextStyle::HALIGN_CENTER;
+        style.hAlign = TextStyle::HALIGN_MIDDLE;
         style.vAlign = TextStyle::VALIGN_MIDDLE;
         style.multiline = true;
         style.font = Test::resourcesUI.getResFont("big");

+ 1 - 1
examples/Demo/src/TestManageRes.h

@@ -86,7 +86,7 @@ public:
     void _loaded(Event* event)
     {
         notify("Loaded!");
-        ui->getChild("loading")->addTween(Sprite::TweenAlpha(0), 400)->setDetachActor(true);
+        ui->getChild("loading")->addTween(Sprite::TweenAlpha(0), 400)->detachWhenDone();
 
         releaseRef();//added ref earlier from void clicked(id)
     }

+ 2 - 2
examples/Demo/src/TestMask.h

@@ -50,7 +50,7 @@ public:
         style.font = resourcesUI.getResFont("big");
         style.color = Color::OrangeRed;
         style.vAlign = TextStyle::VALIGN_MIDDLE;
-        style.hAlign = TextStyle::HALIGN_CENTER;
+        style.hAlign = TextStyle::HALIGN_MIDDLE;
         style.multiline = true;
 
         spTextField text = new TextField();
@@ -127,7 +127,7 @@ public:
             snow->setY(-50);
             snow->attachTo(_masked);
 
-            snow->addTween(Actor::TweenY(content->getHeight() + 50), 6000)->setDetachActor(true);
+            snow->addTween(Actor::TweenY(content->getHeight() + 50), 6000)->detachWhenDone();
             snow->addTween(Actor::TweenRotation(scalar::randFloat(0, MATH_PI * 2)), 5000);
         }
     }

+ 2 - 1
examples/Demo/src/TestProgressBar.h

@@ -19,7 +19,8 @@ public:
         bar->setResAnim(resources.getResAnim("bg"));
         bar->setAnchor(Vector2(0.5f, 0.5f));
         bar->setPosition(getSize() / 2);
-        bar->setScale(0.5f);
+
+        //bar->setSize(600, 200);
         content->addChild(bar);
     }
 

+ 3 - 3
examples/Demo/src/TestText.h

@@ -75,15 +75,15 @@ public:
 
 
         tests.push_back(text_test("It is html style tagged text. <div c='ffff00'>It could be colored.  It <div c='0000ff'>supports</div> <div c='00ff00AA'> nested tags</div> and  <br/> broken lines.</div><br/>It supports CDATA and xml escape sequences:\n<![CDATA[<div c='00ffff'>it is CDATA</div>]]>",
-                                  TextStyle::HALIGN_CENTER, TextStyle::VALIGN_MIDDLE, size, true));
+                                  TextStyle::HALIGN_MIDDLE, TextStyle::VALIGN_MIDDLE, size, true));
 
         for (int h = TextStyle::HALIGN_LEFT; h <= TextStyle::HALIGN_RIGHT; ++h)
         {
-            tests.push_back(text_test("<div c='00ff00'>Scaled Font test<br/></div> The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. ", TextStyle::HALIGN_CENTER, TextStyle::VALIGN_MIDDLE, size, true, 5 * h  + 20));
+            tests.push_back(text_test("<div c='00ff00'>Scaled Font test<br/></div> The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. The quick brown fox jumps over the lazy dog. 1234567890. ", TextStyle::HALIGN_MIDDLE, TextStyle::VALIGN_MIDDLE, size, true, 5 * h  + 20));
         }
 
 
-        tests.push_back(text_test("<div c='00ff00'>Using '\\n' new line test</div>\nnew line\nnew line\nnew line", TextStyle::HALIGN_CENTER, TextStyle::VALIGN_TOP, size));
+        tests.push_back(text_test("<div c='00ff00'>Using '\\n' new line test</div>\nnew line\nnew line\nnew line", TextStyle::HALIGN_MIDDLE, TextStyle::VALIGN_TOP, size));
 
         for (int h = TextStyle::HALIGN_LEFT; h <= TextStyle::HALIGN_RIGHT; ++h)
         {

+ 29 - 14
examples/Demo/src/TestTouches.h

@@ -1,5 +1,6 @@
 #pragma once
 #include "test.h"
+#include "utils/stringUtils.h"
 
 class TestTouches: public Test
 {
@@ -35,20 +36,28 @@ public:
         tf->setY(5);
         tf->attachTo(orange);
 
-        tf = new TextField;
-        tf->setText("");
-        tf->setColor(Color::Black);
-        tf->setName("state2");
-        tf->setX(35);
-        tf->setY(5);
-        tf->attachTo(orange);
+        for (int i = 0; i < MouseButton_Num; ++i)
+        {
+            tf = new TextField;
+            tf->setText("");
+            tf->setColor(Color::Black);
+            char name[255];
+            safe_sprintf(name, "pressed %d", i);
+            tf->setName(name);
+            tf->setX(5.0f);
+            tf->setY(15.0f + i * 10.0f);
+            tf->attachTo(orange);
+        }
+
+
+
 
         tf = new TextField;
         tf->setText("");
         tf->setColor(Color::Black);
         tf->setName("local");
         tf->setX(5);
-        tf->setY(25);
+        tf->setY(50);
         tf->setMultiline(true);
         tf->setWidth(orange->getWidth());
         tf->attachTo(orange);
@@ -66,9 +75,14 @@ public:
 
     void onDownUp(Event* ev)
     {
+        TouchEvent* te = safeCast<TouchEvent*>(ev);
         spSprite s = safeSpCast<Sprite>(ev->currentTarget);
-        spTextField tf = s->getChildT<TextField>("state2");
-        tf->setText(ev->type == TouchEvent::TOUCH_DOWN ? "pressed" : "");
+
+        char name[255];
+        safe_sprintf(name, "pressed %d", (int)te->mouseButton);
+
+        spTextField tf = s->getChildT<TextField>(name);
+        tf->setText(ev->type == TouchEvent::TOUCH_DOWN ? name : "");
         updateLocalPos(ev);
     }
 
@@ -110,10 +124,10 @@ public:
         spSprite Green = createRect("Green", Color::Green, Vector2(100, 25), Vector2(100, 150));
         Green->attachTo(Orange);
 
-        spSprite Beige = createRect("Beige", Color::Beige, Vector2(150, 150), Vector2(250, 100));
+        spSprite Beige = createRect("Beige", Color::Beige, Vector2(150, 150), Vector2(260, 100));
         Beige->attachTo(Orange);
 
-        spSprite LightGreen = createRect("LightGreen", Color::LightGreen, Vector2(180, -50), Vector2(50, 200));
+        spSprite LightGreen = createRect("LightGreen", Color::LightGreen, Vector2(180, -50), Vector2(65, 200));
         LightGreen->attachTo(Beige);
 
 
@@ -174,14 +188,15 @@ public:
                      "\n"
                      "current target: %s\n"
                      "local position: %d %d\n"
+                     "button: %d\n"
                      ,
                      n,
                      eventName,
                      te->target->getName().c_str(),
                      (int)te->position.x, (int)te->position.y,
                      te->currentTarget->getName().c_str(),
-                     (int)te->localPosition.x, (int)te->localPosition.y
-
+                     (int)te->localPosition.x, (int)te->localPosition.y,
+                     (int)te->mouseButton
                     );
 
 

+ 3 - 0
examples/Demo/src/example.cpp

@@ -28,6 +28,7 @@
 #include "TestSignedDistanceFont.h"
 #include "TestTweenPostProcessing.h"
 #include "TestEdges.h"
+#include "TestCamera.h"
 
 #ifdef __S3E__
 #include "s3eKeyboard.h"
@@ -93,6 +94,7 @@ public:
         addButton("counter", "Counter");
         addButton("tweentext", "Tween Text");
         addButton("tweenshine", "Tween Shine");
+        addButton("mtz", "MultiTouch Camera/Zoom");
     }
 
     void showTest(spActor actor)
@@ -136,6 +138,7 @@ public:
         if (id == "sdf") showTest(new TestSignedDistanceFont);
         if (id == "tweenpp") showTest(new TestTweenPostProcessing);
         if (id == "edges") showTest(new TestEdges);
+        if (id == "mtz") showTest(new TestCamera);
         if (id == "openbrowser")
         {
             core::execute("http://oxygine.org/");

+ 2 - 2
examples/Demo/src/test.cpp

@@ -69,7 +69,7 @@ spTextField createText(const std::string& txt)
 #endif
     style.color = textColor;
     style.vAlign = TextStyle::VALIGN_MIDDLE;
-    style.hAlign = TextStyle::HALIGN_CENTER;
+    style.hAlign = TextStyle::HALIGN_MIDDLE;
     style.multiline = true;
 
     text->setStyle(style);
@@ -230,7 +230,7 @@ void Test::notify(std::string txt, int time)
     spTweenQueue tq = new TweenQueue;
     tq->add(Actor::TweenAlpha(255), 300, 1, false, 0, Tween::ease_inExpo);
     tq->add(Actor::TweenAlpha(0), 300, 1, false, 1200);
-    tq->setDetachActor(true);
+    tq->detachWhenDone();
     tq->addDoneCallback(CLOSURE(this, &Test::notifyDone));
 
     sprite->addTween(tq);

+ 2 - 0
examples/DemoBox2D/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/DemoBox2D/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 1
examples/DemoBox2D/src/example.cpp

@@ -183,7 +183,7 @@ public:
 
             spSprite sprite = new Sprite();
             sprite->setResAnim(gameResources.getResAnim("shot"));
-            Vector2 local = actor->global2local(te->localPosition);
+            Vector2 local = actor->parent2local(te->localPosition);
             sprite->setPosition(local);
             sprite->setAnchor(Vector2(0.5f, 0.5f));
             sprite->attachTo(actor);

+ 2 - 0
examples/Game/part1/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Game/part1/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 2 - 0
examples/Game/part2/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Game/part2/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 1
examples/Game/part2/src/Enemy.cpp

@@ -36,6 +36,6 @@ void Enemy::explode()
     {
         //dead, hide it with alpha tween
         _dead = true;
-        _view->addTween(Actor::TweenAlpha(0), 300)->setDetachActor(true);
+        _view->addTween(Actor::TweenAlpha(0), 300)->detachWhenDone();
     }
 }

+ 2 - 2
examples/Game/part2/src/Rocket.cpp

@@ -72,9 +72,9 @@ void Rocket::explode()
     //run tween with explosion animation
     spTween tween = anim->addTween(Sprite::TweenAnim(res::ui.getResAnim("explosion")), 1000);
     //auto detach sprite when tween is done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 
     //hide rocket and then detach it
     tween = _view->addTween(Actor::TweenAlpha(0), 500);
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 }

+ 2 - 0
examples/Game/part3/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Game/part3/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 1
examples/Game/part3/src/Enemy.cpp

@@ -36,6 +36,6 @@ void Enemy::explode()
     {
         //dead, hide it with alpha tween
         _dead = true;
-        _view->addTween(Actor::TweenAlpha(0), 300)->setDetachActor(true);
+        _view->addTween(Actor::TweenAlpha(0), 300)->detachWhenDone();
     }
 }

+ 2 - 2
examples/Game/part3/src/Rocket.cpp

@@ -72,9 +72,9 @@ void Rocket::explode()
     //run tween with explosion animation
     spTween tween = anim->addTween(Sprite::TweenAnim(res::ui.getResAnim("explosion")), 1000);
     //auto detach sprite when tween is done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 
     //hide rocket and then detach it
     tween = _view->addTween(Actor::TweenAlpha(0), 500);
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 }

+ 1 - 1
examples/Game/part3/src/Scene.cpp

@@ -11,7 +11,7 @@ void Scene::changeScene(spScene next)
     //hide current scene
     spTween tween = _view->addTween(Actor::TweenAlpha(0), 300);
     //detach when done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 
     //show next scene
     getStage()->addChild(next->getView());

+ 2 - 0
examples/Game/part4/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Game/part4/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 1
examples/Game/part4/src/Enemy.cpp

@@ -36,6 +36,6 @@ void Enemy::explode()
     {
         //dead, hide it with alpha tween
         _dead = true;
-        _view->addTween(Actor::TweenAlpha(0), 300)->setDetachActor(true);
+        _view->addTween(Actor::TweenAlpha(0), 300)->detachWhenDone();
     }
 }

+ 1 - 1
examples/Game/part4/src/GameMenu.cpp

@@ -29,7 +29,7 @@ GameMenu::GameMenu()
     //vertical align
     style.vAlign = TextStyle::VALIGN_BOTTOM;
     //horizontal align
-    style.hAlign = TextStyle::HALIGN_CENTER;
+    style.hAlign = TextStyle::HALIGN_MIDDLE;
 
     spTextField paused = initActor(new TextField,
                                    arg_style = style,

+ 1 - 1
examples/Game/part4/src/MyButton.cpp

@@ -34,7 +34,7 @@ void MyButton::setText(const string& txt)
         TextStyle style;
         style.font = res::ui.getResFont("normal");
         style.vAlign = TextStyle::VALIGN_MIDDLE;
-        style.hAlign = TextStyle::HALIGN_CENTER;
+        style.hAlign = TextStyle::HALIGN_MIDDLE;
 
         //attach it to MyButton and set the same size as button
         //text would be centered

+ 2 - 2
examples/Game/part4/src/Rocket.cpp

@@ -72,9 +72,9 @@ void Rocket::explode()
     //run tween with explosion animation
     spTween tween = anim->addTween(Sprite::TweenAnim(res::ui.getResAnim("explosion")), 1000);
     //auto detach sprite when tween is done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 
     //hide rocket and then detach it
     tween = _view->addTween(Actor::TweenAlpha(0), 500);
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 }

+ 1 - 1
examples/Game/part4/src/Scene.cpp

@@ -31,7 +31,7 @@ void Scene::hide()
 {
     spTween tween = _view->addTween(Actor::TweenAlpha(0), 300);
     //detach when done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
     //and call Scene::hidden
     tween->addDoneCallback(CLOSURE(this, &Scene::hidden));
 }

+ 2 - 0
examples/Game/part5/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Game/part5/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 1 - 1
examples/Game/part5/src/Enemy.cpp

@@ -36,6 +36,6 @@ void Enemy::explode()
     {
         //dead, hide it with alpha tween
         _dead = true;
-        _view->addTween(Actor::TweenAlpha(0), 300)->setDetachActor(true);
+        _view->addTween(Actor::TweenAlpha(0), 300)->detachWhenDone();
     }
 }

+ 1 - 1
examples/Game/part5/src/GameMenu.cpp

@@ -29,7 +29,7 @@ GameMenu::GameMenu()
     //vertical align
     style.vAlign = TextStyle::VALIGN_BOTTOM;
     //horizontal align
-    style.hAlign = TextStyle::HALIGN_CENTER;
+    style.hAlign = TextStyle::HALIGN_MIDDLE;
 
     spTextField paused = initActor(new TextField,
                                    arg_style = style,

+ 1 - 1
examples/Game/part5/src/MyButton.cpp

@@ -34,7 +34,7 @@ void MyButton::setText(const string& txt)
         TextStyle style;
         style.font = res::ui.getResFont("normal");
         style.vAlign = TextStyle::VALIGN_MIDDLE;
-        style.hAlign = TextStyle::HALIGN_CENTER;
+        style.hAlign = TextStyle::HALIGN_MIDDLE;
 
         //attach it to MyButton and set the same size as button
         //text would be centered

+ 2 - 2
examples/Game/part5/src/Rocket.cpp

@@ -72,9 +72,9 @@ void Rocket::explode()
     //run tween with explosion animation
     spTween tween = anim->addTween(Sprite::TweenAnim(res::ui.getResAnim("explosion")), 1000);
     //auto detach sprite when tween is done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 
     //hide rocket and then detach it
     tween = _view->addTween(Actor::TweenAlpha(0), 500);
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
 }

+ 1 - 1
examples/Game/part5/src/Scene.cpp

@@ -31,7 +31,7 @@ void Scene::hide()
 {
     spTween tween = _view->addTween(Actor::TweenAlpha(0), 300);
     //detach when done
-    tween->setDetachActor(true);
+    tween->detachWhenDone();
     //and call Scene::hidden
     tween->addDoneCallback(CLOSURE(this, &Scene::hidden));
 }

+ 2 - 0
examples/HelloWorld/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/HelloWorld/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

+ 2 - 8
examples/HelloWorld/src/example.cpp

@@ -1,6 +1,5 @@
 #include "oxygine-framework.h"
 #include <functional>
-#include "res/SingleResAnim.h"
 using namespace oxygine;
 
 //it is our resources
@@ -56,12 +55,7 @@ public:
         text->setPosition(button->getSize() / 2);
 
         //initialize text style
-        TextStyle style;
-        style.font = gameResources.getResFont("main");
-        style.color = Color::White;
-        style.vAlign = TextStyle::VALIGN_MIDDLE;
-        style.hAlign = TextStyle::HALIGN_CENTER;
-
+        TextStyle style = TextStyle(gameResources.getResFont("main")).withColor(Color::White).alignMiddle();
         text->setStyle(style);
         text->setText("Click\nMe!");
 
@@ -120,7 +114,7 @@ public:
 
         //and remove sprite from tree when tweenQueue is empty
         //if you don't hold any references to sprite it would be deleted automatically
-        tweenQueue->setDetachActor(true);
+        tweenQueue->detachWhenDone();
     }
 };
 //declare spMainActor as intrusive_ptr holder of MainActor

+ 2 - 0
examples/Match3/proj.cmake/build_emsc.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc

+ 2 - 0
examples/Match3/proj.cmake/build_emsc_release.bat

@@ -1,3 +1,5 @@
+call emsdk activate
+
 python ../../..//tools/others/embed_folder_js.py -s ../data
 
 mkdir build_emsc_release

BIN
libs/SDL2.dll


BIN
libs/SDL2.lib


BIN
libs/SDL2main.lib


+ 3 - 3
oxygine/SDL/android/extension/build.gradle

@@ -10,9 +10,9 @@ buildscript {
 apply plugin: 'com.android.library'
 
 android {
-        compileSdkVersion 23
-  		buildToolsVersion '23.0.3'
-
+        compileSdkVersion rootProject.android.compileSdkVersion
+        buildToolsVersion rootProject.android.buildToolsVersion
+        
         sourceSets {
             main {
                 manifest.srcFile 'AndroidManifest.xml'

+ 7 - 7
oxygine/SDL/android/lib/build.gradle

@@ -11,17 +11,17 @@ apply plugin: 'com.android.library'
 
 dependencies {
         compile project(':oxygine-extension')
-    }
+}
 
 android {
-		lintOptions {
-        	abortOnError false
-    	}
+        lintOptions {
+            abortOnError false
+        }
 
-        compileSdkVersion 23
-  		buildToolsVersion '23.0.2'
+        compileSdkVersion rootProject.android.compileSdkVersion
+        buildToolsVersion rootProject.android.buildToolsVersion
 
-  		sourceSets {
+        sourceSets {
             main {
                 manifest.srcFile 'AndroidManifest.xml'
                 java.srcDirs = ['src']

+ 39 - 25
oxygine/SDL/android/lib/src/org/libsdl/app/SDLActivity.java

@@ -369,7 +369,10 @@ public class SDLActivity extends Activity {
                 break;
             case COMMAND_TEXTEDIT_HIDE:
                 if (mTextEdit != null) {
-                    mTextEdit.setVisibility(View.GONE);
+                    // Note: On some devices setting view to GONE creates a flicker in landscape.
+                    // Setting the View's sizes to 0 is similar to GONE but without the flicker.
+                    // The sizes will be set to useful values when the keyboard is shown again.
+                    mTextEdit.setLayoutParams(new RelativeLayout.LayoutParams(0, 0));
 
                     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                     imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
@@ -724,6 +727,21 @@ public class SDLActivity extends Activity {
         }
     }
 
+    // Check if a given device is considered a possible SDL joystick
+    public static boolean isDeviceSDLJoystick(int deviceId) {
+        InputDevice device = InputDevice.getDevice(deviceId);
+        // We cannot use InputDevice.isVirtual before API 16, so let's accept
+        // only nonnegative device ids (VIRTUAL_KEYBOARD equals -1)
+        if ((device == null) || (deviceId < 0)) {
+            return false;
+        }
+        int sources = device.getSources();
+        return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) ||
+                ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) ||
+                ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
+        );
+    }
+
     // APK expansion files support
 
     /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
@@ -1220,23 +1238,25 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
     @Override
     public boolean onKey(View  v, int keyCode, KeyEvent event) {
         // Dispatch the different events depending on where they come from
-        // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
-        // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
-
-        if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
-                   (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
+        // Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
+        // So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
+        //
+        // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
+        // SOURCE_JOYSTICK, while its key events arrive from the keyboard source
+        // So, retrieve the device itself and check all of its sources
+        if (SDLActivity.isDeviceSDLJoystick(event.getDeviceId())) {
+            // Note that we always process a pressed/released button here, as an unopened
+            // SDL_Joystick's button press should not be processed as a keyboard's key press
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
-                    return true;
-                }
+                SDLActivity.onNativePadDown(event.getDeviceId(), keyCode);
+                return true;
             } else if (event.getAction() == KeyEvent.ACTION_UP) {
-                if (SDLActivity.onNativePadUp(event.getDeviceId(), keyCode) == 0) {
-                    return true;
-                }
+                SDLActivity.onNativePadUp(event.getDeviceId(), keyCode);
+                return true;
             }
         }
 
-        if( (event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
+        if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 //Log.v("SDL", "key down: " + keyCode);
                 SDLActivity.onNativeKeyDown(keyCode);
@@ -1395,7 +1415,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
             }
             SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
                                       y / SensorManager.GRAVITY_EARTH,
-                                      event.values[2] / SensorManager.GRAVITY_EARTH - 1);
+                                      event.values[2] / SensorManager.GRAVITY_EARTH);
         }
     }
 }
@@ -1422,7 +1442,7 @@ class DummyEdit extends View implements View.OnKeyListener {
     public boolean onKey(View v, int keyCode, KeyEvent event) {
 
         // This handles the hardware keyboard input
-        if (event.isPrintingKey()) {
+        if (event.isPrintingKey() || keyCode == KeyEvent.KEYCODE_SPACE) {
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
             }
@@ -1485,7 +1505,7 @@ class SDLInputConnection extends BaseInputConnection {
          */
         int keyCode = event.getKeyCode();
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            if (event.isPrintingKey()) {
+            if (event.isPrintingKey() || keyCode == KeyEvent.KEYCODE_SPACE) {
                 commitText(String.valueOf((char) event.getUnicodeChar()), 1);
             }
             SDLActivity.onNativeKeyDown(keyCode);
@@ -1586,13 +1606,7 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler {
             if (joystick == null) {
                 joystick = new SDLJoystick();
                 InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
-
-                if ( 
-                      (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 
-                   ||
-                      (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_BUTTON) != 0 
-                  )
-                {
+                if (SDLActivity.isDeviceSDLJoystick(deviceIds[i])) {
                     joystick.device_id = deviceIds[i];
                     joystick.name = joystickDevice.getName();
                     joystick.axes = new ArrayList<InputDevice.MotionRange>();
@@ -1601,7 +1615,7 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler {
                     List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
                     Collections.sort(ranges, new RangeComparator());
                     for (InputDevice.MotionRange range : ranges ) {
-                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ) {
+                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
                             if (range.getAxis() == MotionEvent.AXIS_HAT_X ||
                                 range.getAxis() == MotionEvent.AXIS_HAT_Y) {
                                 joystick.hats.add(range);
@@ -1655,7 +1669,7 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler {
 
     @Override
     public boolean handleMotionEvent(MotionEvent event) {
-        if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
+        if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
             int actionPointerIndex = event.getActionIndex();
             int action = event.getActionMasked();
             switch(action) {

+ 32 - 2
oxygine/SDL/android/lib/src/org/oxygine/lib/HttpRequests.java

@@ -104,7 +104,8 @@ class HttpRequest extends AsyncTask<RequestDetails, Integer, String> {
             else
                 connection = (HttpURLConnection) url.openConnection();
 
-
+            connection.setInstanceFollowRedirects(true);
+            
             if (details.postData != null) {
                 connection.setDoOutput(true);
                 //connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
@@ -114,6 +115,35 @@ class HttpRequest extends AsyncTask<RequestDetails, Integer, String> {
 
             //connection.connect();
 
+            /*
+
+            boolean redirect = false;
+
+            int status = conn.getResponseCode();
+            if (status != HttpURLConnection.HTTP_OK) {
+                if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER)
+                    redirect = true;
+            }
+
+            if (redirect) {
+
+                // get redirect url from "location" header field
+                String newUrl = conn.getHeaderField("Location");
+
+                // get the cookie if need, for login
+                String cookies = conn.getHeaderField("Set-Cookie");
+
+                // open the new connnection again
+                conn = (HttpURLConnection) new URL(newUrl).openConnection();
+                conn.setRequestProperty("Cookie", cookies);
+                conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
+                conn.addRequestProperty("User-Agent", "Mozilla");
+                conn.addRequestProperty("Referer", "google.com");
+
+                System.out.println("Redirect to URL : " + newUrl);
+            }
+            */
+
             // expect HTTP 200 OK, so we don't mistakenly save error report
             // instead of the file
             if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
@@ -247,7 +277,7 @@ public class HttpRequests {
     }
 
     static public void release() {
-
+        _handler = null;
     }
 
     static public HttpRequestHolder createRequest(String url, String fname, byte[] post, long handle) {

+ 7 - 0
oxygine/SDL/android/lib/src/org/oxygine/lib/Utils.java

@@ -6,6 +6,7 @@ import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
+import android.provider.Settings;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -27,6 +28,12 @@ public class Utils {
         return _context.getPackageName();
     }
 
+    public static String getProperty(String prop) {
+    	if (prop == "ANDROID_ID")
+    		return Settings.Secure.ANDROID_ID;
+        return "";
+    }
+
     public static boolean isNetworkAvailable() {
         if (_context == null)
             return false;

+ 0 - 16
oxygine/SDL/ios/oxygine/oxygine_ios.xcodeproj/project.pbxproj

@@ -115,8 +115,6 @@
 		C3E86FFF16EBC8EB00052915 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5616EBC8EB00052915 /* Actor.h */; };
 		C3E8700016EBC8EB00052915 /* AnimationFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */; };
 		C3E8700116EBC8EB00052915 /* AnimationFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5816EBC8EB00052915 /* AnimationFrame.h */; };
-		C3E8700216EBC8EB00052915 /* Blocking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5916EBC8EB00052915 /* Blocking.cpp */; };
-		C3E8700316EBC8EB00052915 /* Blocking.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5A16EBC8EB00052915 /* Blocking.h */; };
 		C3E8700416EBC8EB00052915 /* Box9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */; };
 		C3E8700516EBC8EB00052915 /* Box9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */; };
 		C3E8700616EBC8EB00052915 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5D16EBC8EB00052915 /* Button.cpp */; };
@@ -129,8 +127,6 @@
 		C3E8700D16EBC8EB00052915 /* closure_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F6516EBC8EB00052915 /* closure_impl.h */; };
 		C3E8700E16EBC8EB00052915 /* ColorRectSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F6616EBC8EB00052915 /* ColorRectSprite.cpp */; };
 		C3E8700F16EBC8EB00052915 /* ColorRectSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F6716EBC8EB00052915 /* ColorRectSprite.h */; };
-		C3E8701016EBC8EB00052915 /* coroutines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F6A16EBC8EB00052915 /* coroutines.cpp */; };
-		C3E8701116EBC8EB00052915 /* coroutines.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F6B16EBC8EB00052915 /* coroutines.h */; };
 		C3E8701416EBC8EB00052915 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F6E16EBC8EB00052915 /* ImageData.cpp */; };
 		C3E8701516EBC8EB00052915 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F6F16EBC8EB00052915 /* ImageData.h */; };
 		C3E8701616EBC8EB00052915 /* ImageDataOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F7016EBC8EB00052915 /* ImageDataOperations.cpp */; };
@@ -357,8 +353,6 @@
 		C3E86F5616EBC8EB00052915 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../../src/Actor.h; sourceTree = "<group>"; };
 		C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationFrame.cpp; path = ../../../src/AnimationFrame.cpp; sourceTree = "<group>"; };
 		C3E86F5816EBC8EB00052915 /* AnimationFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationFrame.h; path = ../../../src/AnimationFrame.h; sourceTree = "<group>"; };
-		C3E86F5916EBC8EB00052915 /* Blocking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Blocking.cpp; path = ../../../src/Blocking.cpp; sourceTree = "<group>"; };
-		C3E86F5A16EBC8EB00052915 /* Blocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Blocking.h; path = ../../../src/Blocking.h; sourceTree = "<group>"; };
 		C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Box9Sprite.cpp; path = ../../../src/Box9Sprite.cpp; sourceTree = "<group>"; };
 		C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Box9Sprite.h; path = ../../../src/Box9Sprite.h; sourceTree = "<group>"; };
 		C3E86F5D16EBC8EB00052915 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Button.cpp; path = ../../../src/Button.cpp; sourceTree = "<group>"; };
@@ -371,8 +365,6 @@
 		C3E86F6516EBC8EB00052915 /* closure_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = closure_impl.h; sourceTree = "<group>"; };
 		C3E86F6616EBC8EB00052915 /* ColorRectSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ColorRectSprite.cpp; path = ../../../src/ColorRectSprite.cpp; sourceTree = "<group>"; };
 		C3E86F6716EBC8EB00052915 /* ColorRectSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColorRectSprite.h; path = ../../../src/ColorRectSprite.h; sourceTree = "<group>"; };
-		C3E86F6A16EBC8EB00052915 /* coroutines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coroutines.cpp; sourceTree = "<group>"; };
-		C3E86F6B16EBC8EB00052915 /* coroutines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coroutines.h; sourceTree = "<group>"; };
 		C3E86F6E16EBC8EB00052915 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
 		C3E86F6F16EBC8EB00052915 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
 		C3E86F7016EBC8EB00052915 /* ImageDataOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDataOperations.cpp; sourceTree = "<group>"; };
@@ -584,7 +576,6 @@
 				C3E86F5516EBC8EB00052915 /* Actor.cpp */,
 				C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */,
 				9223E3101A5193E000B2770B /* AsyncTask.cpp */,
-				C3E86F5916EBC8EB00052915 /* Blocking.cpp */,
 				C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */,
 				C3E86F5D16EBC8EB00052915 /* Button.cpp */,
 				C3E86F5F16EBC8EB00052915 /* ClipRectActor.cpp */,
@@ -625,7 +616,6 @@
 				C3E86F5616EBC8EB00052915 /* Actor.h */,
 				C3E86F5816EBC8EB00052915 /* AnimationFrame.h */,
 				9223E3111A5193E000B2770B /* AsyncTask.h */,
-				C3E86F5A16EBC8EB00052915 /* Blocking.h */,
 				C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */,
 				C3E86F5E16EBC8EB00052915 /* Button.h */,
 				C3E86F6016EBC8EB00052915 /* ClipRectActor.h */,
@@ -725,8 +715,6 @@
 				0472E35517F8A1A80016A832 /* ZipFileSystem.cpp */,
 				0472E35617F8A1A80016A832 /* ZipFileSystem.h */,
 				C3EE215017BECD6100715678 /* gl */,
-				C3E86F6A16EBC8EB00052915 /* coroutines.cpp */,
-				C3E86F6B16EBC8EB00052915 /* coroutines.h */,
 				C3E86F6E16EBC8EB00052915 /* ImageData.cpp */,
 				C3E86F6F16EBC8EB00052915 /* ImageData.h */,
 				C3E86F7016EBC8EB00052915 /* ImageDataOperations.cpp */,
@@ -894,7 +882,6 @@
 				C3E86FFF16EBC8EB00052915 /* Actor.h in Headers */,
 				9250AFB31C9B14950060A168 /* TweenOutline.h in Headers */,
 				C3E8700116EBC8EB00052915 /* AnimationFrame.h in Headers */,
-				C3E8700316EBC8EB00052915 /* Blocking.h in Headers */,
 				929AF5671C88AA4000D276ED /* ThreadLoader.h in Headers */,
 				9225533A1CAFA4EF00333A1E /* TweenGlow.h in Headers */,
 				C3E8700516EBC8EB00052915 /* Box9Sprite.h in Headers */,
@@ -907,7 +894,6 @@
 				C3E8700D16EBC8EB00052915 /* closure_impl.h in Headers */,
 				9240B40A1ADFB856005F9C5B /* TweenAnim.h in Headers */,
 				C3E8700F16EBC8EB00052915 /* ColorRectSprite.h in Headers */,
-				C3E8701116EBC8EB00052915 /* coroutines.h in Headers */,
 				0472E35A17F8A1A80016A832 /* FileSystem.h in Headers */,
 				0472E36517F8A1A80016A832 /* ZipFileSystem.h in Headers */,
 				0472E36317F8A1A80016A832 /* VertexDeclaration.h in Headers */,
@@ -1077,7 +1063,6 @@
 				C3E86FFE16EBC8EB00052915 /* Actor.cpp in Sources */,
 				922553391CAFA4EF00333A1E /* TweenGlow.cpp in Sources */,
 				C3E8700016EBC8EB00052915 /* AnimationFrame.cpp in Sources */,
-				C3E8700216EBC8EB00052915 /* Blocking.cpp in Sources */,
 				C3E8700416EBC8EB00052915 /* Box9Sprite.cpp in Sources */,
 				C3E8700616EBC8EB00052915 /* Button.cpp in Sources */,
 				0472E37717F8A2D30016A832 /* ioapi_mem.c in Sources */,
@@ -1086,7 +1071,6 @@
 				9264E5BF1B8358D80049F91F /* jsoncpp.cpp in Sources */,
 				C3E8700A16EBC8EB00052915 /* Clock.cpp in Sources */,
 				C3E8700E16EBC8EB00052915 /* ColorRectSprite.cpp in Sources */,
-				C3E8701016EBC8EB00052915 /* coroutines.cpp in Sources */,
 				C3E8701416EBC8EB00052915 /* ImageData.cpp in Sources */,
 				CEC2D00A1C47288E00450163 /* STDMaterial.cpp in Sources */,
 				0472E36417F8A1A80016A832 /* ZipFileSystem.cpp in Sources */,

+ 0 - 16
oxygine/SDL/macosx/oxygine_macosx/oxygine_macosx.xcodeproj/project.pbxproj

@@ -17,8 +17,6 @@
 		049B56661871F21E00EF3C66 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55921871F21D00EF3C66 /* Actor.h */; };
 		049B56671871F21E00EF3C66 /* AnimationFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55931871F21D00EF3C66 /* AnimationFrame.cpp */; };
 		049B56681871F21E00EF3C66 /* AnimationFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55941871F21D00EF3C66 /* AnimationFrame.h */; };
-		049B56691871F21E00EF3C66 /* blocking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55951871F21D00EF3C66 /* blocking.cpp */; };
-		049B566A1871F21E00EF3C66 /* blocking.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55961871F21D00EF3C66 /* blocking.h */; };
 		049B566B1871F21E00EF3C66 /* Box9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55971871F21D00EF3C66 /* Box9Sprite.cpp */; };
 		049B566C1871F21E00EF3C66 /* Box9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55981871F21D00EF3C66 /* Box9Sprite.h */; };
 		049B566D1871F21E00EF3C66 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55991871F21D00EF3C66 /* Button.cpp */; };
@@ -31,8 +29,6 @@
 		049B56741871F21E00EF3C66 /* closure_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55A11871F21D00EF3C66 /* closure_impl.h */; };
 		049B56751871F21E00EF3C66 /* ColorRectSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55A21871F21D00EF3C66 /* ColorRectSprite.cpp */; };
 		049B56761871F21E00EF3C66 /* ColorRectSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55A31871F21D00EF3C66 /* ColorRectSprite.h */; };
-		049B56771871F21E00EF3C66 /* coroutines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55A61871F21D00EF3C66 /* coroutines.cpp */; };
-		049B56781871F21E00EF3C66 /* coroutines.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55A71871F21D00EF3C66 /* coroutines.h */; };
 		049B56791871F21E00EF3C66 /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55A81871F21D00EF3C66 /* file.cpp */; };
 		049B567A1871F21E00EF3C66 /* file.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55A91871F21D00EF3C66 /* file.h */; };
 		049B567C1871F21E00EF3C66 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55AB1871F21D00EF3C66 /* FileSystem.cpp */; };
@@ -258,8 +254,6 @@
 		049B55921871F21D00EF3C66 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../../src/Actor.h; sourceTree = "<group>"; };
 		049B55931871F21D00EF3C66 /* AnimationFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationFrame.cpp; path = ../../../src/AnimationFrame.cpp; sourceTree = "<group>"; };
 		049B55941871F21D00EF3C66 /* AnimationFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationFrame.h; path = ../../../src/AnimationFrame.h; sourceTree = "<group>"; };
-		049B55951871F21D00EF3C66 /* blocking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = blocking.cpp; path = ../../../src/blocking.cpp; sourceTree = "<group>"; };
-		049B55961871F21D00EF3C66 /* blocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = blocking.h; path = ../../../src/blocking.h; sourceTree = "<group>"; };
 		049B55971871F21D00EF3C66 /* Box9Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Box9Sprite.cpp; path = ../../../src/Box9Sprite.cpp; sourceTree = "<group>"; };
 		049B55981871F21D00EF3C66 /* Box9Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Box9Sprite.h; path = ../../../src/Box9Sprite.h; sourceTree = "<group>"; };
 		049B55991871F21D00EF3C66 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Button.cpp; path = ../../../src/Button.cpp; sourceTree = "<group>"; };
@@ -272,8 +266,6 @@
 		049B55A11871F21D00EF3C66 /* closure_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = closure_impl.h; sourceTree = "<group>"; };
 		049B55A21871F21D00EF3C66 /* ColorRectSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ColorRectSprite.cpp; path = ../../../src/ColorRectSprite.cpp; sourceTree = "<group>"; };
 		049B55A31871F21D00EF3C66 /* ColorRectSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColorRectSprite.h; path = ../../../src/ColorRectSprite.h; sourceTree = "<group>"; };
-		049B55A61871F21D00EF3C66 /* coroutines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coroutines.cpp; sourceTree = "<group>"; };
-		049B55A71871F21D00EF3C66 /* coroutines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coroutines.h; sourceTree = "<group>"; };
 		049B55A81871F21D00EF3C66 /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file.cpp; sourceTree = "<group>"; };
 		049B55A91871F21D00EF3C66 /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
 		049B55AB1871F21D00EF3C66 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystem.cpp; sourceTree = "<group>"; };
@@ -531,7 +523,6 @@
 				049B55911871F21D00EF3C66 /* Actor.cpp */,
 				049B55931871F21D00EF3C66 /* AnimationFrame.cpp */,
 				92CE26711A58ABDC003901D6 /* AsyncTask.cpp */,
-				049B55951871F21D00EF3C66 /* blocking.cpp */,
 				049B55971871F21D00EF3C66 /* Box9Sprite.cpp */,
 				049B55991871F21D00EF3C66 /* Button.cpp */,
 				049B559B1871F21D00EF3C66 /* ClipRectActor.cpp */,
@@ -571,7 +562,6 @@
 				049B55921871F21D00EF3C66 /* Actor.h */,
 				049B55941871F21D00EF3C66 /* AnimationFrame.h */,
 				92CE26721A58ABDC003901D6 /* AsyncTask.h */,
-				049B55961871F21D00EF3C66 /* blocking.h */,
 				049B55981871F21D00EF3C66 /* Box9Sprite.h */,
 				049B559A1871F21D00EF3C66 /* Button.h */,
 				049B559C1871F21D00EF3C66 /* ClipRectActor.h */,
@@ -651,8 +641,6 @@
 				92F3F3471CA3BD7B00425D52 /* ThreadDispatcher.h */,
 				92F3F3481CA3BD7B00425D52 /* ThreadMessages.h */,
 				92CE26661A58AADB003901D6 /* ios */,
-				049B55A61871F21D00EF3C66 /* coroutines.cpp */,
-				049B55A71871F21D00EF3C66 /* coroutines.h */,
 				049B55A81871F21D00EF3C66 /* file.cpp */,
 				049B55A91871F21D00EF3C66 /* file.h */,
 				049B55AB1871F21D00EF3C66 /* FileSystem.cpp */,
@@ -956,7 +944,6 @@
 				049B570A1871F21E00EF3C66 /* Sprite.h in Headers */,
 				CEC2CFF91C47274C00450163 /* STDMaterial.h in Headers */,
 				049B56E61871F21E00EF3C66 /* unzip.h in Headers */,
-				049B56781871F21E00EF3C66 /* coroutines.h in Headers */,
 				049B571A1871F21E00EF3C66 /* ImageUtils.h in Headers */,
 				049B57021871F21E00EF3C66 /* Resources.h in Headers */,
 				049B56921871F21E00EF3C66 /* log.h in Headers */,
@@ -989,7 +976,6 @@
 				049B57181871F21E00EF3C66 /* AtlasTool.h in Headers */,
 				049B56EA1871F21E00EF3C66 /* oxygine-framework.h in Headers */,
 				049B571F1871F21E00EF3C66 /* VisualStyle.h in Headers */,
-				049B566A1871F21E00EF3C66 /* blocking.h in Headers */,
 				AD14D5621D72B19600182666 /* Image.h in Headers */,
 				923663591A47561500EB65B3 /* Serializable.h in Headers */,
 				049B56741871F21E00EF3C66 /* closure_impl.h in Headers */,
@@ -1133,7 +1119,6 @@
 				049B56BA1871F21E00EF3C66 /* ZipFileSystem.cpp in Sources */,
 				CEC2CFF61C47274C00450163 /* Material.cpp in Sources */,
 				049B56861871F21E00EF3C66 /* VideoDriverGL.cpp in Sources */,
-				049B56691871F21E00EF3C66 /* blocking.cpp in Sources */,
 				049B56AC1871F21E00EF3C66 /* STDFileSystem.cpp in Sources */,
 				049B56C21871F21E00EF3C66 /* TreeInspector.cpp in Sources */,
 				92CE266C1A58AADB003901D6 /* HttpRequestCocoaTask.mm in Sources */,
@@ -1170,7 +1155,6 @@
 				049B56CD1871F21E00EF3C66 /* EventDispatcher.cpp in Sources */,
 				92F3F3421CA3BD5400425D52 /* PostProcess.cpp in Sources */,
 				049B56C01871F21E00EF3C66 /* TexturesInspector.cpp in Sources */,
-				049B56771871F21E00EF3C66 /* coroutines.cpp in Sources */,
 				049B56F91871F21E00EF3C66 /* ResBuffer.cpp in Sources */,
 				049B568E1871F21E00EF3C66 /* ImageDataOperations.cpp in Sources */,
 				049B56821871F21E00EF3C66 /* ShaderProgramGL.cpp in Sources */,

+ 2 - 4
oxygine/SDL/win32/oxygine.vcxproj

@@ -115,13 +115,11 @@
     <ClCompile Include="..\..\src\Actor.cpp" />
     <ClCompile Include="..\..\src\AnimationFrame.cpp" />
     <ClCompile Include="..\..\src\AsyncTask.cpp" />
-    <ClCompile Include="..\..\src\Blocking.cpp" />
     <ClCompile Include="..\..\src\Box9Sprite.cpp" />
     <ClCompile Include="..\..\src\Button.cpp" />
     <ClCompile Include="..\..\src\ClipRectActor.cpp" />
     <ClCompile Include="..\..\src\Clock.cpp" />
     <ClCompile Include="..\..\src\ColorRectSprite.cpp" />
-    <ClCompile Include="..\..\src\core\coroutines.cpp" />
     <ClCompile Include="..\..\src\core\curl\HttpRequestCurlTask.cpp" />
     <ClCompile Include="..\..\src\core\file.cpp" />
     <ClCompile Include="..\..\src\core\FileSystem.cpp" />
@@ -219,13 +217,11 @@
     <ClInclude Include="..\..\src\Actor.h" />
     <ClInclude Include="..\..\src\AnimationFrame.h" />
     <ClInclude Include="..\..\src\AsyncTask.h" />
-    <ClInclude Include="..\..\src\Blocking.h" />
     <ClInclude Include="..\..\src\Box9Sprite.h" />
     <ClInclude Include="..\..\src\Button.h" />
     <ClInclude Include="..\..\src\ClipRectActor.h" />
     <ClInclude Include="..\..\src\Clock.h" />
     <ClInclude Include="..\..\src\ColorRectSprite.h" />
-    <ClInclude Include="..\..\src\core\coroutines.h" />
     <ClInclude Include="..\..\src\core\curl\HttpRequestCurlTask.h" />
     <ClInclude Include="..\..\src\core\file.h" />
     <ClInclude Include="..\..\src\core\FileSystem.h" />
@@ -286,6 +282,8 @@
     <ClInclude Include="..\..\src\minizip\ioapi.h" />
     <ClInclude Include="..\..\src\minizip\ioapi_mem.h" />
     <ClInclude Include="..\..\src\minizip\unzip.h" />
+    <ClInclude Include="..\..\src\oxygine-forwards.h" />
+    <ClInclude Include="..\..\src\oxygine-include.h" />
     <ClInclude Include="..\..\src\PostProcess.h" />
     <ClInclude Include="..\..\src\res\SingleResAnim.h" />
     <ClInclude Include="..\..\src\ThreadLoader.h" />

+ 6 - 12
oxygine/SDL/win32/oxygine.vcxproj.filters

@@ -135,9 +135,6 @@
     <ClCompile Include="..\..\src\core\gl\VideoDriverGL.cpp">
       <Filter>src\gl</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\coroutines.cpp">
-      <Filter>src\core</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\file.cpp">
       <Filter>src\core</Filter>
     </ClCompile>
@@ -201,9 +198,6 @@
     <ClCompile Include="..\..\src\AnimationFrame.cpp">
       <Filter>src</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\Blocking.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\Box9Sprite.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -482,9 +476,6 @@
     <ClInclude Include="..\..\src\core\gl\VideoDriverGL.h">
       <Filter>src\gl</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\coroutines.h">
-      <Filter>src\core</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\file.h">
       <Filter>src\core</Filter>
     </ClInclude>
@@ -569,9 +560,6 @@
     <ClInclude Include="..\..\src\AnimationFrame.h">
       <Filter>src</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\Blocking.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\Box9Sprite.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -755,6 +743,12 @@
     <ClInclude Include="..\..\src\res\SingleResAnim.h">
       <Filter>src\res</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\oxygine-forwards.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\oxygine-include.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="ReadMe.txt" />

+ 56 - 62
oxygine/src/Actor.cpp

@@ -32,16 +32,15 @@ namespace oxygine
         _zOrder(0),
         _scale(1, 1),
         _rotation(0),
-        _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_childrenRelative | flag_fastTransform),
+        _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_fastTransform),
         _parent(0),
         _alpha(255),
-        _pressed(0),
-        _overred(0),
         _stage(0),
         _material(0)
     {
         _transform.identity();
         _transformInvert.identity();
+        _pressedOvered = 0;
     }
 
     void Actor::copyFrom(const Actor& src, cloneOptions opt)
@@ -58,8 +57,9 @@ namespace oxygine
         _flags = src._flags;
         _parent = 0;
         _alpha = src._alpha;
-        _overred = 0;
-        _pressed = 0;
+
+        _pressedOvered = 0;
+        _material = 0;
 
         _transform = src._transform;
         _transformInvert = src._transformInvert;
@@ -124,8 +124,7 @@ namespace oxygine
         _stage->removeEventListeners(this);
         _stage = 0;
 
-        _pressed = 0;
-        _overred = 0;
+        _pressedOvered = 0;
 
         spActor actor = _children._first;
         while (actor)
@@ -276,9 +275,9 @@ namespace oxygine
         return stream.str();
     }
 
-    pointer_index Actor::getPressed() const
+    pointer_index Actor::getPressed(MouseButton b) const
     {
-        return _pressed;
+        return _pressedButton[b];
     }
 
     pointer_index Actor::getOvered() const
@@ -286,10 +285,15 @@ namespace oxygine
         return _overred;
     }
 
-    void Actor::setNotPressed()
+    void Actor::setNotPressed(MouseButton b)
     {
-        _pressed = 0;
-        _getStage()->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
+        _pressedButton[b] = 0;
+        if (_pressedOvered == _overred)//!_pressed[0] && !_pressed[1] && !_pressed[2])
+        {
+            Stage* stage = _getStage();
+            if (stage)
+                stage->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
+        }
 
         updateStatePressed();
     }
@@ -297,10 +301,10 @@ namespace oxygine
     void Actor::_onGlobalTouchUpEvent(Event* ev)
     {
         TouchEvent* te = safeCast<TouchEvent*>(ev);
-        if (te->index != _pressed)
+        if (te->index != _pressedButton[te->mouseButton])
             return;
 
-        setNotPressed();
+        setNotPressed(te->mouseButton);
 
         TouchEvent up = *te;
         up.bubbles = false;
@@ -351,11 +355,12 @@ namespace oxygine
         if (event->type == TouchEvent::TOUCH_DOWN)
         {
             TouchEvent* te = safeCast<TouchEvent*>(event);
-            if (!_pressed)
+            if (!_pressedButton[te->mouseButton])
             {
-                _pressed = te->index;
-                _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
+                if (_pressedOvered == _overred)//!_pressed[0] && !_pressed[1] && !_pressed[2])
+                    _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
 
+                _pressedButton[te->mouseButton] = te->index;
                 updateStatePressed();
             }
         }
@@ -365,21 +370,21 @@ namespace oxygine
         if (event->type == TouchEvent::TOUCH_UP)
         {
             TouchEvent* te = safeCast<TouchEvent*>(event);
-            if (_pressed == te->index)
+            if (_pressedButton[te->mouseButton] == te->index && !te->__clickDispatched)
             {
+                te->__clickDispatched = true;
                 click = *te;
                 click.type = TouchEvent::CLICK;
-                click.bubbles = false;
+                click.bubbles = true;
                 //will be dispatched later after UP
 
-                setNotPressed();
+                setNotPressed(te->mouseButton);
             }
         }
 
 
         EventDispatcher::dispatchEvent(event);
 
-
         if (!event->stopsImmediatePropagation && event->bubbles && !event->stopsPropagation)
         {
             if (_parent)
@@ -387,7 +392,7 @@ namespace oxygine
                 if (TouchEvent::isTouchEvent(event->type))
                 {
                     TouchEvent* me = safeCast<TouchEvent*>(event);
-                    me->localPosition = local2global(me->localPosition);
+                    me->localPosition = local2parent(me->localPosition);
                 }
 
                 event->phase = Event::phase_bubbling;
@@ -413,12 +418,19 @@ namespace oxygine
         }
 
         Vector2 originalLocalPos;
+        float originalLocalScale;
 
         if (touchEvent)
         {
             TouchEvent* me = safeCast<TouchEvent*>(event);
             originalLocalPos = me->localPosition;
-            me->localPosition = global2local(originalLocalPos);
+            originalLocalScale = me->__localScale;
+            me->localPosition = parent2local(originalLocalPos);
+            me->__localScale *= _transform.a;
+            if (me->__localScale == NAN)
+            {
+                OX_ASSERT(0);
+            }
         }
 
         event->phase = Event::phase_capturing;
@@ -438,7 +450,7 @@ namespace oxygine
             TouchEvent* me = safeCast<TouchEvent*>(event);
             if (!event->target)
             {
-                if ((_flags & flag_touchEnabled) && isOn(me->localPosition))
+                if ((_flags & flag_touchEnabled) && isOn(me->localPosition, me->__localScale))
                 {
                     event->phase = Event::phase_target;
                     event->target = this;
@@ -449,6 +461,7 @@ namespace oxygine
             }
 
             me->localPosition = originalLocalPos;
+            me->__localScale = originalLocalScale;
         }
     }
 
@@ -730,22 +743,20 @@ namespace oxygine
                      _pos.x, _pos.y);
         }
 
-        if (_flags & flag_childrenRelative)
+        Vector2 offset;
+        if (_flags & flag_anchorInPixels)
         {
-            Vector2 offset;
-            if (_flags & flag_anchorInPixels)
-            {
-                offset.x = -_anchor.x;
-                offset.y = -_anchor.y;
-            }
-            else
-            {
-                offset.x = -float(_size.x * _anchor.x);
-                offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality)
-            }
-
-            tr.translate(offset);
+            offset.x = -_anchor.x;
+            offset.y = -_anchor.y;
         }
+        else
+        {
+            offset.x = -float(_size.x * _anchor.x);
+            offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality)
+        }
+
+        tr.translate(offset);
+
 
         _transform = tr;
         _flags &= ~flag_transformDirty;
@@ -753,7 +764,7 @@ namespace oxygine
         const_cast<Actor*>(this)->transformUpdated();
     }
 
-    bool Actor::isOn(const Vector2& localPosition)
+    bool Actor::isOn(const Vector2& localPosition, float localScale)
     {
         RectF r = getDestRect();
         r.expand(Vector2(_extendedIsOn, _extendedIsOn), Vector2(_extendedIsOn, _extendedIsOn));
@@ -1039,13 +1050,13 @@ namespace oxygine
 
     }
 
-    Vector2 Actor::global2local(const Vector2& global) const
+    Vector2 Actor::parent2local(const Vector2& global) const
     {
         const AffineTransform& t = getTransformInvert();
         return t.transform(global);
     }
 
-    Vector2 Actor::local2global(const Vector2& local) const
+    Vector2 Actor::local2parent(const Vector2& local) const
     {
         const AffineTransform& t = getTransform();
         return t.transform(local);
@@ -1135,26 +1146,9 @@ namespace oxygine
         rs.material->render(this, rs);
     }
 
-    RectF Actor::calcDestRectF(const RectF& destRect_, const Vector2& size) const
-    {
-        RectF destRect = destRect_;
-        if (!(_flags & flag_childrenRelative))
-        {
-            Vector2 a;
-
-            if ((_flags & flag_anchorInPixels))
-                a = Vector2(_anchor.x, _anchor.y);
-            else
-                a = Vector2(_anchor.x * size.x, _anchor.y * size.y);
-
-            destRect.pos -= a;
-        }
-        return destRect;
-    }
-
     RectF Actor::getDestRect() const
     {
-        return calcDestRectF(RectF(Vector2(0, 0), getSize()), getSize());
+        return RectF(Vector2(0, 0), getSize());
     }
 
     spTween Actor::_addTween(spTween tween, bool rel)
@@ -1361,7 +1355,7 @@ namespace oxygine
         if (child->getParent() && child->getParent() != parent)
             pos = convert_global2local_(child->getParent(), parent, pos);
 
-        pos = child->global2local(pos);
+        pos = child->parent2local(pos);
         return pos;
     }
 
@@ -1374,7 +1368,7 @@ namespace oxygine
     {
         while (child && child != parent)
         {
-            pos = child->local2global(pos);
+            pos = child->local2parent(pos);
             child = child->getParent();
         }
 
@@ -1446,7 +1440,7 @@ namespace oxygine
         spActor act = actor->getParent();
         while (act && act != mutualParent)
         {
-            pos = act->local2global(pos);
+            pos = act->local2parent(pos);
             act = act->getParent();
         }
 

+ 33 - 72
oxygine/src/Actor.h

@@ -1,5 +1,6 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
+#include "oxygine-forwards.h"
 #include "core/Object.h"
 #include "core/Renderer.h"
 #include "math/Rect.h"
@@ -10,50 +11,8 @@
 #include "TouchEvent.h"
 #include "Tween.h"
 
-
-
 namespace oxygine
 {
-    class Event;
-    typedef char pointer_index;
-
-    typedef unsigned int dumpOptions;
-
-    class RenderState;
-    class UpdateState;
-    class Material;
-
-
-    DECLARE_SMART(Texture, spTexture);
-    DECLARE_SMART(Actor, spActor);
-    DECLARE_SMART(Clock, spClock);
-
-
-    typedef Closure<void (const UpdateState& us)> UpdateCallback;
-    typedef Closure<void (const RenderState& rs)> RenderCallback;
-
-    const int cloneOptionsDoNotCloneClildren = 0x01;
-    const int cloneOptionsResetTransform = 0x02;
-    typedef int cloneOptions;
-    typedef int copyOptions;//deprecated typedef
-
-
-#define DECLARE_COPYCLONE(type) type(const type &src, cloneOptions);\
-    virtual type* clone(cloneOptions opt=0) const {return new type(*this, opt);}\
-
-
-#define DECLARE_COPYCLONE_NEW(type)  type(const type &src, cloneOptions opt = 0){copyFrom(src, opt);}\
-    virtual type* clone(cloneOptions opt=0) const {type *tp = new type(); tp->copyFrom(*this, opt); return tp;}\
-    virtual void copyFrom(const type &src, cloneOptions opt = 0);
-
-#define DECLARE_COPYCLONE_NEW2(type)  type(const type &src, cloneOptions opt = 0);\
-    virtual type* clone(cloneOptions opt=0) const;\
-    virtual void copyFrom(const type &src, cloneOptions opt = 0);
-
-#define CREATE_COPYCLONE_NEW(type) type::type(const type &src, cloneOptions opt){copyFrom(src, opt);}\
-    type* type::clone(cloneOptions opt) const {type *tp = new type(); tp->copyFrom(*this, opt); return tp;}
-
-
     class TweenOptions
     {
     public:
@@ -78,7 +37,9 @@ namespace oxygine
         bool            _detach;
     };
 
-    class Actor : public EventDispatcher, public intrusive_list_item<spActor>, public Serializable
+    DECLARE_SMART(Actor, spActor);
+
+    class Actor: public EventDispatcher, public intrusive_list_item<spActor>, public Serializable
     {
         typedef intrusive_list_item<spActor> intr_list;
     public:
@@ -145,12 +106,11 @@ namespace oxygine
         const spClock&      getClock() const;
         virtual RectF       getDestRect() const;
         /**returns touch id if actor is pressed down*/
-        pointer_index       getPressed() const;
+        pointer_index       getPressed(MouseButton b = MouseButton_Touch) const;
         /**returns touch id if actor is moused overred*/
         pointer_index       getOvered() const;
         bool                getTouchEnabled() const { return (_flags & flag_touchEnabled) != 0; }
         bool                getTouchChildrenEnabled() const { return (_flags & flag_touchChildrenEnabled) != 0; }
-        bool                getChildrenRelative() const {return (_flags & flag_childrenRelative) != 0;;}
         UpdateCallback      getCallbackDoUpdate() const {return _cbDoUpdate;}
         Material*           getMaterial() { return _material; }
         //RenderCallback        getCallbackDoRender() const {return _cbDoRender;}
@@ -193,8 +153,6 @@ namespace oxygine
         void setRotation(float angle);
         /**Sets rotation angle in degrees. Converts internally to radians. (use setRotation!)*/
         void setRotationDegrees(float angle);
-        /**This option is connected with Anchor. By default value is True*/
-        void setChildrenRelative(bool r) {_flags &= ~flag_childrenRelative; if (r) _flags |= flag_childrenRelative;}
 
         /**Sets Size of Actor. Size doesn't scale contents of Actor. Size only affects event handling and rendering if you change Anchor*/
         void setSize(const Vector2&);
@@ -226,7 +184,7 @@ namespace oxygine
         /**Sets callback which would be called each Actor::render cycle before doRender. Use it if you don't want inherit from Actor and overload Actor::doRender.*/
         //void setCallbackDoRender(RenderCallback cb){_cbDoRender = cb;}
 
-        virtual bool isOn(const Vector2& localPosition);
+        virtual bool isOn(const Vector2& localPosition, float localScale = 1.0f);
         /**Returns true if actor is child or located deeper in current subtree*/
         bool isDescendant(const spActor& actor) const;
 
@@ -287,10 +245,10 @@ namespace oxygine
         virtual void handleEvent(Event* event);
         virtual void doRender(const RenderState& rs) {}
 
-        //converts global position (position in parent space) to local space
-        Vector2 global2local(const Vector2& pos) const;
+        //converts position in parent space to local space
+        Vector2 parent2local(const Vector2& pos) const;
         //converts local position to parent space
-        Vector2 local2global(const Vector2& pos = Vector2(0, 0)) const;
+        Vector2 local2parent(const Vector2& pos = Vector2(0, 0)) const;
 
         //converts local position to Stage
         Vector2 local2stage(const Vector2& pos = Vector2(0, 0), Actor* stage = 0) const;
@@ -321,7 +279,7 @@ namespace oxygine
         /**Returns Stage where Actor attached to. Used for multi stage (window) mode*/
         Stage*              _getStage();
 
-        void setNotPressed();
+        void setNotPressed(MouseButton b);
 
         bool internalRender(RenderState& rs, const RenderState& parentRS);
 
@@ -350,9 +308,11 @@ namespace oxygine
         static unsigned short& _getFlags(Actor* actor) { return actor->_flags; }
 
         void _onGlobalTouchUpEvent(Event*);
+        void _onGlobalTouchUpEvent1(Event*);
+        void _onGlobalTouchUpEvent2(Event*);
         void _onGlobalTouchMoveEvent(Event*);
 
-        RectF calcDestRectF(const RectF& destRect, const Vector2& size) const;
+        const Vector2& _getSize() const { return _size; }
         void _setSize(const Vector2&);
         virtual void sizeChanged(const Vector2& size);
         Actor*  _getDescendant(const std::string& name);
@@ -378,13 +338,12 @@ namespace oxygine
             flag_anchorInPixels         = 1,
             flag_visible                = 1 << 1,
             flag_touchEnabled           = 1 << 2,
-            flag_childrenRelative       = 1 << 3,
-            flag_transformDirty         = 1 << 4,
-            flag_transformInvertDirty   = 1 << 5,
-            flag_touchChildrenEnabled   = 1 << 6,
-            flag_cull                   = 1 << 7,
-            flag_fastTransform          = 1 << 8,
-            flag_reserved               = 1 << 9,
+            flag_transformDirty         = 1 << 3,
+            flag_transformInvertDirty   = 1 << 4,
+            flag_touchChildrenEnabled   = 1 << 5,
+            flag_cull                   = 1 << 6,
+            flag_fastTransform          = 1 << 7,
+            flag_reserved               = 1 << 8,
             flag_last                   = flag_reserved
         };
 
@@ -400,17 +359,26 @@ namespace oxygine
 
         children _children;
 
-        pointer_index _pressed;
-        pointer_index _overred;
+        union
+        {
+            //dont change order!!! or brake statements: if (_pressedOvered == _overred)
+            struct
+            {
+                pointer_index _overred;
+                pointer_index _pressedButton[MouseButton_Num];
+            };
+            int32_t _pressedOvered;
+        };
+
 
     private:
-        short   _zOrder;
 
         Vector2 _pos;
         Vector2 _anchor;
         Vector2 _scale;
         Vector2 _size;
         float   _rotation;
+        short   _zOrder;
     };
 
     Vector2 convert_local2stage(spActor child, const Vector2& pos, spActor root = 0);
@@ -446,11 +414,4 @@ namespace oxygine
 }
 
 
-#ifdef OX_EDITOR
-#include "EditorActor.h"
-#else
-namespace oxygine
-{
-    typedef Actor _Actor;
-}
-#endif
+EDITOR_INCLUDE(Actor);

+ 4 - 2
oxygine/src/AnimationFrame.cpp

@@ -82,10 +82,12 @@ namespace oxygine
 
     AnimationFrame::AnimationFrame(spNativeTexture t)
     {
+        _row = _column = 0;
+        _resAnim = 0;
         _diffuse.base = t;
         _diffuse.premultiplied = true;
         _srcRect = RectF(0, 0, 1, 1);
-        _destRect = RectF(0, 0, t->getWidth(), t->getHeight());
-        _frameSize = Vector2(t->getWidth(), t->getHeight());
+        _destRect = RectF(0, 0, (float)t->getWidth(), (float)t->getHeight());
+        _frameSize = Vector2((float)t->getWidth(), (float)t->getHeight());
     }
 }

+ 2 - 5
oxygine/src/AnimationFrame.h

@@ -1,14 +1,11 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "math/Rect.h"
 #include "core/Texture.h"
 #include "core/NativeTexture.h"
 
 namespace oxygine
 {
-    DECLARE_SMART(Texture, spTexture);
-    DECLARE_SMART(NativeTexture, spNativeTexture);
-
     class Diffuse
     {
     public:
@@ -28,7 +25,6 @@ namespace oxygine
         unsigned char pitch;
     };
 
-    class ResAnim;
     class AnimationFrame
     {
     public:
@@ -61,6 +57,7 @@ namespace oxygine
         void            setResAnim(ResAnim* rs) {_resAnim = rs;}
         void            setDiffuse(const Diffuse& d) { _diffuse = d; }
         void            setSize(const Vector2& size) {_frameSize = size;}
+        void            setSize(float w, float h) { setSize(Vector2(w, h)); }
         void            setHitTestData(const HitTestData& ad) { _hittest = ad; }
         void            setRow(int v) {_row = v;}
         void            setColumn(int v) {_column = v;}

+ 6 - 5
oxygine/src/AsyncTask.h

@@ -1,25 +1,26 @@
 #pragma once
+#include "oxygine-include.h"
 #include "core/ThreadDispatcher.h"
 #include "EventDispatcher.h"
 #include "Event.h"
 
-namespace oxygine
-{
-
 #ifdef ERROR
 #undef ERROR
 #endif
 
+namespace oxygine
+{
     DECLARE_SMART(AsyncTask, spAsyncTask);
 
-    class AsyncTaskEvent : public Event
+    class AsyncTaskEvent: public Event
     {
     public:
         AsyncTaskEvent(eventType type, AsyncTask* t) : Event(type), task(t) {}
         AsyncTask* task;
     };
 
-    class AsyncTask : public EventDispatcher
+
+    class AsyncTask: public EventDispatcher
     {
     public:
         enum

+ 6 - 11
oxygine/src/Box9Sprite.cpp

@@ -14,7 +14,7 @@ namespace oxygine
 {
     void Box9Sprite::copyFrom(const Box9Sprite& src, cloneOptions opt)
     {
-        _Sprite::copyFrom(src, opt);
+        inherited::copyFrom(src, opt);
 
         _prepared = src._prepared;
 
@@ -82,15 +82,10 @@ namespace oxygine
         _prepared = false;
     }
 
-    bool Box9Sprite::isOn(const Vector2& localPosition)
-    {
-        return Actor::isOn(localPosition);
-    }
-
     void Box9Sprite::changeAnimFrame(const AnimationFrame& f)
     {
         Vector2 size = getSize();
-        _Sprite::changeAnimFrame(f);
+        inherited::changeAnimFrame(f);
         setSize(size);
     }
 
@@ -121,7 +116,7 @@ namespace oxygine
             attr = resanim->getAttribute("horizontal");
             _horzMode = (StretchMode)attr.as_uint(STRETCHING);
         }
-        _Sprite::animFrameChanged(f);
+        inherited::animFrameChanged(f);
     }
 
     RectF Box9Sprite::getDestRect() const
@@ -274,7 +269,7 @@ namespace oxygine
         stream << "\n";
 
 
-        stream << _Sprite::dump(options);
+        stream << inherited::dump(options);
         return stream.str();
     }
 
@@ -342,7 +337,7 @@ namespace oxygine
 
     void Box9Sprite::serialize(serializedata* data)
     {
-        _Sprite::serialize(data);
+        inherited::serialize(data);
         setAttrV2(data->node, "size", getSize(), Vector2(0, 0));
         data->node.set_name("Box9Sprite");
     }
@@ -351,7 +346,7 @@ namespace oxygine
 
     void Box9Sprite::deserialize(const deserializedata* data)
     {
-        _Sprite::deserialize(data);
+        inherited::deserialize(data);
 
         setSize(attr2Vector2(data->node.attribute("size").as_string()));
     }

+ 4 - 9
oxygine/src/Box9Sprite.h

@@ -1,12 +1,13 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Sprite.h"
 namespace oxygine
 {
     DECLARE_SMART(Box9Sprite, spBox9Sprite);
 
-    class Box9Sprite: public _Sprite
+    class Box9Sprite: public Sprite
     {
+        INHERITED(Sprite);
     public:
         DECLARE_COPYCLONE_NEW(Box9Sprite);
         enum StretchMode
@@ -21,8 +22,6 @@ namespace oxygine
         StretchMode getVerticalMode() const {return _vertMode;}
         StretchMode getHorizontalMode() const {return _horzMode;}
 
-        bool isOn(const Vector2& localPosition);
-
         void setVerticalMode(StretchMode m);
         void setHorizontalMode(StretchMode m);
 
@@ -64,9 +63,5 @@ namespace oxygine
     };
 }
 
-#ifdef OX_EDITOR
-#include "EditorBox9Sprite.h"
-#else
-typedef oxygine::Box9Sprite BaseBox9Sprite;
-#endif
 
+EDITOR_INCLUDE(Box9Sprite);

+ 20 - 11
oxygine/src/Button.cpp

@@ -8,7 +8,7 @@ namespace oxygine
 {
     void Button::copyFrom(const Button& src, cloneOptions opt)
     {
-        _Sprite::copyFrom(src, opt);
+        inherited::copyFrom(src, opt);
 
         _state = src._state;
         _resAnim = src._resAnim;
@@ -34,15 +34,26 @@ namespace oxygine
     void Button::_mouseEvent(Event* event)
     {
         TouchEvent* me = safeCast<TouchEvent*>(event);
-
-        switch (event->type)
+        if (event->type == TouchEvent::CLICK)
         {
-            case TouchEvent::CLICK:
+            if (me->mouseButton == MouseButton_Left)
             {
                 event->phase = Event::phase_target;
                 event->target = this;
             }
-            break;
+            else
+            {
+                event->stopImmediatePropagation();
+            }
+
+            return;
+        }
+
+        if (me->mouseButton != MouseButton_Left)
+            return;
+
+        switch (event->type)
+        {
             case TouchEvent::OVER:
             {
                 if (!_btnOvered)
@@ -69,8 +80,7 @@ namespace oxygine
                 {
                     _btnPressed = me->index;
                     setState(statePressed);
-
-                    _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Button::_mouseEvent));
+                    addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Button::_mouseEvent));
                 }
             }
             break;
@@ -79,8 +89,7 @@ namespace oxygine
                 if (_btnPressed == me->index)
                 {
                     setState(stateNormal);
-                    if (_getStage())
-                        _getStage()->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Button::_mouseEvent));
+                    removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Button::_mouseEvent));
                     _btnPressed = 0;
                 }
             }
@@ -115,9 +124,9 @@ namespace oxygine
             return;
 
         if (_resAnim->getColumns() > s)
-            _Sprite::setAnimFrame(_resAnim->getFrame(s, _row));
+            inherited::setAnimFrame(_resAnim->getFrame(s, _row));
         else
-            _Sprite::setAnimFrame(_resAnim->getFrame(0, _row));
+            inherited::setAnimFrame(_resAnim->getFrame(0, _row));
 
     }
 }

+ 4 - 12
oxygine/src/Button.h

@@ -1,14 +1,13 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Sprite.h"
 namespace oxygine
 {
     DECLARE_SMART(Button, spButton);
 
-    class ResAnim;
-
-    class Button: public _Sprite
+    class Button: public Sprite
     {
+        INHERITED(Sprite);
     public:
         DECLARE_COPYCLONE_NEW(Button);
 
@@ -45,11 +44,4 @@ namespace oxygine
     };
 }
 
-#ifdef OX_EDITOR
-#include "EditorButton.h"
-#else
-namespace oxygine
-{
-    typedef Button _Button;
-}
-#endif
+EDITOR_INCLUDE(Button);

+ 5 - 5
oxygine/src/ClipRectActor.cpp

@@ -10,7 +10,7 @@ namespace oxygine
 {
     void ClipRectActor::copyFrom(const ClipRectActor& src, cloneOptions opt)
     {
-        _Actor::copyFrom(src, opt);
+        inherited::copyFrom(src, opt);
         _clipping = src._clipping;
     }
 
@@ -29,12 +29,12 @@ namespace oxygine
         if (TouchEvent::isTouchEvent(event->type))
         {
             TouchEvent* te = safeCast<TouchEvent*>(event);
-            Vector2 localPosition = global2local(te->localPosition);
+            Vector2 localPosition = parent2local(te->localPosition);
             if (!isOn(localPosition))
                 return;
         }
 
-        _Actor::handleEvent(event);
+        inherited::handleEvent(event);
     }
 
     void ClipRectActor::render(const RenderState& parentRS)
@@ -44,13 +44,13 @@ namespace oxygine
 
     void ClipRectActor::serialize(serializedata* data)
     {
-        _Actor::serialize(data);
+        inherited::serialize(data);
         pugi::xml_node node = data->node;
         node.set_name("ClipRectActor");
     }
 
     void ClipRectActor::deserialize(const deserializedata* data)
     {
-        _Actor::deserialize(data);
+        inherited::deserialize(data);
     }
 }

+ 4 - 7
oxygine/src/ClipRectActor.h

@@ -1,5 +1,5 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Actor.h"
 
 namespace oxygine
@@ -8,8 +8,9 @@ namespace oxygine
     /**
     ClipRectActor clips all out of bound children. Rotation is not supported
     */
-    class ClipRectActor : public _Actor
+    class ClipRectActor : public Actor
     {
+        INHERITED(Actor);
     public:
         DECLARE_COPYCLONE_NEW(ClipRectActor);
         ClipRectActor();
@@ -34,8 +35,4 @@ namespace oxygine
     };
 }
 
-#ifdef OX_EDITOR
-#include "EditorClipRectActor.h"
-#else
-typedef oxygine::ClipRectActor BaseClipRectActor;
-#endif
+EDITOR_INCLUDE(ClipRectActor);

+ 1 - 4
oxygine/src/Clock.h

@@ -1,12 +1,9 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "core/Object.h"
 
 namespace oxygine
 {
-    class UpdateState;
-
-
     DECLARE_SMART(Clock, spClock);
     class Clock: public Object
     {

+ 6 - 1
oxygine/src/ColorRectSprite.cpp

@@ -8,7 +8,7 @@ namespace oxygine
 {
     void ColorRectSprite::copyFrom(const ColorRectSprite& src, cloneOptions opt)
     {
-        _Sprite::copyFrom(src, opt);
+        inherited::copyFrom(src, opt);
     }
 
     ColorRectSprite::ColorRectSprite()
@@ -25,6 +25,11 @@ namespace oxygine
         rs.material->doRender(this, rs);
     }
 
+    void ColorRectSprite::sizeChanged(const Vector2& size)
+    {
+        Actor::sizeChanged(size);
+    }
+
     void ColorRectSprite::serialize(serializedata* data)
     {
         VStyleActor::serialize(data);

+ 8 - 11
oxygine/src/ColorRectSprite.h

@@ -1,13 +1,14 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Sprite.h"
 
 namespace oxygine
 {
     DECLARE_SMART(ColorRectSprite, spColorRectSprite);
 
-    class ColorRectSprite: public _Sprite
+    class ColorRectSprite: public Sprite
     {
+        INHERITED(Sprite);
     public:
         DECLARE_COPYCLONE_NEW(ColorRectSprite);
         ColorRectSprite();
@@ -18,15 +19,11 @@ namespace oxygine
 
         void doRender(const RenderState& rs);
 
-    private:
+        RectF getDestRect() const OVERRIDE { return Actor::getDestRect(); }
+
+    protected:
+        void sizeChanged(const Vector2& size) OVERRIDE;
     };
 }
 
-#ifdef OX_EDITOR
-#include "EditorColorRectSprite.h"
-#else
-namespace oxygine
-{
-    typedef ColorRectSprite _ColorRectSprite;
-}
-#endif
+EDITOR_INCLUDE(ColorRectSprite);

+ 67 - 23
oxygine/src/DebugActor.cpp

@@ -31,18 +31,31 @@
 #include <stdarg.h>
 #include <iomanip>
 
+
 #ifdef __S3E__
 #include "s3eMemory.h"
 #elif __APPLE__
 #include "core/ios/ios.h"
 #endif
 
+#ifndef __S3E__
+#include "SDL_video.h"
+#endif
+
+#ifdef _WIN32
+#pragma comment(lib, "psapi.lib") // Added to support GetProcessMemoryInfo()
+#include <windows.h>
+#include <Psapi.h>
+#endif
+
+
 namespace oxygine
 {
     Resources* DebugActor::resSystem = 0;
     file::ZipFileSystem zp;
 
     spDebugActor DebugActor::instance;
+    int _corner = 0;
 
     void DebugActor::initialize()
     {
@@ -54,7 +67,6 @@ namespace oxygine
         zp.setPrefix("system/");
         zp.add(system_data, system_size);
 
-        //file::ZipFileSystem zp;
         file::mount(&zp);
         resSystem = new Resources;
         resSystem->loadXML("system/res.xml", ResourcesLoadOptions().prebuiltFolder("system"));
@@ -92,8 +104,7 @@ namespace oxygine
 
     void DebugActor::setCorner(int corner)
     {
-        if (DebugActor::instance)
-            DebugActor::instance->setCornerPosition(corner);
+        _corner = corner;
     }
 
     void DebugActor::release()
@@ -105,11 +116,6 @@ namespace oxygine
         zp.reset();
     }
 
-    void DebugActor::setCornerPosition(int corner)
-    {
-        _corner = corner;
-    }
-
     void DebugActor::addButton(float& x, const char* name, const char* anim)
     {
         spButton btn;
@@ -123,7 +129,7 @@ namespace oxygine
         btn->addEventListener(TouchEvent::CLICK, CLOSURE(this, &DebugActor::_btnClicked));
     }
 
-    DebugActor::DebugActor(): _frames(0), _startTime(0), _corner(0), _showTexel2PixelErrors(false), _showTouchedActor(false)
+    DebugActor::DebugActor(): _frames(0), _startTime(0), _showTexel2PixelErrors(false), _showTouchedActor(false), _dragging(false)
     {
         DebugActor::initialize();
 
@@ -183,11 +189,24 @@ namespace oxygine
 
 
         instance = this;
+        /*
+
+        float dpi = 0;
+        float dpi1 = 0;
+        float dpi2 = 0;
+        int ret = SDL_GetDisplayDPI(0, &dpi, &dpi1, &dpi2);
+        {
+            log::messageln("dpi>>>>> %d %f %f %f", ret, dpi, dpi1, dpi2);
+        }
+        */
     }
 
     void DebugActor::onAdded2Stage()
     {
+        _dragging = false;
         _stage->addEventListener(TouchEvent::MOVE, CLOSURE(this, &DebugActor::onDAEvent));
+        _stage->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onDAEvent));
+        _stage->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &DebugActor::onDAEvent));
     }
 
     void DebugActor::onRemovedFromStage()
@@ -195,13 +214,6 @@ namespace oxygine
         _stage->removeEventListeners(this);
     }
 
-    /*
-    void DebugActor::addDebugString(const string &str)
-    {
-        _debugText += str;
-    }
-    */
-
     void DebugActor::addDebugString(const char* format, ...)
     {
         char buff[1024] = "";
@@ -334,7 +346,8 @@ namespace oxygine
 #if OXYGINE_TRACE_VIDEO_STATS
         int primitives = 0;
         primitives += vstats.elements[IVideoDriver::PT_TRIANGLES] / 3;
-        primitives += vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP] - 2;
+        if (vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP])
+            primitives += vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP] - 2;
         s << "batches=" << aligned(vstats.batches, 3) << " primitives=" << aligned(primitives, 3) << std::endl;
 #endif
 
@@ -348,6 +361,13 @@ namespace oxygine
         s << "memory=" << mem / 1024 << "kb ";
 #endif
 
+#ifdef _WIN32
+        PROCESS_MEMORY_COUNTERS_EX pmc;
+        GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc));
+        s << "memory=" << pmc.PrivateUsage / 1024 << "kb ";
+
+#endif
+
         if (!_debugText.empty())
         {
             s << "\n";
@@ -379,7 +399,7 @@ namespace oxygine
                 break;
         }
 
-        pos = getStage()->global2local(pos);
+        pos = getStage()->parent2local(pos);
 
         Vector2 realSize = getScaledSize();
         switch (_corner)
@@ -395,10 +415,9 @@ namespace oxygine
                 break;
         }
 
-        setPosition(pos);
+        //setPosition(pos);
         setScale(1.0f / getStage()->getScaleX());
 
-
         RenderState rs = parentRS;
         parentRS.material->finish();
 
@@ -455,8 +474,33 @@ namespace oxygine
     void DebugActor::onDAEvent(Event* ev)
     {
         TouchEvent* t = safeCast<TouchEvent*>(ev);
-        Vector2 loc = stage2local(t->localPosition, _getStage());
-        setAlpha(isOn(loc) ? 64 : 255);
+        Vector2 loc = parent2local(t->localPosition);
+        if (t->type == TouchEvent::MOVE)
+        {
+            setAlpha(isOn(loc) ? 64 : 255);
+
+            if (_dragging)
+            {
+                Transform tr = getTransform();
+                tr.x = 0;
+                tr.y = 0;
+                Vector2 p = tr.transform(_local);
+                setPosition(t->localPosition - p);
+            }
+        }
+
+        if (t->type == TouchEvent::TOUCH_DOWN)
+        {
+            if (isOn(loc))
+            {
+                _local = loc;
+                _dragging = true;
+            }
+        }
+        if (t->type == TouchEvent::TOUCH_UP)
+        {
+            _dragging = false;
+        }
     }
 
     void DebugActor::onEvent(Event* ev)
@@ -467,7 +511,7 @@ namespace oxygine
         cr->setTouchEnabled(false);
         cr->setColor(Color(rand() % 255, rand() % 255, rand() % 255, 0));
         cr->setSize(actor->getSize());
-        cr->addTween(ColorRectSprite::TweenColor(Color(Color::White, 200)), 700, 1, true, 0, Tween::ease_inCubic)->setDetachActor(true);
+        cr->addTween(ColorRectSprite::TweenColor(Color(Color::White, 200)), 700, 1, true, 0, Tween::ease_inCubic)->detachWhenDone();
         actor->addChild(cr);
         std::string dmp = actor->dump(0);
         log::messageln(">>>>>>>>>>>>>>>>>>>>\ntouched actor '%s' local pos: (%.0f,%.0f), pos: (%.0f,%.0f)\n%s",

+ 6 - 11
oxygine/src/DebugActor.h

@@ -1,16 +1,10 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Actor.h"
 
 
 namespace oxygine
 {
-    class ResFontBM;
-    class ResAnim;
-    class Resources;
-
-    DECLARE_SMART(TextField, spTextField);
-    DECLARE_SMART(ColorRectSprite, spColorRectSprite);
     DECLARE_SMART(DebugActor, spDebugActor);
 
     /**DebugActor is helper class. It displays FPS, memory usage, other stats and dev tools buttons*/
@@ -25,6 +19,7 @@ namespace oxygine
         static void toggle();
         static void hide();
         static void release();
+        /**where to display DebugActor. 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left corner*/
         static void setCorner(int corner);
         static void addDebugString(const char* format, ...);
         static std::string getDefaultName() { return "debug_actor"; }
@@ -32,9 +27,6 @@ namespace oxygine
         DebugActor();
         ~DebugActor();
 
-        /**where to display DebugActor. 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left corner*/
-        void setCornerPosition(int corner);
-        //void addDebugString(const string &str);
 
         /**function for debug. Helps you to find actor who handled TouchEvent*/
         void showTouchedActor(bool show);
@@ -57,11 +49,14 @@ namespace oxygine
         std::string _debugText;
         int _frames;
         timeMS _startTime;
-        int _corner;
+
 
         bool _showTouchedActor;
         bool _showTexel2PixelErrors;
 
+        bool _dragging;
+        Vector2 _local;
+
         void onEvent(Event* ev);
         void onDAEvent(Event* ev);
     };

+ 1 - 2
oxygine/src/Draggable.h

@@ -1,11 +1,10 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "Actor.h"
 //#include "Event.h"
 
 namespace oxygine
 {
-    class TouchEvent;
     Vector2 convertPosUp(Actor* src, Actor* dest, const Vector2& pos, bool direction);
     Vector2 convertPosDown(Actor* src, Actor* dest, const Vector2& pos, bool direction);
 

+ 8 - 11
oxygine/src/Event.h

@@ -1,17 +1,12 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "closure/closure.h"
 #include "Input.h"
 #include "EventDispatcher.h"
 #undef OUT
 
-struct SDL_KeyboardEvent;
-
 namespace oxygine
 {
-    typedef int eventType;
-    DECLARE_SMART(EventDispatcher, spEventDispatcher);
-
     class Event
     {
     public:
@@ -24,6 +19,9 @@ namespace oxygine
             phase_bubbling
         };
 
+        Event(eventType Type, bool Bubbles = false) : listenerID(0), userData(0), type(Type), phase(phase_target), bubbles(Bubbles), stopsImmediatePropagation(false), stopsPropagation(false) {}
+        virtual ~Event() {}
+
         eventType type;
         Phase phase;
         bool bubbles;
@@ -34,11 +32,10 @@ namespace oxygine
         spObject userDataObject;
         int listenerID;
 
-        spEventDispatcher target; //The event target
-        spEventDispatcher currentTarget;// The object that is actively processing the Event object with an event listener.
-
-        Event(eventType Type, bool Bubbles = false) : listenerID(0), userData(0), type(Type), phase(phase_target), bubbles(Bubbles), stopsImmediatePropagation(false), stopsPropagation(false) {}
-        virtual ~Event() {}
+        /**The event target*/
+        spEventDispatcher target;
+        /**The object that is actively processing the Event object with an event listener*/
+        spEventDispatcher currentTarget;
 
         void stopPropagation() { stopsPropagation = true; }
         void stopImmediatePropagation() { stopsPropagation = stopsImmediatePropagation = true; }

+ 0 - 1
oxygine/src/EventDispatcher.cpp

@@ -54,7 +54,6 @@ namespace oxygine
     {
         __doCheck();
 
-        OX_ASSERT(_listeners);
         if (!_listeners)
             return;
 

+ 11 - 7
oxygine/src/EventDispatcher.h

@@ -1,30 +1,34 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include <list>
 #include "core/Object.h"
 #include "closure/closure.h"
 
 namespace oxygine
 {
-    typedef int eventType;
-    class Event;
-
 #define makefourcc(a,b,c,d) ( ((unsigned int)a) | (((unsigned int)b)<< 8) | (((unsigned int)c)<<16) | (((unsigned int)d)<<24))
 
+#ifdef OX_HAS_CPP11
+    inline int error_eventID_should_be_size_of_4_chars(int x) { return x; }
+    constexpr size_t constStringLength(const char* str) { return (*str == 0) ? 0 : constStringLength(str + 1) + 1; }
+    constexpr int EventIDc11(const char* str) { return constStringLength(str) == 4 ? makefourcc(str[0], str[1], str[2], str[3]) : error_eventID_should_be_size_of_4_chars(0); }
+#endif
+
     //eventID('_', '_', '_', '_')
 #define eventID(a,b,c,d) makefourcc(a,b,c,d)
 
     /*sysEventID is used for system Oxygine events, use 'eventID' for custom game events*/
 #define sysEventID(b,c,d) makefourcc(0xA,b,c,d)
 
+#define  EventID(str) EventIDc11(str)
 
-    typedef Closure<void (Event* ev)> EventCallback;
 
     DECLARE_SMART(EventDispatcher, spEventDispatcher);
-    class EventDispatcher: public _Object
+    class EventDispatcher: public Object
     {
+        INHERITED(Object);
     public:
-        EventDispatcher(const EventDispatcher& ed): _Object(ed), _lastID(0), _listeners(0) {}
+        EventDispatcher(const EventDispatcher& ed): inherited(ed), _lastID(0), _listeners(0) {}
         EventDispatcher();
         ~EventDispatcher();
 

+ 6 - 13
oxygine/src/Font.cpp

@@ -32,14 +32,11 @@ namespace oxygine
         _sdf = sdf;
         _size = realSize;
         _baselineDistance = baselineDistance;
-        _lineHeight = lineHeight;
-        //_glyphs.reserve(200);
     }
 
     void Font::addGlyph(const glyph& gl)
     {
         _glyphs.insert(gl);
-        //_glyphs.push_back(gl);
     }
 
     bool glyphFindPred(const glyph& g, int code)
@@ -52,10 +49,11 @@ namespace oxygine
         return ob1.ch < ob2.ch;
     }
 
-    const glyph* Font::findGlyph(int code) const
+    const glyph* Font::findGlyph(int code, const glyphOptions& opt) const
     {
         glyph g;
         g.ch = code;
+        g.opt = opt;
         glyphs::const_iterator it = _glyphs.find(g);
         if (it != _glyphs.end())
         {
@@ -65,18 +63,18 @@ namespace oxygine
         return 0;
     }
 
-    const glyph* Font::getGlyph(int code) const
+    const glyph* Font::getGlyph(int code, const glyphOptions& opt) const
     {
-        const glyph* g = findGlyph(code);
+        const glyph* g = findGlyph(code, opt);
         if (g)
             return g;
 
         glyph gl;
         Font* fn = const_cast<Font*>(this);
-        if (fn->loadGlyph(code, gl))
+        if (fn->loadGlyph(code, gl, opt))
         {
             fn->_glyphs.insert(gl);
-            g = findGlyph(code);
+            g = findGlyph(code, opt);
             OX_ASSERT(g);
         }
 
@@ -98,11 +96,6 @@ namespace oxygine
         return _scale;
     }
 
-    int Font::getLineHeight() const
-    {
-        return _lineHeight;
-    }
-
     bool Font::isSDF() const
     {
         return _sdf;

+ 12 - 10
oxygine/src/Font.h

@@ -1,5 +1,5 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "core/Object.h"
 #include "math/Rect.h"
 #ifdef __S3E__
@@ -7,15 +7,15 @@
 #else
 #include <unordered_set>
 #endif
+
 namespace oxygine
 {
-    DECLARE_SMART(NativeTexture, spNativeTexture);
-
     struct glyph
     {
         RectF src;
 
         int ch;
+        glyphOptions opt;
 
         short sw;
         short sh;
@@ -28,18 +28,21 @@ namespace oxygine
 
         spNativeTexture texture;
 
-        bool operator == (const glyph& r) const {return ch == r.ch;}
+        bool operator == (const glyph& r) const {return ch == r.ch && opt == r.opt;}
+#ifdef __S3E__
         bool operator < (const glyph& r) const { return ch < r.ch; }
+#endif
     };
 
     struct GlyphHasher
     {
         std::size_t operator()(const glyph& k) const
         {
-            return std::hash<int>()(k.ch);
+            return std::hash<int>()(k.ch + k.opt);
         }
     };
 
+
     class Font: public ObjectBase
     {
     public:
@@ -52,18 +55,18 @@ namespace oxygine
         void sortGlyphs() {}
 
         void setScale(float scale) { _scale = scale; }
+        void setBaselineDistance(int d) { _baselineDistance = d; }
 
-        const glyph*    getGlyph(int code) const;
+        const glyph*    getGlyph(int code, const glyphOptions& opt) const;
         int             getBaselineDistance() const;
         int             getSize() const;
         float           getScale() const;
-        int             getLineHeight() const;
         bool            isSDF() const;
 
     protected:
-        const glyph* findGlyph(int code) const;
+        const glyph* findGlyph(int code, const glyphOptions& opt) const;
 
-        virtual bool loadGlyph(int code, glyph&) { return false; }
+        virtual bool loadGlyph(int code, glyph&, const glyphOptions& opt) { return false; }
 
 #ifdef __S3E__
         typedef std::set<glyph> glyphs;
@@ -77,6 +80,5 @@ namespace oxygine
 
         int _size;
         int _baselineDistance;
-        int _lineHeight;
     };
 }

+ 6 - 1
oxygine/src/HttpRequestTask.cpp

@@ -4,7 +4,12 @@
 
 namespace oxygine
 {
-    HttpRequestTask::createHttpRequestCallback _createRequestsCallback = 0;
+    HttpRequestTask* createNullHttpTask()
+    {
+        return 0;
+    }
+
+    HttpRequestTask::createHttpRequestCallback _createRequestsCallback = createNullHttpTask;
 
     spHttpRequestTask HttpRequestTask::create()
     {

+ 1 - 4
oxygine/src/HttpRequestTask.h

@@ -1,5 +1,5 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "AsyncTask.h"
 #include <vector>
 #include <string>
@@ -75,8 +75,5 @@ namespace oxygine
         bool _cacheEnabled;
         std::vector<unsigned char> _response;
         std::vector<unsigned char> _postData;
-
-        //size_t _loaded;
-        //size_t _total;
     };
 }

+ 13 - 3
oxygine/src/Image.cpp

@@ -735,7 +735,7 @@ namespace oxygine
         log::warning("Image. can't unpack data unknown file format");
 
         init(16, 16, TF_R8G8B8A8);
-        fill_zero();
+        fillZero();
 
         return false;
     }
@@ -805,6 +805,16 @@ namespace oxygine
         return lock(lock_read | lock_write, &rect);
     }
 
+    ImageData Image::lock(int x, int y, int w, int h)
+    {
+        return lock(Rect(x, y, w, h));
+    }
+
+    ImageData Image::lock(int x, int y)
+    {
+        return lock(Rect(x, y, _image.w - x, _image.h - y));
+    }
+
     void Image::unlock()
     {
 
@@ -812,9 +822,9 @@ namespace oxygine
 
     void Image::toPOT(Image& dest)
     {
-		OX_ASSERT(this != &dest);
+        OX_ASSERT(this != &dest);
         dest.init(nextPOT(_image.w), nextPOT(_image.h), _image.format);
-        dest.fill_zero();
+        dest.fillZero();
         dest.updateRegion(0, 0, _image);
     }
 

+ 7 - 1
oxygine/src/Image.h

@@ -1,5 +1,5 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "core/Texture.h"
 #include "core/file.h"
 
@@ -34,7 +34,10 @@ namespace oxygine
         void convert(Image& dest, TextureFormat format);
         //void convert2pot(MemoryTexture &dest);
 
+        OXYGINE_DEPRECATED
         void fill_zero();
+
+        void fillZero() { fill(0); }
         void fill(unsigned int val);
 
         unsigned int    getSizeVRAM() const {return (unsigned int)_buffer.size();}
@@ -46,6 +49,9 @@ namespace oxygine
         ImageData   lock(lock_flags f = 0, const Rect* pRect = 0);
         ImageData   lock(const Rect* pRect);
         ImageData   lock(const Rect& pRect);
+        ImageData   lock(int x, int y, int w, int h);
+        ImageData   lock(int x, int y);
+
         void        unlock();
         void        toPOT(Image& dest);
 

+ 29 - 7
oxygine/src/Input.cpp

@@ -17,6 +17,14 @@ namespace oxygine
 
     void Input::sendPointerButtonEvent(spStage stage, MouseButton button, float x, float y, float pressure, int type, PointerState* ps)
     {
+        if (!_multiTouch && ps->getIndex() != 1 && ps != &_pointerMouse)
+        {
+            if (type == TouchEvent::TOUCH_UP)
+                _ids[ps->getIndex() - 1] = 0;
+            
+            return;
+        }
+
         Vector2 p(x, y);
 
         TouchEvent me(type, true, p);
@@ -36,13 +44,15 @@ namespace oxygine
         stage->handleEvent(&me);
 
         if (type == TouchEvent::TOUCH_UP)
-        {
             _ids[ps->getIndex() - 1] = 0;
-        }
     }
 
     void Input::sendPointerMotionEvent(spStage stage, float x, float y, float pressure, PointerState* ps)
     {
+
+        if (!_multiTouch && ps->getIndex() != 1 && ps != &_pointerMouse)
+            return;
+
         TouchEvent me(TouchEvent::MOVE, true, Vector2(x, y));
         me.index = ps->getIndex();
         me.pressure = pressure;
@@ -52,14 +62,17 @@ namespace oxygine
         stage->handleEvent(&me);
     }
 
-    void Input::sendPointerWheelEvent(spStage stage, int scroll, PointerState* ps)
+    void Input::sendPointerWheelEvent(spStage stage, const Vector2& dir, PointerState* ps)
     {
-        TouchEvent me(scroll > 0 ? TouchEvent::WHEEL_UP : TouchEvent::WHEEL_DOWN, true);
+        TouchEvent me(dir.y > 0 ? TouchEvent::WHEEL_UP : TouchEvent::WHEEL_DOWN, true, ps->getPosition());
         me.index = ps->getIndex();
+        stage->handleEvent(&me);
 
-        ps->_position = Vector2(0, 0);
 
-        stage->handleEvent(&me);
+        TouchEvent te(TouchEvent::WHEEL_DIR, true, ps->getPosition());
+        te.index = ps->getIndex();
+        te.wheelDirection = dir;
+        stage->handleEvent(&te);
     }
 
 
@@ -69,6 +82,7 @@ namespace oxygine
         for (int i = 0; i < MAX_TOUCHES; ++i)
             _pointers[i].init(i + 1);
         memset(_ids, 0, sizeof(_ids));
+        _multiTouch = true;
     }
 
     Input::~Input()
@@ -80,8 +94,16 @@ namespace oxygine
     {
     }
 
-    PointerState* Input::getTouchByIndex(int index)
+    void Input::multiTouchEnabled(bool en)
+    {
+        _multiTouch = en;
+    }
+
+    PointerState* Input::getTouchByIndex(pointer_index index_)
     {
+        OX_ASSERT(index_ != 0);
+
+        int index = index_;
         if (index == MAX_TOUCHES + 1)
             return &_pointerMouse;
         index -= 1;

+ 9 - 9
oxygine/src/Input.h

@@ -1,15 +1,11 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "EventDispatcher.h"
 #include "closure/closure.h"
 #include "PointerState.h"
 
 namespace oxygine
 {
-    DECLARE_SMART(Stage, spStage);
-    class Actor;
-    class EventState;
-
     const int MAX_TOUCHES = 17;
 
     class Input
@@ -22,8 +18,10 @@ namespace oxygine
 
         void cleanup();
 
-        /**id should be in range [1, MAX_TOUCHES]*/
-        PointerState* getTouchByIndex(int index);
+        void multiTouchEnabled(bool en);
+
+        /**index should be in range [1, MAX_TOUCHES]*/
+        PointerState* getTouchByIndex(pointer_index index);
 
 #ifndef __S3E__
         int touchID2index(int64 id);
@@ -40,6 +38,8 @@ namespace oxygine
 
         void sendPointerButtonEvent(spStage, MouseButton button, float x, float y, float pressure, int type, PointerState*);
         void sendPointerMotionEvent(spStage, float x, float y, float pressure, PointerState*);
-        void sendPointerWheelEvent(spStage, int scroll, PointerState*);
+        void sendPointerWheelEvent(spStage, const Vector2& dir, PointerState*);
+
+        bool _multiTouch;
     };
-}
+}

+ 1 - 2
oxygine/src/InputText.h

@@ -1,5 +1,5 @@
 #pragma once
-#include "oxygine_include.h"
+#include "oxygine-include.h"
 #include "EventDispatcher.h"
 #include <string>
 
@@ -9,7 +9,6 @@
 
 namespace oxygine
 {
-    DECLARE_SMART(TextField, spTextField);
     DECLARE_SMART(InputText, spInputText);
 
     class InputText: public EventDispatcher

+ 1 - 1
oxygine/src/MaskedRenderer.cpp

@@ -5,7 +5,7 @@
 
 namespace oxygine
 {
-    MaskedRenderer::MaskedRenderer(spNativeTexture mask, const RectF& srcRect, const RectF& destRect, const Transform& t, bool channelR) : _mask(mask)
+    MaskedRenderer::MaskedRenderer(spNativeTexture mask, const RectF& srcRect, const RectF& destRect, const Transform& t, bool channelR, IVideoDriver* driver) : STDRenderer(driver), _mask(mask)
     {
         _clipUV = ClipUV(
                       t.transform(destRect.getLeftTop()),

Some files were not shown because too many files changed in this diff