From a3334035fd65cc375bd3b76f22c300be03536847 Mon Sep 17 00:00:00 2001
From: squid233 <513508220@qq.com>
Date: Wed, 27 Jan 2021 10:51:36 +0800
Subject: [PATCH] 0.4.0 released yesterday
---
build.gradle | 1 -
.../java/io/github/overrun/mc2d/Main.java | 152 ++++++++----------
.../io/github/overrun/mc2d/block/Block.java | 2 +-
.../io/github/overrun/mc2d/block/Blocks.java | 13 +-
.../overrun/mc2d/client/Mc2dClient.java | 110 +++++++++++++
.../mc2d/client/WindowEventHandler.java | 35 ++++
.../overrun/mc2d/client/font/AsciiFont.java | 50 ++++++
.../github/overrun/mc2d/client/font/Font.java | 60 +++++++
.../mc2d/client/font/TextRenderer.java | 88 ++++++++++
.../client/gui/AbstractParentElement.java | 31 ++++
.../overrun/mc2d/client/gui/Drawable.java | 33 ++++
.../mc2d/client/gui/DrawableHelper.java | 148 +++++++++++++++++
.../overrun/mc2d/client/gui/Element.java | 43 +++++
.../mc2d/client/gui/ParentElement.java | 62 +++++++
.../mc2d/client/gui/screen/DirtScreen.java | 44 +++++
.../mc2d/client/gui/screen/Screen.java | 140 ++++++++++++++++
.../client/gui/screen/TickableElement.java | 33 ++++
.../mc2d/client/gui/screen/TitleScreen.java | 86 ++++++++++
.../gui/screen/ingame/CreativeTabScreen.java | 81 ++++++++++
.../gui/screen/ingame/HandledScreen.java | 125 ++++++++++++++
.../gui/screen/ingame/InGameScreen.java | 98 +++++++++++
.../client/gui/screen/ingame/PauseScreen.java | 76 +++++++++
.../gui/screen/world/LoadingWorldScreen.java | 55 +++++++
.../gui/screen/world/SavingWorldScreen.java | 59 +++++++
.../gui/widget/AbstractButtonWidget.java | 140 ++++++++++++++++
.../widget/AbstractPressableButtonWidget.java | 43 +++++
.../mc2d/client/gui/widget/ButtonWidget.java | 72 +++++++++
.../mc2d/client/texture/TextureManager.java | 109 +++++++++++++
.../io/github/overrun/mc2d/event/Event.java | 53 ++++++
.../overrun/mc2d/event/EventContext.java | 32 ++++
.../overrun/mc2d/event/EventPublisher.java | 33 ++++
.../overrun/mc2d/event/KeyCallback.java | 57 +++++++
.../io/github/overrun/mc2d/level/World.java | 80 +++++----
.../github/overrun/mc2d/option/Options.java | 14 +-
.../mc2d/screen/CreativeTabScreen.java | 102 ------------
.../mc2d/screen/CreativeTabScreenHandler.java | 42 +++++
.../overrun/mc2d/screen/ScreenHandler.java | 45 ++++++
.../overrun/mc2d/screen/{ => slot}/Slot.java | 2 +-
.../github/overrun/mc2d/text/TextColor.java | 33 ++++
.../io/github/overrun/mc2d/util/GlUtils.java | 55 +++----
.../github/overrun/mc2d/util/GlfwUtils.java | 11 +-
.../{TextureDrawer.java => Identifier.java} | 73 ++++-----
.../github/overrun/mc2d/util/ImageReader.java | 59 -------
.../io/github/overrun/mc2d/util/Utils.java | 9 ++
src/main/resources/ascii.png | Bin 1286 -> 0 bytes
src/main/resources/{ => assets/mc2d}/icon.png | Bin
.../mc2d/textures/block}/bedrock.png | Bin
.../mc2d/textures/block}/cobblestone.png | Bin
.../{ => assets/mc2d/textures/block}/dirt.png | Bin
.../mc2d/textures/block}/grass_block.png | Bin
.../assets/mc2d/textures/font/ascii.png | Bin 0 -> 1286 bytes
.../assets/mc2d/textures/gui/logo.png | Bin 0 -> 1246 bytes
.../mc2d/textures/gui/options_background.png | Bin 0 -> 90 bytes
.../assets/mc2d/textures/gui/tab_items.png | Bin 0 -> 944 bytes
.../assets/mc2d/textures/gui/widgets.png | Bin 0 -> 3138 bytes
src/main/resources/tab_items.png | Bin 714 -> 0 bytes
56 files changed, 2323 insertions(+), 366 deletions(-)
create mode 100644 src/main/java/io/github/overrun/mc2d/client/Mc2dClient.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/WindowEventHandler.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/font/AsciiFont.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/font/Font.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/font/TextRenderer.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/AbstractParentElement.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/Drawable.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/DrawableHelper.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/Element.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/ParentElement.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/DirtScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/Screen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/TickableElement.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/TitleScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/CreativeTabScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/HandledScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/InGameScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/PauseScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/world/LoadingWorldScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/screen/world/SavingWorldScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractButtonWidget.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractPressableButtonWidget.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/gui/widget/ButtonWidget.java
create mode 100644 src/main/java/io/github/overrun/mc2d/client/texture/TextureManager.java
create mode 100644 src/main/java/io/github/overrun/mc2d/event/Event.java
create mode 100644 src/main/java/io/github/overrun/mc2d/event/EventContext.java
create mode 100644 src/main/java/io/github/overrun/mc2d/event/EventPublisher.java
create mode 100644 src/main/java/io/github/overrun/mc2d/event/KeyCallback.java
delete mode 100644 src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreen.java
create mode 100644 src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreenHandler.java
create mode 100644 src/main/java/io/github/overrun/mc2d/screen/ScreenHandler.java
rename src/main/java/io/github/overrun/mc2d/screen/{ => slot}/Slot.java (96%)
create mode 100644 src/main/java/io/github/overrun/mc2d/text/TextColor.java
rename src/main/java/io/github/overrun/mc2d/util/{TextureDrawer.java => Identifier.java} (50%)
delete mode 100644 src/main/resources/ascii.png
rename src/main/resources/{ => assets/mc2d}/icon.png (100%)
rename src/main/resources/{ => assets/mc2d/textures/block}/bedrock.png (100%)
rename src/main/resources/{ => assets/mc2d/textures/block}/cobblestone.png (100%)
rename src/main/resources/{ => assets/mc2d/textures/block}/dirt.png (100%)
rename src/main/resources/{ => assets/mc2d/textures/block}/grass_block.png (100%)
create mode 100644 src/main/resources/assets/mc2d/textures/font/ascii.png
create mode 100644 src/main/resources/assets/mc2d/textures/gui/logo.png
create mode 100644 src/main/resources/assets/mc2d/textures/gui/options_background.png
create mode 100644 src/main/resources/assets/mc2d/textures/gui/tab_items.png
create mode 100644 src/main/resources/assets/mc2d/textures/gui/widgets.png
delete mode 100644 src/main/resources/tab_items.png
diff --git a/build.gradle b/build.gradle
index 18cbadf..a947e38 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,7 +18,6 @@ repositories {
project.ext.lwjglVersion = '3.2.3'
dependencies {
- implementation 'com.google.guava:guava:30.1-jre'
implementation 'it.unimi.dsi:fastutil:8.4.4'
implementation 'org.apache.logging.log4j:log4j-core:2.14.0'
compileOnly 'org.jetbrains:annotations:20.1.0'
diff --git a/src/main/java/io/github/overrun/mc2d/Main.java b/src/main/java/io/github/overrun/mc2d/Main.java
index 20d84a3..483d93c 100644
--- a/src/main/java/io/github/overrun/mc2d/Main.java
+++ b/src/main/java/io/github/overrun/mc2d/Main.java
@@ -24,13 +24,11 @@
package io.github.overrun.mc2d;
-import io.github.overrun.mc2d.block.Blocks;
-import io.github.overrun.mc2d.level.World;
+import io.github.overrun.mc2d.client.Mc2dClient;
+import io.github.overrun.mc2d.client.WindowEventHandler;
+import io.github.overrun.mc2d.event.KeyCallback;
import io.github.overrun.mc2d.option.Options;
-import io.github.overrun.mc2d.screen.CreativeTabScreen;
-import io.github.overrun.mc2d.util.GlfwUtils;
import io.github.overrun.mc2d.util.ImageReader;
-import io.github.overrun.mc2d.util.TextureDrawer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFWErrorCallback;
@@ -38,106 +36,88 @@
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
+import java.io.Closeable;
import java.nio.IntBuffer;
-import java.util.Objects;
+import java.util.ArrayList;
+import java.util.List;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;
+import static org.lwjgl.system.MemoryUtil.memUTF8;
/**
* @author squid233
* @since 2021/01/07
*/
-public final class Main {
+public final class Main implements Runnable, Closeable {
public static final String VERSION = "0.4.0";
- public static boolean openingGroup;
private static final Logger logger = LogManager.getLogger();
- private final Player player = new Player();
- private World world;
+ private static final List WINDOW_EVENT_HANDLERS = new ArrayList<>(1);
+ private final Mc2dClient client = registerWindowEventHandler(Mc2dClient.getInstance());
private long window;
- private int width = 896;
- private int height = 512;
- private int mouseX;
- private int mouseY;
- private void run() {
+ public T registerWindowEventHandler(T handler) {
+ WINDOW_EVENT_HANDLERS.add(handler);
+ return handler;
+ }
+
+ @Override
+ public void run() {
logger.info("Loading for game Minecraft2D {}", VERSION);
init();
- resize(width, height);
glClearColor(.4f, .6f, .9f, .1f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- render();
- if (!openingGroup) {
- player.move();
- }
+ client.render();
+ client.tick();
glfwSwapBuffers(window);
glfwPollEvents();
}
- logger.info("Stopping!");
- glfwFreeCallbacks(window);
- glfwDestroyWindow(window);
- glfwTerminate();
- Objects.requireNonNull(glfwSetErrorCallback(null)).free();
}
private void init() {
- GLFWErrorCallback.createPrint(System.err).set();
+ GLFWErrorCallback.create((error, description) -> {
+ String desc = memUTF8(description);
+ logger.error("########## GL ERROR ##########");
+ logger.error("{}: {}", error, desc);
+ });
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
- window = glfwCreateWindow(width, height, "Minecraft2D " + VERSION, NULL, NULL);
+ window = glfwCreateWindow(896, 512, "Minecraft2D " + VERSION, NULL, NULL);
if (window == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
- ImageReader.withGlfwImg("icon.png",
+ ImageReader.withGlfwImg("assets/mc2d/icon.png",
imgs -> glfwSetWindowIcon(window, imgs));
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
+ KeyCallback.post(new KeyCallback.Context(window, key, scancode, action, mods));
+ if (action == GLFW_PRESS) {
+ client.screen.keyPressed(key, scancode, mods);
+ }
+ });
+ glfwSetMouseButtonCallback(window, (window, button, action, mods) -> {
if (action == GLFW_PRESS) {
- if (key == GLFW_KEY_ESCAPE) {
- if (openingGroup) {
- openingGroup = false;
- } else {
- world.save();
- glfwSetWindowShouldClose(window, true);
- }
- }
- if (key == (int) Options.get(Options.KEY_CREATIVE_TAB,
- "E").toUpperCase().toCharArray()[0]) {
- openingGroup = !openingGroup;
- if (!openingGroup) {
- GlfwUtils.setDefaultCursor();
- }
- }
- if (key == GLFW_KEY_ENTER) {
- world.save();
- }
- if (key == GLFW_KEY_1) {
- player.handledBlock = 1;
- }
- if (key == GLFW_KEY_2) {
- player.handledBlock = 2;
- }
- if (key == GLFW_KEY_3) {
- player.handledBlock = 3;
- }
- if (key == GLFW_KEY_4) {
- player.handledBlock = 4;
- }
+ client.screen.mouseClicked(client.mouseX, client.mouseY, button);
+ }
+ });
+ glfwSetWindowCloseCallback(window, window -> {
+ if (client.world != null) {
+ client.world.save();
}
});
- glfwSetWindowCloseCallback(window, window -> world.save());
glfwSetWindowSizeCallback(window, (window, width, height) -> resize(width, height));
glfwSetCursorPosCallback(window, (window, x, y) -> {
- mouseX = (int) Math.floor(x);
- mouseY = (int) Math.floor(y);
+ for (WindowEventHandler handler : WINDOW_EVENT_HANDLERS) {
+ handler.onMouseMove((int) Math.floor(x), (int) Math.floor(y));
+ }
});
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer pWidth = stack.mallocInt(1);
@@ -154,46 +134,44 @@ private void init() {
}
glfwMakeContextCurrent(window);
GL.createCapabilities();
- world = new World(player, 64, 64);
+ client.player = new Player();
glfwSwapInterval(1);
glfwShowWindow(window);
- GlfwUtils.setDefaultCursor();
- }
-
- private void render() {
- world.render(mouseX, mouseY, width, height);
- if (openingGroup) {
- CreativeTabScreen.render(mouseX, mouseY, height, player);
- } else {
- glPushMatrix();
- glTranslatef(width, height, 0);
- TextureDrawer.begin(ImageReader.loadTexture(
- Blocks.RAW_ID_BLOCKS.get(player.handledBlock).toString() + ".png"))
- .color4f(1, 1, 1, 1)
- .tex2dVertex2d(0, 0, -64, 0)
- .tex2dVertex2d(0, 1, -64, -64)
- .tex2dVertex2d(1, 1, 0, -64)
- .tex2dVertex2d(1, 0, 0, 0)
- .end();
- glPopMatrix();
- }
}
private void resize(int width, int height) {
int w = Math.max(width, 1);
int h = Math.max(height, 1);
- CreativeTabScreen.init(w, h);
- this.width = w;
- this.height = h;
+ if (client.screen == null) {
+ client.openScreen(null);
+ }
+ for (WindowEventHandler handler : WINDOW_EVENT_HANDLERS) {
+ handler.onResize(w, h);
+ }
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0, w, 0, h, 1, -1);
+ glOrtho(0, w, h, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, w, h);
}
+ @Override
+ public void close() {
+ client.close();
+ logger.info("Stopping!");
+ glfwFreeCallbacks(window);
+ glfwDestroyWindow(window);
+ glfwTerminate();
+ GLFWErrorCallback gec = glfwSetErrorCallback(null);
+ if (gec != null) {
+ gec.free();
+ }
+ }
+
public static void main(String[] args) {
Options.init();
- new Main().run();
+ try (Main main = new Main()) {
+ main.run();
+ }
}
}
diff --git a/src/main/java/io/github/overrun/mc2d/block/Block.java b/src/main/java/io/github/overrun/mc2d/block/Block.java
index 19d2c76..10399f5 100644
--- a/src/main/java/io/github/overrun/mc2d/block/Block.java
+++ b/src/main/java/io/github/overrun/mc2d/block/Block.java
@@ -54,6 +54,6 @@ public boolean equals(Object o) {
@Override
public String toString() {
- return Blocks.BLOCKS.inverse().get(this);
+ return Blocks.BLOCK2ID.get(this);
}
}
diff --git a/src/main/java/io/github/overrun/mc2d/block/Blocks.java b/src/main/java/io/github/overrun/mc2d/block/Blocks.java
index 098fffd..32f1254 100644
--- a/src/main/java/io/github/overrun/mc2d/block/Blocks.java
+++ b/src/main/java/io/github/overrun/mc2d/block/Blocks.java
@@ -24,18 +24,20 @@
package io.github.overrun.mc2d.block;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import it.unimi.dsi.fastutil.bytes.Byte2ObjectLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap;
import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
/**
* @author squid233
* @since 2021/01/09
*/
public final class Blocks {
- public static final BiMap BLOCKS = HashBiMap.create(5);
- public static final Byte2ObjectMap RAW_ID_BLOCKS = new Byte2ObjectLinkedOpenHashMap<>(5);
+ public static final Map BLOCKS = new LinkedHashMap<>(5);
+ public static final Map BLOCK2ID = new LinkedHashMap<>(5);
+ public static final Byte2ObjectMap RAW_ID_BLOCKS = new Byte2ObjectArrayMap<>(5);
public static final int BLOCK_SIZE = 32;
public static final Block AIR = register("air", 0);
public static final Block GRASS_BLOCK = register("grass_block", 1);
@@ -46,6 +48,7 @@ public final class Blocks {
public static Block register(String id, int rawId) {
Block b = new Block(rawId);
BLOCKS.putIfAbsent(id, b);
+ BLOCK2ID.putIfAbsent(b, id);
RAW_ID_BLOCKS.putIfAbsent(b.getRawId(), b);
return b;
}
diff --git a/src/main/java/io/github/overrun/mc2d/client/Mc2dClient.java b/src/main/java/io/github/overrun/mc2d/client/Mc2dClient.java
new file mode 100644
index 0000000..87e671b
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/Mc2dClient.java
@@ -0,0 +1,110 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client;
+
+import io.github.overrun.mc2d.Player;
+import io.github.overrun.mc2d.client.font.TextRenderer;
+import io.github.overrun.mc2d.client.gui.screen.Screen;
+import io.github.overrun.mc2d.client.gui.screen.TitleScreen;
+import io.github.overrun.mc2d.client.texture.TextureManager;
+import io.github.overrun.mc2d.level.World;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.Closeable;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public final class Mc2dClient implements Closeable, WindowEventHandler {
+ private static final Mc2dClient INSTANCE = new Mc2dClient();
+ public final TextRenderer textRenderer;
+ private final TextureManager textureManager;
+ public Screen screen;
+ public @Nullable World world;
+ public Player player;
+ private int width, height;
+ public int mouseX, mouseY;
+
+ private Mc2dClient() {
+ textRenderer = new TextRenderer(this);
+ textureManager = new TextureManager();
+ }
+
+ public void openScreen(@Nullable Screen screen) {
+ if (this.screen != null) {
+ this.screen.removed(screen);
+ }
+ if (screen == null && world == null) {
+ screen = new TitleScreen();
+ }
+ this.screen = screen;
+ if (screen != null) {
+ screen.init(this, width, height);
+ }
+ }
+
+ public void render() {
+ screen.render(mouseX, mouseY);
+ }
+
+ public void tick() {
+ screen.tick();
+ }
+
+ public TextureManager getTextureManager() {
+ return textureManager;
+ }
+
+ public int width() {
+ return width;
+ }
+
+ public int height() {
+ return height;
+ }
+
+ public static Mc2dClient getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public void close() {
+ textureManager.close();
+ }
+
+ @Override
+ public void onResize(int newWidth, int newHeight) {
+ width = newWidth;
+ height = newHeight;
+ screen.init(this, width, height);
+ }
+
+ @Override
+ public void onMouseMove(int newX, int newY) {
+ mouseX = newX;
+ mouseY = newY;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/WindowEventHandler.java b/src/main/java/io/github/overrun/mc2d/client/WindowEventHandler.java
new file mode 100644
index 0000000..0ab2aa6
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/WindowEventHandler.java
@@ -0,0 +1,35 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public interface WindowEventHandler {
+ void onResize(int newWidth, int newHeight);
+
+ void onMouseMove(int newX, int newY);
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/font/AsciiFont.java b/src/main/java/io/github/overrun/mc2d/client/font/AsciiFont.java
new file mode 100644
index 0000000..03f367b
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/font/AsciiFont.java
@@ -0,0 +1,50 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.font;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class AsciiFont implements Font {
+ @Override
+ public int width() {
+ return 8;
+ }
+
+ @Override
+ public int height() {
+ return 16;
+ }
+
+ @Override
+ public char[] availableChars() {
+ char[] chars = new char[128];
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = (char) i;
+ }
+ return chars;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/font/Font.java b/src/main/java/io/github/overrun/mc2d/client/font/Font.java
new file mode 100644
index 0000000..a26de0e
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/font/Font.java
@@ -0,0 +1,60 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.font;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public interface Font {
+ int width();
+
+ int height();
+
+ default int width(String text) {
+ return text.length() * width();
+ }
+
+ default char[] availableChars() {
+ return new char[0];
+ }
+
+ default int textureWidth() {
+ return availableChars().length * width();
+ }
+
+ default int textureHeight() {
+ return height();
+ }
+
+ default boolean contains(char c) {
+ for (char ch : availableChars()) {
+ if (ch == c) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/font/TextRenderer.java b/src/main/java/io/github/overrun/mc2d/client/font/TextRenderer.java
new file mode 100644
index 0000000..0b8ba17
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/font/TextRenderer.java
@@ -0,0 +1,88 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.font;
+
+import io.github.overrun.mc2d.client.Mc2dClient;
+import io.github.overrun.mc2d.client.gui.DrawableHelper;
+import io.github.overrun.mc2d.text.TextColor;
+import io.github.overrun.mc2d.util.Identifier;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class TextRenderer {
+ public static final Identifier ASCII_FONT_ID = new Identifier("textures/font/ascii.png");
+ private static final AsciiFont ASCII_FONT = new AsciiFont();
+ private final Mc2dClient client;
+
+ public TextRenderer(Mc2dClient client) {
+ this.client = client;
+ }
+
+ public void draw(int x, int y, char c, int rgba) {
+ if (ASCII_FONT.contains(c)) {
+ client.getTextureManager().bindTexture(ASCII_FONT_ID);
+ DrawableHelper.drawTexture(x,
+ y,
+ (int) c * width(c),
+ 0,
+ width(c),
+ height(c),
+ width(c),
+ height(c),
+ ASCII_FONT.textureWidth(),
+ ASCII_FONT.textureHeight(),
+ rgba);
+ }
+ }
+
+ public void draw(int x, int y, String text) {
+ draw(x, y, text, TextColor.WHITE);
+ }
+
+ public void draw(int x, int y, String text, int rgba) {
+ char[] chars = text.toCharArray();
+ for (int i = 0, len = chars.length; i < len; i++) {
+ draw(x + i * width(chars[i]) * 2, y, chars[i], rgba);
+ }
+ }
+
+ public int width(char c) {
+ int width = 0;
+ if (ASCII_FONT.contains(c)) {
+ width = ASCII_FONT.width();
+ }
+ return width;
+ }
+
+ public int height(char c) {
+ int height = 0;
+ if (ASCII_FONT.contains(c)) {
+ height = ASCII_FONT.height();
+ }
+ return height;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/AbstractParentElement.java b/src/main/java/io/github/overrun/mc2d/client/gui/AbstractParentElement.java
new file mode 100644
index 0000000..a868f21
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/AbstractParentElement.java
@@ -0,0 +1,31 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class AbstractParentElement extends DrawableHelper implements ParentElement { }
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/Drawable.java b/src/main/java/io/github/overrun/mc2d/client/gui/Drawable.java
new file mode 100644
index 0000000..faeabf1
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/Drawable.java
@@ -0,0 +1,33 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public interface Drawable {
+ void render(int mouseX, int mouseY);
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/DrawableHelper.java b/src/main/java/io/github/overrun/mc2d/client/gui/DrawableHelper.java
new file mode 100644
index 0000000..5f4bd27
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/DrawableHelper.java
@@ -0,0 +1,148 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui;
+
+import io.github.overrun.mc2d.client.font.TextRenderer;
+import io.github.overrun.mc2d.util.GlUtils;
+
+import java.awt.Color;
+
+import static org.lwjgl.opengl.GL11.*;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class DrawableHelper {
+ public static void drawCenteredText(TextRenderer renderer, String text, int centerX, int y, int rgba) {
+ renderer.draw(centerX - (text.length() << 3), y, text, rgba);
+ }
+
+ public static void fillGradient(int xStart, int yStart, int xEnd, int yEnd, int colorStart, int colorEnd) {
+ glDisable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ Color lt = new Color(colorStart, true);
+ Color rt = new Color((colorStart + colorEnd) >> 1, true);
+ Color rd = new Color(colorEnd, true);
+ // Left top
+ GlUtils.glColor4f(lt);
+ glVertex2f(xStart, yStart);
+ // Left down
+ GlUtils.glColor4f(rt);
+ glVertex2f(xStart, yEnd);
+ // Right down
+ GlUtils.glColor4f(rd);
+ glVertex2f(xEnd, yEnd);
+ // Right top
+ GlUtils.glColor4f(rt);
+ glVertex2f(xEnd, yStart);
+ glEnd();
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ public static void drawTexture(int x,
+ int y,
+ int u,
+ int v,
+ int regionW,
+ int regionH,
+ int width,
+ int height,
+ int texW,
+ int texH,
+ int rgba) {
+ glEnable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ GlUtils.glColor4f(new Color(rgba, true));
+ // Left top
+ glTexCoord2f((float) u / texW, (float) v / texH);
+ glVertex2f(x, y);
+ // Left down
+ glTexCoord2f((float) u / texW, (float) (v + regionH) / texH);
+ glVertex2f(x, y + (height << 1));
+ // Right down
+ glTexCoord2f((float) (u + regionW) / texW, (float) (v + regionH) / texH);
+ glVertex2f(x + (width << 1), y + (height << 1));
+ // Right top
+ glTexCoord2f((float) (u + regionW) / texW, (float) v / texH);
+ glVertex2f(x + (width << 1), y);
+ glEnd();
+ }
+
+ public static void drawTexture(int x,
+ int y,
+ int u,
+ int v,
+ int regionW,
+ int regionH,
+ int width,
+ int height,
+ int texW,
+ int texH) {
+ drawTexture(x, y, u, v, regionW, regionH, width, height, texW, texH, 0xffffffff);
+ }
+
+ public static void drawTexture(double x,
+ double y,
+ double width,
+ double height) {
+ glEnable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ glColor4f(1, 1, 1, 1);
+ // Left top
+ glTexCoord2f(0, 0);
+ glVertex2d(x, y);
+ // Left down
+ glTexCoord2f(0, 1);
+ glVertex2d(x, y + height);
+ // Right down
+ glTexCoord2f(1, 1);
+ glVertex2d(x + width, y + height);
+ // Right top
+ glTexCoord2f(1, 0);
+ glVertex2d(x + width, y);
+ glEnd();
+ }
+
+ public static void drawTexture(int x,
+ int y,
+ int u,
+ int v,
+ int regionW,
+ int regionH,
+ int width,
+ int height) {
+ drawTexture(x, y, u, v, regionW, regionH, width, height, 256, 256);
+ }
+
+ public static void drawTexture(int x,
+ int y,
+ int u,
+ int v,
+ int width,
+ int height) {
+ drawTexture(x, y, u, v, width, height, width, height);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/Element.java b/src/main/java/io/github/overrun/mc2d/client/gui/Element.java
new file mode 100644
index 0000000..0f2b0fa
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/Element.java
@@ -0,0 +1,43 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public interface Element {
+ default boolean mouseClicked(int mouseX, int mouseY, int button) {
+ return false;
+ }
+
+ default boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ return false;
+ }
+
+ default boolean isMouseOver(int mouseX, int mouseY) {
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/ParentElement.java b/src/main/java/io/github/overrun/mc2d/client/gui/ParentElement.java
new file mode 100644
index 0000000..e9ef912
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/ParentElement.java
@@ -0,0 +1,62 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public interface ParentElement extends Element {
+ List extends Element> children();
+
+ default Optional hoveredElement(int mouseX, int mouseY) {
+ Iterator extends Element> iterator = children().iterator();
+ Element element;
+ do {
+ if (!iterator.hasNext()) {
+ return Optional.empty();
+ }
+ element = iterator.next();
+ } while (!element.isMouseOver(mouseX, mouseY));
+ return Optional.of(element);
+ }
+
+ @Override
+ default boolean mouseClicked(int mouseX, int mouseY, int button) {
+ Iterator extends Element> iterator = children().iterator();
+ Element element;
+ do {
+ if (!iterator.hasNext()) {
+ return false;
+ }
+ element = iterator.next();
+ } while (!element.mouseClicked(mouseX, mouseY, button));
+ return true;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/DirtScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/DirtScreen.java
new file mode 100644
index 0000000..3dbf2c8
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/DirtScreen.java
@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen;
+
+import io.github.overrun.mc2d.text.TextColor;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public class DirtScreen extends Screen {
+ protected DirtScreen(String title) {
+ super(title);
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ renderBackgroundTexture();
+ super.render(mouseX, mouseY);
+ drawCenteredText(textRenderer, title, width >> 1, 50, TextColor.WHITE);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/Screen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/Screen.java
new file mode 100644
index 0000000..9f531bd
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/Screen.java
@@ -0,0 +1,140 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen;
+
+import io.github.overrun.mc2d.client.Mc2dClient;
+import io.github.overrun.mc2d.client.font.TextRenderer;
+import io.github.overrun.mc2d.client.gui.AbstractParentElement;
+import io.github.overrun.mc2d.client.gui.Drawable;
+import io.github.overrun.mc2d.client.gui.Element;
+import io.github.overrun.mc2d.client.gui.widget.AbstractButtonWidget;
+import io.github.overrun.mc2d.util.Identifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
+import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LEFT;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class Screen extends AbstractParentElement implements TickableElement, Drawable {
+ public static final Identifier OPTIONS_BACKGROUND = new Identifier("textures/gui/options_background.png");
+ protected final List children = new ArrayList<>();
+ public final String title;
+ protected Mc2dClient client;
+ protected TextRenderer textRenderer;
+ public int width;
+ public int height;
+ protected final List buttons = new ArrayList<>();
+
+ protected Screen(String title) {
+ this.title = title;
+ }
+
+ public void init(Mc2dClient client, int width, int height) {
+ this.client = client;
+ textRenderer = client.textRenderer;
+ this.width = width;
+ this.height = height;
+ buttons.clear();
+ children.clear();
+ init();
+ }
+
+ protected void init() { }
+
+ @Override
+ public void tick() { }
+
+ public void removed(Screen newScreen) { }
+
+ public void renderBackground() {
+ if (client.world != null) {
+ client.world.render(client, client.mouseX, client.mouseY, width, height);
+ fillGradient(0, 0, width, height, 0xc0101010, 0xd0101010);
+ } else {
+ renderBackgroundTexture();
+ }
+ }
+
+ public void renderBackgroundTexture() {
+ client.getTextureManager().bindTexture(OPTIONS_BACKGROUND);
+ for (int i = 0; i < height; i += 32) {
+ for (int j = 0; j < width; j += 32) {
+ drawTexture(j, i, 32, 32);
+ }
+ }
+ }
+
+ public void onClose() { }
+
+ public boolean shouldCloseOnEsc() {
+ return true;
+ }
+
+ protected T addButton(T button) {
+ buttons.add(button);
+ return addChild(button);
+ }
+
+ protected T addChild(T child) {
+ children.add(child);
+ return child;
+ }
+
+ @Override
+ public List extends Element> children() {
+ return children;
+ }
+
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ if (keyCode == GLFW_KEY_ESCAPE && shouldCloseOnEsc()) {
+ client.screen.onClose();
+ return true;
+ }
+ return super.keyPressed(keyCode, scanCode, modifiers);
+ }
+
+ @Override
+ public boolean mouseClicked(int mouseX, int mouseY, int button) {
+ for (AbstractButtonWidget b : buttons) {
+ if (b.isMouseOver(mouseX, mouseY) && button == GLFW_MOUSE_BUTTON_LEFT) {
+ b.onClick(mouseX, mouseY);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ for (AbstractButtonWidget button : buttons) {
+ button.render(mouseX, mouseY);
+ }
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/TickableElement.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/TickableElement.java
new file mode 100644
index 0000000..b85edb2
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/TickableElement.java
@@ -0,0 +1,33 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public interface TickableElement {
+ void tick();
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/TitleScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/TitleScreen.java
new file mode 100644
index 0000000..1cc2ce8
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/TitleScreen.java
@@ -0,0 +1,86 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen;
+
+import io.github.overrun.mc2d.Main;
+import io.github.overrun.mc2d.client.gui.screen.ingame.InGameScreen;
+import io.github.overrun.mc2d.client.gui.screen.world.LoadingWorldScreen;
+import io.github.overrun.mc2d.client.gui.widget.ButtonWidget;
+import io.github.overrun.mc2d.level.World;
+import io.github.overrun.mc2d.util.Identifier;
+
+import static org.lwjgl.glfw.GLFW.glfwGetCurrentContext;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public final class TitleScreen extends Screen {
+ public static final Identifier LOGO = new Identifier("textures/gui/logo.png");
+ public TitleScreen() {
+ super("");
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ addButton(new ButtonWidget(width - 400 >> 1,
+ (height - 40 >> 1) - 50,
+ 200,
+ 20,
+ "Play",
+ b -> {
+ client.world = new World(client.player, 64, 64);
+ client.openScreen(new LoadingWorldScreen());
+ }));
+ addButton(new ButtonWidget(width - 400 >> 1,
+ height - 40 >> 1,
+ 200,
+ 20,
+ "Mods",
+ b -> {})).active = false;
+ addButton(new ButtonWidget(width - 400 >> 1,
+ (height - 40 >> 1) + 50,
+ 200,
+ 20,
+ "Exit Game",
+ b -> glfwSetWindowShouldClose(glfwGetCurrentContext(), true)));
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ renderBackground();
+ super.render(mouseX, mouseY);
+ client.getTextureManager().bindTexture(LOGO);
+ drawTexture((width >> 1) - 202, 15, 404, 84);
+ textRenderer.draw(0, height - 20, "Minecraft2D " + Main.VERSION);
+ }
+
+ @Override
+ public boolean shouldCloseOnEsc() {
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/CreativeTabScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/CreativeTabScreen.java
new file mode 100644
index 0000000..f01bd7b
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/CreativeTabScreen.java
@@ -0,0 +1,81 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.ingame;
+
+import io.github.overrun.mc2d.Player;
+import io.github.overrun.mc2d.client.gui.screen.Screen;
+import io.github.overrun.mc2d.screen.CreativeTabScreenHandler;
+import io.github.overrun.mc2d.screen.slot.Slot;
+import io.github.overrun.mc2d.util.Identifier;
+
+import static org.lwjgl.glfw.GLFW.GLFW_KEY_E;
+
+/**
+ * @author squid233
+ * @since 2021/01/23
+ */
+public final class CreativeTabScreen extends HandledScreen {
+ private static final Identifier TEXTURE = new Identifier("textures/gui/tab_items.png");
+ private final Screen parent;
+ private final Player player;
+
+ public CreativeTabScreen(Player player, Screen parent) {
+ super(new CreativeTabScreenHandler(), "Creative Tab");
+ this.player = player;
+ this.parent = parent;
+ }
+
+ @Override
+ protected void onClickSlot(Slot slot) {
+ super.onClickSlot(slot);
+ player.handledBlock = slot.item;
+ }
+
+ @Override
+ public void drawBackground(int mouseX, int mouseY) {
+ client.getTextureManager().bindTexture(TEXTURE);
+ drawTexture(x, y, 0, 0, backgroundWidth, backgroundHeight);
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ renderBackground();
+ super.render(mouseX, mouseY);
+ }
+
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ if (keyCode == GLFW_KEY_E) {
+ onClose();
+ }
+ return super.keyPressed(keyCode, scanCode, modifiers);
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ client.openScreen(parent);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/HandledScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/HandledScreen.java
new file mode 100644
index 0000000..4010e6e
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/HandledScreen.java
@@ -0,0 +1,125 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.ingame;
+
+import io.github.overrun.mc2d.block.Blocks;
+import io.github.overrun.mc2d.client.gui.DrawableHelper;
+import io.github.overrun.mc2d.client.gui.screen.Screen;
+import io.github.overrun.mc2d.client.texture.TextureManager;
+import io.github.overrun.mc2d.screen.ScreenHandler;
+import io.github.overrun.mc2d.screen.slot.Slot;
+import io.github.overrun.mc2d.util.GlUtils;
+import io.github.overrun.mc2d.util.GlfwUtils;
+import io.github.overrun.mc2d.util.Identifier;
+
+import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LEFT;
+import static org.lwjgl.opengl.GL11.*;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class HandledScreen extends Screen {
+ protected final T handler;
+ protected int backgroundWidth = 195;
+ protected int backgroundHeight = 136;
+ protected int titleX;
+ protected int titleY;
+ protected int x;
+ protected int y;
+
+ protected HandledScreen(T handler, String title) {
+ super(title);
+ this.handler = handler;
+ }
+
+ protected void drawForeground(int mouseX, int mouseY) {
+ textRenderer.draw(titleX, titleY, title);
+ }
+
+ /**
+ * Draw background likes GUI texture.
+ * How to draw texture
+ * Steps:
+ *
+ * - {@link TextureManager#bindTexture(Identifier) Bind texture}
+ * - {@link DrawableHelper#drawTexture(int, int, int, int, int, int) Draw texture}
+ *
+ *
+ * @param mouseX X of mouse pos.
+ * @param mouseY Y of mouse pos.
+ */
+ protected abstract void drawBackground(int mouseX, int mouseY);
+
+ protected void onClickSlot(Slot slot) { }
+
+ @Override
+ protected void init() {
+ super.init();
+ x = width - (backgroundWidth << 1) >> 1;
+ y = height - (backgroundHeight << 1) >> 1;
+ titleX = x + 16;
+ titleY = y + 6;
+ handler.slots.clear();
+ handler.init();
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ drawBackground(mouseX, mouseY);
+ super.render(mouseX, mouseY);
+ for (Slot slot : handler.slots) {
+ drawSlot(slot);
+ mouseOverSlotEffect(slot, mouseX, mouseY);
+ }
+ drawForeground(mouseX, mouseY);
+ }
+
+ private void mouseOverSlotEffect(Slot slot, int mouseX, int mouseY) {
+ int slotX = x + slot.x, slotY = y + slot.y;
+ if (mouseX >= slotX
+ && mouseX < slotX + 32
+ && mouseY >= slotY
+ && mouseY < slotY + 32) {
+ glDisable(GL_TEXTURE_2D);
+ GlUtils.fillRect(slotX, slotY, slotX + 32, slotY + 32, 0x80ffffff, true);
+ glEnable(GL_TEXTURE_2D);
+ if (GlfwUtils.isMousePress(GLFW_MOUSE_BUTTON_LEFT)) {
+ onClickSlot(slot);
+ }
+ }
+ }
+
+ private void drawSlot(Slot slot) {
+ int slotX = x + slot.x, slotY = y + slot.y;
+ client.getTextureManager().bindTexture(new Identifier("textures/block/" + Blocks.RAW_ID_BLOCKS.get(slot.item).toString() + ".png"));
+ drawTexture(slotX, slotY, 32, 32);
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/InGameScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/InGameScreen.java
new file mode 100644
index 0000000..d655f45
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/InGameScreen.java
@@ -0,0 +1,98 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.ingame;
+
+import io.github.overrun.mc2d.Player;
+import io.github.overrun.mc2d.client.gui.screen.Screen;
+import io.github.overrun.mc2d.level.World;
+import io.github.overrun.mc2d.option.Options;
+import io.github.overrun.mc2d.util.Identifier;
+
+import static io.github.overrun.mc2d.block.Blocks.RAW_ID_BLOCKS;
+import static org.lwjgl.glfw.GLFW.*;
+import static org.lwjgl.opengl.GL11.*;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public final class InGameScreen extends Screen {
+ private World world;
+ private Player player;
+
+ public InGameScreen() {
+ super("");
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ world = client.world;
+ player = client.player;
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ super.render(mouseX, mouseY);
+ if (world != null) {
+ world.render(client, mouseX, mouseY, width, height);
+ }
+ glPushMatrix();
+ glTranslatef(width - 64, 0, 0);
+ client.getTextureManager().bindTexture(new Identifier("textures/block/" + RAW_ID_BLOCKS.get(player.handledBlock).toString() + ".png"));
+ drawTexture(0, 0, 64, 64);
+ glPopMatrix();
+ player.move();
+ }
+
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ if (keyCode == GLFW_KEY_ENTER && world != null) {
+ world.save();
+ }
+ if (keyCode == GLFW_KEY_1) {
+ player.handledBlock = 1;
+ }
+ if (keyCode == GLFW_KEY_2) {
+ player.handledBlock = 2;
+ }
+ if (keyCode == GLFW_KEY_3) {
+ player.handledBlock = 3;
+ }
+ if (keyCode == GLFW_KEY_4) {
+ player.handledBlock = 4;
+ }
+ if (keyCode == Options.getI(Options.KEY_CREATIVE_TAB, GLFW_KEY_E)) {
+ client.openScreen(new CreativeTabScreen(player, this));
+ }
+ return super.keyPressed(keyCode, scanCode, modifiers);
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ client.openScreen(new PauseScreen(this));
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/PauseScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/PauseScreen.java
new file mode 100644
index 0000000..d5e08e0
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/ingame/PauseScreen.java
@@ -0,0 +1,76 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.ingame;
+
+import io.github.overrun.mc2d.client.gui.screen.Screen;
+import io.github.overrun.mc2d.client.gui.screen.world.SavingWorldScreen;
+import io.github.overrun.mc2d.client.gui.widget.ButtonWidget;
+import io.github.overrun.mc2d.text.TextColor;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class PauseScreen extends Screen {
+ private final Screen parent;
+
+ public PauseScreen(Screen parent) {
+ super("Pausing");
+ this.parent = parent;
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ if (client.world != null) {
+ client.world.save();
+ }
+ addButton(new ButtonWidget((width >> 1) - 300,
+ 80,
+ 300,
+ 20,
+ "Back to Game",
+ b -> onClose()));
+ addButton(new ButtonWidget((width >> 1) - 300,
+ 130,
+ 300,
+ 20,
+ "Save and Back to Title Screen",
+ b -> client.openScreen(new SavingWorldScreen())));
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ renderBackground();
+ super.render(mouseX, mouseY);
+ drawCenteredText(textRenderer, title, width >> 1, 50, TextColor.WHITE);
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ client.openScreen(parent);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/LoadingWorldScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/LoadingWorldScreen.java
new file mode 100644
index 0000000..18f9303
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/LoadingWorldScreen.java
@@ -0,0 +1,55 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.world;
+
+import io.github.overrun.mc2d.client.gui.screen.DirtScreen;
+import io.github.overrun.mc2d.client.gui.screen.ingame.InGameScreen;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class LoadingWorldScreen extends DirtScreen {
+ public LoadingWorldScreen() {
+ super("Loading World");
+ }
+
+ @Override
+ public void tick() {
+ super.tick();
+ onClose();
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ client.openScreen(new InGameScreen());
+ }
+
+ @Override
+ public boolean shouldCloseOnEsc() {
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/SavingWorldScreen.java b/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/SavingWorldScreen.java
new file mode 100644
index 0000000..51b2c99
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/screen/world/SavingWorldScreen.java
@@ -0,0 +1,59 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.screen.world;
+
+import io.github.overrun.mc2d.client.gui.screen.DirtScreen;
+import io.github.overrun.mc2d.client.gui.screen.TitleScreen;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class SavingWorldScreen extends DirtScreen {
+ public SavingWorldScreen() {
+ super("Saving World");
+ }
+
+ @Override
+ public void tick() {
+ super.tick();
+ if (client.world != null) {
+ client.world.save();
+ }
+ onClose();
+ }
+
+ @Override
+ public void onClose() {
+ super.onClose();
+ client.openScreen(new TitleScreen());
+ client.world = null;
+ }
+
+ @Override
+ public boolean shouldCloseOnEsc() {
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractButtonWidget.java b/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractButtonWidget.java
new file mode 100644
index 0000000..6a3e7bc
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractButtonWidget.java
@@ -0,0 +1,140 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.widget;
+
+import io.github.overrun.mc2d.client.Mc2dClient;
+import io.github.overrun.mc2d.client.gui.Drawable;
+import io.github.overrun.mc2d.client.gui.DrawableHelper;
+import io.github.overrun.mc2d.client.gui.Element;
+import io.github.overrun.mc2d.text.TextColor;
+import io.github.overrun.mc2d.util.Identifier;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class AbstractButtonWidget extends DrawableHelper implements Drawable, Element {
+ public static final Identifier WIDGETS_LOCATION = new Identifier("textures/gui/widgets.png");
+ protected int width;
+ protected int height;
+ public int x;
+ public int y;
+ private String message;
+ protected boolean hovered;
+ public boolean active = true;
+
+ public AbstractButtonWidget(int x, int y, int width, int height, String message) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.message = message;
+ }
+
+ protected int getImageY(boolean hovered) {
+ int i = 1;
+ if (!active) {
+ i = 0;
+ } else if (hovered) {
+ i = 2;
+ }
+ return i;
+ }
+
+ public void renderButton(int mouseX, int mouseY) {
+ Mc2dClient client = Mc2dClient.getInstance();
+ client.getTextureManager().bindTexture(WIDGETS_LOCATION);
+ int i = getImageY(isHovered());
+ drawTexture(x, y, 0, 46 + i * 20, width >> 1, height);
+ drawTexture(x + width, y, 200 - (width >> 1), 46 + i * 20, width >> 1, height);
+ renderBg(client, mouseX, mouseY);
+ drawCenteredText(client.textRenderer,
+ getMessage(),
+ x + width,
+ y + ((height - 9) >> 1),
+ active ? TextColor.WHITE : 0xffa0a0a0);
+ }
+
+ protected void renderBg(Mc2dClient client, int mouseX, int mouseY) { }
+
+ public void onClick(int mouseX, int mouseY) { }
+
+ public void renderToolTip(int mouseX, int mouseY) { }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isHovered() {
+ return hovered;
+ }
+
+ @Override
+ public void render(int mouseX, int mouseY) {
+ hovered = mouseX >= x && mouseY >= y && mouseX < x + (width << 1) && mouseY < y + (height << 1);
+ renderButton(mouseX, mouseY);
+ }
+
+ @Override
+ public boolean isMouseOver(int mouseX, int mouseY) {
+ return active && hovered;
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractPressableButtonWidget.java b/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractPressableButtonWidget.java
new file mode 100644
index 0000000..80102ce
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/widget/AbstractPressableButtonWidget.java
@@ -0,0 +1,43 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.widget;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class AbstractPressableButtonWidget extends AbstractButtonWidget {
+ public AbstractPressableButtonWidget(int x, int y, int width, int height, String message) {
+ super(x, y, width, height, message);
+ }
+
+ public abstract void onPress();
+
+ @Override
+ public void onClick(int mouseX, int mouseY) {
+ super.onClick(mouseX, mouseY);
+ onPress();
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/gui/widget/ButtonWidget.java b/src/main/java/io/github/overrun/mc2d/client/gui/widget/ButtonWidget.java
new file mode 100644
index 0000000..81ac9ed
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/gui/widget/ButtonWidget.java
@@ -0,0 +1,72 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.gui.widget;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public class ButtonWidget extends AbstractPressableButtonWidget {
+ public static final TooltipSupplier EMPTY = (button, mouseX, mouseY) -> { };
+ protected final PressAction onPress;
+ protected final TooltipSupplier tooltipSupplier;
+
+ public ButtonWidget(int x, int y, int width, int height, String message, PressAction onPress) {
+ this(x, y, width, height, message, onPress, EMPTY);
+ }
+
+ public ButtonWidget(int x, int y, int width, int height, String message, PressAction onPress, TooltipSupplier tooltipSupplier) {
+ super(x, y, width, height, message);
+ this.onPress = onPress;
+ this.tooltipSupplier = tooltipSupplier;
+ }
+
+ @Override
+ public void onPress() {
+ onPress.onPress(this);
+ }
+
+ @Override
+ public void renderButton(int mouseX, int mouseY) {
+ super.renderButton(mouseX, mouseY);
+ if (isHovered()) {
+ renderToolTip(mouseX, mouseY);
+ }
+ }
+
+ @Override
+ public void renderToolTip(int mouseX, int mouseY) {
+ super.renderToolTip(mouseX, mouseY);
+ tooltipSupplier.onTooltip(this, mouseX, mouseY);
+ }
+
+ public interface TooltipSupplier {
+ void onTooltip(ButtonWidget button, int mouseX, int mouseY);
+ }
+
+ public interface PressAction {
+ void onPress(ButtonWidget button);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/client/texture/TextureManager.java b/src/main/java/io/github/overrun/mc2d/client/texture/TextureManager.java
new file mode 100644
index 0000000..5a6b656
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/client/texture/TextureManager.java
@@ -0,0 +1,109 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.client.texture;
+
+import io.github.overrun.mc2d.util.GlUtils;
+import io.github.overrun.mc2d.util.Identifier;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.system.MemoryStack;
+
+import java.awt.image.BufferedImage;
+import java.io.Closeable;
+import java.nio.ByteBuffer;
+
+import static io.github.overrun.mc2d.util.ImageReader.read;
+import static org.lwjgl.opengl.GL11.*;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public final class TextureManager implements Closeable {
+ private final Object2IntMap idMap = new Object2IntOpenHashMap<>(16);
+ private int lastId = -999999;
+
+ public int loadTexture(Identifier id) {
+ return loadTexture(id, GL_NEAREST);
+ }
+
+ public int loadTexture(Identifier id, int mode) {
+ if (idMap.containsKey(id.toString())) {
+ return idMap.getInt(id.toString());
+ } else {
+ int[] buf = {0};
+ glGenTextures(buf);
+ int texId = buf[0];
+ glBindTexture(GL_TEXTURE_2D, texId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode);
+ BufferedImage img = read("assets/" + id.getNamespace() + "/" + id.getPath());
+ if (img == null) {
+ try (MemoryStack stack = MemoryStack.stackPush()) {
+ ByteBuffer pixels = stack.malloc(16);
+ pixels.asIntBuffer().put(new int[]{
+ 0xfff800f8, 0xff000000,
+ 0xff000000, 0xfff800f8
+ });
+ GlUtils.generateMipmap(GL_TEXTURE_2D, GL_RGBA, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
+ } else {
+ int w = img.getWidth();
+ int h = img.getHeight();
+ ByteBuffer pixels = BufferUtils.createByteBuffer(w * h * 4);
+ int[] rawPixels = new int[w * h];
+ img.getRGB(0, 0, w, h, rawPixels, 0, w);
+ for (int i = 0; i < rawPixels.length; ++i) {
+ int a = rawPixels[i] >> 24 & 255;
+ int r = rawPixels[i] >> 16 & 255;
+ int g = rawPixels[i] >> 8 & 255;
+ int b = rawPixels[i] & 255;
+ rawPixels[i] = a << 24 | b << 16 | g << 8 | r;
+ }
+ pixels.asIntBuffer().put(rawPixels);
+ GlUtils.generateMipmap(GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
+ idMap.put(id.toString(), texId);
+ return texId;
+ }
+ }
+
+ public void bindTexture(Identifier id) {
+ int texId = loadTexture(id);
+ if (lastId != texId) {
+ glBindTexture(GL_TEXTURE_2D, texId);
+ lastId = texId;
+ }
+ }
+
+ @Override
+ public void close() {
+ for (int id : idMap.values()) {
+ glDeleteTextures(id);
+ }
+ idMap.clear();
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/event/Event.java b/src/main/java/io/github/overrun/mc2d/event/Event.java
new file mode 100644
index 0000000..426958c
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/event/Event.java
@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Lightweight event system.
+ *
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class Event, C extends EventContext> {
+ public final List listeners = new ArrayList<>();
+ public final Invoker invoker;
+
+ public Event(Invoker invoker) {
+ this.invoker = invoker;
+ }
+
+ public void register(T listener) {
+ if (listener != null) {
+ listeners.add(listener);
+ }
+ }
+
+ public interface Invoker {
+ T invoke(List listeners);
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/event/EventContext.java b/src/main/java/io/github/overrun/mc2d/event/EventContext.java
new file mode 100644
index 0000000..639da48
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/event/EventContext.java
@@ -0,0 +1,32 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.event;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public interface EventContext {
+}
diff --git a/src/main/java/io/github/overrun/mc2d/event/EventPublisher.java b/src/main/java/io/github/overrun/mc2d/event/EventPublisher.java
new file mode 100644
index 0000000..4177956
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/event/EventPublisher.java
@@ -0,0 +1,33 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.event;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public interface EventPublisher {
+ void publish(T context);
+}
diff --git a/src/main/java/io/github/overrun/mc2d/event/KeyCallback.java b/src/main/java/io/github/overrun/mc2d/event/KeyCallback.java
new file mode 100644
index 0000000..c1a24f4
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/event/KeyCallback.java
@@ -0,0 +1,57 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.event;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public interface KeyCallback extends EventPublisher {
+ Event EVENT = new Event<>(listeners -> context -> {
+ for (KeyCallback callback : listeners) {
+ callback.publish(context);
+ }
+ });
+
+ static void post(Context context) {
+ EVENT.invoker.invoke(EVENT.listeners).publish(context);
+ }
+
+ @Override
+ void publish(Context context);
+
+ final class Context implements EventContext {
+ public final long window;
+ public final int key, scancode, action, mods;
+
+ public Context(long window, int key, int scancode, int action, int mods) {
+ this.window = window;
+ this.key = key;
+ this.scancode = scancode;
+ this.action = action;
+ this.mods = mods;
+ }
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/level/World.java b/src/main/java/io/github/overrun/mc2d/level/World.java
index 3ff1991..3f199f1 100644
--- a/src/main/java/io/github/overrun/mc2d/level/World.java
+++ b/src/main/java/io/github/overrun/mc2d/level/World.java
@@ -27,10 +27,12 @@
import io.github.overrun.mc2d.Main;
import io.github.overrun.mc2d.Player;
import io.github.overrun.mc2d.block.Block;
+import io.github.overrun.mc2d.client.Mc2dClient;
+import io.github.overrun.mc2d.client.gui.screen.ingame.InGameScreen;
+import io.github.overrun.mc2d.event.KeyCallback;
import io.github.overrun.mc2d.option.Options;
import io.github.overrun.mc2d.util.GlUtils;
-import io.github.overrun.mc2d.util.ImageReader;
-import io.github.overrun.mc2d.util.TextureDrawer;
+import io.github.overrun.mc2d.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -46,9 +48,9 @@
import java.util.Arrays;
import static io.github.overrun.mc2d.block.Blocks.*;
-import static io.github.overrun.mc2d.util.GlfwUtils.isMousePress;
-import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LEFT;
-import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_RIGHT;
+import static io.github.overrun.mc2d.client.gui.DrawableHelper.drawTexture;
+import static io.github.overrun.mc2d.util.GlfwUtils.*;
+import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
/**
@@ -62,6 +64,15 @@ public final class World implements Serializable {
private final Player player;
public final transient int width;
public final transient int height;
+ private static boolean debug;
+
+ static {
+ KeyCallback.EVENT.register(context -> {
+ if (context.key == GLFW_KEY_F3 && context.action == GLFW_PRESS) {
+ debug = !debug;
+ }
+ });
+ }
public World(Player player, int w, int h) {
this.player = player;
@@ -90,7 +101,9 @@ public World(Player player, int w, int h) {
}
public void setBlock(int x, int y, byte type) {
- blocks[x % width + y * width] = type;
+ if (x >= 0 && x < width && y >= 0 && y < height) {
+ blocks[x % width + y * width] = type;
+ }
}
public void setBlock(int x, int y, Block block) {
@@ -98,50 +111,44 @@ public void setBlock(int x, int y, Block block) {
}
public Block getBlock(int x, int y) {
- try {
+ if (x >= 0 && x < width && y >= 0 && y < height) {
return RAW_ID_BLOCKS.get(blocks[x % width + y * width]);
- } catch (Exception e) {
+ } else {
return AIR;
}
}
- public void render(int mouseX, int mouseY, int windowW, int windowH) {
- mouseY = windowH - mouseY;
+ public void render(Mc2dClient client, int mouseX, int mouseY, int windowW, int windowH) {
+ byte pointBlock = 0;
+ int pointBlockX = 0, pointBlockY = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Block b = getBlock(j, i);
- double ltX = ((windowW >> 1) - 1) + (j * BLOCK_SIZE - player.x * BLOCK_SIZE),
- ltY = ((windowH >> 1) - 1) + ((i + 1) * BLOCK_SIZE - player.y * BLOCK_SIZE),
- rdX = ((windowW >> 1) - 1) + ((j + 1) * BLOCK_SIZE - player.x * BLOCK_SIZE),
- rdY = ((windowH >> 1) - 1) + (i * BLOCK_SIZE - player.y * BLOCK_SIZE);
- if (b != AIR) {
- TextureDrawer.begin(ImageReader.loadTexture(BLOCKS.inverse().get(b) + ".png"))
- .color4f(1, 1, 1, 1)
- .tex2dVertex2d(0, 1,
- ((windowW >> 1) - 1) + (j * BLOCK_SIZE - player.x * BLOCK_SIZE),
- ((windowH >> 1) - 1) + (i * BLOCK_SIZE - player.y * BLOCK_SIZE))
- .tex2dVertex2d(1, 1, rdX, rdY)
- .tex2dVertex2d(1, 0,
- ((windowW >> 1) - 1) + ((j + 1) * BLOCK_SIZE - player.x * BLOCK_SIZE),
- ((windowH >> 1) - 1) + ((i + 1) * BLOCK_SIZE - player.y * BLOCK_SIZE))
- .tex2dVertex2d(0, 0, ltX, ltY)
- .end();
+ double ltX = (windowW >> 1) - 1 + (j - player.x) * BLOCK_SIZE,
+ ltY = (windowH >> 1) - 1 - (i - player.y) * BLOCK_SIZE,
+ rdX = ltX + BLOCK_SIZE,
+ rdY = ltY + BLOCK_SIZE;
+ if (b != AIR && rdX >= 0 && rdY >= 0 && ltX < windowW && ltY < windowH) {
+ client.getTextureManager().bindTexture(new Identifier("textures/block/" + BLOCK2ID.get(b) + ".png"));
+ drawTexture(ltX, ltY, BLOCK_SIZE, BLOCK_SIZE);
}
- if (!Main.openingGroup
+ if (client.screen instanceof InGameScreen
&& mouseX >= ltX
&& mouseX < rdX
- && mouseY <= ltY
- && mouseY > rdY) {
+ && mouseY >= ltY
+ && mouseY < rdY) {
+ pointBlock = b.getRawId();
+ pointBlockX = j;
+ pointBlockY = i;
if (
Options.getB(Options.BLOCK_HIGHLIGHT,
System.getProperty("mc2d.block.highlight",
"false"))
) {
glDisable(GL_TEXTURE_2D);
- GlUtils.fillRect(ltX, ltY, rdX, rdY, 0x7fffffff, true);
+ GlUtils.fillRect(ltX, ltY, rdX, rdY, 0x80ffffff, true);
glEnable(GL_TEXTURE_2D);
- }
- else {
+ } else {
GlUtils.drawRect(ltX, ltY, rdX, rdY, 0, false);
}
if (getBlock(j, i) != AIR
@@ -154,10 +161,18 @@ && isMousePress(GLFW_MOUSE_BUTTON_RIGHT)) {
}
}
}
+ if (debug) {
+ client.textRenderer.draw(0, 0, "Minecraft2D " + Main.VERSION);
+ client.textRenderer.draw(0, 30, String.format("Pos: %.4f, %.4f", player.x, player.y));
+ client.textRenderer.draw(0, 60, "Handled block: " + RAW_ID_BLOCKS.get(player.handledBlock));
+ client.textRenderer.draw(0, 90, "Point block pos: " + pointBlockX + ", " + pointBlockY);
+ client.textRenderer.draw(0, 120, "Point block: " + RAW_ID_BLOCKS.get(pointBlock));
+ }
glFinish();
}
public void load() {
+ logger.info("Loading world");
File file = new File("level.dat");
if (file.exists()) {
try (InputStream is = new FileInputStream(file);
@@ -173,6 +188,7 @@ public void load() {
}
public void save() {
+ logger.info("Saving world");
try (OutputStream os = new FileOutputStream("level.dat");
ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeObject(this);
diff --git a/src/main/java/io/github/overrun/mc2d/option/Options.java b/src/main/java/io/github/overrun/mc2d/option/Options.java
index 4608eb8..3ee74fa 100644
--- a/src/main/java/io/github/overrun/mc2d/option/Options.java
+++ b/src/main/java/io/github/overrun/mc2d/option/Options.java
@@ -24,6 +24,7 @@
package io.github.overrun.mc2d.option;
+import io.github.overrun.mc2d.util.Utils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,6 +36,8 @@
import java.io.Reader;
import java.util.Properties;
+import static org.lwjgl.glfw.GLFW.GLFW_KEY_E;
+
/**
* @author squid233
* @since 2021/01/23
@@ -45,11 +48,15 @@ public final class Options {
public static final String KEY_CREATIVE_TAB = "key.creativeTab";
private static final Logger logger = LogManager.getLogger();
+ private static void put(String key, int value) {
+ OPTIONS.put(key, String.valueOf(value));
+ }
+
public static void init() {
File file = new File("options.txt");
if (!file.exists()) {
try (OutputStream os = new FileOutputStream(file)) {
- OPTIONS.put(KEY_CREATIVE_TAB, "E");
+ put(KEY_CREATIVE_TAB, GLFW_KEY_E);
OPTIONS.put(BLOCK_HIGHLIGHT, "false");
OPTIONS.store(os, null);
} catch (IOException e) {
@@ -69,6 +76,11 @@ public static boolean getB(String key, String def) {
: Boolean.parseBoolean(def);
}
+ public static int getI(String key, int def) {
+ String value = OPTIONS.getProperty(key, String.valueOf(def));
+ return Utils.isParsableNumber(value) ? Integer.parseInt(value) : def;
+ }
+
public static String get(String key, String def) {
return OPTIONS.getProperty(key, def);
}
diff --git a/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreen.java b/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreen.java
deleted file mode 100644
index ef76f95..0000000
--- a/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreen.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020-2021 Over-Run
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package io.github.overrun.mc2d.screen;
-
-import io.github.overrun.mc2d.Main;
-import io.github.overrun.mc2d.Player;
-import io.github.overrun.mc2d.block.Blocks;
-import io.github.overrun.mc2d.util.GlUtils;
-import io.github.overrun.mc2d.util.GlfwUtils;
-import io.github.overrun.mc2d.util.ImageReader;
-import io.github.overrun.mc2d.util.TextureDrawer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static io.github.overrun.mc2d.util.GlfwUtils.isMousePress;
-import static org.lwjgl.glfw.GLFW.*;
-import static org.lwjgl.opengl.GL11.*;
-
-/**
- * @author squid233
- * @since 2021/01/23
- */
-public final class CreativeTabScreen {
- private static final List SLOTS = new ArrayList<>(4);
- public static int x;
- public static int y;
-
- public static void init(int width, int height) {
- x = (width >> 1) - 195;
- y = (height >> 1) + 136;
- SLOTS.clear();
- for (int i = 0; i < 4; i++) {
- Slot slot = new Slot(x + 18 + i * 36, y - 36);
- slot.item = (byte) (i + 1);
- SLOTS.add(slot);
- }
- }
-
- public static void render(int mouseX, int mouseY, int windowH, Player player) {
- mouseY = windowH - mouseY;
- TextureDrawer.begin(ImageReader.loadTexture("tab_items.png"))
- .color4f(1, 1, 1, 1)
- .tex2dVertex2d(0, 0, x, y)
- .tex2dVertex2d(0, 1, x, y - 272)
- .tex2dVertex2d(1, 1, x + 390, y - 272)
- .tex2dVertex2d(1, 0, x + 390, y)
- .end();
- GlUtils.drawText(x + 16, y, "Creative Tab");
- boolean showHand = false;
- for (Slot slot : SLOTS) {
- TextureDrawer.begin(ImageReader.loadTexture(Blocks.RAW_ID_BLOCKS.get(slot.item).toString() + ".png"))
- .color4f(1, 1, 1, 1)
- .tex2dVertex2d(0, 0, slot.x, slot.y)
- .tex2dVertex2d(0, 1, slot.x, slot.y - 32)
- .tex2dVertex2d(1, 1, slot.x + 32, slot.y - 32)
- .tex2dVertex2d(1, 0, slot.x + 32, slot.y)
- .end();
- if (mouseX >= slot.x
- && mouseX < slot.x + 32
- && mouseY <= slot.y
- && mouseY > slot.y - 32) {
- showHand = true;
- glDisable(GL_TEXTURE_2D);
- GlUtils.fillRect(slot.x, slot.y, slot.x + 32, slot.y - 32, 0x7fffffff, true);
- glEnable(GL_TEXTURE_2D);
- if (isMousePress(GLFW_MOUSE_BUTTON_LEFT)) {
- player.handledBlock = slot.item;
- showHand = false;
- Main.openingGroup = false;
- }
- }
- }
- if (showHand) {
- glfwSetCursor(glfwGetCurrentContext(), GlfwUtils.HAND_CURSOR);
- } else {
- GlfwUtils.setDefaultCursor();
- }
- }
-}
diff --git a/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreenHandler.java b/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreenHandler.java
new file mode 100644
index 0000000..03b58ce
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/screen/CreativeTabScreenHandler.java
@@ -0,0 +1,42 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.screen;
+
+import io.github.overrun.mc2d.screen.slot.Slot;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public final class CreativeTabScreenHandler extends ScreenHandler {
+ @Override
+ public void init() {
+ super.init();
+ for (int i = 0; i < 4; i++) {
+ Slot slot = addSlot(new Slot(18 + i * 36, 36));
+ slot.item = (byte) (i + 1);
+ }
+ }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/screen/ScreenHandler.java b/src/main/java/io/github/overrun/mc2d/screen/ScreenHandler.java
new file mode 100644
index 0000000..7dcee4b
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/screen/ScreenHandler.java
@@ -0,0 +1,45 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.screen;
+
+import io.github.overrun.mc2d.screen.slot.Slot;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author squid233
+ * @since 2021/01/25
+ */
+public abstract class ScreenHandler {
+ public final List slots = new ArrayList<>();
+
+ public Slot addSlot(Slot slot) {
+ slots.add(slot);
+ return slot;
+ }
+
+ public void init() { }
+}
diff --git a/src/main/java/io/github/overrun/mc2d/screen/Slot.java b/src/main/java/io/github/overrun/mc2d/screen/slot/Slot.java
similarity index 96%
rename from src/main/java/io/github/overrun/mc2d/screen/Slot.java
rename to src/main/java/io/github/overrun/mc2d/screen/slot/Slot.java
index 0c11f2c..799d7a7 100644
--- a/src/main/java/io/github/overrun/mc2d/screen/Slot.java
+++ b/src/main/java/io/github/overrun/mc2d/screen/slot/Slot.java
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-package io.github.overrun.mc2d.screen;
+package io.github.overrun.mc2d.screen.slot;
/**
* @author squid233
diff --git a/src/main/java/io/github/overrun/mc2d/text/TextColor.java b/src/main/java/io/github/overrun/mc2d/text/TextColor.java
new file mode 100644
index 0000000..9e161c1
--- /dev/null
+++ b/src/main/java/io/github/overrun/mc2d/text/TextColor.java
@@ -0,0 +1,33 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-2021 Over-Run
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.github.overrun.mc2d.text;
+
+/**
+ * @author squid233
+ * @since 2021/01/26
+ */
+public final class TextColor {
+ public static final int WHITE = 0xffffffff;
+}
diff --git a/src/main/java/io/github/overrun/mc2d/util/GlUtils.java b/src/main/java/io/github/overrun/mc2d/util/GlUtils.java
index cbc3830..6855c89 100644
--- a/src/main/java/io/github/overrun/mc2d/util/GlUtils.java
+++ b/src/main/java/io/github/overrun/mc2d/util/GlUtils.java
@@ -25,12 +25,12 @@
package io.github.overrun.mc2d.util;
import org.lwjgl.opengl.GL;
+import org.lwjgl.opengl.GL11;
import java.awt.Color;
import java.nio.ByteBuffer;
-import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL30.glGenerateMipmap;
+import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryUtil.NULL;
/**
@@ -45,20 +45,20 @@ public static void generateMipmap(int target,
int format,
int type,
ByteBuffer pixels) {
+ // If support to generate mipmap, use
if (GL.getCapabilities().glGenerateMipmap != NULL) {
glGenerateMipmap(target);
- } else {
- glTexImage2D(target, 0, components,
- width, height, 0,
- format, type, pixels);
+ }
+ else {
+ glTexImage2D(target, 0, components, width, height, 0, format, type, pixels);
}
}
/**
* Draw a rect.
* If {@code alpha} is {@code true}, you should
- * {@link org.lwjgl.opengl.GL11#glEnable(int) enable}
- * {@link org.lwjgl.opengl.GL11#GL_BLEND blend} before using.
+ * {@link GL11#glEnable(int) enable}
+ * {@link GL11#GL_BLEND blend} before using.
*
* @param x1 The left top coord x.
* @param y1 The left top coord y.
@@ -71,36 +71,30 @@ public static void drawRect(double x1, double y1, double x2, double y2, int colo
glBegin(GL_LINE_STRIP);
Color c = new Color(color, alpha);
if (alpha) {
- glColor4f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f,
- c.getAlpha() / 255f);
+ glColor4f(c);
} else {
- glColor3f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f);
+ glColor3f(c);
}
// Left top
- glVertex2d(x1, y1 - 1);
+ glVertex2d(x1, y1 + 1);
// Left down
glVertex2d(x1 + 1, y2);
// Right down
glVertex2d(x2 - 1, y2);
// Right up
- glVertex2d(x2, y1 - 1);
+ glVertex2d(x2, y1 + 1);
// Origin point
- glVertex2d(x1, y1);
+ glVertex2d(x1, y1 + 1);
glEnd();
}
- public static void drawRect(double x1, double y1, double x2, double y2, Color color) {
- drawRect(x1, y1, x2, y2, color.getRGB(), true);
- }
-
public static void fillRect(double x1, double y1, double x2, double y2, int color, boolean alpha) {
glBegin(GL_QUADS);
Color c = new Color(color, alpha);
if (alpha) {
- glColor4f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f,
- c.getAlpha() / 255f);
+ glColor4f(c);
} else {
- glColor3f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f);
+ glColor3f(c);
}
// Left top
glVertex2d(x1, y1);
@@ -113,18 +107,11 @@ public static void fillRect(double x1, double y1, double x2, double y2, int colo
glEnd();
}
- public static void drawText(int x, int y, String text) {
- TextureDrawer drawer = TextureDrawer.begin(ImageReader.loadTexture("ascii.png"))
- .color4f(1, 1, 1, 1);
- char[] chars = text.toCharArray();
- for (int i = 0; i < chars.length; i++) {
- double texX = (int) chars[i] * .0078125;
- double resultX = x + (i << 4);
- drawer.tex2dVertex2d(texX, 0, resultX, y)
- .tex2dVertex2d(texX, 1, resultX, y - 32)
- .tex2dVertex2d(texX + .0078125, 1, resultX + 16, y - 32)
- .tex2dVertex2d(texX + .0078125, 0, resultX + 16, y);
- }
- drawer.end();
+ public static void glColor4f(Color c) {
+ GL11.glColor4f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f, c.getAlpha() / 255f);
+ }
+
+ public static void glColor3f(Color c) {
+ GL11.glColor3f(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f);
}
}
diff --git a/src/main/java/io/github/overrun/mc2d/util/GlfwUtils.java b/src/main/java/io/github/overrun/mc2d/util/GlfwUtils.java
index 0224b48..4f029c8 100644
--- a/src/main/java/io/github/overrun/mc2d/util/GlfwUtils.java
+++ b/src/main/java/io/github/overrun/mc2d/util/GlfwUtils.java
@@ -25,24 +25,21 @@
package io.github.overrun.mc2d.util;
import static org.lwjgl.glfw.GLFW.*;
-import static org.lwjgl.system.MemoryUtil.NULL;
/**
* @author squid233
* @since 2021/01/10
*/
public final class GlfwUtils {
- public static final long HAND_CURSOR = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
-
public static boolean isKeyPress(int key) {
return glfwGetKey(glfwGetCurrentContext(), key) == GLFW_PRESS;
}
- public static boolean isMousePress(int button) {
- return glfwGetMouseButton(glfwGetCurrentContext(), button) == GLFW_PRESS;
+ public static boolean isKeyRelease(int key) {
+ return glfwGetKey(glfwGetCurrentContext(), key) == GLFW_RELEASE;
}
- public static void setDefaultCursor() {
- glfwSetCursor(glfwGetCurrentContext(), NULL);
+ public static boolean isMousePress(int button) {
+ return glfwGetMouseButton(glfwGetCurrentContext(), button) == GLFW_PRESS;
}
}
diff --git a/src/main/java/io/github/overrun/mc2d/util/TextureDrawer.java b/src/main/java/io/github/overrun/mc2d/util/Identifier.java
similarity index 50%
rename from src/main/java/io/github/overrun/mc2d/util/TextureDrawer.java
rename to src/main/java/io/github/overrun/mc2d/util/Identifier.java
index c0d1321..9e1136f 100644
--- a/src/main/java/io/github/overrun/mc2d/util/TextureDrawer.java
+++ b/src/main/java/io/github/overrun/mc2d/util/Identifier.java
@@ -24,56 +24,57 @@
package io.github.overrun.mc2d.util;
-import static org.lwjgl.opengl.GL11.*;
+import java.util.Objects;
/**
* @author squid233
- * @since 2021/01/11
+ * @since 2021/01/25
*/
-public final class TextureDrawer {
- private static TextureDrawer instance;
- private TextureDrawer() {}
+public final class Identifier {
+ private final String namespace;
+ private final String path;
- /**
- * Starting draw texture.
- * Call {@link TextureDrawer#end()} when end.
- *
- * @param texture The texture id.
- * @return This
- */
- public static TextureDrawer begin(int texture) {
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- ImageReader.bindTexture(texture);
- glBegin(GL_QUADS);
- return instance != null
- ? instance
- : (instance = new TextureDrawer());
+ protected Identifier(String[] id) {
+ if (id.length > 1) {
+ namespace = id[0];
+ path = id[1];
+ } else {
+ namespace = "mc2d";
+ path = id[0];
+ }
}
- public TextureDrawer color4f(float r, float g, float b, float a) {
- glColor4f(r, g, b, a);
- return this;
+ public Identifier(String namespace, String path) {
+ this(new String[]{namespace, path});
}
- public TextureDrawer vertex2d(double x, double y) {
- glVertex2d(x, y);
- return this;
+ public Identifier(String id) {
+ this(id.split(":", 2));
}
- public TextureDrawer tex2dVertex2d(double s, double t, double x, double y) {
- glTexCoord2d(s, t);
- return vertex2d(x, y);
+ public String getNamespace() {
+ return namespace;
}
- public TextureDrawer bind(int texture) {
- end();
- return begin(texture);
+ public String getPath() {
+ return path;
}
- public TextureDrawer end() {
- glEnd();
- return this;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) { return true; }
+ if (o == null || getClass() != o.getClass()) { return false; }
+ Identifier that = (Identifier) o;
+ return Objects.equals(getNamespace(), that.getNamespace()) && Objects.equals(getPath(), that.getPath());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getNamespace(), getPath());
+ }
+
+ @Override
+ public String toString() {
+ return namespace + ":" + path;
}
}
diff --git a/src/main/java/io/github/overrun/mc2d/util/ImageReader.java b/src/main/java/io/github/overrun/mc2d/util/ImageReader.java
index 742c900..f73c7ef 100644
--- a/src/main/java/io/github/overrun/mc2d/util/ImageReader.java
+++ b/src/main/java/io/github/overrun/mc2d/util/ImageReader.java
@@ -24,8 +24,6 @@
package io.github.overrun.mc2d.util;
-import it.unimi.dsi.fastutil.objects.Object2IntMap;
-import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.BufferUtils;
@@ -36,18 +34,13 @@
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
import java.util.function.Consumer;
-import static org.lwjgl.opengl.GL11.*;
-
/**
* @author squid233
* @since 2021/01/07
*/
public final class ImageReader {
- private static final Object2IntMap ID_MAP = new Object2IntOpenHashMap<>(16);
- private static int lastId = -999999;
private static final Logger logger = LogManager.getLogger();
/**
@@ -106,58 +99,6 @@ public static GLFWImage.Buffer readGlfwImg(String path) {
}
}
- public static int loadTexture(String path) {
- return loadTexture(path, GL_NEAREST);
- }
-
- public static int loadTexture(String path, int mode) {
- if (ID_MAP.containsKey(path)) {
- return ID_MAP.getInt(path);
- } else {
- try (MemoryStack stack = MemoryStack.stackPush()) {
- final IntBuffer ib = stack.mallocInt(1);
- glGenTextures(ib);
- final int id = ib.get(0);
- bindTexture(id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode);
- BufferedImage img = read(path);
- if (img == null) {
- ByteBuffer pixels = stack.malloc(16);
- pixels.asIntBuffer().put(new int[]{
- 0xfff800f8, 0xff000000,
- 0xff000000, 0xfff800f8
- });
- GlUtils.generateMipmap(GL_TEXTURE_2D, GL_RGBA, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- } else {
- final int w = img.getWidth();
- final int h = img.getHeight();
- final ByteBuffer pixels = BufferUtils.createByteBuffer(w * h * 4);
- final int[] rawPixels = new int[w * h];
- img.getRGB(0, 0, w, h, rawPixels, 0, w);
- for (int i = 0; i < rawPixels.length; ++i) {
- final int a = rawPixels[i] >> 24 & 255;
- final int r = rawPixels[i] >> 16 & 255;
- final int g = rawPixels[i] >> 8 & 255;
- final int b = rawPixels[i] & 255;
- rawPixels[i] = a << 24 | b << 16 | g << 8 | r;
- }
- pixels.asIntBuffer().put(rawPixels);
- GlUtils.generateMipmap(GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- }
- ID_MAP.put(path, id);
- return id;
- }
- }
- }
-
- public static void bindTexture(int id) {
- if (lastId != id) {
- glBindTexture(GL_TEXTURE_2D, id);
- lastId = id;
- }
- }
-
/**
* Execute some statements with an image.
* Will auto close the buffer.
diff --git a/src/main/java/io/github/overrun/mc2d/util/Utils.java b/src/main/java/io/github/overrun/mc2d/util/Utils.java
index f00c1d0..56dfe18 100644
--- a/src/main/java/io/github/overrun/mc2d/util/Utils.java
+++ b/src/main/java/io/github/overrun/mc2d/util/Utils.java
@@ -37,4 +37,13 @@ public static ByteBuffer putInt(ByteBuffer buffer, int[] values) {
}
return buffer;
}
+
+ public static boolean isParsableNumber(String s) {
+ try {
+ Integer.parseInt(s);
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
}
diff --git a/src/main/resources/ascii.png b/src/main/resources/ascii.png
deleted file mode 100644
index 6c58ecd9e488b4a88f03d1251d075403ede9efe0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1286
zcmV+h1^N1kP)Px#1ZP1_K>z@;j|==^1poj52~bQ_MF0Q*|Ns900048wgK+==00VSVPE-H?0N2V5
zK>z>%32;bRa{vGizyJUazyWI3i3tDz1b0b9K~#8N?Np0y+%ODV`~M$3ks>A8Ns9J>
zZNSb%CGjCA*Ib)lp9cpAZ;SH+I5>D?oEN~s!5ibe01n;_ADY6)rvG=Wzwdbg6!c&)
zRO!e!KCIg(+t$8~xSo!xOO~CNhO8hv(0iUYSOSZAPNZb9jyZ#QcAg~(kU6x?PTfMi
zHWobw$X%iBUhZeeQLx@@o@(rA;CdY~V5njsUEXOr(*BcG7@
zR%pAI6^+bDYI`PuRc;}$So`@F#Yk@a*YN7;_2XQ1;=BNi?H>RVj-M8%qjts=L2vdo
zVk6h{ezI8ROfQ~hG-ob!jxjkJWq?pbo7}og7m$I*IHwNG%r<@td?M76eWB@%z8Bi=
zY3PJ79MTb8aFZ?8oGjLu2h3)x-
zq@(AVPRdBq0h|UvnFmCalrKe4VY665B)8GBtaAcor08Ja&htT09)yz3>yQH$^7ovQ
z+>Y30$KXx4&Z#WrMPuTe5=Bdmi*OX-sCh#kz#J_~}1hAqfL)DvQA=}dRR3S&B{eyt@k{dlrh*1a2@1mQQnn|8u{>>
zI4R#+GCwcGER&&!P_D66?nOhdVC{feI|Jth@Bn;&dbIiE24A0KsU*FyuI*6DdytpG
z0hrF|nmt*MeR4Dw!vd3BWb!INlOtM3-N~YPPM&hRz9VZ2N8M+kEm}PXYv{zF7a+@{
zNxW;{+N8V=m9#ITq`g@ti%ukyc0MW(MMIxKVke~+oEJc0dq5%K;I9%va@m*7F)p~S
zL)&bT4*IM+Fa7RQVodu6zH
zQ%_9316du5vfe8j=kj^Qh&w+TFKXLmvgo##Oq#=fO$F(tMsHGj!Fd4`wg(h49d$E2
z=Clg(Q(T}gtdP1qd~YE*#w6*D)}BE$%BOCWu_U{T^TE1OC#zUKe)UY9dPL%{KkKND@t{m3WYq
zO}1H4fMnYxcAOW$pT@(3|MU1~H+~iMm-{z>n*owP22S3ce)1nNmVb2aikFU`7r?>6
wD|mW){P3+Z)_-_%#jA(U3*g}3ZSnc}8$keeVm)Xd@c;k-07*qoM6N<$f`7AIOaK4?
diff --git a/src/main/resources/icon.png b/src/main/resources/assets/mc2d/icon.png
similarity index 100%
rename from src/main/resources/icon.png
rename to src/main/resources/assets/mc2d/icon.png
diff --git a/src/main/resources/bedrock.png b/src/main/resources/assets/mc2d/textures/block/bedrock.png
similarity index 100%
rename from src/main/resources/bedrock.png
rename to src/main/resources/assets/mc2d/textures/block/bedrock.png
diff --git a/src/main/resources/cobblestone.png b/src/main/resources/assets/mc2d/textures/block/cobblestone.png
similarity index 100%
rename from src/main/resources/cobblestone.png
rename to src/main/resources/assets/mc2d/textures/block/cobblestone.png
diff --git a/src/main/resources/dirt.png b/src/main/resources/assets/mc2d/textures/block/dirt.png
similarity index 100%
rename from src/main/resources/dirt.png
rename to src/main/resources/assets/mc2d/textures/block/dirt.png
diff --git a/src/main/resources/grass_block.png b/src/main/resources/assets/mc2d/textures/block/grass_block.png
similarity index 100%
rename from src/main/resources/grass_block.png
rename to src/main/resources/assets/mc2d/textures/block/grass_block.png
diff --git a/src/main/resources/assets/mc2d/textures/font/ascii.png b/src/main/resources/assets/mc2d/textures/font/ascii.png
new file mode 100644
index 0000000000000000000000000000000000000000..f87a9b58b27111e6c92f3e78793652cc456b01d7
GIT binary patch
literal 1286
zcmV+h1^N1kP)Px#1ZP1_K>z@;j|==^1poj52~bQ_MF0Q*|Ns900048wgK+==00VSVPE-H?0N2V5
zK>z>%32;bRa{vGizW@LZzX3P}QzQTY1b0b9K~#8N?Np0y+%ODV`~M$3ks>A8Ns9J>
zZNSb%CGjCA*Ib)lp9cr;g%3^PW7GdT*5CKM01A3A7^-yS8z0u~lWl9?MqE!v)g{Z$
zOG8$W9q2vJ8!UmvJSS4JSjU{fJUh>l1jroPW~XkUUK@)Z1LUsIb}#oc?%`f<(+!0;D^uA%{dJTlw4G|AlhF4lhtI?-p*YCgt&va2d@How%Zf&3B(*)0z$&*8Sgieg
zi((`<{%d&k^!jnGI&oeA#`X^Y3CB;1(@{HPil8_98nKb(qC
zjWR$eqD^jHrVGeGW1Le5W@a0|1wIjK$-dC^M&Ao<_cU}u7!K)(F1X1SYtNsq)&A4Q
z_we%RIw*2~q4NST_~%K&A3QG@er&~SZ3IHnzECIkz(SM`^tzdC%*8X9t^Wk*xuPir
z*-4LR^dW4d$(_P4+_cI{O+8H=6fWr2CLekOmOebX|=>Sdxpv(gzO3Ifa
zsIXZqA(Go@S=Kp$GE#IfaOe4;C=Wu(=5@#c3;BCaNp44Mvt#fkT<27l@}eXRv)V`!OU_HxZ;bV8lop)XUh3)a+Vamx_
zU4H_?;NFlmw{9@DNxk03z>s65b!~7&oADKPx9f~fpD7$PYNV~RtZn5UYId?{p3$bq
z8(AkYO+Bm{ie}{^uhx4WP0AST2DlD#v?%XNMvZ*zovrpQlmF1z2Lk63flt;nU1;{9&=g+`6({Y7gk7J9=^8_9AlF7
zMr+R?8s$?r%2<-!#ra@esgqSKAHRC0PI5=mb`A!R;4*7!1090^qZDDVPlh?bT+wPY
zi;i7F_7jl$r;nF!Z5xnX1boPgk7k>GUL=X8)JiaC_u995!T)*u
zvm3vP`pf+rz|8>39|I@vPCxmN7|TC8cg0J`&kNw-;1xW*J%0FB8S6hhx#HEs=LK+Z
w@WwbVfP;fK#(4o89K12k3*g}3ZSnc}8>v@zV!=KFga7~l07*qoM6N<$f)jID$p8QV
literal 0
HcmV?d00001
diff --git a/src/main/resources/assets/mc2d/textures/gui/logo.png b/src/main/resources/assets/mc2d/textures/gui/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..e369fcac4fb01529888b1e4282938322505b130c
GIT binary patch
literal 1246
zcmV<41R?v0P)Px#1ZP1_K>z@;j|==^1poj56;Mo6MF0Q*KtMn+Ffbq>Ah)lr;oR2%00240jrsrp
z00(qZPE-H?|NsC002)gJMgRZ+32;bRa{vGi!2kdb!2!6DYwZ941V2ecK~!i%-l_sya;kz01EX#u_$O$?bRx+Q65IVyA1qs0A)YDo3L|C&)uSjnr<>Vw}OWpXVMwPZA2SEr3l
zsbDekISt;o|BX?M;dOP|*pv#Y!B-A>-~JayF~Zl?X=76=D26fD$@}*GDEJQi720gU
zV&(u-ENQCQcwH(eMu?_;DYc`(^hqv{FO$?#r0TWE#zU!~7%oct?!;~sm@&!K@!7<|
z)F^pshL??}Qb93Hl=j%ToY;+G3qWz{1GK4BHycl-f?}9ZaN_`i7zG=!T{co&`T%Vz
z)y>9Jsh}7p6x=v~V2l!R19{jEic24$O{Kcocq$bX!-Rqx2M~P3=YInK%TerAg~dUN
z{~g~Q2c*MFWJ?glF+>eGjb*F{+#bbx`A?FkfX31|4oHWU$d(|8V~83Uy~ldO?NPqJ
z{XOyg4p`$4RyqgOgt=t7FX*g_SUYj?^$(Bo?8ifrik{t!>SkZ7D;rI=eS%J<~nkXW$=g16*JHDPs)z
zQ7zfDXY3j`M!^+Xv)Pd=-z`!ZYj^cxAr-fhJqk>J_;aQ)238$lZxy-8q?;Kn_c~qpu?a
z!^VE@KZ&eBzG#3?h%1o(|NsB7W5+^6L(R?2ySuxABB`6FO9LtPk|4iepeztDNO?26
z0fjgVJR*x382Ao>Fr%o3R|5kBv!JJoV@O5Z+nX1&o)`$Y1p22v{{R2U-LQ4X6{{pu
zI(t_}>$CC-u5EU9xcRMicj>q8o8R6RzK#*SkyrQs_;J@pwhx7mZRTHR;c8g?PLh#D
zpkZ~7D+7o|a2uE(oIhW4DgEE)CAT;EK4Yx;cjEDO-(9-5U4RN7XeA3e0O=LQEHkz~
z+vT}^DT66UV8^Kl76FEa^Xu!k*PqUxePtRqV@0av<`22;cAu{;$vt^DT8+8jl{UBi
zvyG^FfO=oaFs7~DnRh8y)4`WTz=2_%kr*RiL#e*yX0@$Pofz)Lp3|whz3}`V)6D3i
z@6%2)%=vZdP=93(ih7{F1}pc5$n15qOQN{~grQz*U{1K}eQu3s?oNS*^6AFh_sd=w
z=lkB8c4u#@5ySF*n?5AVp{NH1#e#E!3D;)5R=Ycm=?cut4;Ui8PcqI9iq>O!aQEq%
zL)&G4or#{jO|?9KCeMMD>vjIjIF6zoR}fh+T-*EP%q&pwyc1;HQQZv;y#z6a{PpQ#
z``%wlzc*`(?#}AdDGYwKsSoA15FJ$OcWzeuJI!<^Tfub>1qZVOpN$UeyQ)}zF0`Tc
z@q*dUZvEwcaDV;5xt~k>AIALsdE1@A%8cp4M!|-@UWSq!mIcYm46@RUFK%!+9CsT+
gQoa@k_WfsNUmzad(2~Cmm}3|`UHx3vIVCg!0Pcit1^@s6
literal 0
HcmV?d00001
diff --git a/src/main/resources/assets/mc2d/textures/gui/widgets.png b/src/main/resources/assets/mc2d/textures/gui/widgets.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dcfe6d3277813da289321b6c84c5a613d19b994
GIT binary patch
literal 3138
zcmb_ec{r5&9{;{$-)V%V#S~eRL#xm*lr4phgo{wNZeu4~%zLimq{VU)r7Uxl&_b4s
zZBR<7EXg*FWs(|Wr0k`^eRb~g+;i^p+<)%-Jn!@VKJWW|e&6rsyL^7{IXfE*DRF{0
z07zL`?*9=0!IlV!3S$q~kV2mo6#AouDHOM@<6=P2*W{21Kxv8u-%|*~VnLS9p#ah~
zD>t&bVRt8hM6cC;lOvJGJ`UI>t~
ExIy5r6dO!jaU3@rO;f-&wu%c9>DqD2sI3
zbv9``kDynKf6^o=x{-KL`jJoS)?n{v6lu>^nxUM~llZb0viT&jEn0lI(MHWPp5TPf
zIJA9k`ZOc^TF&ia`e3w{+oI8sOx=-ihhEle()7~UNBYu1b*oGF0+8b>R91fS2GZE#
zJaulI+18Um{l*QuWHZof>&wW5tC^Wx5^ht_SeItz9+Acqoc4m0e#Z28`67&FEriu{
z4fMQBkAu4-R?LQh-9C%w%+hu^W*c`9{WFjwxLnJPdt%mL1j-wDyx~i%#J9
zz#4G>>bG!lRbYfWXKEoCs$%8?7Jd%Fz44SfvmTjBO%Y2vBjHJaWK|$lHp*Tk=5h!!0Y=`
z!&SmgVD>?I{gz&wpM}i7om3_vKc_C*DB@fP5Y+QS3DHT=#YAvKV^nQT_|P
z!*AxMX$h)OKRuG>vlJT|+EQCy?z2Rt2dZ=Q^jhogUJ1|G`_z}QmHv7QOPRVj>(6>V
zGo(}J(L>(?rYYOH_{qJMxgz>DOOZ^&LR+swdtO%e3fyJUdG!DW!Q$TzB$`?3>-Vj_?V4i?=-WW>SF;FewXR~
z#xfz6aE5n>-f1xrw{$^fR)C$J8)xV?Ht|)FdQ=n2Vn*|XDGA4hjzHJqzQHZxXhzl;
zb0s1QocVH2g?lL^aGBS=9#Pequu~-{^a#MeO
zdlaE{-*m~*KE7NpbM53{jY(8{@W3(i*ZGDdr@NIU5x*J=+xglW%`OJ&3Zrk%H)9b`
z*e<=h7glUR2xcmgnRBNliEi?wXi(DX^z)xQ9PzDB7SQ8@KvP1{qc5a8)6@4xwQFr5
zY!h`7h(}x3%oa6rDKnxdK@=_;*5ly3+&|4h!yMpz@V?Y*d&JS;N^LMDNTR8xf@DiU
zXzo@KL&FaH4I-&F`&2;p^a7G9yj%
zOz+bR?1%A7CrVE_>V$e#XDi01l#d%^p3mcWd*=qW#1Q!UTb-}OmPD~6YP0XA`HwJK
zwrf@{Q3ja3@|A<*q38SBJIn@s(-xz=V&~@X`?hb`!HD>j}
z-pq0^OAMl#AiCJSA!n<$b_=Bov0L{O^nGj!rNtw0Y83uM%E
zNZIbCAWBM>AS>dbSp7OAO1L9`5Da*75Q4OUmL>+pLQwfSB;aDTa^uWQSXp&7(*@UP
z8F(2VzUnHBw&I@2MF1t3K(s6T=0IEmr(?%#l#RST^){0bdO54bfN4H>eQVlrUVBe=
z>>*EHt5HGXqNLkM>~3bRMUO94rXL^lg@iadI;K@u>le+x)zL9sgj79Annm+t1x3Xh
zGU%|VpezXwog^GBMGW;EN`S{ND$Y!ZiH>^V&=?%f;MKf{{0>C+>#x!vbP(jT$p|sv
zjL@HSa0k-(08kq>s8WDFn-|sFKEy$Jd3j6HTD?v)cw8OI3G0_t%@)xmF2HC84e4mb
zw`rMI9DgBz2kys|Q_jxLRv$PVG1#yD22zDx&-U*-G`10B%lmNXTPnG9JqdkXV0*pj
z&by~6*ELDtN6Qll8tvFvfb*zZ9Vc`(ayUOO>Z2poCWFe-I=u#+p)%iVdesF4W5PjLOTzYP1
z4K!zl$^iL{xBz*M?_87i?%;+hBaj)oCw99F3G0ZmcKyF1+XJY&cN=t>6Au
zpEooQRoee_Cr5bep4Cd%_Q&p`Ndc?y4iRW3UA;KVrumb6XvU`Epsnq7Ql#4q$ku8!
z;AVW9h#1*X9F66%Z%Fe(f9A)&-~WV-QDdK5MbkjXc|j1obnE
zl?U_(!)Q3EH<-zH+-M>Lgu+o|WMEmR1e5|3+>t7EqO5VjHo!{yxJVbiLyUMoUN*74
z1MWv4!#OB9D=P+I*j@?Z=NHQvh@p%JUw`(yZNVd8V+Q=nY;o7wogNR18aq_S?jZiq
zXYMA1fK*<+0+~>6`%XkR=b#Lkz!-nX%M(HS%)YKBX3He3(2zg_#MXmJ`1Col$*KKo
zz}niHVX@1#I%IQZZm!<+MxF|EsJ#+KcUBpUQ-xRkj{k~dKT43`y4E+HrRT18Qh@qd
zIq<_fAVE_jEiE(=*~7ukycnN@b%p!Rbx00Nnz`M;|Z{z
zYQnYsI-r#Ot1$XetYa;ht3=4&r#v2fzPsNu9t|HmAuH>jH>}ZkUoOVFX2Jp2NH@ZP
z|D(g`wc9=F%2l^;)TmtF(N$}cG1*PxYXJHxSRB4ee=lYN
z)SJt7&Y$9k&H`OfP*CWsK4Wih
z&vmtRhA%x90Ih2XV5UCy%xtd_!nXfzH|r>X^GkmH0G=kV-?3Sq$vMD|9jG!Rmc
zfv$lH)|q&k9$Yk^AbKzp8R`C2O~MGT>nV}gk@W~PYL7VnD7O{Dv0aUApest#&qs*y5zHSQM;GABJ6$5p>FpD;gOmg)V;uM5SG3^P!)|W@
zqE{^TVjVX0XSC#i9C|Z2*xrt;iHEebG^{P|-Mg20lD$HEBX(449PJaRikkK@xDvR$
zw8-t>*AxxA#%_qfPA@-9iV9T}C%*`yzAHPXc9sBBYyM`}>KY?h%4!C$Pg(S{b1Nv$
z+(^{&zqJ5?Qe_s8?&4uB;AiOxm)&k_xy^4u>~3Hk;3xVgz9WWpJaW#3j#=b$6A>fm
z2~~xw;0IA)zj`hO?q&%40#@lK*r%&pWX8wk!UpXB{Qq^K$E~KQYUlby*H^K_S2ndW
Mv)Ny4>hZU~17=-K{Qv*}
literal 0
HcmV?d00001
diff --git a/src/main/resources/tab_items.png b/src/main/resources/tab_items.png
deleted file mode 100644
index fbd8aa5bc57330d482d950faf53f1d8464ab1fee..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 714
zcmeAS@N?(olHy`uVBq!ia0vp^hk>|*gBeKX+O0PSQjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`MFV_7T!Hle|NoC2I~E!mYHn`c-Q5ioN!>hM8c4C11o;I6Wr2V}%A45@
zD8yOd5n0T@zz4L6?=a)>{1qt-3{2XdE{-7;ac}1y%xg9fVe!2D;s5-YH~WrehB$yue`5z~)fxT3FU*MI8zH{B_1>l-WWwzFrwVKFahlKypo
zxAsAsU4gUwj)na9r1#lZ9^Lx!Ja^=^r~ZduH@oKpSx0%LFSY92Wmv);xr@<5d{YVY
z1ih4(Yzna_F7Z0-ny^&5p+xbtrgYr?^`Gy*$km*7oVU;{OJ&}PN4G4thMc~zzQFm;
z4bK{_b-L)9yv-S2I!()CKrwyJCdK!EO0Ng$^h-b5a>c`D;?b>zSu3Y4jDOg+W8>r>
zAu-WN)?zgQ>^{p>=X*b2uUi@+XMQAe<-`i5?(D}`f^?ntAL1=cR{ywi$2N$=ahm}4
zVbQ6!J)f_~dT+GJ>$n`G{Lw}1`mvQuquT0Pr5_#hdlX!lt4P2Ea2P$E!dv-#{qAW=
zm3Iu-@?JFmlz#NqQTZdUYmD^rX<3rLMDseNtvmNmx-Nz_bkVKwyE);z-J^A_x~D(g
zGtdH>$0;>$X=3cD(v(yGcjx@Q?Y~3u|8Ur+c-mezEfcD77+py85}Sb4q9e
E0NYtIK>z>%