Refactored F3 layer

- Renamed from LayerTestGUI to LayerDebug
- Many of the displays have been removed
- Fullscreen and VSync displays have been merged with FPS display
- Updates are automatic
This commit is contained in:
OLEGSHA 2021-12-13 17:03:23 +03:00
parent c93f0df30d
commit 49d283e7a3
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
5 changed files with 282 additions and 453 deletions

View File

@ -0,0 +1,260 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.test;
import glm.vec._3.Vec3;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.graphics.Colors;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.font.Font;
import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
import ru.windcorp.progressia.client.graphics.gui.Label;
import ru.windcorp.progressia.client.graphics.gui.Group;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.client.localization.MutableString;
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.Units;
import ru.windcorp.progressia.common.util.dynstr.DynamicStrings;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.ServerState;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
public class LayerDebug extends GUILayer {
private final List<Runnable> updateTriggers = new ArrayList<>();
public LayerDebug() {
super("LayerDebug", new LayoutAlign(0, 1, 5));
getRoot().addChild(new Group("Displays", new LayoutVertical(5)));
TestPlayerControls tpc = TestPlayerControls.getInstance();
addDynamicDisplay(
"FPSDisplay",
DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerDebug.FPSDisplay"))
.addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1)
.addDyn(() -> GraphicsBackend.isFullscreen() ? " Fullscreen" : "")
.addDyn(() -> GraphicsBackend.isVSyncEnabled() ? " VSync" : "")
.buildSupplier()
);
addDynamicDisplay("TPSDisplay", LayerDebug::getTPS);
addDynamicDisplay(
"ChunkStatsDisplay",
DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerDebug.ChunkStatsDisplay"))
.addDyn(() -> {
if (ClientState.getInstance() == null) {
return -1;
} else {
WorldRender world = ClientState.getInstance().getWorld();
return world.getChunks().size() - world.getPendingChunkUpdates();
}
}, 4)
.add('/')
.addDyn(() -> {
if (ClientState.getInstance() == null) {
return -1;
} else {
return ClientState.getInstance().getWorld().getPendingChunkUpdates();
}
}, 4)
.add('/')
.addDyn(() -> {
if (ServerState.getInstance() == null) {
return -1;
} else {
return ServerState.getInstance().getWorld().getChunks().size();
}
}, 4)
.buildSupplier()
);
addDynamicDisplay("PosDisplay", LayerDebug::getPos);
addDisplay("SelectedBlockDisplay", () -> tpc.isBlockSelected() ? ">" : " ", () -> tpc.getSelectedBlock().getId());
addDisplay("SelectedTileDisplay", () -> tpc.isBlockSelected() ? " " : ">", () -> tpc.getSelectedTile().getId());
addDisplay("PlacementModeHint", () -> "\u2B04");
}
private void addDisplay(String name, Supplier<?>... params) {
Font font = new Font().withColor(Colors.WHITE).deriveOutlined();
Label component = new Label(name, font, tmp_dynFormat("LayerDebug." + name, params));
getRoot().getChild(0).addChild(component);
for (Supplier<?> param : params) {
if (param == null) {
continue;
}
updateTriggers.add(new Runnable() {
private Object displayedValue;
@Override
public void run() {
Object newValue = param.get();
if (!Objects.equals(newValue, displayedValue)) {
component.update();
}
displayedValue = newValue;
}
});
}
}
private void addDynamicDisplay(String name, Supplier<CharSequence> contents) {
Font font = new Font().withColor(Colors.WHITE).deriveOutlined();
DynamicLabel component = new DynamicLabel(name, font, contents, 128);
getRoot().getChild(0).addChild(component);
}
@Override
protected void doRender() {
updateTriggers.forEach(Runnable::run);
super.doRender();
}
private static class Averager {
private static final int DISPLAY_INERTIA = 32;
private static final double UPDATE_INTERVAL = Units.get(50.0, "ms");
private final double[] values = new double[DISPLAY_INERTIA];
private int size;
private int head;
private long lastUpdate;
public void add(double value) {
if (size == values.length) {
values[head] = value;
head++;
if (head == values.length)
head = 0;
} else {
values[size] = value;
size++;
}
}
public double average() {
double product = 1;
if (size == values.length) {
for (double d : values)
product *= d;
} else {
for (int i = 0; i < size; ++i)
product *= values[i];
}
return Math.pow(product, 1.0 / size);
}
public double update(double value) {
long now = (long) (GraphicsInterface.getTime() / UPDATE_INTERVAL);
if (lastUpdate != now) {
lastUpdate = now;
add(value);
}
return average();
}
}
private static final String[] CLOCK_CHARS = "\u2591\u2598\u259d\u2580\u2596\u258c\u259e\u259b\u2597\u259a\u2590\u259c\u2584\u2599\u259f\u2588"
.chars().mapToObj(c -> ((char) c) + "").toArray(String[]::new);
private static String getTPSClockChar() {
return CLOCK_CHARS[(int) (ServerState.getInstance().getUptimeTicks() % CLOCK_CHARS.length)];
}
private static final Averager FPS_RECORD = new Averager();
private static final Averager TPS_RECORD = new Averager();
private static final Supplier<CharSequence> TPS_STRING = DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerDebug.TPSDisplay"))
.addDyn(() -> TPS_RECORD.update(ServerState.getInstance().getTPS()), 5, 1)
.add(' ')
.addDyn(LayerDebug::getTPSClockChar)
.buildSupplier();
private static final Supplier<CharSequence> POS_STRING = DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerDebug.PosDisplay"))
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().x, 7, 1)
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().y, 7, 1)
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().z, 7, 1)
.buildSupplier();
private static CharSequence getTPS() {
Server server = ServerState.getInstance();
if (server == null)
return Localizer.getInstance().getValue("LayerDebug.TPSDisplay.NA");
return TPS_STRING.get();
}
private static CharSequence getPos() {
Client client = ClientState.getInstance();
if (client == null)
return Localizer.getInstance().getValue("LayerDebug.PosDisplay.NA.Client");
Vec3 pos = client.getCamera().getLastAnchorPosition();
if (Float.isNaN(pos.x)) {
return Localizer.getInstance().getValue("LayerDebug.PosDisplay.NA.Entity");
} else {
return POS_STRING.get();
}
}
private static MutableString tmp_dynFormat(String formatKey, Supplier<?>... suppliers) {
return new MutableStringLocalized(formatKey).apply(s -> {
Object[] args = new Object[suppliers.length];
for (int i = 0; i < suppliers.length; ++i) {
Supplier<?> supplier = suppliers[i];
Object value = supplier != null ? supplier.get() : "null";
if (!(value instanceof Number)) {
value = Objects.toString(value);
}
args[i] = value;
}
return String.format(s, args);
});
}
}

View File

@ -1,406 +0,0 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.test;
import glm.vec._3.Vec3;
import glm.vec._4.Vec4;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.graphics.Colors;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.font.Font;
import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
import ru.windcorp.progressia.client.graphics.gui.Label;
import ru.windcorp.progressia.client.graphics.gui.Group;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.client.localization.MutableString;
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.Units;
import ru.windcorp.progressia.common.util.dynstr.DynamicStrings;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.ServerState;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Supplier;
public class LayerTestGUI extends GUILayer {
public LayerTestGUI() {
super("LayerTestGui", new LayoutAlign(0, 1, 5));
Group group = new Group("ControlDisplays", new LayoutVertical(5));
Vec4 color = Colors.WHITE;
Font font = new Font().withColor(color).deriveOutlined();
TestPlayerControls tpc = TestPlayerControls.getInstance();
group.addChild(
new Label(
"CameraModeDisplay",
font,
tmp_dynFormat(
"LayerTestGUI.CameraModeDisplay",
ClientState.getInstance().getCamera()::getCurrentModeIndex
)
)
);
group.addChild(
new Label(
"LanguageDisplay",
font,
tmp_dynFormat("LayerTestGUI.LanguageDisplay", Localizer.getInstance()::getLanguage)
)
);
group.addChild(
new Label(
"FullscreenDisplay",
font,
tmp_dynFormat("LayerTestGUI.IsFullscreen", GraphicsBackend::isFullscreen)
)
);
group.addChild(
new Label(
"VSyncDisplay",
font,
tmp_dynFormat("LayerTestGUI.IsVSync", GraphicsBackend::isVSyncEnabled)
)
);
group.addChild(
new DynamicLabel(
"FPSDisplay",
font,
DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerTestGUI.FPSDisplay"))
.addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1)
.buildSupplier(),
128
)
);
group.addChild(
new DynamicLabel(
"TPSDisplay",
font,
LayerTestGUI::getTPS,
128
)
);
group.addChild(
new DynamicLabel(
"ChunkStatsDisplay",
font,
DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerTestGUI.ChunkStatsDisplay"))
.addDyn(() -> {
if (ClientState.getInstance() == null) {
return -1;
} else {
WorldRender world = ClientState.getInstance().getWorld();
return world.getChunks().size() - world.getPendingChunkUpdates();
}
}, 4)
.add('/')
.addDyn(() -> {
if (ClientState.getInstance() == null) {
return -1;
} else {
return ClientState.getInstance().getWorld().getPendingChunkUpdates();
}
}, 4)
.add('/')
.addDyn(() -> {
if (ServerState.getInstance() == null) {
return -1;
} else {
return ServerState.getInstance().getWorld().getChunks().size();
}
}, 4)
.buildSupplier(),
128
)
);
group.addChild(
new DynamicLabel(
"PosDisplay",
font,
LayerTestGUI::getPos,
128
)
);
group.addChild(
new Label(
"SelectedBlockDisplay",
font,
tmp_dynFormat(
"LayerTestGUI.SelectedBlockDisplay",
() -> tpc.isBlockSelected() ? ">" : " ",
() -> tpc.getSelectedBlock().getId()
)
)
);
group.addChild(
new Label(
"SelectedTileDisplay",
font,
tmp_dynFormat(
"LayerTestGUI.SelectedTileDisplay",
() -> tpc.isBlockSelected() ? " " : ">",
() -> tpc.getSelectedTile().getId()
)
)
);
group.addChild(
new Label(
"PlacementModeHint",
font,
new MutableStringLocalized("LayerTestGUI.PlacementModeHint").format("\u2B04")
)
);
getRoot().addChild(group);
}
public Runnable getUpdateCallback() {
Collection<Label> labels = new ArrayList<>();
getRoot().getChild(0).getChildren().forEach(c -> {
if (c instanceof Label) {
labels.add((Label) c);
}
});
return () -> labels.forEach(Label::update);
}
private static class Averager {
private static final int DISPLAY_INERTIA = 32;
private static final double UPDATE_INTERVAL = Units.get(50.0, "ms");
private final double[] values = new double[DISPLAY_INERTIA];
private int size;
private int head;
private long lastUpdate;
public void add(double value) {
if (size == values.length) {
values[head] = value;
head++;
if (head == values.length)
head = 0;
} else {
values[size] = value;
size++;
}
}
public double average() {
double product = 1;
if (size == values.length) {
for (double d : values)
product *= d;
} else {
for (int i = 0; i < size; ++i)
product *= values[i];
}
return Math.pow(product, 1.0 / size);
}
public double update(double value) {
long now = (long) (GraphicsInterface.getTime() / UPDATE_INTERVAL);
if (lastUpdate != now) {
lastUpdate = now;
add(value);
}
return average();
}
}
private static final String[] CLOCK_CHARS = "\u2591\u2598\u259d\u2580\u2596\u258c\u259e\u259b\u2597\u259a\u2590\u259c\u2584\u2599\u259f\u2588"
.chars().mapToObj(c -> ((char) c) + "").toArray(String[]::new);
private static String getTPSClockChar() {
return CLOCK_CHARS[(int) (ServerState.getInstance().getUptimeTicks() % CLOCK_CHARS.length)];
}
private static final Averager FPS_RECORD = new Averager();
private static final Averager TPS_RECORD = new Averager();
private static final Supplier<CharSequence> TPS_STRING = DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerTestGUI.TPSDisplay"))
.addDyn(() -> TPS_RECORD.update(ServerState.getInstance().getTPS()), 5, 1)
.add(' ')
.addDyn(LayerTestGUI::getTPSClockChar)
.buildSupplier();
private static final Supplier<CharSequence> POS_STRING = DynamicStrings.builder()
.addDyn(new MutableStringLocalized("LayerTestGUI.PosDisplay"))
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().x, 7, 1)
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().y, 7, 1)
.addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().z, 7, 1)
.buildSupplier();
private static CharSequence getTPS() {
Server server = ServerState.getInstance();
if (server == null)
return Localizer.getInstance().getValue("LayerTestGUI.TPSDisplay.NA");
return TPS_STRING.get();
}
private static CharSequence getPos() {
Client client = ClientState.getInstance();
if (client == null)
return Localizer.getInstance().getValue("LayerTestGUI.PosDisplay.NA.Client");
Vec3 pos = client.getCamera().getLastAnchorPosition();
if (Float.isNaN(pos.x)) {
return Localizer.getInstance().getValue("LayerTestGUI.PosDisplay.NA.Entity");
} else {
return POS_STRING.get();
}
}
private static MutableString tmp_dynFormat(String formatKey, Supplier<?>... suppliers) {
return new MutableStringLocalized(formatKey).apply(s -> {
Object[] args = new Object[suppliers.length];
for (int i = 0; i < suppliers.length; ++i) {
Supplier<?> supplier = suppliers[i];
Object value = supplier != null ? supplier.get() : "null";
if (!(value instanceof Number)) {
value = Objects.toString(value);
}
args[i] = value;
}
return String.format(s, args);
});
}
// private static class DebugComponent extends Component {
// private final int color;
//
// public DebugComponent(String name, Vec2i size, int color) {
// super(name);
// this.color = color;
//
// setPreferredSize(size);
//
// addListener(new Object() {
// @Subscribe
// public void onHoverChanged(HoverEvent e) {
// requestReassembly();
// }
// });
//
// addListener(KeyEvent.class, this::onClicked);
// }
//
// private boolean onClicked(KeyEvent event) {
// if (!event.isMouse()) {
// return false;
// } else if (event.isPress() && event.isLeftMouseButton()) {
// System.out.println("You pressed a Component!");
// }
// return true;
// }
//
// @Override
// protected void assembleSelf(RenderTarget target) {
// target.fill(getX(), getY(), getWidth(), getHeight(), Colors.BLACK);
//
// target.fill(
// getX() + 2, getY() + 2,
// getWidth() - 4, getHeight() - 4,
// isHovered() ? Colors.DEBUG_YELLOW : color
// );
// }
// }
//
// public LayerTestGUI() {
// super("LayerTestGui", new LayoutAlign(1, 0.75, 5));
//
// Panel panel = new Panel("Alex", new LayoutVertical(5));
//
// panel.addChild(new DebugComponent("Bravo", new Vec2i(200, 100), 0x44FF44));
//
// Component charlie = new DebugComponent("Charlie", null, 0x222222);
// charlie.setLayout(new LayoutVertical(5));
//
// //Debug
// Localizer.getInstance().setLanguage("ru-RU");
// MutableString epsilon = new MutableStringLocalized("Epsilon")
// .addListener(() -> ((Label)charlie.getChild(0)).update()).format(34, "thirty-four");
// // These two are swapped in code due to a bug in layouts, fixing ATM
// charlie.addChild(
// new Label(
// "Delta",
// new Font().withColor(0xCCBB44).deriveShadow().deriveBold(),
// "Пре-альфа!"
// )
// );
// charlie.addChild(
// new Label(
// "Epsilon",
// new Font().withColor(0x4444BB).deriveItalic(),
// () -> epsilon.get().concat("\u269b")
// )
// );
// panel.addChild(charlie);
//
//
// charlie.addListener(KeyEvent.class, e -> {
// if(e.isPress() && e.getKey() == GLFW.GLFW_KEY_L) {
// Localizer localizer = Localizer.getInstance();
// if (localizer.getLanguage().equals("ru-RU")) {
// localizer.setLanguage("en-US");
// } else {
// localizer.setLanguage("ru-RU");
// }
// return true;
// } return false;
// });
// charlie.setFocusable(true);
// charlie.takeFocus();
//
// getRoot().addChild(panel);
// }
}

