Jean-Patrick G [Mon, 26 Oct 2015 14:25:18 +0000 (15:25 +0100)]
Translated using Weblate (French)
Currently translated at 56.3% (424 of 753 strings)
PilzAdam [Mon, 26 Oct 2015 13:49:49 +0000 (14:49 +0100)]
Translated using Weblate (Hebrew)
Currently translated at 100% (0 of 0 strings)
Created new translation.
pilino1234 [Mon, 26 Oct 2015 10:41:17 +0000 (11:41 +0100)]
Translated using Weblate (German)
Currently translated at 94.1% (709 of 753 strings)
Jordi Fornaguera [Mon, 26 Oct 2015 06:09:05 +0000 (07:09 +0100)]
Translated using Weblate (Spanish)
Currently translated at 32.5% (245 of 753 strings)
PilzAdam [Sun, 25 Oct 2015 20:15:46 +0000 (21:15 +0100)]
Translated using Weblate (German)
Currently translated at 94.0% (708 of 753 strings)
PilzAdam [Sun, 25 Oct 2015 18:11:24 +0000 (19:11 +0100)]
Translated using Weblate (German)
Currently translated at 98.1% (739 of 753 strings)
PilzAdam [Sun, 25 Oct 2015 17:19:45 +0000 (18:19 +0100)]
Translated using Weblate (German)
Currently translated at 98.1% (739 of 753 strings)
Wuzzy [Sun, 25 Oct 2015 16:23:58 +0000 (17:23 +0100)]
Translated using Weblate (German)
Currently translated at 98.0% (738 of 753 strings)
Wuzzy [Sun, 25 Oct 2015 15:11:35 +0000 (16:11 +0100)]
Translated using Weblate (German)
Currently translated at 95.4% (719 of 753 strings)
Jeff Huang [Sun, 25 Oct 2015 13:01:46 +0000 (14:01 +0100)]
Translated using Weblate (Chinese (Taiwan))
Currently translated at 43.8% (330 of 753 strings)
Wuzzy [Sun, 25 Oct 2015 12:14:23 +0000 (13:14 +0100)]
Translated using Weblate (German)
Currently translated at 75.5% (569 of 753 strings)
Muhammad Rifqi Priyo Susanto [Sun, 25 Oct 2015 09:46:27 +0000 (10:46 +0100)]
Translated using Weblate (Indonesian)
Currently translated at 40.2% (303 of 753 strings)
Jeff Huang [Sun, 25 Oct 2015 10:08:19 +0000 (11:08 +0100)]
Translated using Weblate (Chinese (Taiwan))
Currently translated at 36.9% (278 of 753 strings)
PilzAdam [Sat, 24 Oct 2015 22:01:38 +0000 (00:01 +0200)]
Translated using Weblate (German)
Currently translated at 61.6% (464 of 753 strings)
PilzAdam [Sat, 24 Oct 2015 21:09:05 +0000 (23:09 +0200)]
Translated using Weblate (German)
Currently translated at 54.1% (408 of 753 strings)
PilzAdam [Sat, 24 Oct 2015 19:36:54 +0000 (21:36 +0200)]
Translated using Weblate (German)
Currently translated at 52.3% (394 of 753 strings)
Jean-Patrick G [Sat, 24 Oct 2015 19:58:23 +0000 (21:58 +0200)]
Translated using Weblate (French)
Currently translated at 35.4% (267 of 753 strings)
pilzadam [Sat, 24 Oct 2015 18:51:12 +0000 (20:51 +0200)]
Translated using Weblate (German)
Currently translated at 36.2% (273 of 753 strings)
est31 [Sun, 8 Nov 2015 17:16:20 +0000 (18:16 +0100)]
Don't compile pcgrandom on Windows
There it isn't needed.
kwolekr [Sat, 7 Nov 2015 08:27:33 +0000 (03:27 -0500)]
Improve LuaVoxelManip documentation
BlockMen [Sat, 24 Oct 2015 10:28:35 +0000 (12:28 +0200)]
Add support for audio feedback if placing node failed
Kahrl [Fri, 6 Nov 2015 22:05:40 +0000 (23:05 +0100)]
Document ENABLE_CURSES in README.txt
paramat [Fri, 6 Nov 2015 08:38:01 +0000 (08:38 +0000)]
Conf.example, settingtypes: Improve mgfractal documentation
est31 [Sat, 25 Jul 2015 05:43:32 +0000 (07:43 +0200)]
Add server side ncurses terminal
This adds a chat console the server owner can use for administration
or to talk with players.
It runs in its own thread, which makes the user interface immune to
the server's lag, behaving just like a client, except timeout.
As it uses the same console code as the f10 console, things like nick
completion or a scroll buffer basically come for free.
The terminal itself is written in a general way so that adding a
client version later on is just about implementing an interface.
Fatal errors are printed after the console exists and the ncurses
terminal buffer gets cleaned up with endwin(), so that the error still
remains visible.
The server owner can chose their username their entered text will
have in chat and where players can send PMs to.
Once the username is secured with a password to prevent anybody to
take over the server, the owner can execute admin tasks over the
console.
This change includes a contribution by @kahrl who has improved ncurses
library detection.
kwolekr [Wed, 4 Nov 2015 08:33:12 +0000 (03:33 -0500)]
Schematics: Add core.place_schematic_on_vmanip API
Fix memory leak in minetest.place_schematic
Slightly refactor Schematic code
paramat [Wed, 4 Nov 2015 23:07:29 +0000 (23:07 +0000)]
Settingtypes: Correct documentation for mgfractal
Use type 'string' for v3fs and add comments
est31 [Wed, 4 Nov 2015 05:44:55 +0000 (06:44 +0100)]
Fix time progressing too fast
Before, time progressed wrongly. This was due to a mistake in how m_time_of_day_f was calculated,
and a regression of the last two commits.
paramat [Wed, 4 Nov 2015 02:18:37 +0000 (02:18 +0000)]
Mgfractal: Add documentation to conf.example and settingtypes
est31 [Wed, 4 Nov 2015 02:07:32 +0000 (03:07 +0100)]
Time: use locks again
The Atomic implementation was only partially correct, and was very complex.
Use locks for sake of simplicity, following KISS principle.
Only remaining atomic operation use is time of day speed, because that
really is only read + written.
Also fixes a bug with m_time_conversion_skew only being decremented, never
incremented (Regresion from previous commit).
atomic.h changes:
* Add GenericAtomic<T> class for non-integral types like floats.
* Remove some last remainders from atomic.h of the volatile use.
est31 [Tue, 3 Nov 2015 07:56:56 +0000 (08:56 +0100)]
Time: Remove serverside getter, and use atomic operations
It isn't possible to use atomic operations for floats, so don't use them there.
Having a lock is good out of other reasons too, because this way the float time
and the integer time both match, and can't get different values in a race,
e.g. when two setTimeofDay() get executed simultaneously.
est31 [Tue, 3 Nov 2015 12:09:23 +0000 (13:09 +0100)]
Atomic: cleanup and add more operations
Cleanup:
* Remove volatile keyword, it is of no use at all. [1]
* Remove the enable_if stuff. It had no use either.
The most likely explanation why the enable_if stuff was there is that it
was used as something like a STATIC_ASSERT to verify that sizeof(T) is not larger
than sizeof(void *). This check however is not just misplaced in a place where we
already use a lock, it isn't needed at all, as gcc will just generate a call to
to the runtime if it compiles for platforms that don't support atomic instructions.
The runtime will then most likely use locks.
Code style fixes:
* Prefix name of the mutex
* Line everything up nicely, where it makes things look nice
* Filling \ continuations with spaces is code style rule
Added operations on the atomic var:
* Compare and swap
* Swap
The second point of the cleanup also fixes the Android build of the next commit.
[1]: http://stackoverflow.com/q/
2484980
est31 [Tue, 3 Nov 2015 14:29:52 +0000 (15:29 +0100)]
Only go fast in autorun if fast move is enabled
kwolekr [Tue, 3 Nov 2015 06:03:33 +0000 (01:03 -0500)]
Silence 'unused typedef' warning for STATIC_ASSERT()
kwolekr [Fri, 30 Oct 2015 06:48:37 +0000 (02:48 -0400)]
Add callback parameter for core.emerge_area()
gregorycu [Mon, 2 Nov 2015 03:17:44 +0000 (14:17 +1100)]
Speed up saving of profiling data by 27x
On Windows Release x64 bit build this changes:
ProfilerGraph::put
1.68% -> 0.061%
ProfilerGraph::draw
12% -> 17.%
So yes, there is a tradeoff between saving profiling data
(executed always) and drawing the profiler graph (executed very rarely).
But usually you don't have the profiler graph open.
est31 [Sat, 31 Oct 2015 02:06:36 +0000 (03:06 +0100)]
Rename and move basicmacros.h to util/basic_macros.h
Kahrl [Mon, 2 Nov 2015 01:46:36 +0000 (02:46 +0100)]
Print --videomodes response to standard output, too
Perttu Ahola [Sun, 1 Nov 2015 22:10:09 +0000 (00:10 +0200)]
Print direct command line responses to standard output instead of using the log system
Using logging for these just makes them bloated and hard to read and overally just not neat at all.
kwolekr [Sat, 31 Oct 2015 20:31:43 +0000 (16:31 -0400)]
Fix Lua scripting synchronization
For several years now, the lua script lock has been completely broken.
This commit fixes the main issue (creation of a temporary rather than
scoped object), and fixes a subsequent deadlock issue caused by
nested script API calls by adding support for recursive mutexes.
kwolekr [Sun, 1 Nov 2015 16:16:18 +0000 (11:16 -0500)]
Fix Noise compiled under clang >= 3.7.x with -O2 or higher
When compiled with optimizations, the most recent versions of clang seem
to 'optimize' out a crucial "and %reg, 0x7FFFFFFF" instruction in noise2d(),
probably because it somehow assumed the variable n would never become greater
than that amount.
Indeed, signed integer underflow is undefined behavior in C and C++, so while
this optimization is "correct" in that sense, it breaks lots of existing code.
Solved by changing n to an unsigned type, making behavior well-defined.
ShadowNinja [Thu, 29 Oct 2015 18:48:10 +0000 (14:48 -0400)]
Fix server crashing on Lua errors
Previously, the server called FATAL_ERROR when a Lua error occured.
This caused a (mostly useless) core dump.
The server now simply throws an exception, which is caught and printed before
exiting with a non-zero return value.
This also fixes a number of instances where errors were logged multiple times.
ShadowNinja [Fri, 30 Oct 2015 03:10:05 +0000 (23:10 -0400)]
Fix clang warning
kwolekr [Sat, 31 Oct 2015 06:38:23 +0000 (02:38 -0400)]
Fix C++11 compatibility
Rui914 [Fri, 30 Oct 2015 23:35:27 +0000 (08:35 +0900)]
minetest. to core.
Duane Robertson [Mon, 28 Sep 2015 18:59:03 +0000 (13:59 -0500)]
WoW-style Autorun
This allows the player to toggle continuous forward with a key (F by default),
so we don't have to hold down the forward key endlessly.
paramat [Thu, 29 Oct 2015 00:17:48 +0000 (00:17 +0000)]
findSpawnPos: Add setting for max height above water level
Increase default from 6 to 16 to help with mgv7 and mgfractal
Large-scale or alternative mapgens can result in a lowland spawn point not
being found, causing a spawn at (0, 0, 0) possibly buried underground
The max height is now settable to allow correct player spawn
in any mapgen or when using custom noise parameters
paramat [Wed, 28 Oct 2015 22:58:39 +0000 (22:58 +0000)]
Mgfractal: Add filler depth noise
kwolekr [Wed, 28 Oct 2015 02:27:32 +0000 (22:27 -0400)]
Add STATIC_ASSERT() macro and use it
kwolekr [Tue, 27 Oct 2015 06:51:43 +0000 (02:51 -0400)]
Add DISABLE_CLASS_COPY macro (and use it)
Use this macro to disallow copying of an object using the assignment
operator or copy constructor. This catches otherwise silent-but-deadly
mistakes such as "ServerMap map = env->getMap();" at compile time.
If so desired, it is still possible to copy a class, but it now requires
an explicit call to memcpy or std::copy.
est31 [Tue, 27 Oct 2015 20:03:59 +0000 (21:03 +0100)]
Environment: Time of day fixes and add serverside getter
-> Put access to time variables under the time lock.
-> Merge both time locks, there is no point to have two locks.
-> Fix the lock being released too early in Environment::setTimeOfDay
-> Add serverside getter so that you don't have to get
the environment if you only have the server
PilzAdam [Tue, 27 Oct 2015 14:55:34 +0000 (15:55 +0100)]
Fix missing #include
kwolekr [Tue, 27 Oct 2015 05:50:46 +0000 (01:50 -0400)]
Move basic, non-numeric macros from util/numeric.h to basicmacros.h
BlockMen [Wed, 12 Aug 2015 15:13:19 +0000 (17:13 +0200)]
Fix jittering sounds on entities (fixes #2974)
BlockMen [Mon, 26 Oct 2015 14:14:22 +0000 (15:14 +0100)]
Fix typo
kwolekr [Mon, 26 Oct 2015 08:01:01 +0000 (04:01 -0400)]
SAPI: Fix seed parameter truncation for LuaPseudoRandom constructor
Also fix a potential seed truncation issue on platforms where the
range of ptrdiff_t (the underlying type of lua_Integer) is too small.
kwolekr [Mon, 26 Oct 2015 07:45:55 +0000 (03:45 -0400)]
SAPI: Move core.get_us_time() to Util module
est31 [Mon, 26 Oct 2015 03:13:27 +0000 (04:13 +0100)]
Remove some abort() calls
abort() doesn't benefit from the high level abstractions from FATAL_ERROR.
kwolekr [Mon, 26 Oct 2015 03:12:59 +0000 (23:12 -0400)]
SAPI: Throw runtime error instead of if l_get_mapgen_object called in incorrect thread
kwolekr [Sun, 25 Oct 2015 04:45:18 +0000 (00:45 -0400)]
SAPI: Mark all Lua API functions requiring envlock
est31 [Sun, 25 Oct 2015 23:12:39 +0000 (00:12 +0100)]
Correct comment in l_util.cpp
Remove outdated loglevel list from a l_util.cpp comment,
and rather point to the updated code.
PilzAdam [Sun, 25 Oct 2015 18:14:07 +0000 (19:14 +0100)]
Fix parameter passing to gettext call
BlockMen [Sun, 25 Oct 2015 17:15:31 +0000 (18:15 +0100)]
Check if hitter has inventory when punching item
Fixes #3280
Rui [Sat, 24 Oct 2015 08:30:36 +0000 (17:30 +0900)]
Credits: Remove my name
BlockMen [Mon, 28 Sep 2015 18:49:38 +0000 (20:49 +0200)]
Add option to disable backface culling for models
- Disabled by default (except players)
- Fixes #2984
PilzAdam [Sun, 25 Oct 2015 09:56:58 +0000 (10:56 +0100)]
Escape " in generated settings_translation_file.cpp
est31 [Sat, 24 Oct 2015 22:01:57 +0000 (00:01 +0200)]
Fix out of bounds vector write in Logger::addOutput(ILogOutput *out)
Previously, the invocation of Logger::addOutput(ILogOutput *out) led to
an out of bounds write of the m_outputs vector, resulting in the
m_silenced_levels array being modified.
Fortunately, the only caller of that method was android system logging,
and only since a few commits ago.
PilzAdam [Sat, 24 Oct 2015 21:11:21 +0000 (23:11 +0200)]
Fix setting comments
PilzAdam [Sat, 24 Oct 2015 20:31:54 +0000 (22:31 +0200)]
Don't allow games or mods to add secure. settings
paramat [Fri, 23 Oct 2015 22:02:10 +0000 (23:02 +0100)]
Mgfractal: Independent iterations and scale parameters
Complete set of parameters for each of mandelbrot and julia sets
The julia set structure often needs different iterations and scale
est31 [Sat, 24 Oct 2015 18:44:07 +0000 (20:44 +0200)]
Android: statically load iconv library
Fixes #3291
Thanks to @arpruss for reporting the bug, and suggesting the fix.
Also, remove trailing whitespaces.
est31 [Sat, 24 Oct 2015 18:29:11 +0000 (20:29 +0200)]
Run updatepo.sh
est31 [Sun, 4 Oct 2015 23:52:41 +0000 (01:52 +0200)]
Better gettext support for protocol version mismatch messages
Previously, xgettext failed to resolve the dynamic call.
Thanks to @JakubVanek for pointing this out.
est31 [Sat, 24 Oct 2015 10:52:14 +0000 (12:52 +0200)]
Small logging refactor and additional options
-> Get rid of Logger::logToSystem and use normal downstream output system for android instead
-> Give the downstream output system more information: enrich the log function of ILogOutput
with information and add ICombinedLogOutput for easier use.
-> Make Logger::getLevelLabel() static and public so that it can be used by downstream log output.
-> Add g_ and m_ prefixes where required
PilzAdam [Sun, 18 Oct 2015 08:41:52 +0000 (10:41 +0200)]
Improve Lua settings menu
* Add key settings to setting table and ignore them later
This way they are added to the auto-generated minetest.conf.example
* Add flags type
* Add input validation for int, float and flags
* Break in-game graphic settings into multiple sections
* Parse settingtpes.txt in mods and games
* Improve description for a lot of settings
* Fix typos and wording in settingtypes.txt
* Convert language setting to an enum
kwolekr [Sat, 24 Oct 2015 17:31:42 +0000 (13:31 -0400)]
Fix compilation under MSVC and remove unnecessary conditional function prototype
Thanks to SmallJoker for pointing this out.
BlockMen [Fri, 23 Oct 2015 21:38:21 +0000 (23:38 +0200)]
Fix on_rightclick() being called directly after placing node
fixes https://github.com/minetest/minetest_game/issues/537
cheapie [Sat, 24 Oct 2015 04:52:45 +0000 (23:52 -0500)]
Improve rollback database indexing
Index more columns in the action table of the rollback DB to improve the performance of /rollback_check
est31 [Sat, 24 Oct 2015 06:20:42 +0000 (08:20 +0200)]
Flush rollback log more often
Flushes the buffer of rollback actions that wait to get saved in two more situations:
1. Flushes in the destructor of the rollback. This makes the server not
forget the last < 500 rollback entries when it shuts down.
2. Flushes the rollback when /rollback_check is invoked. This is neccessary
as otherwise it leads to confusion if users want to test the rollback functionality
by placing a node and then executing the check on it, or if the actions were
very recent out of other reasons.
kwolekr [Sun, 18 Oct 2015 02:42:48 +0000 (22:42 -0400)]
Fix some threading things and add additional thread unittests
- Fix thread name reset on start()
- Fully reset thread state on kill()
- Add unittests to check for correct object states under various circumstances
paramat [Wed, 21 Oct 2015 07:51:59 +0000 (08:51 +0100)]
Decoration API: Add flag for placement on liquid surface
Add findLiquidSurface() function to mapgen.cpp
Update lua_api.txt
Robert Zenz [Thu, 3 Sep 2015 19:28:38 +0000 (21:28 +0200)]
Add more ways to pass data to check_player_privs
The callback can now be invoked with either the player object or name as
the first parameter, and with either a table or a list of strings, like
this:
minetest.check_player_privs(player_name, { shout = true, fly = true })
minetest.check_player_privs(player_name, "shout", "fly")
minetest.check_player_privs(player, { shout = true, fly = true })
minetest.check_player_privs(player, "shout", "fly")
Leonardo [Thu, 15 Oct 2015 02:11:56 +0000 (04:11 +0200)]
Translated using Weblate (Portuguese (Brazil))
Currently translated at 72.6% (202 of 278 strings)
Rui [Mon, 5 Oct 2015 06:20:24 +0000 (08:20 +0200)]
Translated using Weblate (Japanese)
Currently translated at 100.0% (278 of 278 strings)
est31 [Mon, 5 Oct 2015 00:00:34 +0000 (02:00 +0200)]
Translated using Weblate (German)
Currently translated at 100.0% (278 of 278 strings)
Jun Zhang [Mon, 19 Oct 2015 03:47:14 +0000 (11:47 +0800)]
init_log_streams: check if log_filename is empty.
Fixes #3262.
paramat [Tue, 13 Oct 2015 04:17:33 +0000 (05:17 +0100)]
ABMs: Make catch-up behaviour optional
Default is true for backwards compatibility
Update lua_api.txt
Kahrl [Sun, 18 Oct 2015 09:03:59 +0000 (11:03 +0200)]
Settings tab: double click opens/closes trees
Kahrl [Sun, 18 Oct 2015 08:42:44 +0000 (10:42 +0200)]
Settings tab: don't autoscroll when toggling "Show technical names"
est31 [Sun, 18 Oct 2015 00:29:06 +0000 (02:29 +0200)]
Remove wstrgettext
Everywhere where wstrgettext was used, its output was converted back
to utf8. As wstrgettext internally converts the return value
from utf8 to wstring, it has been a waste. Remove the function, and
use strgettext instead.
est31 [Sun, 18 Oct 2015 00:18:10 +0000 (02:18 +0200)]
Display sane output for empty descriptions
According to its man page, the function gettext(3)
"may return a nonempty string" when msgid is "".
This commit fixes a bug where the comment ""
for some settings caused gettext to return a
"nonempty string", in this case header info of the
po file.
Kahrl [Sat, 17 Oct 2015 21:34:45 +0000 (23:34 +0200)]
Fix GUITable selection issues with trees
- setOpenedTrees(): this internal function was calling setSelected()
to update m_selected. Since setSelected() calls autoScroll(),
this caused the scrollbar to scroll back to the selected row
in some cases when that shouldn't be done.
For example, clicking the "+" to open a tree caused autoscroll.
Fix this by making setOpenedTrees() modify m_selected directly.
- setDynamicData(): set scrollbar position after calling
setSelected(), not before. This avoids setSelected()'s autoscroll
messing up the scrollbar position again.
- setSelected(): If an invisible row is selected, open all parents
of the selected row in order to make the selected row visible.
This fixes the issue where all the trees are closed again whenever
you return from the setting edit dialog to the settings tab.
est31 [Sat, 17 Oct 2015 20:19:04 +0000 (22:19 +0200)]
Re-add "file" type for --add-location for xgettext call
Passing line numbers in the comments is bad.
References:
* Commit
94961b3364f76d5861913af321e9be6200d080b3
* Previous commit
PilzAdam [Thu, 15 Oct 2015 19:32:31 +0000 (21:32 +0200)]
New settings tab contain all possible settings
Settings are automatically parsed from builtin/settingtypes.txt
The edit dialog automatically adjust based on the type of setting
Rui [Sat, 17 Oct 2015 10:23:07 +0000 (19:23 +0900)]
Fix == to =
kwolekr [Sat, 17 Oct 2015 05:16:17 +0000 (01:16 -0400)]
Fix missing include on AIX
kwolekr [Sat, 17 Oct 2015 03:43:29 +0000 (23:43 -0400)]
Refactor Thread class to improve readability and portability
- Fix some incompatibilities with obscure platforms (AIX and WinCE)
- Clean up Thread class interface
- Add m_ prefix to private member variables
- Simplify platform-dependent logic, reducing preprocessor
conditional clauses and improving readibility
- Add Thread class documentation
kwolekr [Sat, 17 Oct 2015 01:12:30 +0000 (21:12 -0400)]
Refactor thread utility interface
- Add "thr_" prefix to thread utility functions
- Compare threadid_ts in a portable manner, where possible
est31 [Fri, 16 Oct 2015 23:01:12 +0000 (01:01 +0200)]
Fix crash regression when invsize formspec gets used
The invsize formspec element is outdated. Even though,
it is still supported, only a deprecation warning is shown,
introduced by commit [1]. The lua context passed to the
log_deprecated method added by commit [1] is NULL for the
invsize deprecation warning, as its run on the client and not
the server.
Commit [1] has removed checks for NULL inside the log_deprecated
method, resulting in a crash when a formspec with an invsize
element is parsed. This commit puts the check back.
Fixes #3260.
Referenced commits:
[1]:
b5acec0a3c5701c53854ff7afdf4008863e6e8df "Add proper lua api deprecated handling"
[2]:
7b8d372947aae232ddf598155e972bb4dda157a "Use warningstream for deprecated field messages and refactor log_deprecated"
est31 [Thu, 15 Oct 2015 21:46:03 +0000 (23:46 +0200)]
Fix enforcing of nametag hiding
Commit
d2ca662569427d36642660314668e416bf68f3c8 "Enforce hiding nametag"
didn't fix the issue for "client" instances, where the nametag update
was received before the object was added to the scene. This resulted
in the grey shadow on the nametag that commit tried to fix.
Thanks to @neoascetic for pointing out that there still is a shadow.
Maksim Gamarnik [Thu, 15 Oct 2015 05:45:59 +0000 (01:45 -0400)]
Compress textures and fonts
Used PNGOUT, OptiPNG and DeflOpt.
Removes ~350 KB without any loss in quality.