+
+
@@ -31,48 +31,55 @@
-
-
-
+
-
+ I18N="In the user screen" text="Password"/>
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp
index f717129ee..14754bdc2 100644
--- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp
+++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp
@@ -48,6 +48,8 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
: CIrrDeviceStub(param),
Accelerometer(0),
Gyroscope(0),
+ AccelerometerActive(false),
+ GyroscopeActive(false),
IsMousePressed(false),
GamepadAxisX(0),
GamepadAxisY(0),
@@ -246,14 +248,14 @@ bool CIrrDeviceAndroid::run()
accEvent.AccelerometerEvent.X = event.acceleration.x;
accEvent.AccelerometerEvent.Y = event.acceleration.y;
}
- accEvent.AccelerometerEvent.Z = event.acceleration.z;
if (accEvent.AccelerometerEvent.X < 0)
{
accEvent.AccelerometerEvent.X *= -1;
accEvent.AccelerometerEvent.Y *= -1;
- accEvent.AccelerometerEvent.Z *= -1;
}
+
+ accEvent.AccelerometerEvent.Z = event.acceleration.z;
postEventFromUser(accEvent);
break;
@@ -769,7 +771,7 @@ s32 CIrrDeviceAndroid::handleGamepad(AInputEvent* androidEvent)
{
event.KeyInput.PressedDown = true;
event.KeyInput.Key = axis_x < 0 ? IRR_KEY_BUTTON_LEFT
- : IRR_KEY_BUTTON_RIGHT;
+ : IRR_KEY_BUTTON_RIGHT;
postEventFromUser(event);
}
@@ -790,7 +792,7 @@ s32 CIrrDeviceAndroid::handleGamepad(AInputEvent* androidEvent)
{
event.KeyInput.PressedDown = true;
event.KeyInput.Key = axis_y < 0 ? IRR_KEY_BUTTON_UP
- : IRR_KEY_BUTTON_DOWN;
+ : IRR_KEY_BUTTON_DOWN;
postEventFromUser(event);
}
@@ -1210,12 +1212,19 @@ bool CIrrDeviceAndroid::activateAccelerometer(float updateInterval)
DefaultOrientation = getDefaultOrientation();
}
- ASensorEventQueue_enableSensor(SensorEventQueue, Accelerometer);
- ASensorEventQueue_setEventRate(SensorEventQueue, Accelerometer,
+ int err = ASensorEventQueue_enableSensor(SensorEventQueue, Accelerometer);
+
+ if (err == 0)
+ {
+ AccelerometerActive = true;
+
+ ASensorEventQueue_setEventRate(SensorEventQueue, Accelerometer,
(int32_t)(updateInterval*1000.f*1000.f)); // in microseconds
+
+ os::Printer::log("Activated accelerometer", ELL_DEBUG);
+ }
- os::Printer::log("Activated accelerometer", ELL_DEBUG);
- return true;
+ return AccelerometerActive;
}
bool CIrrDeviceAndroid::deactivateAccelerometer()
@@ -1223,15 +1232,20 @@ bool CIrrDeviceAndroid::deactivateAccelerometer()
if (!Accelerometer)
return false;
- ASensorEventQueue_disableSensor(SensorEventQueue, Accelerometer);
- Accelerometer = 0;
- os::Printer::log("Deactivated accelerometer", ELL_DEBUG);
- return true;
+ int err = ASensorEventQueue_disableSensor(SensorEventQueue, Accelerometer);
+
+ if (err == 0)
+ {
+ AccelerometerActive = false;
+ os::Printer::log("Deactivated accelerometer", ELL_DEBUG);
+ }
+
+ return !AccelerometerActive;
}
bool CIrrDeviceAndroid::isAccelerometerActive()
{
- return (Accelerometer != NULL);
+ return AccelerometerActive;
}
bool CIrrDeviceAndroid::isAccelerometerAvailable()
@@ -1250,12 +1264,19 @@ bool CIrrDeviceAndroid::activateGyroscope(float updateInterval)
if (!isGyroscopeAvailable())
return false;
- ASensorEventQueue_enableSensor(SensorEventQueue, Gyroscope);
- ASensorEventQueue_setEventRate(SensorEventQueue, Gyroscope,
+ int err = ASensorEventQueue_enableSensor(SensorEventQueue, Gyroscope);
+
+ if (err == 0)
+ {
+ GyroscopeActive = true;
+
+ ASensorEventQueue_setEventRate(SensorEventQueue, Gyroscope,
(int32_t)(updateInterval*1000.f*1000.f)); // in microseconds
- os::Printer::log("Activated gyroscope", ELL_DEBUG);
- return true;
+ os::Printer::log("Activated gyroscope", ELL_DEBUG);
+ }
+
+ return GyroscopeActive;
}
bool CIrrDeviceAndroid::deactivateGyroscope()
@@ -1263,15 +1284,20 @@ bool CIrrDeviceAndroid::deactivateGyroscope()
if (!Gyroscope)
return false;
- ASensorEventQueue_disableSensor(SensorEventQueue, Gyroscope);
- Gyroscope = 0;
- os::Printer::log("Deactivated gyroscope", ELL_DEBUG);
- return true;
+ int err = ASensorEventQueue_disableSensor(SensorEventQueue, Gyroscope);
+
+ if (err == 0)
+ {
+ GyroscopeActive = false;
+ os::Printer::log("Deactivated gyroscope", ELL_DEBUG);
+ }
+
+ return !GyroscopeActive;
}
bool CIrrDeviceAndroid::isGyroscopeActive()
{
- return (Gyroscope != NULL);
+ return GyroscopeActive;
}
bool CIrrDeviceAndroid::isGyroscopeAvailable()
diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h
index 33ce575b9..60002e116 100644
--- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h
+++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h
@@ -111,6 +111,8 @@ namespace irr
ASensorEventQueue* SensorEventQueue;
const ASensor* Accelerometer;
const ASensor* Gyroscope;
+ bool AccelerometerActive;
+ bool GyroscopeActive;
static bool IsPaused;
static bool IsFocused;
diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp
index 97fb7b82f..055cd447d 100644
--- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp
+++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp
@@ -991,88 +991,105 @@ bool CIrrDeviceLinux::createWindow()
Atom wmDelete;
wmDelete = XInternAtom(display, wmDeleteWindow, True);
XSetWMProtocols(display, window, &wmDelete, 1);
-
+
if (CreationParams.Fullscreen)
{
- if (netWM)
+ // Some window managers don't respect values from XCreateWindow and
+ // place window in random position. This may cause that fullscreen
+ // window is showed in wrong screen. It doesn't matter for vidmode
+ // which displays cloned image in all devices.
+ #ifdef _IRR_LINUX_X11_RANDR_
+ XMoveResizeWindow(display, window, crtc_x, crtc_y, Width, Height);
+ XRaiseWindow(display, window);
+ XFlush(display);
+ #endif
+ }
+
+ unsigned int display_width = XDisplayWidth(display, screennr);
+ unsigned int display_height = XDisplayHeight(display, screennr);
+
+ bool has_display_size = (Width == display_width && Height == display_height);
+
+ if (netWM && (CreationParams.Fullscreen || has_display_size))
+ {
+ Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
+ Atom WMStateAtom1 = None;
+ Atom WMStateAtom2 = None;
+
+ if (CreationParams.Fullscreen)
{
- // Some window managers don't respect values from XCreateWindow and
- // place window in random position. This may cause that fullscreen
- // window is showed in wrong screen. It doesn't matter for vidmode
- // which displays cloned image in all devices.
- #ifdef _IRR_LINUX_X11_RANDR_
- XMoveResizeWindow(display, window, crtc_x, crtc_y, Width, Height);
- XRaiseWindow(display, window);
- XFlush(display);
- #endif
-
- // Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others.
- // Get the needed atom from there freedesktop names
- Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
- Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
-
- XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
- xev.type = ClientMessage;
- xev.xclient.window = window;
- xev.xclient.message_type = WMStateAtom;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = WMFullscreenAtom;
- XSendEvent(display, RootWindow(display, visual->screen), false,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-
- XFlush(display);
-
- // Wait until window state is already changed to fullscreen
- bool fullscreen = false;
- for (int i = 0; i < 500; i++)
- {
- Atom type;
- int format;
- unsigned long numItems, bytesAfter;
- Atom* atoms = NULL;
-
- int s = XGetWindowProperty(display, window, WMStateAtom,
- 0l, 1024, False, XA_ATOM, &type,
- &format, &numItems, &bytesAfter,
- (unsigned char**)&atoms);
-
- if (s == Success)
- {
- for (unsigned int i = 0; i < numItems; ++i)
- {
- if (atoms[i] == WMFullscreenAtom)
- {
- fullscreen = true;
- break;
- }
- }
-
- XFree(atoms);
- }
-
- if (fullscreen == true)
- break;
-
- usleep(1000);
- }
-
- if (!fullscreen)
- {
- os::Printer::log("Warning! Got timeout while checking fullscreen sate", ELL_WARNING);
- }
+ WMStateAtom1 = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
}
else
{
- XSetInputFocus(display, window, RevertToParent, CurrentTime);
- int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
- GrabModeAsync, CurrentTime);
- IrrPrintXGrabError(grabKb, "XGrabKeyboard");
- int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
- GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
- IrrPrintXGrabError(grabPointer, "XGrabPointer");
- XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
+ WMStateAtom1 = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", true);
+ WMStateAtom2 = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", true);
}
+
+ XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
+ xev.type = ClientMessage;
+ xev.xclient.window = window;
+ xev.xclient.message_type = WMStateAtom;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = WMStateAtom1;
+ xev.xclient.data.l[2] = WMStateAtom2;
+
+ XSendEvent(display, RootWindow(display, visual->screen), false,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+
+ XFlush(display);
+
+ // Wait until window state is already changed
+ bool changed = false;
+ for (int i = 0; i < 500; i++)
+ {
+ Atom type;
+ int format;
+ unsigned long numItems, bytesAfter;
+ Atom* atoms = NULL;
+
+ int s = XGetWindowProperty(display, window, WMStateAtom,
+ 0l, 1024, False, XA_ATOM, &type,
+ &format, &numItems, &bytesAfter,
+ (unsigned char**)&atoms);
+
+ if (s == Success)
+ {
+ for (unsigned int i = 0; i < numItems; ++i)
+ {
+ if (atoms[i] == WMStateAtom1)
+ {
+ changed = true;
+ break;
+ }
+ }
+
+ XFree(atoms);
+ }
+
+ if (changed == true)
+ break;
+
+ usleep(1000);
+ }
+
+ if (!changed)
+ {
+ os::Printer::log("Warning! Got timeout when changing window state", ELL_WARNING);
+ }
+ }
+
+ if (!netWM && CreationParams.Fullscreen)
+ {
+ XSetInputFocus(display, window, RevertToParent, CurrentTime);
+ int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
+ GrabModeAsync, CurrentTime);
+ IrrPrintXGrabError(grabKb, "XGrabKeyboard");
+ int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
+ GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
+ IrrPrintXGrabError(grabPointer, "XGrabPointer");
+ XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
}
}
else
diff --git a/src/font/font_with_face.cpp b/src/font/font_with_face.cpp
index d4be51ede..905489c55 100644
--- a/src/font/font_with_face.cpp
+++ b/src/font/font_with_face.cpp
@@ -331,6 +331,12 @@ void FontWithFace::setDPI()
{
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
+
+#ifdef ANDROID
+ float scale = screen_height / 480.0f;
+ m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
+
+#else
float scale = std::max(0, screen_width - 640) / 564.0f;
// attempt to compensate for small screens
@@ -341,6 +347,7 @@ void FontWithFace::setDPI()
m_face_dpi = unsigned((getScalingFactorOne() + 0.2f * scale) *
getScalingFactorTwo());
+#endif
} // setDPI
diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp
index 04f5546fb..2a1b8c04a 100644
--- a/src/graphics/material_manager.cpp
+++ b/src/graphics/material_manager.cpp
@@ -25,6 +25,7 @@
#include "config/user_config.hpp"
#include "graphics/material.hpp"
#include "graphics/particle_kind_manager.hpp"
+#include "graphics/sp/sp_texture_manager.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "modes/profile_world.hpp"
@@ -55,6 +56,10 @@ MaterialManager::MaterialManager()
*/
MaterialManager::~MaterialManager()
{
+#ifndef SERVER_ONLY
+ SP::SPTextureManager::get()->stopThreads();
+#endif
+
for(unsigned int i=0; i
stopThreads();
SPShaderManager::destroy();
g_glow_shader = NULL;
g_normal_visualizer = NULL;
diff --git a/src/graphics/sp/sp_texture_manager.cpp b/src/graphics/sp/sp_texture_manager.cpp
index fbd955fa3..24281efde 100644
--- a/src/graphics/sp/sp_texture_manager.cpp
+++ b/src/graphics/sp/sp_texture_manager.cpp
@@ -78,16 +78,7 @@ SPTextureManager::SPTextureManager()
// ----------------------------------------------------------------------------
SPTextureManager::~SPTextureManager()
{
- m_max_threaded_load_obj.store(0);
- std::unique_lock ul(m_thread_obj_mutex);
- m_threaded_functions.push_back([](){ return true; });
- m_thread_obj_cv.notify_all();
- ul.unlock();
- for (std::thread& t : m_threaded_load_obj)
- {
- t.join();
- }
- m_threaded_load_obj.clear();
+ assert(m_threaded_load_obj.empty());
removeUnusedTextures();
#ifdef DEBUG
for (auto p : m_textures)
diff --git a/src/graphics/sp/sp_texture_manager.hpp b/src/graphics/sp/sp_texture_manager.hpp
index 25efa2c1a..685803fe5 100644
--- a/src/graphics/sp/sp_texture_manager.hpp
+++ b/src/graphics/sp/sp_texture_manager.hpp
@@ -85,6 +85,20 @@ public:
// ------------------------------------------------------------------------
~SPTextureManager();
// ------------------------------------------------------------------------
+ void stopThreads()
+ {
+ m_max_threaded_load_obj.store(0);
+ std::unique_lock ul(m_thread_obj_mutex);
+ m_threaded_functions.push_back([](){ return true; });
+ m_thread_obj_cv.notify_all();
+ ul.unlock();
+ for (std::thread& t : m_threaded_load_obj)
+ {
+ t.join();
+ }
+ m_threaded_load_obj.clear();
+ }
+ // ------------------------------------------------------------------------
void removeUnusedTextures();
// ------------------------------------------------------------------------
void addThreadedFunction(std::function threaded_function)
diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp
index 6c996f1a5..1c73b38d4 100644
--- a/src/guiengine/engine.cpp
+++ b/src/guiengine/engine.cpp
@@ -1163,14 +1163,26 @@ namespace GUIEngine
// ---- some menus may need updating
if (gamestate != GAME)
{
- if (ModalDialog::isADialogActive())
+ if (ScreenKeyboard::isActive())
+ {
+ ScreenKeyboard::getCurrent()->onUpdate(dt);
+ }
+ else if (ModalDialog::isADialogActive())
+ {
ModalDialog::getCurrent()->onUpdate(dt);
+ }
else
+ {
getCurrentScreen()->onUpdate(elapsed_time);
+ }
}
else
{
- if (ModalDialog::isADialogActive())
+ if (ScreenKeyboard::isActive())
+ {
+ ScreenKeyboard::getCurrent()->onUpdate(dt);
+ }
+ else if (ModalDialog::isADialogActive())
{
ModalDialog::getCurrent()->onUpdate(dt);
}
diff --git a/src/guiengine/screen_keyboard.cpp b/src/guiengine/screen_keyboard.cpp
index 7c7ae5ac1..22619ef7b 100644
--- a/src/guiengine/screen_keyboard.cpp
+++ b/src/guiengine/screen_keyboard.cpp
@@ -37,23 +37,23 @@ typedef std::string KeyboardLayout[KEYBOARD_ROWS_NUM][KEYBOARD_COLS_NUM];
KeyboardLayout layout_lower =
{{"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "123" },
- {"a", "s", "d", "f", "g", "h", "j", "k", "l", "Back", "Shift"},
+ {"a", "s", "d", "f", "g", "h", "j", "k", "l", "Shift", "Back" },
{"z", "x", "c", "v", "b", "n", "m", ",", ".", "Space", "Enter"}};
KeyboardLayout layout_upper =
{{"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "123" },
- {"A", "S", "D", "F", "G", "H", "J", "K", "L", "Back", "Shift"},
+ {"A", "S", "D", "F", "G", "H", "J", "K", "L", "Shift", "Back" },
{"Z", "X", "C", "V", "B", "N", "M", ",", ".", "Space", "Enter"}};
-
+
KeyboardLayout layout_digits =
- {{"1", "2", "3", "!", "@", "#", "$", "%", "^", "&", "Text" },
- {"4", "5", "6", "*", "(", ")", "-", "_", "=", "Back", "Shift"},
- {"7", "8", "9", "0", "+", "/", "?", ",", ".", "Space", "Enter"}};
+ {{"1", "2", "3", "!", "@", "#", "$", "%", "^", "&", "Text" },
+ {"4", "5", "6", "*", "(", ")", "-", "+", "?", "Shift", "Back" },
+ {"7", "8", "9", "0", "\"", ";", ":", ",", ".", "Space", "Enter"}};
KeyboardLayout layout_digits2 =
- {{"1", "2", "3", "[", "]", "{", "}", ";", ":", "\\", "Text" },
- {"4", "5", "6", "|", "\'", "\"", "<", ">", "`", "Back", "Shift"},
- {"7", "8", "9", "0", "~", "/", "?", ",", ".", "Space", "Enter"}};
+ {{"1", "2", "3", "[", "]", "{", "}", "~", "`", "\\", "Text" },
+ {"4", "5", "6", "|", "<", ">", "_", "=", "/", "Shift", "Back" },
+ {"7", "8", "9", "0", "\'", ";", ":", ",", ".", "Space", "Enter"}};
ScreenKeyboard* ScreenKeyboard::m_screen_keyboard = NULL;
@@ -81,6 +81,8 @@ ScreenKeyboard::ScreenKeyboard(float percent_width, float percent_height,
m_percent_height = std::min(std::max(percent_height, 0.0f), 1.0f);
m_irrlicht_window = NULL;
m_edit_box = edit_box;
+ m_back_button = NULL;
+ m_repeat_time = 0;
init();
} // ScreenKeyboard
@@ -135,6 +137,10 @@ void ScreenKeyboard::init()
createButtons();
assignButtons(BUTTONS_LOWER);
+
+ Widget* button_widget = getWidget("Back");
+ assert(button_widget != NULL);
+ m_back_button = button_widget->getIrrlichtElement();
} // init
// ----------------------------------------------------------------------------
@@ -179,6 +185,37 @@ void ScreenKeyboard::createButtons()
addWidgetsRecursively(m_widgets);
} // createButtons
+// ----------------------------------------------------------------------------
+
+std::wstring ScreenKeyboard::getKeyName(std::string key_id)
+{
+ std::wstring key_name;
+
+ if (key_id == "Enter")
+ {
+ key_name = L"\u23CE";
+ }
+ else if (key_id == "Shift")
+ {
+ key_name = L"\u21E7";
+ }
+ else if (key_id == "Back")
+ {
+ key_name = L"\u232B";
+ }
+ else if (key_id == "Space")
+ {
+ key_name = L"\u2423";
+ }
+ else
+ {
+ std::wstring tmp(key_id.begin(), key_id.end());
+ key_name = tmp;
+ }
+
+ return key_name;
+}
+
// ----------------------------------------------------------------------------
/** A function that allows to select one of the available buttons layout
* \param buttons_type One of the available buttons type
@@ -213,14 +250,52 @@ void ScreenKeyboard::assignButtons(ButtonsType buttons_type)
for (int j = 0; j < KEYBOARD_COLS_NUM; j++)
{
std::string key = keys != NULL ? (*keys)[i][j] : "?";
+ std::wstring key_name = getKeyName(key);
ButtonWidget* button = m_buttons[i * KEYBOARD_COLS_NUM + j];
- button->setText(key.c_str());
+
+ button->setText(key_name.c_str());
button->m_properties[PROP_ID] = key;
}
}
} // assignButtons
+// ----------------------------------------------------------------------------
+
+void ScreenKeyboard::onUpdate(float dt)
+{
+ if (m_back_button->isPressed())
+ {
+ const unsigned int repeat_rate = 40;
+ const unsigned int repeat_delay = 400;
+
+ SEvent event;
+ event.KeyInput.Key = IRR_KEY_BACK;
+ event.KeyInput.Char = 0;
+ event.EventType = EET_KEY_INPUT_EVENT;
+ event.KeyInput.PressedDown = true;
+ event.KeyInput.Control = false;
+ event.KeyInput.Shift = false;
+
+ if (m_repeat_time == 0)
+ {
+ m_edit_box->OnEvent(event);
+ }
+
+ while (m_repeat_time > repeat_delay + repeat_rate)
+ {
+ m_edit_box->OnEvent(event);
+ m_repeat_time -= repeat_rate;
+ }
+
+ m_repeat_time += (unsigned int)(dt * 1000);
+ }
+ else
+ {
+ m_repeat_time = 0;
+ }
+}
+
// ----------------------------------------------------------------------------
/** A function that handles buttons events
* \param eventSource Button ID
@@ -272,9 +347,7 @@ EventPropagation ScreenKeyboard::processEvent(const std::string& eventSource)
}
else if (eventSource == "Back")
{
- event.KeyInput.Key = IRR_KEY_BACK;
- event.KeyInput.Char = 0;
- send_event = true;
+ send_event = false;
}
else if (eventSource == "Space")
{
diff --git a/src/guiengine/screen_keyboard.hpp b/src/guiengine/screen_keyboard.hpp
index 04df28b43..bbb12fd5c 100644
--- a/src/guiengine/screen_keyboard.hpp
+++ b/src/guiengine/screen_keyboard.hpp
@@ -19,6 +19,7 @@
#ifndef HEADER_SCREEN_KEYBOARD_HPP
#define HEADER_SCREEN_KEYBOARD_HPP
+#include
#include
#include "guiengine/abstract_top_level_container.hpp"
@@ -67,9 +68,15 @@ namespace GUIEngine
* that is used by the keyboard */
float m_percent_height;
+ /** A time for repeat key feature */
+ unsigned int m_repeat_time;
+
/** The edit box that is assigned to the keyboard */
CGUIEditBox* m_edit_box;
+ /** A button that is used as backspace key */
+ irr::gui::IGUIButton* m_back_button;
+
/** Remembers currently selected button type */
ButtonsType m_buttons_type;
@@ -88,6 +95,7 @@ namespace GUIEngine
void init();
void createButtons();
void assignButtons(ButtonsType buttons_type);
+ std::wstring getKeyName(std::string key_id);
public:
LEAK_CHECK()
@@ -100,7 +108,6 @@ namespace GUIEngine
static void dismiss();
static bool onEscapePressed();
-
/** Returns pointer to the created keyboard or NULL if keyboard was
* not created */
static ScreenKeyboard* getCurrent() {return m_screen_keyboard;}
@@ -108,6 +115,9 @@ namespace GUIEngine
/** Returns true if keyboard is created */
static bool isActive() {return m_screen_keyboard != NULL;}
+ /** Override to be notified of updates */
+ virtual void onUpdate(float dt);
+
/** Get irrlicht window used by the keyboard widget */
irr::gui::IGUIWindow* getIrrlichtElement() {return m_irrlicht_window;}
diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp
index b82629fa7..63639f148 100644
--- a/src/input/input_manager.cpp
+++ b/src/input/input_manager.cpp
@@ -809,7 +809,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
Controller* controller = pk->getController();
if (controller != NULL) controller->action(action, abs(value));
}
- else if (race_manager->isWatchingReplay())
+ else if (race_manager->isWatchingReplay() && !GUIEngine::ModalDialog::isADialogActive())
{
// Get the first ghost kart
World::getWorld()->getKart(0)
diff --git a/src/io/assets_android.cpp b/src/io/assets_android.cpp
index e2964d4d7..cf451b191 100644
--- a/src/io/assets_android.cpp
+++ b/src/io/assets_android.cpp
@@ -36,6 +36,7 @@
AssetsAndroid::AssetsAndroid(FileManager* file_manager)
{
m_file_manager = file_manager;
+ m_progress_bar = NULL;
}
//-----------------------------------------------------------------------------
@@ -203,8 +204,13 @@ void AssetsAndroid::init()
// Extract data directory from apk if it's needed
if (needs_extract_data)
{
+ m_progress_bar = new ProgressBarAndroid();
+ m_progress_bar->draw(0.01f);
+
removeData();
extractData();
+
+ delete m_progress_bar;
if (!m_file_manager->fileExists(m_stk_dir + "/.extracted"))
{
@@ -262,8 +268,6 @@ void AssetsAndroid::extractData()
file.clear();
file.seekg(0, std::ios::beg);
- ProgressBarAndroid* progress_bar = new ProgressBarAndroid();
- progress_bar->draw(0.0f);
unsigned int current_line = 1;
while (!file.eof())
@@ -277,10 +281,11 @@ void AssetsAndroid::extractData()
success = extractDir(dir_name);
assert(lines_count > 0);
- progress_bar->draw((float)(current_line) / lines_count);
+ float pos = 0.01f + (float)(current_line) / lines_count * 0.99f;
+ m_progress_bar->draw(pos);
current_line++;
- if (progress_bar->closeEventReceived())
+ if (m_progress_bar->closeEventReceived())
{
success = false;
}
@@ -288,8 +293,6 @@ void AssetsAndroid::extractData()
if (!success)
break;
}
-
- delete progress_bar;
}
}
else
diff --git a/src/io/assets_android.hpp b/src/io/assets_android.hpp
index 7ce164f97..031a7d0b8 100644
--- a/src/io/assets_android.hpp
+++ b/src/io/assets_android.hpp
@@ -21,11 +21,13 @@
#include
class FileManager;
+class ProgressBarAndroid;
class AssetsAndroid
{
private:
FileManager* m_file_manager;
+ ProgressBarAndroid* m_progress_bar;
std::string m_stk_dir;
void extractData();
diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp
index ec080e044..0e278741e 100644
--- a/src/items/attachment.cpp
+++ b/src/items/attachment.cpp
@@ -511,20 +511,16 @@ void Attachment::update(int ticks)
int slow_flashes = stk_config->time2Ticks(3.0f);
if (is_shield && m_ticks_left < slow_flashes)
{
- int flashes_per_second = 4;
- int ticks_per_flash = stk_config->time2Ticks(0.25f);
-
+ int ticks_per_flash = stk_config->time2Ticks(0.2f);
+
int fast_flashes = stk_config->time2Ticks(0.5f);
if (m_ticks_left < fast_flashes)
{
- flashes_per_second = 12;
- ticks_per_flash = stk_config->time2Ticks(1.0f/12);
+ ticks_per_flash = stk_config->time2Ticks(0.07f);
}
- //int divisor = 2;
- //int mod = (int)(m_ticks_left * flashes_per_second * 2) % divisor;
- int mod = m_ticks_left % ticks_per_flash;
- m_node->setVisible(mod > ticks_per_flash);
+ int division = (m_ticks_left / ticks_per_flash);
+ m_node->setVisible((division & 0x1) == 0);
}
float dt = stk_config->ticks2Time(ticks);
diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp
index 3ad5981b3..73f5f1220 100644
--- a/src/modes/linear_world.cpp
+++ b/src/modes/linear_world.cpp
@@ -893,6 +893,7 @@ void LinearWorld::checkForWrongDirection(unsigned int i, int ticks)
if (wrongway_counter > stk_config->time2Ticks(1.0f))
{
+ m_race_gui->cleanupMessages(0.0f);
m_race_gui->addMessage(_("WRONG WAY!"), kart,
/* time */ -1.0f,
video::SColor(255,255,255,255),
diff --git a/src/states_screens/dialogs/ghost_replay_info_dialog.cpp b/src/states_screens/dialogs/ghost_replay_info_dialog.cpp
index 5fc2eda53..ee8a704ff 100644
--- a/src/states_screens/dialogs/ghost_replay_info_dialog.cpp
+++ b/src/states_screens/dialogs/ghost_replay_info_dialog.cpp
@@ -43,7 +43,6 @@ GhostReplayInfoDialog::GhostReplayInfoDialog(unsigned int replay_id)
(m_rd.m_filename) : m_rd.m_filename).c_str()), false);
m_back_widget = getWidget("back");
- m_back_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// Non-deletable for custom (standard) replay file
getWidget("remove")->setActive(!m_rd.m_custom_replay_file);
@@ -62,6 +61,8 @@ GhostReplayInfoDialog::GhostReplayInfoDialog(unsigned int replay_id)
m_record_widget->setState(false);
m_watch_widget->setState(false);
+ m_action_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
+ m_action_widget->select("start", PLAYER_ID_GAME_MASTER);
} // GhostReplayInfoDialog
// -----------------------------------------------------------------------------
diff --git a/src/states_screens/race_gui_base.hpp b/src/states_screens/race_gui_base.hpp
index 24d4f742a..72c4ee38f 100644
--- a/src/states_screens/race_gui_base.hpp
+++ b/src/states_screens/race_gui_base.hpp
@@ -185,7 +185,6 @@ protected:
RaceGUIMultitouch* m_multitouch_gui;
- void cleanupMessages(const float dt);
//void createMarkerTexture();
void createRegularPolygon(unsigned int n, float radius,
const core::vector2df ¢er,
@@ -248,6 +247,8 @@ public:
const core::recti &viewport,
const core::vector2df &scaling) {};
+ void cleanupMessages(const float dt);
+
}; // RaceGUIBase
#endif
diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp
index cbbc55aab..4332ce8c0 100644
--- a/src/states_screens/user_screen.cpp
+++ b/src/states_screens/user_screen.cpp
@@ -156,8 +156,8 @@ void BaseUserScreen::init()
m_new_registered_data = false;
if (m_auto_login)
{
- login();
m_auto_login = false;
+ login();
return;
}
m_auto_login = false;
@@ -403,7 +403,14 @@ void BaseUserScreen::eventCallback(Widget* widget,
*/
void BaseUserScreen::closeScreen()
{
- StateManager::get()->popMenu();
+ if (StateManager::get()->getMenuStackSize() > 1)
+ {
+ StateManager::get()->popMenu();
+ }
+ else
+ {
+ StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
+ }
} // closeScreen
// ----------------------------------------------------------------------------
diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp
index 4587017cd..a8aed45d4 100644
--- a/src/utils/debug.cpp
+++ b/src/utils/debug.cpp
@@ -122,6 +122,7 @@ enum DebugMenuCommand
DEBUG_GUI_CAM_NORMAL,
DEBUG_GUI_CAM_SMOOTH,
DEBUG_GUI_CAM_ATTACH,
+ DEBUG_VIEW_KART_PREVIOUS,
DEBUG_VIEW_KART_ONE,
DEBUG_VIEW_KART_TWO,
DEBUG_VIEW_KART_THREE,
@@ -130,6 +131,7 @@ enum DebugMenuCommand
DEBUG_VIEW_KART_SIX,
DEBUG_VIEW_KART_SEVEN,
DEBUG_VIEW_KART_EIGHT,
+ DEBUG_VIEW_KART_NEXT,
DEBUG_HIDE_KARTS,
DEBUG_THROTTLE_FPS,
DEBUG_VISUAL_VALUES,
@@ -244,6 +246,7 @@ LightNode* findNearestLight()
bool handleContextMenuAction(s32 cmd_id)
{
+ unsigned int kart_num = Camera::getActiveCamera()->getKart()->getWorldKartId();
World *world = World::getWorld();
Physics *physics = Physics::getInstance();
@@ -603,6 +606,19 @@ bool handleContextMenuAction(s32 cmd_id)
}
break;
}
+ case DEBUG_VIEW_KART_PREVIOUS:
+ {
+ if (kart_num == 0)
+ {
+ kart_num += World::getWorld()->getNumKarts() - 1;
+ }
+ else
+ {
+ kart_num--;
+ }
+ Camera::getActiveCamera()->setKart(World::getWorld()->getKart(kart_num));
+ break;
+ }
case DEBUG_VIEW_KART_ONE:
changeCameraTarget(1);
break;
@@ -627,6 +643,20 @@ bool handleContextMenuAction(s32 cmd_id)
case DEBUG_VIEW_KART_EIGHT:
changeCameraTarget(8);
break;
+ case DEBUG_VIEW_KART_NEXT:
+ {
+ if (kart_num == World::getWorld()->getNumKarts() - 1)
+ {
+ kart_num = 0;
+ }
+ else
+ {
+ kart_num++;
+ }
+ Camera::getActiveCamera()->setKart(World::getWorld()->getKart(kart_num));
+ break;
+ }
+
case DEBUG_PRINT_START_POS:
if (!world) return false;
for (unsigned int i = 0; igetNumKarts(); i++)
@@ -893,6 +923,7 @@ bool onEvent(const SEvent &event)
mnu->addItem(L"Change camera target >",-1,true, true);
sub = mnu->getSubMenu(5);
+ sub->addItem(L"To previous kart (Ctrl + F5)", DEBUG_VIEW_KART_PREVIOUS);
sub->addItem(L"To kart one", DEBUG_VIEW_KART_ONE);
sub->addItem(L"To kart two", DEBUG_VIEW_KART_TWO);
sub->addItem(L"To kart three", DEBUG_VIEW_KART_THREE);
@@ -901,6 +932,7 @@ bool onEvent(const SEvent &event)
sub->addItem(L"To kart six", DEBUG_VIEW_KART_SIX);
sub->addItem(L"To kart seven", DEBUG_VIEW_KART_SEVEN);
sub->addItem(L"To kart eight", DEBUG_VIEW_KART_EIGHT);
+ sub->addItem(L"To next kart (Ctrl + F6)", DEBUG_VIEW_KART_NEXT);
mnu->addItem(L"Font >",-1,true, true);
sub = mnu->getSubMenu(6);
@@ -970,6 +1002,7 @@ bool onEvent(const SEvent &event)
bool handleStaticAction(int key)
{
+ unsigned int kart_num = Camera::getActiveCamera()->getKart()->getWorldKartId();
if (key == IRR_KEY_F1)
{
handleContextMenuAction(DEBUG_GUI_CAM_FREE);
@@ -985,6 +1018,32 @@ bool handleStaticAction(int key)
#endif
return true;
}
+ else if (key == IRR_KEY_F5)
+ {
+ if (kart_num == 0)
+ {
+ kart_num += World::getWorld()->getNumKarts() - 1;
+ }
+ else
+ {
+ kart_num--;
+ }
+ Camera::getActiveCamera()->setKart(World::getWorld()->getKart(kart_num));
+ return true;
+ }
+ else if (key == IRR_KEY_F6)
+ {
+ if (kart_num == World::getWorld()->getNumKarts() - 1)
+ {
+ kart_num = 0;
+ }
+ else
+ {
+ kart_num++;
+ }
+ Camera::getActiveCamera()->setKart(World::getWorld()->getKart(kart_num));
+ return true;
+ }
// TODO: create more keyboard shortcuts
return false;
diff --git a/tools/ai_test/test_track.sh b/tools/ai_test/test_track.sh
index 6121aff82..06937c880 100755
--- a/tools/ai_test/test_track.sh
+++ b/tools/ai_test/test_track.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-for track in abyss cocoa_temple fortmagma greenvalley lighthouse olivermath snowmountain stk_enterprise zengarden hacienda mansion snowtuxpeak farm mines sandtrack city gran_paradiso_island minigolf scotland xr591; do
+for track in abyss candela_city cocoa_temple cornfield_crossing fortmagma gran_paradiso_island greenvalley hacienda lighthouse mansion mines minigolf olivermath sandtrack scotland snowmountain snowtuxpeak stk_enterprise volcano_island xr591 zengarden; do
echo "Testing $track"
$1 --log=0 -R \
--ai=nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok \