Explorar o código

Merge branch 'master' of github.com:bkaradzic/bgfx

Branimir Karadžić %!s(int64=9) %!d(string=hai) anos
pai
achega
0c633a61a4

+ 16 - 15
3rdparty/ocornut-imgui/imgui.cpp

@@ -150,6 +150,7 @@
  Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
  Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
  Also read releases logs https://github.com/ocornut/imgui/releases for more details.
  Also read releases logs https://github.com/ocornut/imgui/releases for more details.
 
 
+ - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it.
  - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
  - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
  - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
  - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
  - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. 
  - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. 
@@ -708,8 +709,8 @@ static bool             DataTypeApplyOpFromText(const char* buf, const char* ini
 // Platform dependent default implementations
 // Platform dependent default implementations
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-static const char*      GetClipboardTextFn_DefaultImpl();
-static void             SetClipboardTextFn_DefaultImpl(const char* text);
+static const char*      GetClipboardTextFn_DefaultImpl(void* user_data);
+static void             SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
 static void             ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
 static void             ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -834,6 +835,7 @@ ImGuiIO::ImGuiIO()
     MemFreeFn = free;
     MemFreeFn = free;
     GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;   // Platform dependent default implementations
     GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;   // Platform dependent default implementations
     SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
     SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
+    ClipboardUserData = NULL;
     ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
     ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
 
 
     // Set OS X style defaults based on __APPLE__ compile time flag
     // Set OS X style defaults based on __APPLE__ compile time flag
@@ -2015,13 +2017,13 @@ void ImGui::MemFree(void* ptr)
 
 
 const char* ImGui::GetClipboardText()
 const char* ImGui::GetClipboardText()
 {
 {
-    return GImGui->IO.GetClipboardTextFn ? GImGui->IO.GetClipboardTextFn() : "";
+    return GImGui->IO.GetClipboardTextFn ? GImGui->IO.GetClipboardTextFn(GImGui->IO.ClipboardUserData) : "";
 }
 }
 
 
 void ImGui::SetClipboardText(const char* text)
 void ImGui::SetClipboardText(const char* text)
 {
 {
     if (GImGui->IO.SetClipboardTextFn)
     if (GImGui->IO.SetClipboardTextFn)
-        GImGui->IO.SetClipboardTextFn(text);
+        GImGui->IO.SetClipboardTextFn(GImGui->IO.ClipboardUserData, text);
 }
 }
 
 
 const char* ImGui::GetVersion()
 const char* ImGui::GetVersion()
@@ -5802,8 +5804,7 @@ void ImGui::LogFinish()
     }
     }
     if (g.LogClipboard->size() > 1)
     if (g.LogClipboard->size() > 1)
     {
     {
-        if (g.IO.SetClipboardTextFn)
-            g.IO.SetClipboardTextFn(g.LogClipboard->begin());
+        SetClipboardText(g.LogClipboard->begin());
         g.LogClipboard->clear();
         g.LogClipboard->clear();
     }
     }
 }
 }
@@ -7434,12 +7435,12 @@ static void    STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob
 
 
 static bool is_separator(unsigned int c)                                        { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
 static bool is_separator(unsigned int c)                                        { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
 static int  is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx)      { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; }
 static int  is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx)      { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; }
-static int  STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)   { while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
+static int  STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)   { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
 #ifdef __APPLE__    // FIXME: Move setting to IO structure
 #ifdef __APPLE__    // FIXME: Move setting to IO structure
 static int  is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx)       { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; }
 static int  is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx)       { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; }
-static int  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)  { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
+static int  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)  { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
 #else
 #else
-static int  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)  { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
+static int  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)  { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
 #endif
 #endif
 #define STB_TEXTEDIT_MOVEWORDLEFT   STB_TEXTEDIT_MOVEWORDLEFT_IMPL    // They need to be #define for stb_textedit.h
 #define STB_TEXTEDIT_MOVEWORDLEFT   STB_TEXTEDIT_MOVEWORDLEFT_IMPL    // They need to be #define for stb_textedit.h
 #define STB_TEXTEDIT_MOVEWORDRIGHT  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
 #define STB_TEXTEDIT_MOVEWORDRIGHT  STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
@@ -7865,7 +7866,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
                 const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW;
                 const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW;
                 edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1);
                 edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1);
                 ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie);
                 ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie);
