Skip to content

Commit 1d0d0f7

Browse files
committed
splitscreen(feature): window close button functionality
1 parent a5e1427 commit 1d0d0f7

File tree

8 files changed

+70
-4
lines changed

8 files changed

+70
-4
lines changed

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/SplitscreenPawn.java

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ public interface SplitscreenPawn {
5050
*/
5151
void setWindowFocusState(boolean focused);
5252

53+
/**
54+
* Closes the game.
55+
*/
56+
void closeGame();
57+
5358
/**
5459
* @return the current splitscreen mode of the window
5560
*/

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/client/LocalSplitscreenPawn.java

+5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public void setWindowFocusState(boolean focused) {
5454
this.minecraft.setWindowActive(focused);
5555
}
5656

57+
@Override
58+
public void closeGame() {
59+
this.minecraft.stop();
60+
}
61+
5762
@Override
5863
public SplitscreenPosition getWindowSplitscreenMode() {
5964
return position;

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/client/protocol/PawnPlayPacketListener.java

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public void handleWindowFocusState(PawnboundWindowFocusStatePacket packet) {
5353
this.pawn.setWindowFocusState(packet.focused());
5454
}
5555

56+
public void handleCloseGame(PawnboundCloseGamePacket packet) {
57+
this.pawn.closeGame();
58+
}
59+
5660
public void handleKeepAlive(PawnboundKeepAlivePacket packet) {
5761
this.connection.send(ControllerboundKeepAlivePacket.INSTANCE);
5862
}

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/mixins/core/MinecraftMixin.java

+15
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
import com.mojang.blaze3d.platform.DisplayData;
77
import com.mojang.blaze3d.platform.Window;
88
import dev.isxander.controlify.splitscreen.SplitscreenBootstrapper;
9+
import dev.isxander.controlify.splitscreen.window.ParentWindow;
910
import net.minecraft.client.Minecraft;
1011
import net.minecraft.client.renderer.VirtualScreen;
1112
import org.spongepowered.asm.mixin.Mixin;
1213
import org.spongepowered.asm.mixin.injection.At;
14+
import org.spongepowered.asm.mixin.injection.Inject;
15+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
16+
17+
import java.util.Optional;
1318

1419
@Mixin(Minecraft.class)
1520
public class MinecraftMixin {
@@ -46,4 +51,14 @@ private boolean markWindowReady(Minecraft instance) {
4651
return false;
4752
}).orElse(true);
4853
}
54+
55+
/**
56+
* Ensures the parent window is closed when the game exist.
57+
*/
58+
@Inject(method = "close", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;close()V", shift = At.Shift.AFTER))
59+
private void closeParentWindow(CallbackInfo ci) {
60+
SplitscreenBootstrapper.getController()
61+
.flatMap(controller -> Optional.ofNullable(controller.getParentWindow()))
62+
.ifPresent(ParentWindow::close);
63+
}
4964
}

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/protocol/PlayProtocols.java

+1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ public final class PlayProtocols {
2828
.addPacket(PawnboundParentWindowPacket.TYPE, PawnboundParentWindowPacket.CODEC)
2929
.addPacket(PawnboundSplitscreenPositionPacket.TYPE, PawnboundSplitscreenPositionPacket.CODEC)
3030
.addPacket(PawnboundWindowFocusStatePacket.TYPE, PawnboundWindowFocusStatePacket.CODEC)
31+
.addPacket(PawnboundCloseGamePacket.TYPE, PawnboundCloseGamePacket.CODEC)
3132
).bind(FriendlyByteBuf::new);
3233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dev.isxander.controlify.splitscreen.protocol.pawnbound.play;
2+
3+
import dev.isxander.controlify.splitscreen.client.protocol.PawnPlayPacketListener;
4+
import net.minecraft.network.FriendlyByteBuf;
5+
import net.minecraft.network.codec.StreamCodec;
6+
import net.minecraft.network.protocol.PacketType;
7+
8+
public record PawnboundCloseGamePacket() implements PawnboundPlayPacket {
9+
public static final PawnboundCloseGamePacket INSTANCE = new PawnboundCloseGamePacket();
10+
public static final StreamCodec<FriendlyByteBuf, PawnboundCloseGamePacket> CODEC =
11+
StreamCodec.unit(INSTANCE);
12+
public static final PacketType<PawnboundCloseGamePacket> TYPE =
13+
PawnboundPlayPacket.createType("close_game");
14+
15+
@Override
16+
public void handle(PawnPlayPacketListener handler) {
17+
handler.handleCloseGame(this);
18+
}
19+
20+
@Override
21+
public PacketType<PawnboundCloseGamePacket> type() {
22+
return TYPE;
23+
}
24+
}

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/server/RemoteSplitscreenPawn.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package dev.isxander.controlify.splitscreen.server;
22

33
import dev.isxander.controlify.splitscreen.SplitscreenPawn;
4-
import dev.isxander.controlify.splitscreen.protocol.pawnbound.play.PawnboundJoinServerPacket;
5-
import dev.isxander.controlify.splitscreen.protocol.pawnbound.play.PawnboundParentWindowPacket;
6-
import dev.isxander.controlify.splitscreen.protocol.pawnbound.play.PawnboundSplitscreenPositionPacket;
7-
import dev.isxander.controlify.splitscreen.protocol.pawnbound.play.PawnboundWindowFocusStatePacket;
4+
import dev.isxander.controlify.splitscreen.protocol.pawnbound.play.*;
85
import dev.isxander.controlify.splitscreen.window.SplitscreenPosition;
96
import dev.isxander.controlify.splitscreen.window.manager.NativeWindowHandle;
107
import net.minecraft.network.Connection;
@@ -52,6 +49,11 @@ public void setWindowFocusState(boolean focused) {
5249
this.connection.send(new PawnboundWindowFocusStatePacket(focused));
5350
}
5451

52+
@Override
53+
public void closeGame() {
54+
this.connection.send(new PawnboundCloseGamePacket());
55+
}
56+
5557
@Override
5658
public SplitscreenPosition getWindowSplitscreenMode() {
5759
return this.position;

splitscreen/src/main/java/dev/isxander/controlify/splitscreen/server/SplitscreenController.java

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import dev.isxander.controlify.splitscreen.window.ParentWindowEventHandler;
1313
import dev.isxander.controlify.splitscreen.window.SplitscreenPosition;
1414
import dev.isxander.controlify.splitscreen.window.manager.WindowManager;
15+
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
1516
import net.minecraft.client.Minecraft;
1617
import net.minecraft.client.gui.navigation.ScreenRectangle;
1718
import org.jetbrains.annotations.NotNull;
@@ -85,6 +86,15 @@ public void setupParentWindow(DisplayData screenSize, ScreenManager screenManage
8586
}
8687

8788
this.parentWindow = new ParentWindow(this.minecraft, screenSize, screenManager, this, initialTitle);
89+
90+
executeWhenWindowReady(parentWindow -> {
91+
ClientTickEvents.START_CLIENT_TICK.register(client -> {
92+
if (this.parentWindow.shouldClose() && this.minecraft.isRunning()) {
93+
this.forEachPawn(SplitscreenPawn::closeGame);
94+
}
95+
});
96+
});
97+
8898
}
8999

90100
@Override

0 commit comments

Comments
 (0)