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 children(); + + default Optional hoveredElement(int mouseX, int mouseY) { + Iterator 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 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 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:

+ *
    + *
  1. {@link TextureManager#bindTexture(Identifier) Bind texture}
  2. + *
  3. {@link DrawableHelper#drawTexture(int, int, int, int, int, int) Draw texture}
  4. + *
+ * + * @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>%