-                io.SetClipboardTextFn(edit_state.TempTextBuffer.Data);
+                SetClipboardText(edit_state.TempTextBuffer.Data);
             }
             }
 
 
             if (cut)
             if (cut)
@@ -7877,7 +7878,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
         else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable)
         else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable)
         {
         {
             // Paste
             // Paste
-            if (const char* clipboard = io.GetClipboardTextFn ? io.GetClipboardTextFn() : NULL)
+            if (const char* clipboard = GetClipboardText())
             {
             {
                 // Filter pasted buffer
                 // Filter pasted buffer
                 const int clipboard_len = (int)strlen(clipboard);
                 const int clipboard_len = (int)strlen(clipboard);
@@ -9571,7 +9572,7 @@ void ImGui::ValueColor(const char* prefix, ImU32 v)
 #pragma comment(lib, "user32")
 #pragma comment(lib, "user32")
 #endif
 #endif
 
 
-static const char* GetClipboardTextFn_DefaultImpl()
+static const char* GetClipboardTextFn_DefaultImpl(void*)
 {
 {
     static ImVector<char> buf_local;
     static ImVector<char> buf_local;
     buf_local.clear();
     buf_local.clear();
@@ -9591,7 +9592,7 @@ static const char* GetClipboardTextFn_DefaultImpl()
     return buf_local.Data;
     return buf_local.Data;
 }
 }
 
 
-static void SetClipboardTextFn_DefaultImpl(const char* text)
+static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
 {
 {
     if (!OpenClipboard(NULL))
     if (!OpenClipboard(NULL))
         return;
         return;
@@ -9610,13 +9611,13 @@ static void SetClipboardTextFn_DefaultImpl(const char* text)
 #else
 #else
 
 
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
-static const char* GetClipboardTextFn_DefaultImpl()
+static const char* GetClipboardTextFn_DefaultImpl(void*)
 {
 {
     return GImGui->PrivateClipboard;
     return GImGui->PrivateClipboard;
 }
 }
 
 
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
-static void SetClipboardTextFn_DefaultImpl(const char* text)
+static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     if (g.PrivateClipboard)
     if (g.PrivateClipboard)

+ 12 - 15
3rdparty/ocornut-imgui/imgui.h

@@ -759,8 +759,9 @@ struct ImGuiIO
 
 
     // Optional: access OS clipboard
     // Optional: access OS clipboard
     // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
     // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
-    const char* (*GetClipboardTextFn)();
-    void        (*SetClipboardTextFn)(const char* text);
+    const char* (*GetClipboardTextFn)(void* user_data);
+    void        (*SetClipboardTextFn)(void* user_data, const char* text);
+    void*       ClipboardUserData;
 
 
     // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
     // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
     // (default to posix malloc/free)
     // (default to posix malloc/free)
@@ -806,7 +807,7 @@ struct ImGuiIO
     int         MetricsActiveWindows;       // Number of visible windows (exclude child windows)
     int         MetricsActiveWindows;       // Number of visible windows (exclude child windows)
 
 
     //------------------------------------------------------------------
     //------------------------------------------------------------------
-    // [Internal] ImGui will maintain those fields for you
+    // [Private] ImGui will maintain those fields. Forward compatibility not guaranteed!
     //------------------------------------------------------------------
     //------------------------------------------------------------------
 
 
     ImVec2      MousePosPrev;               // Previous mouse position
     ImVec2      MousePosPrev;               // Previous mouse position
@@ -953,10 +954,9 @@ struct ImGuiTextBuffer
 };
 };
 
 
 // Helper: Simple Key->value storage
 // Helper: Simple Key->value storage
-// - Store collapse state for a tree (Int 0/1)
-// - Store color edit options (Int using values in ImGuiColorEditMode enum).
-// - Custom user storage for temporary values.
 // Typically you don't have to worry about this since a storage is held within each Window.
 // Typically you don't have to worry about this since a storage is held within each Window.
+// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options.
+// You can use it as custom user storage for temporary values.
 // Declare your own storage if:
 // Declare your own storage if:
 // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
 // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
 // - You want to store custom debug data easily without adding or editing structures in your code.
 // - You want to store custom debug data easily without adding or editing structures in your code.
@@ -988,9 +988,8 @@ struct ImGuiStorage
 
 
     // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.
     // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.
     // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
     // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
-    // - A typical use case where this is convenient:
+    // - A typical use case where this is convenient for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct)
     //      float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar;
     //      float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar;
-    // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application.
     IMGUI_API int*      GetIntRef(ImGuiID key, int default_val = 0);
     IMGUI_API int*      GetIntRef(ImGuiID key, int default_val = 0);
     IMGUI_API bool*     GetBoolRef(ImGuiID key, bool default_val = false);
     IMGUI_API bool*     GetBoolRef(ImGuiID key, bool default_val = false);
     IMGUI_API float*    GetFloatRef(ImGuiID key, float default_val = 0.0f);
     IMGUI_API float*    GetFloatRef(ImGuiID key, float default_val = 0.0f);
@@ -1059,8 +1058,8 @@ struct ImGuiSizeConstraintCallbackData
 
 
 // ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
 // ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
 // Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
 // Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
-// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
-// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
+// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
+// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
 struct ImColor
 struct ImColor
 {
 {
     ImVec4              Value;
     ImVec4              Value;
@@ -1174,7 +1173,7 @@ struct ImDrawList
     ImVector<ImDrawVert>    VtxBuffer;          // Vertex buffer.
     ImVector<ImDrawVert>    VtxBuffer;          // Vertex buffer.
 
 
     // [Internal, used while building lists]
     // [Internal, used while building lists]
-    const char*             _OwnerName;         // Pointer to owner window's name (if any) for debugging
+    const char*             _OwnerName;         // Pointer to owner window's name for debugging
     unsigned int            _VtxCurrentIdx;     // [Internal] == VtxBuffer.Size
     unsigned int            _VtxCurrentIdx;     // [Internal] == VtxBuffer.Size
     ImDrawVert*             _VtxWritePtr;       // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
     ImDrawVert*             _VtxWritePtr;       // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
     ImDrawIdx*              _IdxWritePtr;       // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
     ImDrawIdx*              _IdxWritePtr;       // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
@@ -1185,7 +1184,7 @@ struct ImDrawList
     int                     _ChannelsCount;     // [Internal] number of active channels (1+)
     int                     _ChannelsCount;     // [Internal] number of active channels (1+)
     ImVector<ImDrawChannel> _Channels;          // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
     ImVector<ImDrawChannel> _Channels;          // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
 
 
-    ImDrawList() { _OwnerName = NULL; Clear(); }
+    ImDrawList()  { _OwnerName = NULL; Clear(); }
     ~ImDrawList() { ClearFreeMemory(); }
     ~ImDrawList() { ClearFreeMemory(); }
     IMGUI_API void  PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false);  // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
     IMGUI_API void  PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false);  // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
     IMGUI_API void  PushClipRectFullScreen();
     IMGUI_API void  PushClipRectFullScreen();
@@ -1398,9 +1397,7 @@ struct ImFont
 #pragma clang diagnostic pop
 #pragma clang diagnostic pop
 #endif
 #endif
 
 
-//---- Include imgui_user.h at the end of imgui.h
-//---- So you can include code that extends ImGui using any of the types declared above.
-//---- (also convenient for user to only explicitly include vanilla imgui.h)
+// Include imgui_user.h at the end of imgui.h (convenient for user to only explicitly include vanilla imgui.h)
 #ifdef IMGUI_INCLUDE_IMGUI_USER_H
 #ifdef IMGUI_INCLUDE_IMGUI_USER_H
 #include "imgui_user.h"
 #include "imgui_user.h"
 #endif
 #endif

+ 1 - 1
3rdparty/ocornut-imgui/imgui_demo.cpp

@@ -1542,7 +1542,7 @@ void ImGui::ShowTestWindow(bool* p_open)
 
 
         if (ImGui::TreeNode("Dragging"))
         if (ImGui::TreeNode("Dragging"))
         {
         {
-            ImGui::TextWrapped("You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget.");
+            ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
             ImGui::Button("Drag Me");
             ImGui::Button("Drag Me");
             if (ImGui::IsItemActive())
             if (ImGui::IsItemActive())
             {
             {

+ 44 - 40
3rdparty/stb/stb_textedit.h

@@ -1,9 +1,10 @@
-// [ImGui] this is a slightly modified version of stb_truetype.h 1.8
+// [ImGui] this is a slightly modified version of stb_truetype.h 1.9. Those changes would need to be pushed into nothings/sb
+// [ImGui] - fixed linestart handler when over last character of multi-line buffer + simplified existing code (#588, #815)
+// [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715)
 // [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681)
 // [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681)
 // [ImGui] - fixed some minor warnings
 // [ImGui] - fixed some minor warnings
-// [ImGui] - added STB_TEXTEDIT_MOVEWORDLEFT/STB_TEXTEDIT_MOVEWORDRIGHT custom handler (#473)
 
 
-// stb_textedit.h - v1.8  - public domain - Sean Barrett
+// stb_textedit.h - v1.9  - public domain - Sean Barrett
 // Development of this library was sponsored by RAD Game Tools
 // Development of this library was sponsored by RAD Game Tools
 //
 //
 // This C header file implements the guts of a multi-line text-editing
 // This C header file implements the guts of a multi-line text-editing
@@ -36,6 +37,7 @@
 //
 //
 // VERSION HISTORY
 // VERSION HISTORY
 //
 //
+//   1.9  (2016-08-27) customizable move-by-word
 //   1.8  (2016-04-02) better keyboard handling when mouse button is down
 //   1.8  (2016-04-02) better keyboard handling when mouse button is down
 //   1.7  (2015-09-13) change y range handling in case baseline is non-0
 //   1.7  (2015-09-13) change y range handling in case baseline is non-0
 //   1.6  (2015-04-15) allow STB_TEXTEDIT_memmove
 //   1.6  (2015-04-15) allow STB_TEXTEDIT_memmove
@@ -424,10 +426,9 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
    // check if it's before the end of the line
    // check if it's before the end of the line
    if (x < r.x1) {
    if (x < r.x1) {
       // search characters in row for one that straddles 'x'
       // search characters in row for one that straddles 'x'
-      k = i;
       prev_x = r.x0;
       prev_x = r.x0;
-      for (i=0; i < r.num_chars; ++i) {
-         float w = STB_TEXTEDIT_GETWIDTH(str, k, i);
+      for (k=0; k < r.num_chars; ++k) {
+         float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
          if (x < prev_x+w) {
          if (x < prev_x+w) {
             if (x < prev_x+w/2)
             if (x < prev_x+w/2)
                return k+i;
                return k+i;
@@ -617,15 +618,16 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
 }
 }
 
 
 #ifdef STB_TEXTEDIT_IS_SPACE
 #ifdef STB_TEXTEDIT_IS_SPACE
-static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx )
+static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
 {
 {
-   return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1;
+   return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
 }
 }
 
 
 #ifndef STB_TEXTEDIT_MOVEWORDLEFT
 #ifndef STB_TEXTEDIT_MOVEWORDLEFT
-static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c )
+static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
 {
 {
-   while( c >= 0 && !is_word_boundary( _str, c ) )
+   --c; // always move at least one character
+   while( c >= 0 && !is_word_boundary( str, c ) )
       --c;
       --c;
 
 
    if( c < 0 )
    if( c < 0 )
@@ -637,10 +639,11 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c
 #endif
 #endif
 
 
 #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
 #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
-static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, int c )
+static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
 {
 {
-   const int len = STB_TEXTEDIT_STRINGLEN(_str);
-   while( c < len && !is_word_boundary( _str, c ) )
+   const int len = STB_TEXTEDIT_STRINGLEN(str);
+   ++c; // always move at least one character
+   while( c < len && !is_word_boundary( str, c ) )
       ++c;
       ++c;
 
 
    if( c > len )
    if( c > len )
@@ -777,7 +780,7 @@ retry:
          if (STB_TEXT_HAS_SELECTION(state))
          if (STB_TEXT_HAS_SELECTION(state))
             stb_textedit_move_to_first(state);
             stb_textedit_move_to_first(state);
          else {
          else {
-            state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
+            state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
             stb_textedit_clamp( str, state );
             stb_textedit_clamp( str, state );
          }
          }
          break;
          break;
@@ -786,7 +789,7 @@ retry:
          if( !STB_TEXT_HAS_SELECTION( state ) )
          if( !STB_TEXT_HAS_SELECTION( state ) )
             stb_textedit_prep_selection_at_cursor(state);
             stb_textedit_prep_selection_at_cursor(state);
 
 
-         state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
+         state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
          state->select_end = state->cursor;
          state->select_end = state->cursor;
 
 
          stb_textedit_clamp( str, state );
          stb_textedit_clamp( str, state );
@@ -798,7 +801,7 @@ retry:
          if (STB_TEXT_HAS_SELECTION(state)) 
          if (STB_TEXT_HAS_SELECTION(state)) 
             stb_textedit_move_to_last(str, state);
             stb_textedit_move_to_last(str, state);
          else {
          else {
-            state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
+            state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
             stb_textedit_clamp( str, state );
             stb_textedit_clamp( str, state );
          }
          }
          break;
          break;
@@ -807,7 +810,7 @@ retry:
          if( !STB_TEXT_HAS_SELECTION( state ) )
          if( !STB_TEXT_HAS_SELECTION( state ) )
             stb_textedit_prep_selection_at_cursor(state);
             stb_textedit_prep_selection_at_cursor(state);
 
 
-         state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
+         state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
          state->select_end = state->cursor;
          state->select_end = state->cursor;
 
 
          stb_textedit_clamp( str, state );
          stb_textedit_clamp( str, state );
@@ -990,58 +993,58 @@ retry:
 #ifdef STB_TEXTEDIT_K_LINESTART2
 #ifdef STB_TEXTEDIT_K_LINESTART2
       case STB_TEXTEDIT_K_LINESTART2:
       case STB_TEXTEDIT_K_LINESTART2:
 #endif
 #endif
-      case STB_TEXTEDIT_K_LINESTART: {
-         StbFindState find;
+      case STB_TEXTEDIT_K_LINESTART:
          stb_textedit_clamp(str, state);
          stb_textedit_clamp(str, state);
          stb_textedit_move_to_first(state);
          stb_textedit_move_to_first(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->cursor = find.first_char;
+         if (state->single_line)
+            state->cursor = 0;
+         else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
+            --state->cursor;
          state->has_preferred_x = 0;
          state->has_preferred_x = 0;
          break;
          break;
-      }
 
 
 #ifdef STB_TEXTEDIT_K_LINEEND2
 #ifdef STB_TEXTEDIT_K_LINEEND2
       case STB_TEXTEDIT_K_LINEEND2:
       case STB_TEXTEDIT_K_LINEEND2:
 #endif
 #endif
       case STB_TEXTEDIT_K_LINEEND: {
       case STB_TEXTEDIT_K_LINEEND: {
-         StbFindState find;
+         int n = STB_TEXTEDIT_STRINGLEN(str);
          stb_textedit_clamp(str, state);
          stb_textedit_clamp(str, state);
          stb_textedit_move_to_first(state);
          stb_textedit_move_to_first(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-
+         if (state->single_line)
+             state->cursor = n;
+         else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
+             ++state->cursor;
          state->has_preferred_x = 0;
          state->has_preferred_x = 0;
-         state->cursor = find.first_char + find.length;
-         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
-            --state->cursor;
          break;
          break;
       }
       }
 
 
 #ifdef STB_TEXTEDIT_K_LINESTART2
 #ifdef STB_TEXTEDIT_K_LINESTART2
       case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
       case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
 #endif
 #endif
-      case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
-         StbFindState find;
+      case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT:
          stb_textedit_clamp(str, state);
          stb_textedit_clamp(str, state);
          stb_textedit_prep_selection_at_cursor(state);
          stb_textedit_prep_selection_at_cursor(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->cursor = state->select_end = find.first_char;
+         if (state->single_line)
+            state->cursor = 0;
+         else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
+            --state->cursor;
+         state->select_end = state->cursor;
          state->has_preferred_x = 0;
          state->has_preferred_x = 0;
          break;
          break;
-      }
 
 
 #ifdef STB_TEXTEDIT_K_LINEEND2
 #ifdef STB_TEXTEDIT_K_LINEEND2
       case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
       case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
 #endif
 #endif
       case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
       case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
-         StbFindState find;
+         int n = STB_TEXTEDIT_STRINGLEN(str);
          stb_textedit_clamp(str, state);
          stb_textedit_clamp(str, state);
          stb_textedit_prep_selection_at_cursor(state);
          stb_textedit_prep_selection_at_cursor(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->has_preferred_x = 0;
-         state->cursor = find.first_char + find.length;
-         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
-            --state->cursor;
+         if (state->single_line)
+             state->cursor = n;
+         else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
+            ++state->cursor;
          state->select_end = state->cursor;
          state->select_end = state->cursor;
+         state->has_preferred_x = 0;
          break;
          break;
       }
       }
 
 
@@ -1101,8 +1104,8 @@ static void stb_textedit_discard_redo(StbUndoState *state)
             if (state->undo_rec[i].char_storage >= 0)
             if (state->undo_rec[i].char_storage >= 0)
                state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
                state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
       }
       }
+      STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point-1, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
       ++state->redo_point;
       ++state->redo_point;
-      STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
    }
    }
 }
 }
 
 
@@ -1260,6 +1263,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
    if (r.insert_length) {
    if (r.insert_length) {
       // easy case: need to insert n characters
       // easy case: need to insert n characters
       STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
       STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
+      s->redo_char_point += r.insert_length;
    }
    }
 
 
    state->cursor = r.where + r.insert_length;
    state->cursor = r.where + r.insert_length;

+ 2 - 5
examples/common/entry/entry_windows.cpp

@@ -34,11 +34,8 @@ namespace entry
 	inline void winSetHwnd(::HWND _window)
 	inline void winSetHwnd(::HWND _window)
 	{
 	{
 		bgfx::PlatformData pd;
 		bgfx::PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
+		memset(&pd, 0, sizeof(pd) );
+		pd.nwh = _window;
 		bgfx::setPlatformData(pd);
 		bgfx::setPlatformData(pd);
 	}
 	}
 
 

+ 20 - 2
src/renderer_gl.cpp

@@ -4350,6 +4350,11 @@ namespace bgfx { namespace gl
 		, const GLvoid* _data
 		, const GLvoid* _data
 	)
 	)
 	{
 	{
+		if (NULL == _data)
+		{
+			return;
+		}
+
 		if (_target == GL_TEXTURE_3D
 		if (_target == GL_TEXTURE_3D
 		||  _target == GL_TEXTURE_2D_ARRAY
 		||  _target == GL_TEXTURE_2D_ARRAY
 		||  _target == GL_TEXTURE_CUBE_MAP_ARRAY)
 		||  _target == GL_TEXTURE_CUBE_MAP_ARRAY)
@@ -4420,7 +4425,19 @@ namespace bgfx { namespace gl
 		else if (_target == GL_TEXTURE_2D_ARRAY
 		else if (_target == GL_TEXTURE_2D_ARRAY
 			 ||  _target == GL_TEXTURE_CUBE_MAP_ARRAY)
 			 ||  _target == GL_TEXTURE_CUBE_MAP_ARRAY)
 		{
 		{
-			texSubImage(_target, _level, 0, 0, _depth, _width, _height, 1, _format, _type, _data);
+			texSubImage(
+				  _target
+				, _level
+				, 0
+				, 0
+				, _depth
+				, _width
+				, _height
+				, 1
+				, _format
+				, _type
+				, _data
+				);
 		}
 		}
 		else if (_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
 		else if (_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
 		{
 		{
@@ -5963,7 +5980,8 @@ namespace bgfx { namespace gl
 		uint32_t dsFlags = _flags & (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL);
 		uint32_t dsFlags = _flags & (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL);
 		if (BGFX_CLEAR_NONE != dsFlags)
 		if (BGFX_CLEAR_NONE != dsFlags)
 		{
 		{
-			if ( (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL) == dsFlags)
+			if (!BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES)
+			&&  (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL) == dsFlags)
 			{
 			{
 				buffers[idx++] = GL_DEPTH_STENCIL_ATTACHMENT;
 				buffers[idx++] = GL_DEPTH_STENCIL_ATTACHMENT;
 			}
 			}

+ 33 - 13
tools/shaderc/shaderc.cpp

@@ -784,8 +784,7 @@ namespace bgfx
 		const char* platform = cmdLine.findOption('\0', "platform");
 		const char* platform = cmdLine.findOption('\0', "platform");
 		if (NULL == platform)
 		if (NULL == platform)
 		{
 		{
-			help("Must specify platform.");
-			return EXIT_FAILURE;
+			platform = "";
 		}
 		}
 
 
 		bool raw = cmdLine.hasArg('\0', "raw");
 		bool raw = cmdLine.hasArg('\0', "raw");
@@ -796,6 +795,7 @@ namespace bgfx
 		uint32_t d3d   = 11;
 		uint32_t d3d   = 11;
 		uint32_t metal = 0;
 		uint32_t metal = 0;
 		uint32_t pssl  = 0;
 		uint32_t pssl  = 0;
+		uint32_t spirv = 0;
 		const char* profile = cmdLine.findOption('p', "profile");
 		const char* profile = cmdLine.findOption('p', "profile");
 		if (NULL != profile)
 		if (NULL != profile)
 		{
 		{
@@ -824,6 +824,10 @@ namespace bgfx
 			{
 			{
 				pssl = 1;
 				pssl = 1;
 			}
 			}
+			else if (0 == strcmp(profile, "spirv") )
+			{
+				spirv = 1;
+			}
 			else
 			else
 			{
 			{
 				glsl = atoi(profile);
 				glsl = atoi(profile);
@@ -902,11 +906,15 @@ namespace bgfx
 		preprocessor.setDefaultDefine("BX_PLATFORM_PS4");
 		preprocessor.setDefaultDefine("BX_PLATFORM_PS4");
 		preprocessor.setDefaultDefine("BX_PLATFORM_WINDOWS");
 		preprocessor.setDefaultDefine("BX_PLATFORM_WINDOWS");
 		preprocessor.setDefaultDefine("BX_PLATFORM_XBOX360");
 		preprocessor.setDefaultDefine("BX_PLATFORM_XBOX360");
+		preprocessor.setDefaultDefine("BX_PLATFORM_XBOXONE");
+
 //		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_ESSL");
 //		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_ESSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_GLSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_GLSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_HLSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_HLSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_METAL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_METAL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_PSSL");
 		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_PSSL");
+		preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_SPIRV");
+
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_COMPUTE");
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_COMPUTE");
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_FRAGMENT");
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_FRAGMENT");
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_VERTEX");
 		preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_VERTEX");
@@ -965,11 +973,6 @@ namespace bgfx
 			preprocessor.setDefine("BGFX_SHADER_LANGUAGE_PSSL=1");
 			preprocessor.setDefine("BGFX_SHADER_LANGUAGE_PSSL=1");
 			preprocessor.setDefine("lit=lit_reserved");
 			preprocessor.setDefine("lit=lit_reserved");
 		}
 		}
-		else
-		{
-			fprintf(stderr, "Unknown platform %s?!", platform);
-			return EXIT_FAILURE;
-		}
 
 
 		preprocessor.setDefine("M_PI=3.1415926535897932384626433832795");
 		preprocessor.setDefine("M_PI=3.1415926535897932384626433832795");
 
 
@@ -1384,6 +1387,10 @@ namespace bgfx
 								compiled = compileGLSLShader(cmdLine, essl, code, writer);
 								compiled = compileGLSLShader(cmdLine, essl, code, writer);
 	#endif // 0
 	#endif // 0
 							}
 							}
+							else if (0 != spirv)
+							{
+								compiled = compileSPIRVShader(cmdLine, 0, preprocessor.m_preprocessed, writer);
+							}
 							else if (0 != pssl)
 							else if (0 != pssl)
 							{
 							{
 								compiled = compilePSSLShader(cmdLine, 0, preprocessor.m_preprocessed, writer);
 								compiled = compilePSSLShader(cmdLine, 0, preprocessor.m_preprocessed, writer);
@@ -1807,7 +1814,8 @@ namespace bgfx
 
 
 							if (0 != glsl
 							if (0 != glsl
 							||  0 != essl
 							||  0 != essl
-							||  0 != metal)
+							||  0 != metal
+							||  0 != spirv )
 							{
 							{
 								std::string code;
 								std::string code;
 
 
@@ -1957,11 +1965,23 @@ namespace bgfx
 								}
 								}
 
 
 								code += preprocessor.m_preprocessed;
 								code += preprocessor.m_preprocessed;
-								compiled = compileGLSLShader(cmdLine
-									, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : essl
-									, code
-									, writer
-									);
+
+								if (0 != spirv)
+								{
+									compiled = compileSPIRVShader(cmdLine
+										, 0
+										, code
+										, writer
+										);
+								}
+								else
+								{
+									compiled = compileGLSLShader(cmdLine
+										, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : essl
+										, code
+										, writer
+										);
+								}
 							}
 							}
 							else if (0 != pssl)
 							else if (0 != pssl)
 							{
 							{