View File

@ -54,8 +54,7 @@ public class TestPlayerControls {
private int selectedTile = 0; private int selectedTile = 0;
private boolean isBlockSelected = true; private boolean isBlockSelected = true;
private LayerTestGUI debugLayer = null; private LayerDebug debugLayer = null;
private Runnable updateCallback = null;
{ {
reset(); reset();
@ -69,7 +68,6 @@ public class TestPlayerControls {
movementControls.reset(); movementControls.reset();
debugLayer = null; debugLayer = null;
updateCallback = null;
selectedBlock = 0; selectedBlock = 0;
selectedTile = 0; selectedTile = 0;
isBlockSelected = true; isBlockSelected = true;
@ -104,12 +102,10 @@ public class TestPlayerControls {
case GLFW.GLFW_KEY_F11: case GLFW.GLFW_KEY_F11:
GraphicsInterface.makeFullscreen(!GraphicsBackend.isFullscreen()); GraphicsInterface.makeFullscreen(!GraphicsBackend.isFullscreen());
updateGUI();
break; break;
case GLFW.GLFW_KEY_F12: case GLFW.GLFW_KEY_F12:
GraphicsBackend.setVSyncEnabled(!GraphicsBackend.isVSyncEnabled()); GraphicsBackend.setVSyncEnabled(!GraphicsBackend.isVSyncEnabled());
updateGUI();
break; break;
case GLFW.GLFW_KEY_F3: case GLFW.GLFW_KEY_F3:
@ -137,8 +133,7 @@ public class TestPlayerControls {
private void handleDebugLayerSwitch() { private void handleDebugLayerSwitch() {
if (debugLayer == null) { if (debugLayer == null) {
this.debugLayer = new LayerTestGUI(); this.debugLayer = new LayerDebug();
this.updateCallback = debugLayer.getUpdateCallback();
} }
if (GUI.getLayers().contains(debugLayer)) { if (GUI.getLayers().contains(debugLayer)) {
@ -155,7 +150,6 @@ public class TestPlayerControls {
if (ClientState.getInstance().getCamera().hasAnchor()) { if (ClientState.getInstance().getCamera().hasAnchor()) {
ClientState.getInstance().getCamera().selectNextMode(); ClientState.getInstance().getCamera().selectNextMode();
updateGUI();
} }
} }
@ -166,8 +160,6 @@ public class TestPlayerControls {
} else { } else {
localizer.setLanguage("ru-RU"); localizer.setLanguage("ru-RU");
} }
updateGUI();
} }
private void onMouseMoved(CursorMoveEvent event) { private void onMouseMoved(CursorMoveEvent event) {
@ -209,7 +201,6 @@ public class TestPlayerControls {
public void switchPlacingMode() { public void switchPlacingMode() {
isBlockSelected = !isBlockSelected; isBlockSelected = !isBlockSelected;
updateGUI();
} }
public void selectNextBlockOrTile(WheelScrollEvent event) { public void selectNextBlockOrTile(WheelScrollEvent event) {
@ -234,8 +225,6 @@ public class TestPlayerControls {
selectedTile = 0; selectedTile = 0;
} }
} }
updateGUI();
} }
public EntityData getEntity() { public EntityData getEntity() {
@ -245,12 +234,6 @@ public class TestPlayerControls {
public LocalPlayer getPlayer() { public LocalPlayer getPlayer() {
return ClientState.getInstance().getLocalPlayer(); return ClientState.getInstance().getLocalPlayer();
} }
private void updateGUI() {
if (this.updateCallback != null) {
this.updateCallback.run();
}
}
public MovementControls getMovementControls() { public MovementControls getMovementControls() {
return movementControls; return movementControls;

View File

@ -4,20 +4,16 @@ LayerAbout.Title = Progressia
LayerAbout.Version = Version: %s LayerAbout.Version = Version: %s
LayerAbout.DebugHint = Debug GUI: F3 LayerAbout.DebugHint = Debug GUI: F3
LayerTestGUI.CameraModeDisplay = Camera mode: %5d (F5) LayerDebug.FPSDisplay = FPS:
LayerTestGUI.LanguageDisplay = Language: %5s (L) LayerDebug.TPSDisplay = TPS:
LayerTestGUI.FPSDisplay = FPS: LayerDebug.TPSDisplay.NA = TPS: n/a
LayerTestGUI.TPSDisplay = TPS: LayerDebug.ChunkStatsDisplay = Chunks vis/pnd/load:
LayerTestGUI.TPSDisplay.NA = TPS: n/a LayerDebug.PosDisplay = Pos:
LayerTestGUI.ChunkStatsDisplay = Chunks vis/pnd/load: LayerDebug.PosDisplay.NA.Client = Pos: client n/a
LayerTestGUI.PosDisplay = Pos: LayerDebug.PosDisplay.NA.Entity = Pos: entity n/a
LayerTestGUI.PosDisplay.NA.Client = Pos: client n/a LayerDebug.SelectedBlockDisplay = %s Block: %s
LayerTestGUI.PosDisplay.NA.Entity = Pos: entity n/a LayerDebug.SelectedTileDisplay = %s Tile: %s
LayerTestGUI.SelectedBlockDisplay = %s Block: %s LayerDebug.PlacementModeHint = (Blocks %s Tiles: Ctrl + Mouse Wheel)
LayerTestGUI.SelectedTileDisplay = %s Tile: %s
LayerTestGUI.PlacementModeHint = (Blocks %s Tiles: Ctrl + Mouse Wheel)
LayerTestGUI.IsFullscreen = Fullscreen: %5s (F11)
LayerTestGUI.IsVSync = VSync: %5s (F12)
LayerButtonTest.Title = Button Test LayerButtonTest.Title = Button Test
LayerButtonTest.Return = Back To Menu LayerButtonTest.Return = Back To Menu

View File

@ -4,20 +4,16 @@ LayerAbout.Title = Прогрессия
LayerAbout.Version = Версия: %s LayerAbout.Version = Версия: %s
LayerAbout.DebugHint = Отладочный GUI: F3 LayerAbout.DebugHint = Отладочный GUI: F3
LayerTestGUI.CameraModeDisplay = Камера: %5d (F5) LayerDebug.FPSDisplay = FPS:
LayerTestGUI.LanguageDisplay = Язык: %5s (L) LayerDebug.TPSDisplay = TPS:
LayerTestGUI.FPSDisplay = FPS: LayerDebug.TPSDisplay.NA = TPS: н/д
LayerTestGUI.TPSDisplay = TPS: LayerDebug.ChunkStatsDisplay = Чанки вид/очр/загр:
LayerTestGUI.TPSDisplay.NA = TPS: н/д LayerDebug.PosDisplay = Поз:
LayerTestGUI.ChunkStatsDisplay = Чанки вид/очр/загр: LayerDebug.PosDisplay.NA.Client = Поз: клиент н/д
LayerTestGUI.PosDisplay = Поз: LayerDebug.PosDisplay.NA.Entity = Поз: сущность н/д
LayerTestGUI.PosDisplay.NA.Client = Поз: клиент н/д LayerDebug.SelectedBlockDisplay = %s Блок: %s
LayerTestGUI.PosDisplay.NA.Entity = Поз: сущность н/д LayerDebug.SelectedTileDisplay = %s Плитка: %s
LayerTestGUI.SelectedBlockDisplay = %s Блок: %s LayerDebug.PlacementModeHint = (Блок %s плитки: Ctrl + прокрутка)
LayerTestGUI.SelectedTileDisplay = %s Плитка: %s
LayerTestGUI.PlacementModeHint = (Блок %s плитки: Ctrl + прокрутка)
LayerTestGUI.IsFullscreen = Полный экран: %5s (F11)
LayerTestGUI.IsVSync = Верт. синхр.: %5s (F12)
LayerButtonTest.Title = Тест кнопок LayerButtonTest.Title = Тест кнопок
LayerButtonTest.Return = Главное меню LayerButtonTest.Return = Главное меню