From e83044258593dbd9c0e873a18f3db2a7581c5f97 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 17 Feb 2018 14:06:37 +0100 Subject: [PATCH 1/9] Use a mixin for calling Hooks.draw instead of a @Hook --- .../net/runelite/client/callback/Hooks.java | 7 +++ .../mixins/RSMainBufferProviderMixin.java | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSMainBufferProviderMixin.java diff --git a/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java index 88c6063d4d..31946dd301 100644 --- a/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java @@ -25,6 +25,8 @@ package net.runelite.client.callback; import com.google.common.eventbus.EventBus; +import java.awt.Graphics; +import net.runelite.api.MainBufferProvider; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; @@ -41,6 +43,11 @@ public class Hooks public static EventBus eventBus; + public static void draw(MainBufferProvider mainBufferProvider, Graphics graphics, int x, int y) + { + throw new IllegalStateException(); + } + public static MouseEvent mousePressed(MouseEvent mouseEvent) { throw new RuntimeException(); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSMainBufferProviderMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSMainBufferProviderMixin.java new file mode 100644 index 0000000000..ceb9a0cfac --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSMainBufferProviderMixin.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import java.awt.Graphics; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; +import net.runelite.client.callback.Hooks; +import net.runelite.rs.api.RSMainBufferProvider; + +@Mixin(RSMainBufferProvider.class) +public abstract class RSMainBufferProviderMixin implements RSMainBufferProvider +{ + /** + * Replacing this method makes it so we can completely + * control when/what is drawn on the game's canvas, + * as the method that is replaced draws + * the game's image on the canvas. + */ + @Replace("draw") + final void draw(Graphics graphics, int x, int y) + { + Hooks.draw(this, graphics, x, y); + } +} From 725762460a1222e7404f2003ff442fd9a7006546 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:38:48 +0100 Subject: [PATCH 2/9] Move the 765x503 constants to a Constants API class --- .../main/java/net/runelite/api/Constants.java | 36 +++++++++++++++++++ .../client/config/RuneLiteConfig.java | 3 +- .../net/runelite/client/ui/ClientPanel.java | 12 +++---- 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/Constants.java diff --git a/runelite-api/src/main/java/net/runelite/api/Constants.java b/runelite-api/src/main/java/net/runelite/api/Constants.java new file mode 100644 index 0000000000..9dd6844e5c --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/Constants.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +import java.awt.Dimension; + +public class Constants +{ + public static final int GAME_FIXED_WIDTH = 765; + public static final int GAME_FIXED_HEIGHT = 503; + public static final Dimension GAME_FIXED_SIZE = new Dimension(GAME_FIXED_WIDTH, GAME_FIXED_HEIGHT); + public static final double GAME_FIXED_ASPECT_RATIO = (double) GAME_FIXED_WIDTH / (double) GAME_FIXED_HEIGHT; +} diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 471570c193..deb2acaed8 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -25,6 +25,7 @@ package net.runelite.client.config; import java.awt.Dimension; +import net.runelite.api.Constants; @ConfigGroup( keyName = "runelite", @@ -40,7 +41,7 @@ public interface RuneLiteConfig extends Config ) default Dimension gameSize() { - return new Dimension(765, 503); + return Constants.GAME_FIXED_SIZE; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java index 92336b67ba..da2b287a34 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java @@ -27,22 +27,20 @@ package net.runelite.client.ui; import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Dimension; import javax.annotation.Nullable; import javax.swing.JPanel; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.Constants; @Slf4j final class ClientPanel extends JPanel { - public static final int PANEL_WIDTH = 765, PANEL_HEIGHT = 503; - public ClientPanel(@Nullable Applet client) { - setSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); - setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); - setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); + setSize(Constants.GAME_FIXED_SIZE); + setMinimumSize(Constants.GAME_FIXED_SIZE); + setPreferredSize(Constants.GAME_FIXED_SIZE); setLayout(new BorderLayout()); setBackground(Color.black); @@ -52,7 +50,7 @@ final class ClientPanel extends JPanel } client.setLayout(null); - client.setSize(PANEL_WIDTH, PANEL_HEIGHT); + client.setSize(Constants.GAME_FIXED_SIZE); client.init(); client.start(); From 22f931a438c6da99ea7738391e08c79bc915069f Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:39:59 +0100 Subject: [PATCH 3/9] Add a mixin for storing stretched fixed mode setting states --- .../main/java/net/runelite/api/Client.java | 13 +++ .../mixins/StretchedFixedModeMixin.java | 106 ++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index f522c706f0..a076d8ef4d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -25,6 +25,7 @@ package net.runelite.api; import java.awt.Canvas; +import java.awt.Dimension; import java.util.List; import java.util.Map; import net.runelite.api.widgets.Widget; @@ -295,4 +296,16 @@ public interface Client extends GameEngine void setCameraPitchRelaxerEnabled(boolean enabled); RenderOverview getRenderOverview(); + + boolean isStretchedEnabled(); + + void setStretchedEnabled(boolean state); + + boolean isStretchedFast(); + + void setStretchedFast(boolean state); + + void setStretchedKeepAspectRatio(boolean state); + + Dimension getStretchedDimensions(); } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java new file mode 100644 index 0000000000..c6c5ff2173 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import java.awt.Canvas; +import java.awt.Dimension; +import net.runelite.api.Constants; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSClient; + +@Mixin(RSClient.class) +public abstract class StretchedFixedModeMixin implements RSClient +{ + @Inject + private static boolean stretchedEnabled; + + @Inject + private static boolean stretchedFast; + + @Inject + private static boolean stretchedKeepAspectRatio; + + @Inject + @Override + public boolean isStretchedEnabled() + { + return stretchedEnabled; + } + + @Inject + @Override + public void setStretchedEnabled(boolean state) + { + stretchedEnabled = state; + } + + @Inject + @Override + public boolean isStretchedFast() + { + return stretchedFast; + } + + @Inject + @Override + public void setStretchedFast(boolean state) + { + stretchedFast = state; + } + + @Inject + @Override + public void setStretchedKeepAspectRatio(boolean state) + { + stretchedKeepAspectRatio = state; + } + + @Inject + @Override + public Dimension getStretchedDimensions() + { + Canvas canvas = getCanvas(); + + int newWidth = canvas.getWidth(); + int newHeight = canvas.getHeight(); + + if (stretchedKeepAspectRatio) + { + int tempNewWidth = (int) (newHeight * Constants.GAME_FIXED_ASPECT_RATIO); + + if (tempNewWidth > canvas.getWidth()) + { + newHeight = (int) (newWidth / Constants.GAME_FIXED_ASPECT_RATIO); + } + else + { + newWidth = tempNewWidth; + } + } + + return new Dimension(newWidth, newHeight); + } +} From 4e198b6e0ea616fa39ff179e5bf59837b654b64d Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:41:21 +0100 Subject: [PATCH 4/9] Add logic for game image stretching in Hooks#draw Cache stretched dimensions and image Fix rendering hint not being set until you resize window --- .../net/runelite/client/callback/Hooks.java | 46 ++++++++++++++++++- .../mixins/StretchedFixedModeMixin.java | 37 ++++++++++----- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 0106907433..78ecfc56fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -26,8 +26,10 @@ package net.runelite.client.callback; import com.google.common.eventbus.EventBus; import com.google.inject.Injector; +import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; @@ -83,6 +85,10 @@ public class Hooks private static final DeathChecker death = new DeathChecker(client, eventBus); private static final GameTick tick = new GameTick(); + private static Dimension lastStretchedDimensions; + private static BufferedImage stretchedImage; + private static Graphics2D stretchedGraphics; + private static long lastCheck; public static void clientMainLoop(Client client, boolean arg1) @@ -204,7 +210,12 @@ public class Hooks public static void draw(MainBufferProvider mainBufferProvider, Graphics graphics, int x, int y) { - final BufferedImage image = (BufferedImage) mainBufferProvider.getImage(); + if (graphics == null) + { + return; + } + + BufferedImage image = (BufferedImage) mainBufferProvider.getImage(); final Graphics2D graphics2d = (Graphics2D) image.getGraphics(); try @@ -216,6 +227,39 @@ public class Hooks log.warn("Error during overlay rendering", ex); } + // Stretch the game image if the user has that enabled + if (!client.isResized() && client.isStretchedEnabled()) + { + Dimension stretchedDimensions = client.getStretchedDimensions(); + + if (lastStretchedDimensions == null || !lastStretchedDimensions.equals(stretchedDimensions)) + { + /* + Reuse the resulting image instance to avoid creating an extreme amount of objects + */ + stretchedImage = new BufferedImage(stretchedDimensions.width, stretchedDimensions.height, BufferedImage.TYPE_INT_RGB); + + if (stretchedGraphics != null) + { + stretchedGraphics.dispose(); + } + stretchedGraphics = (Graphics2D) stretchedImage.getGraphics(); + + lastStretchedDimensions = stretchedDimensions; + } + + stretchedGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + client.isStretchedFast() + ? RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR + : RenderingHints.VALUE_INTERPOLATION_BILINEAR); + stretchedGraphics.drawImage(image, 0, 0, stretchedDimensions.width, stretchedDimensions.height, null); + + image = stretchedImage; + } + + // Draw the image onto the game canvas + graphics.drawImage(image, 0, 0, client.getCanvas()); + renderer.provideScreenshot(image); } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java index c6c5ff2173..3550defaa6 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedFixedModeMixin.java @@ -43,6 +43,12 @@ public abstract class StretchedFixedModeMixin implements RSClient @Inject private static boolean stretchedKeepAspectRatio; + @Inject + private static Dimension cachedStretchedDimensions; + + @Inject + private static Dimension lastCanvasDimensions; + @Inject @Override public boolean isStretchedEnabled() @@ -76,6 +82,7 @@ public abstract class StretchedFixedModeMixin implements RSClient public void setStretchedKeepAspectRatio(boolean state) { stretchedKeepAspectRatio = state; + cachedStretchedDimensions = null; } @Inject @@ -84,23 +91,29 @@ public abstract class StretchedFixedModeMixin implements RSClient { Canvas canvas = getCanvas(); - int newWidth = canvas.getWidth(); - int newHeight = canvas.getHeight(); + int width = canvas.getWidth(); + int height = canvas.getHeight(); - if (stretchedKeepAspectRatio) + if (cachedStretchedDimensions == null || width != lastCanvasDimensions.width || height != lastCanvasDimensions.height) { - int tempNewWidth = (int) (newHeight * Constants.GAME_FIXED_ASPECT_RATIO); + if (stretchedKeepAspectRatio) + { + int tempNewWidth = (int) (height * Constants.GAME_FIXED_ASPECT_RATIO); - if (tempNewWidth > canvas.getWidth()) - { - newHeight = (int) (newWidth / Constants.GAME_FIXED_ASPECT_RATIO); - } - else - { - newWidth = tempNewWidth; + if (tempNewWidth > canvas.getWidth()) + { + height = (int) (width / Constants.GAME_FIXED_ASPECT_RATIO); + } + else + { + width = tempNewWidth; + } } + + cachedStretchedDimensions = new Dimension(width, height); + lastCanvasDimensions = new Dimension(width, height); } - return new Dimension(newWidth, newHeight); + return cachedStretchedDimensions; } } From d1d45eb11fa46bbe8c8f271f3960a44f3e042ff1 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:44:12 +0100 Subject: [PATCH 5/9] Modify the size and location of the game canvas if stretched is enabled --- .../runelite/mixins/RSGameCanvasMixin.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameCanvasMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameCanvasMixin.java index b2b33d5354..8e160ceb69 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameCanvasMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameCanvasMixin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Abex + * Copyright (c) 2018, Lotto * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,11 +29,16 @@ import java.awt.Canvas; import java.awt.event.FocusListener; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSGameCanvas; @Mixin(RSGameCanvas.class) public abstract class RSGameCanvasMixin extends Canvas implements RSGameCanvas { + @Shadow("clientInstance") + private static RSClient client; + // This is inverted because it is false initialized. @Inject private static boolean shouldNotHaveFocus; @@ -56,4 +62,32 @@ public abstract class RSGameCanvasMixin extends Canvas implements RSGameCanvas this.requestFocusInWindow(); } } + + @Inject + @Override + public void setSize(int width, int height) + { + if (!client.isResized() && client.isStretchedEnabled()) + { + super.setSize(getParent().getWidth(), getParent().getHeight()); + } + else + { + super.setSize(width, height); + } + } + + @Inject + @Override + public void setLocation(int x, int y) + { + if (!client.isResized() && client.isStretchedEnabled()) + { + super.setLocation(0, 0); + } + else + { + super.setLocation(x, y); + } + } } From d0aa72f61bc47c6e56df91759715c0980d5ce05a Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:44:56 +0100 Subject: [PATCH 6/9] Add support for proxying mouseWheelMoved events --- .../src/main/java/net/runelite/client/callback/Hooks.java | 4 ++-- .../main/java/net/runelite/client/input/MouseManager.java | 5 +++-- .../net/runelite/client/input/MouseWheelListener.java | 8 +++++++- .../src/main/java/net/runelite/client/callback/Hooks.java | 2 +- .../net/runelite/mixins/RSMouseWheelHandlerMixin.java | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 78ecfc56fc..cc97cc2313 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -188,9 +188,9 @@ public class Hooks return mouseManager.processMouseMoved(mouseEvent); } - public static void mouseWheelMoved(MouseWheelEvent event) + public static MouseWheelEvent mouseWheelMoved(MouseWheelEvent event) { - mouseManager.processMouseWheelMoved(event); + return mouseManager.processMouseWheelMoved(event); } public static void keyPressed(KeyEvent keyEvent) diff --git a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java index dbb8bd3695..348899e127 100644 --- a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java +++ b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java @@ -125,11 +125,12 @@ public class MouseManager return mouseEvent; } - public void processMouseWheelMoved(MouseWheelEvent mouseWheelEvent) + public MouseWheelEvent processMouseWheelMoved(MouseWheelEvent mouseWheelEvent) { for (MouseWheelListener mouseWheelListener : mouseWheelListeners) { - mouseWheelListener.mouseWheelMoved(mouseWheelEvent); + mouseWheelEvent = mouseWheelListener.mouseWheelMoved(mouseWheelEvent); } + return mouseWheelEvent; } } diff --git a/runelite-client/src/main/java/net/runelite/client/input/MouseWheelListener.java b/runelite-client/src/main/java/net/runelite/client/input/MouseWheelListener.java index f0c6775510..060b3814de 100644 --- a/runelite-client/src/main/java/net/runelite/client/input/MouseWheelListener.java +++ b/runelite-client/src/main/java/net/runelite/client/input/MouseWheelListener.java @@ -24,6 +24,12 @@ */ package net.runelite.client.input; -public interface MouseWheelListener extends java.awt.event.MouseWheelListener +import java.awt.event.MouseWheelEvent; + +public abstract class MouseWheelListener { + public MouseWheelEvent mouseWheelMoved(MouseWheelEvent event) + { + return event; + } } diff --git a/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java index 31946dd301..5f5e3205d0 100644 --- a/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-mixins/src/main/java/net/runelite/client/callback/Hooks.java @@ -83,7 +83,7 @@ public class Hooks throw new RuntimeException(); } - public static void mouseWheelMoved(MouseWheelEvent event) + public static MouseWheelEvent mouseWheelMoved(MouseWheelEvent event) { throw new RuntimeException(); } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSMouseWheelHandlerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSMouseWheelHandlerMixin.java index a906f069f8..3f167a5721 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSMouseWheelHandlerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSMouseWheelHandlerMixin.java @@ -41,7 +41,7 @@ public abstract class RSMouseWheelHandlerMixin implements RSMouseWheelHandler @Replace("mouseWheelMoved") public void mouseWheelMoved(MouseWheelEvent event) { - Hooks.mouseWheelMoved(event); + event = Hooks.mouseWheelMoved(event); if (!event.isConsumed()) { rs$mouseWheelMoved(event); From 6da6307d503921c6e812d4401a59f4d8bd453fe3 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:46:12 +0100 Subject: [PATCH 7/9] Add support for specifying the position to insert mouse listeners in --- .../java/net/runelite/client/input/MouseManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java index 348899e127..ba1e3b80e8 100644 --- a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java +++ b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java @@ -44,6 +44,11 @@ public class MouseManager } } + public void registerMouseListener(int position, MouseListener mouseListener) + { + mouseListeners.add(position, mouseListener); + } + public void unregisterMouseListener(MouseListener mouseListener) { mouseListeners.remove(mouseListener); @@ -57,6 +62,11 @@ public class MouseManager } } + public void registerMouseWheelListener(int position, MouseWheelListener mouseWheelListener) + { + mouseWheelListeners.add(position, mouseWheelListener); + } + public void unregisterMouseWheelListener(MouseWheelListener mouseWheelListener) { mouseWheelListeners.remove(mouseWheelListener); From e0e0b850930366db89084d4d4cfa1e1d9581b353 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:47:42 +0100 Subject: [PATCH 8/9] Add mouse listeners that stretch event x/y Don't use Provider for getting client instance --- .../TranslateMouseListener.java | 104 ++++++++++++++++++ .../TranslateMouseWheelListener.java | 68 ++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseWheelListener.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseListener.java new file mode 100644 index 0000000000..3df2fbd4b9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseListener.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.stretchedfixedmode; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.MouseEvent; +import javax.inject.Inject; +import javax.inject.Provider; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.client.input.MouseListener; + +public class TranslateMouseListener extends MouseListener +{ + private final Client client; + + @Inject + public TranslateMouseListener(Client client) + { + this.client = client; + } + + @Override + public MouseEvent mouseClicked(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mousePressed(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mouseReleased(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mouseEntered(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mouseExited(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mouseDragged(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + @Override + public MouseEvent mouseMoved(MouseEvent mouseEvent) + { + return translateEvent(mouseEvent); + } + + private MouseEvent translateEvent(MouseEvent e) + { + if (!client.isResized()) + { + Dimension stretchedDimensions = client.getStretchedDimensions(); + + int newX = (int) (e.getX() / (stretchedDimensions.width / (double) Constants.GAME_FIXED_WIDTH)); + int newY = (int) (e.getY() / (stretchedDimensions.height / (double) Constants.GAME_FIXED_HEIGHT)); + + return new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), + newX, newY, e.getClickCount(), e.isPopupTrigger()); + } + + return e; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseWheelListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseWheelListener.java new file mode 100644 index 0000000000..8c9d556952 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/TranslateMouseWheelListener.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.stretchedfixedmode; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.MouseWheelEvent; +import javax.inject.Inject; +import javax.inject.Provider; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.client.input.MouseWheelListener; + +public class TranslateMouseWheelListener extends MouseWheelListener +{ + private final Client client; + + @Inject + public TranslateMouseWheelListener(Client client) + { + this.client = client; + } + + @Override + public MouseWheelEvent mouseWheelMoved(MouseWheelEvent event) + { + return translateEvent(event); + } + + private MouseWheelEvent translateEvent(MouseWheelEvent e) + { + if (!client.isResized()) + { + Dimension stretchedDimensions = client.getStretchedDimensions(); + + int newX = (int) (e.getX() / (stretchedDimensions.width / (double) Constants.GAME_FIXED_WIDTH)); + int newY = (int) (e.getY() / (stretchedDimensions.height / (double) Constants.GAME_FIXED_HEIGHT)); + + return new MouseWheelEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), newX, newY, + e.getClickCount(), e.isPopupTrigger(), e.getScrollType(), e.getScrollAmount(), e.getWheelRotation()); + } + + return e; + } +} From 1acaeb4826a339da24431b02203cfcd5aa1ac3e5 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 3 Mar 2018 00:47:55 +0100 Subject: [PATCH 9/9] Add stretched fixed mode plugin --- .../StretchedFixedModeConfig.java | 58 ++++++++++ .../StretchedFixedModePlugin.java | 100 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModeConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModePlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModeConfig.java new file mode 100644 index 0000000000..d263140651 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModeConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.stretchedfixedmode; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = "stretchedfixedmode", + name = "Stretched Fixed Mode", + description = "Resizes the game while in fixed mode" +) +public interface StretchedFixedModeConfig extends Config +{ + @ConfigItem( + keyName = "keepAspectRatio", + name = "Keep aspect ratio", + description = "Keeps the aspect ratio when stretching" + ) + default boolean keepAspectRatio() + { + return false; + } + + @ConfigItem( + keyName = "increasedPerformance", + name = "Increased performance mode", + description = "Uses a fast algorithm when stretching, lowering quality but increasing performance" + ) + default boolean increasedPerformance() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModePlugin.java new file mode 100644 index 0000000000..f84f36690f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedfixedmode/StretchedFixedModePlugin.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.stretchedfixedmode; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.input.MouseManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "Stretched Fixed Mode", + enabledByDefault = false +) +public class StretchedFixedModePlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private StretchedFixedModeConfig config; + + @Inject + private MouseManager mouseManager; + + @Inject + private TranslateMouseListener mouseListener; + + @Inject + private TranslateMouseWheelListener mouseWheelListener; + + @Provides + StretchedFixedModeConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(StretchedFixedModeConfig.class); + } + + @Override + protected void startUp() + { + mouseManager.registerMouseListener(0, mouseListener); + mouseManager.registerMouseWheelListener(0, mouseWheelListener); + + client.setStretchedEnabled(true); + updateConfig(); + } + + @Override + protected void shutDown() throws Exception + { + client.setStretchedEnabled(false); + + mouseManager.unregisterMouseListener(mouseListener); + mouseManager.unregisterMouseWheelListener(mouseWheelListener); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!event.getGroup().equals("stretchedfixedmode")) + { + return; + } + + updateConfig(); + } + + private void updateConfig() + { + client.setStretchedKeepAspectRatio(config.keepAspectRatio()); + client.setStretchedFast(config.increasedPerformance()); + } +}