aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/CMakeLists.txt1
-rw-r--r--src/client/clientlauncher.cpp25
-rw-r--r--src/client/clientlauncher.h36
-rw-r--r--src/client/inputhandler.cpp119
-rw-r--r--src/client/inputhandler.h360
-rw-r--r--src/client/joystick_controller.cpp8
-rw-r--r--src/client/joystick_controller.h6
-rw-r--r--src/client/keys.h5
-rw-r--r--src/client/tile.cpp23
-rw-r--r--src/client/tile.h122
10 files changed, 374 insertions, 331 deletions
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
index 5faa186a7..2d274ae68 100644
--- a/src/client/CMakeLists.txt
+++ b/src/client/CMakeLists.txt
@@ -1,5 +1,6 @@
set(client_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
PARENT_SCOPE
diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp
index 249f6727a..289d1537b 100644
--- a/src/client/clientlauncher.cpp
+++ b/src/client/clientlauncher.cpp
@@ -42,31 +42,15 @@ gui::IGUIEnvironment *guienv = NULL;
gui::IGUIStaticText *guiroot = NULL;
MainMenuManager g_menumgr;
-bool noMenuActive()
+bool isMenuActive()
{
- return g_menumgr.menuCount() == 0;
+ return g_menumgr.menuCount() != 0;
}
// Passed to menus to allow disconnecting and exiting
MainGameCallback *g_gamecallback = NULL;
-// Instance of the time getter
-static TimeGetter *g_timegetter = NULL;
-
-u32 getTimeMs()
-{
- if (g_timegetter == NULL)
- return 0;
- return g_timegetter->getTime(PRECISION_MILLI);
-}
-
-u32 getTime(TimePrecision prec) {
- if (g_timegetter == NULL)
- return 0;
- return g_timegetter->getTime(prec);
-}
-
ClientLauncher::~ClientLauncher()
{
if (receiver)
@@ -96,9 +80,6 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
return false;
}
- // Create time getter
- g_timegetter = new IrrlichtTimeGetter(device);
-
// Speed tests (done after irrlicht is loaded to get timer)
if (cmd_args.getFlag("speedtests")) {
dstream << "Running speed tests" << std::endl;
@@ -515,7 +496,7 @@ void ClientLauncher::main_menu(MainMenuData *menudata)
infostream << "Waiting for other menus" << std::endl;
while (device->run() && *kill == false) {
- if (noMenuActive())
+ if (!isMenuActive())
break;
driver->beginScene(true, true, video::SColor(255, 128, 128, 128));
guienv->drawAll();
diff --git a/src/client/clientlauncher.h b/src/client/clientlauncher.h
index ab22d7aaa..4ff77bc03 100644
--- a/src/client/clientlauncher.h
+++ b/src/client/clientlauncher.h
@@ -24,42 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/inputhandler.h"
#include "gameparams.h"
-// A small helper class
-class TimeGetter
-{
-public:
- virtual u32 getTime(TimePrecision prec) = 0;
-};
-
-// A precise irrlicht one
-class IrrlichtTimeGetter: public TimeGetter
-{
-public:
- IrrlichtTimeGetter(IrrlichtDevice *device):
- m_device(device)
- {}
- u32 getTime(TimePrecision prec)
- {
- if (prec == PRECISION_MILLI) {
- if (m_device == NULL)
- return 0;
- return m_device->getTimer()->getRealTime();
- } else {
- return porting::getTime(prec);
- }
- }
-private:
- IrrlichtDevice *m_device;
-};
-// Not so precise one which works without irrlicht
-class SimpleTimeGetter: public TimeGetter
-{
-public:
- u32 getTime(TimePrecision prec)
- {
- return porting::getTime(prec);
- }
-};
class ClientLauncher
{
diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp
new file mode 100644
index 000000000..9c7a94c4e
--- /dev/null
+++ b/src/client/inputhandler.cpp
@@ -0,0 +1,119 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "util/numeric.h"
+#include "inputhandler.h"
+#include "mainmenumanager.h"
+
+bool MyEventReceiver::OnEvent(const SEvent &event)
+{
+ /*
+ React to nothing here if a menu is active
+ */
+ if (isMenuActive()) {
+#ifdef HAVE_TOUCHSCREENGUI
+ if (m_touchscreengui) {
+ m_touchscreengui->Toggle(false);
+ }
+#endif
+ return g_menumgr.preprocessEvent(event);
+ }
+
+ // Remember whether each key is down or up
+ if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
+ const KeyPress &keyCode = event.KeyInput;
+ if (keysListenedFor[keyCode]) {
+ if (event.KeyInput.PressedDown) {
+ keyIsDown.set(keyCode);
+ keyWasDown.set(keyCode);
+ } else {
+ keyIsDown.unset(keyCode);
+ }
+ return true;
+ }
+ }
+
+#ifdef HAVE_TOUCHSCREENGUI
+ // case of touchscreengui we have to handle different events
+ if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) {
+ m_touchscreengui->translateEvent(event);
+ return true;
+ }
+#endif
+
+ if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) {
+ /* TODO add a check like:
+ if (event.JoystickEvent != joystick_we_listen_for)
+ return false;
+ */
+ return joystick->handleEvent(event.JoystickEvent);
+ }
+ // handle mouse events
+ if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
+ if (isMenuActive()) {
+ left_active = false;
+ middle_active = false;
+ right_active = false;
+ } else {
+ left_active = event.MouseInput.isLeftPressed();
+ middle_active = event.MouseInput.isMiddlePressed();
+ right_active = event.MouseInput.isRightPressed();
+
+ if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
+ leftclicked = true;
+ }
+ if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
+ rightclicked = true;
+ }
+ if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
+ leftreleased = true;
+ }
+ if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
+ rightreleased = true;
+ }
+ if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
+ mouse_wheel += event.MouseInput.Wheel;
+ }
+ }
+ } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
+ static const LogLevel irr_loglev_conv[] = {
+ LL_VERBOSE, // ELL_DEBUG
+ LL_INFO, // ELL_INFORMATION
+ LL_WARNING, // ELL_WARNING
+ LL_ERROR, // ELL_ERROR
+ LL_NONE, // ELL_NONE
+ };
+ assert(event.LogEvent.Level < ARRLEN(irr_loglev_conv));
+ g_logger.log(irr_loglev_conv[event.LogEvent.Level],
+ std::string("Irrlicht: ") +
+ (const char *)event.LogEvent.Text);
+ return true;
+ }
+ /* always return false in order to continue processing events */
+ return false;
+}
+
+/*
+ * RandomInputHandler
+ */
+s32 RandomInputHandler::Rand(s32 min, s32 max)
+{
+ return (myrand() % (max - min + 1)) + min;
+}
diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h
index 824b0da2e..7c422d189 100644
--- a/src/client/inputhandler.h
+++ b/src/client/inputhandler.h
@@ -22,104 +22,87 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h"
#include "joystick_controller.h"
+#include <list>
+#include "keycode.h"
-class MyEventReceiver : public IEventReceiver
-{
-public:
- // This is the one method that we have to implement
- virtual bool OnEvent(const SEvent& event)
- {
- /*
- React to nothing here if a menu is active
- */
- if (noMenuActive() == false) {
#ifdef HAVE_TOUCHSCREENGUI
- if (m_touchscreengui != 0) {
- m_touchscreengui->Toggle(false);
- }
+#include "touchscreengui.h"
#endif
- return g_menumgr.preprocessEvent(event);
- }
- // Remember whether each key is down or up
- if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
- const KeyPress &keyCode = event.KeyInput;
- if (keysListenedFor[keyCode]) {
- if (event.KeyInput.PressedDown) {
- keyIsDown.set(keyCode);
- keyWasDown.set(keyCode);
- } else {
- keyIsDown.unset(keyCode);
- }
- return true;
- }
- }
+class KeyList : private std::list<KeyPress>
+{
+ typedef std::list<KeyPress> super;
+ typedef super::iterator iterator;
+ typedef super::const_iterator const_iterator;
-#ifdef HAVE_TOUCHSCREENGUI
- // case of touchscreengui we have to handle different events
- if ((m_touchscreengui != 0) &&
- (event.EventType == irr::EET_TOUCH_INPUT_EVENT)) {
- m_touchscreengui->translateEvent(event);
- return true;
- }
-#endif
+ virtual const_iterator find(const KeyPress &key) const
+ {
+ const_iterator f(begin());
+ const_iterator e(end());
+
+ while (f != e) {
+ if (*f == key)
+ return f;
- if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) {
- /* TODO add a check like:
- if (event.JoystickEvent != joystick_we_listen_for)
- return false;
- */
- return joystick->handleEvent(event.JoystickEvent);
+ ++f;
}
- // handle mouse events
- if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
- if (noMenuActive() == false) {
- left_active = false;
- middle_active = false;
- right_active = false;
- } else {
- left_active = event.MouseInput.isLeftPressed();
- middle_active = event.MouseInput.isMiddlePressed();
- right_active = event.MouseInput.isRightPressed();
-
- if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
- leftclicked = true;
- }
- if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
- rightclicked = true;
- }
- if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
- leftreleased = true;
- }
- if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
- rightreleased = true;
- }
- if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
- mouse_wheel += event.MouseInput.Wheel;
- }
- }
- } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
- static const LogLevel irr_loglev_conv[] = {
- LL_VERBOSE, // ELL_DEBUG
- LL_INFO, // ELL_INFORMATION
- LL_WARNING, // ELL_WARNING
- LL_ERROR, // ELL_ERROR
- LL_NONE, // ELL_NONE
- };
- assert(event.LogEvent.Level < ARRLEN(irr_loglev_conv));
- g_logger.log(irr_loglev_conv[event.LogEvent.Level],
- std::string("Irrlicht: ") + (const char*) event.LogEvent.Text);
- return true;
+
+ return e;
+ }
+
+ virtual iterator find(const KeyPress &key)
+ {
+ iterator f(begin());
+ iterator e(end());
+
+ while (f != e) {
+ if (*f == key)
+ return f;
+
+ ++f;
}
- /* always return false in order to continue processing events */
- return false;
+
+ return e;
+ }
+
+public:
+ void clear() { super::clear(); }
+
+ void set(const KeyPress &key)
+ {
+ if (find(key) == end())
+ push_back(key);
}
- bool IsKeyDown(const KeyPress &keyCode) const
+ void unset(const KeyPress &key)
{
- return keyIsDown[keyCode];
+ iterator p(find(key));
+
+ if (p != end())
+ erase(p);
}
+ void toggle(const KeyPress &key)
+ {
+ iterator p(this->find(key));
+
+ if (p != end())
+ erase(p);
+ else
+ push_back(key);
+ }
+
+ bool operator[](const KeyPress &key) const { return find(key) != end(); }
+};
+
+class MyEventReceiver : public IEventReceiver
+{
+public:
+ // This is the one method that we have to implement
+ virtual bool OnEvent(const SEvent &event);
+
+ bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; }
+
// Checks whether a key was down and resets the state
bool WasKeyDown(const KeyPress &keyCode)
{
@@ -129,14 +112,8 @@ public:
return b;
}
- void listenForKey(const KeyPress &keyCode)
- {
- keysListenedFor.set(keyCode);
- }
- void dontListenForKeys()
- {
- keysListenedFor.clear();
- }
+ void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
+ void dontListenForKeys() { keysListenedFor.clear(); }
s32 getMouseWheel()
{
@@ -184,7 +161,7 @@ public:
JoystickController *joystick;
#ifdef HAVE_TOUCHSCREENGUI
- TouchScreenGUI* m_touchscreengui;
+ TouchScreenGUI *m_touchscreengui;
#endif
private:
@@ -200,7 +177,42 @@ private:
KeyList keysListenedFor;
};
+class InputHandler
+{
+public:
+ InputHandler() {}
+ virtual ~InputHandler() {}
+
+ virtual bool isKeyDown(const KeyPress &keyCode) = 0;
+ virtual bool wasKeyDown(const KeyPress &keyCode) = 0;
+
+ virtual void listenForKey(const KeyPress &keyCode) {}
+ virtual void dontListenForKeys() {}
+
+ virtual v2s32 getMousePos() = 0;
+ virtual void setMousePos(s32 x, s32 y) = 0;
+
+ virtual bool getLeftState() = 0;
+ virtual bool getRightState() = 0;
+
+ virtual bool getLeftClicked() = 0;
+ virtual bool getRightClicked() = 0;
+ virtual void resetLeftClicked() = 0;
+ virtual void resetRightClicked() = 0;
+
+ virtual bool getLeftReleased() = 0;
+ virtual bool getRightReleased() = 0;
+ virtual void resetLeftReleased() = 0;
+ virtual void resetRightReleased() = 0;
+ virtual s32 getMouseWheel() = 0;
+
+ virtual void step(float dtime) {}
+
+ virtual void clear() {}
+
+ JoystickController joystick;
+};
/*
Separated input handler
*/
@@ -208,10 +220,8 @@ private:
class RealInputHandler : public InputHandler
{
public:
- RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver):
- m_device(device),
- m_receiver(receiver),
- m_mousepos(0,0)
+ RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver)
+ : m_device(device), m_receiver(receiver), m_mousepos(0, 0)
{
m_receiver->joystick = &joystick;
}
@@ -227,16 +237,12 @@ public:
{
m_receiver->listenForKey(keyCode);
}
- virtual void dontListenForKeys()
- {
- m_receiver->dontListenForKeys();
- }
+ virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); }
virtual v2s32 getMousePos()
{
if (m_device->getCursorControl()) {
return m_device->getCursorControl()->getPosition();
- }
- else {
+ } else {
return m_mousepos;
}
}
@@ -244,69 +250,36 @@ public:
{
if (m_device->getCursorControl()) {
m_device->getCursorControl()->setPosition(x, y);
- }
- else {
- m_mousepos = v2s32(x,y);
+ } else {
+ m_mousepos = v2s32(x, y);
}
}
- virtual bool getLeftState()
- {
- return m_receiver->left_active;
- }
- virtual bool getRightState()
- {
- return m_receiver->right_active;
- }
+ virtual bool getLeftState() { return m_receiver->left_active; }
+ virtual bool getRightState() { return m_receiver->right_active; }
- virtual bool getLeftClicked()
- {
- return m_receiver->leftclicked;
- }
- virtual bool getRightClicked()
- {
- return m_receiver->rightclicked;
- }
- virtual void resetLeftClicked()
- {
- m_receiver->leftclicked = false;
- }
- virtual void resetRightClicked()
- {
- m_receiver->rightclicked = false;
- }
+ virtual bool getLeftClicked() { return m_receiver->leftclicked; }
+ virtual bool getRightClicked() { return m_receiver->rightclicked; }
+ virtual void resetLeftClicked() { m_receiver->leftclicked = false; }
+ virtual void resetRightClicked() { m_receiver->rightclicked = false; }
- virtual bool getLeftReleased()
- {
- return m_receiver->leftreleased;
- }
- virtual bool getRightReleased()
- {
- return m_receiver->rightreleased;
- }
- virtual void resetLeftReleased()
- {
- m_receiver->leftreleased = false;
- }
- virtual void resetRightReleased()
- {
- m_receiver->rightreleased = false;
- }
+ virtual bool getLeftReleased() { return m_receiver->leftreleased; }
+ virtual bool getRightReleased() { return m_receiver->rightreleased; }
+ virtual void resetLeftReleased() { m_receiver->leftreleased = false; }
+ virtual void resetRightReleased() { m_receiver->rightreleased = false; }
- virtual s32 getMouseWheel()
- {
- return m_receiver->getMouseWheel();
- }
+ virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); }
void clear()
{
joystick.clear();
m_receiver->clearInput();
}
+
private:
- IrrlichtDevice *m_device;
+ IrrlichtDevice *m_device;
MyEventReceiver *m_receiver;
- v2s32 m_mousepos;
+ v2s32 m_mousepos;
};
class RandomInputHandler : public InputHandler
@@ -322,70 +295,25 @@ public:
rightreleased = false;
keydown.clear();
}
- virtual bool isKeyDown(const KeyPress &keyCode)
- {
- return keydown[keyCode];
- }
- virtual bool wasKeyDown(const KeyPress &keyCode)
- {
- return false;
- }
- virtual v2s32 getMousePos()
- {
- return mousepos;
- }
- virtual void setMousePos(s32 x, s32 y)
- {
- mousepos = v2s32(x, y);
- }
+ virtual bool isKeyDown(const KeyPress &keyCode) { return keydown[keyCode]; }
+ virtual bool wasKeyDown(const KeyPress &keyCode) { return false; }
+ virtual v2s32 getMousePos() { return mousepos; }
+ virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); }
- virtual bool getLeftState()
- {
- return leftdown;
- }
- virtual bool getRightState()
- {
- return rightdown;
- }
+ virtual bool getLeftState() { return leftdown; }
+ virtual bool getRightState() { return rightdown; }
- virtual bool getLeftClicked()
- {
- return leftclicked;
- }
- virtual bool getRightClicked()
- {
- return rightclicked;
- }
- virtual void resetLeftClicked()
- {
- leftclicked = false;
- }
- virtual void resetRightClicked()
- {
- rightclicked = false;
- }
+ virtual bool getLeftClicked() { return leftclicked; }
+ virtual bool getRightClicked() { return rightclicked; }
+ virtual void resetLeftClicked() { leftclicked = false; }
+ virtual void resetRightClicked() { rightclicked = false; }
- virtual bool getLeftReleased()
- {
- return leftreleased;
- }
- virtual bool getRightReleased()
- {
- return rightreleased;
- }
- virtual void resetLeftReleased()
- {
- leftreleased = false;
- }
- virtual void resetRightReleased()
- {
- rightreleased = false;
- }
+ virtual bool getLeftReleased() { return leftreleased; }
+ virtual bool getRightReleased() { return rightreleased; }
+ virtual void resetLeftReleased() { leftreleased = false; }
+ virtual void resetRightReleased() { rightreleased = false; }
- virtual s32 getMouseWheel()
- {
- return 0;
- }
+ virtual s32 getMouseWheel() { return 0; }
virtual void step(float dtime)
{
@@ -456,10 +384,8 @@ public:
mousepos += mousespeed;
}
- s32 Rand(s32 min, s32 max)
- {
- return (myrand()%(max-min+1))+min;
- }
+ s32 Rand(s32 min, s32 max);
+
private:
KeyList keydown;
v2s32 mousepos;
diff --git a/src/client/joystick_controller.cpp b/src/client/joystick_controller.cpp
index e6a572adb..905ca6420 100644
--- a/src/client/joystick_controller.cpp
+++ b/src/client/joystick_controller.cpp
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "keys.h"
#include "settings.h"
#include "gettime.h"
+#include "porting.h"
#include "../util/string.h"
bool JoystickButtonCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const
@@ -185,8 +186,9 @@ void JoystickController::onJoystickConnect(const std::vector<irr::SJoystickInfo>
m_joystick_id = id;
}
-void JoystickController::setLayoutFromControllerName(std::string name) {
- if (lowercase(name).find("xbox") >= 0) {
+void JoystickController::setLayoutFromControllerName(const std::string &name)
+{
+ if (lowercase(name).find("xbox") != std::string::npos) {
m_layout = create_xbox_layout();
} else {
m_layout = create_default_layout();
@@ -198,7 +200,7 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev)
if (ev.Joystick != m_joystick_id)
return false;
- m_internal_time = getTimeMs() / 1000.f;
+ m_internal_time = porting::getTimeMs() / 1000.f;
std::bitset<KeyType::INTERNAL_ENUM_COUNT> keys_pressed;
diff --git a/src/client/joystick_controller.h b/src/client/joystick_controller.h
index 867a0c3f2..744315011 100644
--- a/src/client/joystick_controller.h
+++ b/src/client/joystick_controller.h
@@ -60,6 +60,8 @@ struct JoystickButtonCmb : public JoystickCombination {
this->key = key;
}
+ virtual ~JoystickButtonCmb() {}
+
virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const;
u32 filter_mask;
@@ -77,6 +79,8 @@ struct JoystickAxisCmb : public JoystickCombination {
this->key = key;
}
+ virtual ~JoystickAxisCmb() {}
+
virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const;
u16 axis_to_compare;
@@ -149,7 +153,7 @@ public:
f32 doubling_dtime;
private:
- void setLayoutFromControllerName(std::string name);
+ void setLayoutFromControllerName(const std::string &name);
JoystickLayout m_layout;
diff --git a/src/client/keys.h b/src/client/keys.h
index 76ae38ff0..9478737f6 100644
--- a/src/client/keys.h
+++ b/src/client/keys.h
@@ -50,6 +50,11 @@ public:
FREEMOVE,
FASTMOVE,
NOCLIP,
+ HOTBAR_PREV,
+ HOTBAR_NEXT,
+ MUTE,
+ INC_VOLUME,
+ DEC_VOLUME,
CINEMATIC,
SCREENSHOT,
TOGGLE_HUD,
diff --git a/src/client/tile.cpp b/src/client/tile.cpp
index f0f1800b0..cfdff1bb2 100644
--- a/src/client/tile.cpp
+++ b/src/client/tile.cpp
@@ -1208,17 +1208,17 @@ bool TextureSource::generateImagePart(std::string part_of_name,
#endif
if (image == NULL) {
if (part_of_name != "") {
- if (part_of_name.find("_normal.png") == std::string::npos){
- errorstream<<"generateImage(): Could not load image \""
- <<part_of_name<<"\""<<" while building texture"<<std::endl;
- errorstream<<"generateImage(): Creating a dummy"
- <<" image for \""<<part_of_name<<"\""<<std::endl;
- } else {
- infostream<<"generateImage(): Could not load normal map \""
- <<part_of_name<<"\""<<std::endl;
- infostream<<"generateImage(): Creating a dummy"
- <<" normal map for \""<<part_of_name<<"\""<<std::endl;
+
+ // Do not create normalmap dummies
+ if (part_of_name.find("_normal.png") != std::string::npos) {
+ warningstream << "generateImage(): Could not load normal map \""
+ << part_of_name << "\"" << std::endl;
+ return true;
}
+
+ errorstream << "generateImage(): Could not load image \""
+ << part_of_name << "\" while building texture; "
+ "Creating a dummy image" << std::endl;
}
// Just create a dummy image
@@ -1805,7 +1805,8 @@ bool TextureSource::generateImagePart(std::string part_of_name,
* mix high- and low-res textures, or for mods with least-common-denominator
* textures that don't have the resources to offer high-res alternatives.
*/
- s32 scaleto = g_settings->getS32("texture_min_size");
+ const bool filter = m_setting_trilinear_filter || m_setting_bilinear_filter;
+ const s32 scaleto = filter ? g_settings->getS32("texture_min_size") : 1;
if (scaleto > 1) {
const core::dimension2d<u32> dim = baseimg->getDimension();
diff --git a/src/client/tile.h b/src/client/tile.h
index 5eec0f2ea..66ca8be1d 100644
--- a/src/client/tile.h
+++ b/src/client/tile.h
@@ -159,7 +159,8 @@ enum MaterialType{
TILE_MATERIAL_LIQUID_TRANSPARENT,
TILE_MATERIAL_LIQUID_OPAQUE,
TILE_MATERIAL_WAVING_LEAVES,
- TILE_MATERIAL_WAVING_PLANTS
+ TILE_MATERIAL_WAVING_PLANTS,
+ TILE_MATERIAL_OPAQUE
};
// Material flags
@@ -194,72 +195,68 @@ struct FrameSpec
video::ITexture *flags_texture;
};
-struct TileSpec
+#define MAX_TILE_LAYERS 2
+
+//! Defines a layer of a tile.
+struct TileLayer
{
- TileSpec():
- texture_id(0),
+ TileLayer():
texture(NULL),
normal_texture(NULL),
flags_texture(NULL),
+ shader_id(0),
+ texture_id(0),
+ animation_frame_length_ms(0),
+ animation_frame_count(1),
material_type(TILE_MATERIAL_BASIC),
material_flags(
//0 // <- DEBUG, Use the one below
- MATERIAL_FLAG_BACKFACE_CULLING
+ MATERIAL_FLAG_BACKFACE_CULLING |
+ MATERIAL_FLAG_TILEABLE_HORIZONTAL|
+ MATERIAL_FLAG_TILEABLE_VERTICAL
),
- shader_id(0),
- animation_frame_count(1),
- animation_frame_length_ms(0),
- rotation(0),
has_color(false),
- color(),
- emissive_light(0)
+ color()
{
}
/*!
- * Two tiles are equal if they can be appended to
- * the same mesh buffer.
+ * Two layers are equal if they can be merged.
*/
- bool operator==(const TileSpec &other) const
+ bool operator==(const TileLayer &other) const
{
- return (
+ return
texture_id == other.texture_id &&
material_type == other.material_type &&
material_flags == other.material_flags &&
- rotation == other.rotation
- );
+ color == other.color;
}
/*!
- * Two tiles are not equal if they must be in different mesh buffers.
+ * Two tiles are not equal if they must have different vertices.
*/
- bool operator!=(const TileSpec &other) const
+ bool operator!=(const TileLayer &other) const
{
return !(*this == other);
}
-
+
// Sets everything else except the texture in the material
void applyMaterialOptions(video::SMaterial &material) const
{
switch (material_type) {
- case TILE_MATERIAL_BASIC:
- material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- break;
- case TILE_MATERIAL_ALPHA:
- material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- break;
- case TILE_MATERIAL_LIQUID_TRANSPARENT:
- material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- break;
+ case TILE_MATERIAL_OPAQUE:
case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID;
break;
+ case TILE_MATERIAL_BASIC:
case TILE_MATERIAL_WAVING_LEAVES:
- material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- break;
case TILE_MATERIAL_WAVING_PLANTS:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break;
+ case TILE_MATERIAL_ALPHA:
+ case TILE_MATERIAL_LIQUID_TRANSPARENT:
+ material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ break;
}
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING)
? true : false;
@@ -284,30 +281,73 @@ struct TileSpec
material.TextureLayer[1].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
}
}
-
- u32 texture_id;
+
+ bool isTileable() const
+ {
+ return (material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)
+ && (material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL);
+ }
+
+ // Ordered for size, please do not reorder
+
video::ITexture *texture;
video::ITexture *normal_texture;
video::ITexture *flags_texture;
-
- // Material parameters
- u8 material_type;
- u8 material_flags;
+
u32 shader_id;
- // Animation parameters
- u8 animation_frame_count;
+
+ u32 texture_id;
+
u16 animation_frame_length_ms;
- std::vector<FrameSpec> frames;
+ u8 animation_frame_count;
+
+ u8 material_type;
+ u8 material_flags;
- u8 rotation;
//! If true, the tile has its own color.
bool has_color;
+
+ std::vector<FrameSpec> frames;
+
/*!
* The color of the tile, or if the tile does not own
* a color then the color of the node owning this tile.
*/
video::SColor color;
+};
+
+/*!
+ * Defines a face of a node. May have up to two layers.
+ */
+struct TileSpec
+{
+ TileSpec():
+ rotation(0),
+ emissive_light(0)
+ {
+ for (int layer = 0; layer < MAX_TILE_LAYERS; layer++)
+ layers[layer] = TileLayer();
+ }
+
+ /*!
+ * Returns true if this tile can be merged with the other tile.
+ */
+ bool isTileable(const TileSpec &other) const {
+ for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
+ if (layers[layer] != other.layers[layer])
+ return false;
+ if (!layers[layer].isTileable())
+ return false;
+ }
+ return rotation == 0
+ && rotation == other.rotation
+ && emissive_light == other.emissive_light;
+ }
+
+ u8 rotation;
//! This much light does the tile emit.
u8 emissive_light;
+ //! The first is base texture, the second is overlay.
+ TileLayer layers[MAX_TILE_LAYERS];
};
#endif