Compare commits

..

3 Commits

17 changed files with 558 additions and 324 deletions

View File

@ -1,179 +1,114 @@
plugins {
id 'java'
id 'idea'
id 'eclipse'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'net.neoforged.moddev.legacyforge' version '2.0.103'
id 'net.neoforged.gradle' version '[6.0.18,6.2)'
id 'org.spongepowered.mixin' version '0.7.+'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
}
apply plugin: 'org.spongepowered.mixin'
// Only add ProGuard if building with it
def enableProguard = project.hasProperty("enableProguard") && project.enableProguard.toBoolean()
if (enableProguard) {
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.guardsquare:proguard-gradle:7.7.0'
}
}
}
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
base {
archivesName = mod_id
}
group = mod_group_id
version = "${minecraft_version}-${mod_version}"
version = mod_version
group = maven_group // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = archives_base_name
// set java version
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
println "Java: ${System.getProperty 'java.version'}"
// required for making a functional mod
sourceSets.main.resources.srcDirs += 'src/generated/resources'
mixin.add sourceSets.main, "webdisplays.refmap.json"
repositories {
mavenCentral()
maven { url = "https://libraries.minecraft.net/" }
maven { url = "https://cursemaven.com" }
maven { url = "https://maven.parchmentmc.org" }
maven { url = 'https://mcef-download.cinemamod.com/repositories/releases/' }
maven { url = "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/" }
maven { url = "https://maven.theillusivec4.top/" }
maven { url = "https://repo.lucko.me/" }
maven { url = "https://maven.kosmx.dev/" }
maven { url = "https://modmaven.dev" }
flatDir { dir "libs" }
}
// neoforge gradle
minecraft {
mappings channel: 'parchment', version: '2023.06.26-1.20.1'
legacyForge {
version = "${minecraft_version}-${forge_version}"
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Access transformer
accessTransformers = files("src/main/resources/META-INF/accesstransformer.cfg")
// Parchment mappings
parchment {
minecraftVersion = minecraft_version
mappingsVersion = mapping_lasting_version
}
copyIdeResources = true
runs {
configureEach {
systemProperty 'forge.logging.console.level', 'debug'
logLevel = org.slf4j.event.Level.DEBUG
}
client {
client()
programArgument "-mixin.config=${mod_id}.mixins.json"
systemProperty 'mixin.debug.export', 'true'
properties 'mixin.env.remapRefMap': 'true'
property 'mixin.env.refMapRemappingFile', "${project.projectDir}/build/createSrgToMcp/output.srg"
workingDirectory project.file('run')
arg "-mixin.config=webdisplays.mixins.json"
property 'forge.logging.console.level', 'debug'
mods {
webdisplays {
source sourceSets.main
}
}
}
server {
server()
programArgument "-mixin.config=${mod_id}.mixins.json"
properties 'mixin.env.remapRefMap': 'true'
property 'mixin.env.refMapRemappingFile', "${project.projectDir}/build/createSrgToMcp/output.srg"
workingDirectory project.file('run')
arg "-mixin.config=webdisplays.mixins.json"
property 'forge.logging.console.level', 'debug'
mods {
webdisplays {
source sourceSets.main
}
}
}
data {
data()
programArguments.addAll '--mod', mod_id, '--all',
'--output', file('src/generated/resources/').absolutePath,
'--existing', file('src/main/resources/').absolutePath
}
}
mods {
"${mod_id}" {
sourceSet sourceSets.main
workingDirectory project.file('run')
properties 'mixin.env.remapRefMap': 'true'
property 'mixin.env.refMapRemappingFile', "${project.projectDir}/build/createSrgToMcp/output.srg"
property 'forge.logging.console.level', 'debug'
args '--mod', 'webdisplays', '--all', '--output', file('src/generated/resources/'), '--existing', sourceSets.main.resources.srcDirs[0]
mods {
webdisplays {
source sourceSets.main
}
}
}
}
}
sourceSets.main.resources {
srcDir 'src/generated/resources'
repositories{
maven {
name = "cursemaven"
url = "https://www.cursemaven.com"
}
maven { url 'https://mcef-download.cinemamod.com/repositories/releases/' }
flatDir name: 'libs', dirs: 'libs'
}
dependencies {
// MCEF dependency
modImplementation("com.cinemamod:mcef-forge:2.1.1-1.20.1") {
minecraft 'net.neoforged:forge:1.20.1-47.1.65'
annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
// useful for debugging performance problems
implementation fg.deobf("curse.maven:spark-361579:4381167")
// here because we need to manually open the VR keyboard
compileOnly fg.deobf("curse.maven:vivecraft-667903:4794431")
implementation fg.deobf("com.cinemamod:mcef-forge:2.1.5-1.20.1") {
transitive = false
}
// Optional mods (make sure versions exist)
modRuntimeOnly "curse.maven:spark-361579:4738952"
modCompileOnly "curse.maven:vivecraft-667903:4794431"
modImplementation "software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}"
modCompileOnly "top.theillusivec4.curios:curios-forge:${curios_version}:api"
modRuntimeOnly "top.theillusivec4.curios:curios-forge:${curios_version}"
// Mixin Extras
compileOnly annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")
modImplementation "io.github.llamalad7:mixinextras-forge:0.4.1"
}
tasks.named('jar', Jar) {
// jar meta-info
jar {
manifest {
attributes([
'Specification-Title': mod_name,
'Specification-Vendor': mod_authors,
'Specification-Version': '1',
'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Implementation-Vendor': mod_authors,
'MixinConfigs': "${mod_id}.mixins.json"
"Specification-Title": "WebDisplays",
"Specification-Vendor": "CinemaMod Group",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": project.version,
"Implementation-Vendor": "CinemaMod Group",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "webdisplays.mixins.json"
])
}
// Exclude ProGuard renamed files if ProGuard is used
if (enableProguard) {
exclude 'META-INF/versions/**'
}
}
// Generate sources jar
tasks.register('sourcesJar', Jar) {
dependsOn classes
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
// Reobfuscation handling
tasks.named('reobfJar') {
if (enableProguard) {
dependsOn 'proguard'
input = file("${buildDir}/libs/${mod_id}-${minecraft_version}-${mod_version}-proguard.jar")
} else {
dependsOn 'jar'
input = tasks.jar.archiveFile.get().asFile
}
}
// ProGuard configuration (if enabled)
if (enableProguard) {
tasks.register('proguard', proguard.gradle.ProGuardTask) {
dependsOn tasks.jar
configuration 'proguard.pro'
libraryjars "${System.getProperty('java.home')}/jmods"
def inputJar = tasks.jar.archiveFile.get().asFile
injars inputJar
outjars "${buildDir}/libs/${mod_id}-${minecraft_version}-${mod_version}-proguard.jar"
}
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId = mod_id
artifact reobfJar
artifact sourcesJar
}
}
repositories {
maven {
name = "local"
url = layout.buildDirectory.dir("repo")
}
}
}

View File

@ -1,36 +1,5 @@
# Gradle settings
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.caching=true
# ProGuard
enableProguard=false
# Mod properties
mod_id=webdisplays
mod_name=WebDisplays
mod_version=2.0.3
mod_group_id=com.cinemamod
mod_authors=CinemaMod Group
mod_description=Web browser displays for Minecraft
mod_license=All Rights Reserved
mod_credits=CinemaMod Group
# Minecraft/Forge versions
minecraft_version=1.20.1
forge_version=47.3.4
minecraft_version_range=[1.20.1,1.21)
forge_version_range=[47,)
loader_version_range=[47,)
# Parchment mappings
mapping_channel=parchment
mapping_version=2023.09.03-1.20.1
mapping_lasting_version=2023.09.03
# Other mod versions
jei_version=15.20.0.112
player_anim_version=1.0.2-rc1+1.20
geckolib_version=4.2.1
curios_version=5.5.0+1.20.1
# Done to increase the memory available to gradle.
org.gradle.jvmargs = -Xmx3G
mod_version = 2.0.2-1.20.1
maven_group = com.cinemamod
archives_base_name = webdisplays

Binary file not shown.

View File

@ -1,11 +1,28 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
maven { url = 'https://maven.neoforged.net/releases' }
maven {
name = 'NeoForged'
url = 'https://maven.neoforged.net/releases'
}
maven { url = 'https://maven.parchmentmc.org' } // Add this line
}
// resolutionStrategy {
// eachPlugin {
// switch (requested.id.toString()) {
// case "net.minecraftforge.gradle": {
// useModule("${requested.id}:ForgeGradle:${requested.version}")
// break
// }
// case "org.spongepowered.mixin": {
// useModule("org.spongepowered:mixingradle:${requested.version}")
// break;
// }
// }
// }
// }
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0'
}

View File

@ -21,7 +21,6 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.multiplayer.ClientAdvancements;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
@ -62,6 +61,7 @@ import net.minecraftforge.network.NetworkEvent;
import net.montoyo.wd.SharedProxy;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.block.ScreenBlock;
import net.montoyo.wd.client.audio.WDAudioHandler;
import net.montoyo.wd.client.gui.*;
import net.montoyo.wd.client.gui.loading.GuiLoader;
import net.montoyo.wd.client.renderers.*;
@ -287,6 +287,7 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis
}
);
MCEF.getClient().addAudioHandler(WDAudioHandler.INSTANCE);
MCEF.getClient().addDisplayHandler(DisplayHandler.INSTANCE);
MCEF.getClient().getHandle().addMessageRouter(CefMessageRouter.create(WDRouter.INSTANCE));
@ -590,9 +591,7 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis
if (!tes.isLoaded())
tes.load();
} else {
EntityRenderDispatcher entityRenderDispatcher = mc.getEntityRenderDispatcher();
if (entityRenderDispatcher == null) return;
Camera camera = entityRenderDispatcher.camera;
Camera camera = mc.getEntityRenderDispatcher().camera;
Entity entity = null;
// ide inspection says this is a bunch of constant expressions

View File

@ -0,0 +1,84 @@
package net.montoyo.wd.client.audio;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.utilities.Log;
import org.cef.browser.CefBrowser;
import org.cef.handler.CefAudioHandler;
import org.cef.misc.CefAudioParameters;
import org.cef.misc.DataPointer;
public class WDAudioHandler implements CefAudioHandler {
public static final WDAudioHandler INSTANCE = new WDAudioHandler();
@Override
public boolean getAudioParameters(CefBrowser cefBrowser, CefAudioParameters cefAudioParameters) {
ClientProxy proxy = ((ClientProxy) WebDisplays.PROXY);
boolean didParameterize = false;
for (ScreenBlockEntity tes : proxy.getScreens()) {
WDAudioSource source = tes.getSoundSource(cefBrowser);
if (source != null) {
source.parameterize(cefAudioParameters);
didParameterize = true;
}
}
return didParameterize;
}
@Override
public void onAudioStreamStarted(CefBrowser cefBrowser, CefAudioParameters cefAudioParameters, int channels) {
ClientProxy proxy = ((ClientProxy) WebDisplays.PROXY);
if (cefAudioParameters == null) return;
for (ScreenBlockEntity tes : proxy.getScreens()) {
WDAudioSource source = tes.getSoundSource(cefBrowser);
if (source != null) {
source.parameterize(channels, cefAudioParameters);
}
}
}
//
// Called on the audio stream thread when a PCM packet is received for the
// stream. |data| is an array representing the raw PCM data as a floating
// point type, i.e. 4-byte value(s). |frames| is the number of frames in the
// PCM packet. |pts| is the presentation timestamp (in milliseconds since the
// Unix Epoch) and represents the time at which the decompressed packet
// should be presented to the user. Based on |frames| and the
// |channel_layout| value passed to OnAudioStreamStarted you can calculate
// the size of the |data| array in bytes.
//
@Override
public void onAudioStreamPacket(CefBrowser cefBrowser, DataPointer pointer, int frames, long pts) {
ClientProxy proxy = ((ClientProxy) WebDisplays.PROXY);
for (ScreenBlockEntity tes : proxy.getScreens()) {
WDAudioSource source = tes.getSoundSource(cefBrowser);
if (source != null) {
source.audioStream.setData(pointer);
}
}
}
@Override
public void onAudioStreamStopped(CefBrowser cefBrowser) {
}
@Override
public void onAudioStreamError(CefBrowser cefBrowser, String s) {
ClientProxy proxy = ((ClientProxy) WebDisplays.PROXY);
for (ScreenBlockEntity tes : proxy.getScreens()) {
WDAudioSource source = tes.getSoundSource(cefBrowser);
if (source != null) {
Log.warning("Audio stream errored: " + s);
}
}
}
}

View File

@ -12,105 +12,115 @@ import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.SampledFloat;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.entity.ScreenData;
import org.cef.misc.CefAudioParameters;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public class WDAudioSource implements SoundInstance {
private static final ResourceLocation location = new ResourceLocation("webdisplays:audio_source");
private static final WeighedSoundEvents events = new WeighedSoundEvents(
location, "webdisplays.browser"
);
private static final SampledFloat CONST_1 = new SampledFloat() {
@Override
public float sample(RandomSource pRandom) {
return 1.0f;
}
};
private final Sound sound = new Sound(
"unused",
CONST_1,
CONST_1,
1, Sound.Type.SOUND_EVENT,
true, false,
100
);
ScreenBlockEntity blockEntity;
ScreenData data;
public WDAudioSource(ScreenBlockEntity blockEntity, ScreenData data) {
this.blockEntity = blockEntity;
this.data = data;
}
@Override
public ResourceLocation getLocation() {
return location;
}
@Nullable
@Override
public WeighedSoundEvents resolve(SoundManager pManager) {
return events;
}
@Override
public CompletableFuture<AudioStream> getStream(SoundBufferLibrary soundBuffers, Sound sound, boolean looping) {
return null;
}
@Override
public Sound getSound() {
return sound;
}
@Override
public SoundSource getSource() {
return SoundSource.RECORDS;
}
@Override
public boolean isLooping() {
return true;
}
@Override
public boolean isRelative() {
return false;
}
@Override
public int getDelay() {
return 0;
}
@Override
public float getVolume() {
return blockEntity.ytVolume;
}
@Override
public float getPitch() {
return 1;
}
@Override
public double getX() {
return blockEntity.getBlockPos().getX();
}
@Override
public double getY() {
return blockEntity.getBlockPos().getY();
}
@Override
public double getZ() {
return blockEntity.getBlockPos().getZ();
}
@Override
public Attenuation getAttenuation() {
return Attenuation.LINEAR;
}
private static final ResourceLocation location = new ResourceLocation("webdisplays:audio_source");
private static final WeighedSoundEvents events = new WeighedSoundEvents(
location, "webdisplays.browser"
);
private static final SampledFloat CONST_1 = new SampledFloat() {
@Override
public float sample(RandomSource pRandom) {
return 1.0f;
}
};
private final Sound sound = new Sound(
"unused",
CONST_1,
CONST_1,
1, Sound.Type.SOUND_EVENT,
true, false,
100
);
ScreenBlockEntity blockEntity;
ScreenData data;
WDAudioStream audioStream = new WDAudioStream();
public WDAudioSource(ScreenBlockEntity blockEntity, ScreenData data) {
this.blockEntity = blockEntity;
this.data = data;
}
public void parameterize(int channels, CefAudioParameters cefAudioParameters) {
audioStream.setFormat(channels, cefAudioParameters);
}
public void parameterize(CefAudioParameters cefAudioParameters) {
audioStream.setFormat(cefAudioParameters);
}
@Override
public ResourceLocation getLocation() {
return location;
}
@Nullable
@Override
public WeighedSoundEvents resolve(SoundManager pManager) {
return events;
}
@Override
public CompletableFuture<AudioStream> getStream(SoundBufferLibrary soundBuffers, Sound sound, boolean looping) {
return CompletableFuture.completedFuture(audioStream);
}
@Override
public Sound getSound() {
return sound;
}
@Override
public SoundSource getSource() {
return SoundSource.RECORDS;
}
@Override
public boolean isLooping() {
return true;
}
@Override
public boolean isRelative() {
return false;
}
@Override
public int getDelay() {
return 0;
}
@Override
public float getVolume() {
return blockEntity.ytVolume;
}
@Override
public float getPitch() {
return 1;
}
@Override
public double getX() {
return blockEntity.getBlockPos().getX();
}
@Override
public double getY() {
return blockEntity.getBlockPos().getY();
}
@Override
public double getZ() {
return blockEntity.getBlockPos().getZ();
}
@Override
public Attenuation getAttenuation() {
return Attenuation.LINEAR;
}
}

View File

@ -0,0 +1,141 @@
package net.montoyo.wd.client.audio;
import com.mojang.blaze3d.audio.Channel;
import net.minecraft.client.sounds.AudioStream;
import org.cef.misc.CefAudioParameters;
import org.cef.misc.CefChannelLayout;
import org.cef.misc.DataPointer;
import org.checkerframework.checker.units.qual.A;
import org.lwjgl.system.MemoryUtil;
import javax.sound.sampled.AudioFormat;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
public class WDAudioStream implements AudioStream, WDExtendedAudioStream {
AudioFormat currentFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100, 16,
1, (4096 / 8) * 2, 44100,
false
);
@Override
public AudioFormat getFormat() {
return currentFormat;
}
int fpb;
public void setFormat(int channels, CefAudioParameters cefAudioParameters) {
currentFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
cefAudioParameters.sampleRate, 16,
1, (16 / 8) * channels, cefAudioParameters.sampleRate,
false
);
fpb = cefAudioParameters.framesPerBuffer;
}
public void setFormat(CefAudioParameters cefAudioParameters) {
CefChannelLayout layout = cefAudioParameters.channelLayout;
int channels = 0;
if (layout == CefChannelLayout.CEF_CHANNEL_LAYOUT_MONO)
channels = 1;
else if (layout == CefChannelLayout.CEF_CHANNEL_LAYOUT_STEREO)
channels = 2;
setFormat(channels, cefAudioParameters);
}
ArrayDeque<float[]> buffers = new ArrayDeque<>();
public void setData(DataPointer data) {
int cap = fpb;
DataPointer ptr = data
.forCapacity(currentFormat.getChannels() << 3)
.withAlignment(3);
for (int i = 0; i < 1; i++) {
DataPointer subPtr = ptr.getData(i)
.withAlignment(2)
.forCapacity(cap << 2);
float[] flts = new float[cap];
for (int i1 = 0; i1 < cap; i1++)
flts[i1] = subPtr.getFloat(i1);
buffers.add(flts);
}
}
boolean checking = false;
@Override
public ByteBuffer read(int pSize) throws IOException {
System.out.println(buffers.size());
int sz = 2048 * buffers.size();
if (sz < 2048) sz = 4096;
pSize = sz;
ByteBuffer buffer = ByteBuffer.allocateDirect(pSize);
if (!buffers.isEmpty()) {
final int MAX_16_BIT = 32767;
final int MIN_16_BIT = -32768;
int i0 = 0;
loopBufs:
while (true) {
if (!buffers.isEmpty()) {
for (float v : buffers.pop()) {
if (buffer.position() >= pSize) break loopBufs;
// Scale and clip the float value to the range of a signed 16-bit int
float floatSample = v;
int intSample = (int) (floatSample * MAX_16_BIT);
if (intSample > MAX_16_BIT) {
intSample = MAX_16_BIT;
} else if (intSample < MIN_16_BIT) {
intSample = MIN_16_BIT;
}
// Convert the int sample to bytes (little-endian format)
buffer.put((byte) (intSample & 0xFF));
buffer.put((byte) ((intSample >> 8) & 0xFF));
}
i0++;
} else break;
}
buffer.position(0);
System.out.println("Consumed " + i0 + " buffers");
}
return buffer;
}
@Override
public void close() throws IOException {
}
Channel channel;
@Override
public void attach(Channel channel) {
WDExtendedAudioStream.super.attach(channel);
this.channel = channel;
}
@Override
public int getPumpCount(int defaultAmount) {
return defaultAmount;
}
@Override
public int computeSize(AudioFormat format, int streamingBufferSize) {
return 2048;
}
@Override
public boolean canStop() {
return true;
}
}

View File

@ -0,0 +1,23 @@
package net.montoyo.wd.client.audio;
import com.mojang.blaze3d.audio.Channel;
import javax.sound.sampled.AudioFormat;
public interface WDExtendedAudioStream {
default int getPumpCount(int defaultAmount) {
return defaultAmount;
}
default void attach(Channel channel) {
return;
}
default int computeSize(AudioFormat format, int streamingBufferSize) {
return streamingBufferSize;
}
default boolean canStop() {
return true;
}
}

View File

@ -17,6 +17,7 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.ViewportEvent;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLPaths;
import net.montoyo.wd.WebDisplays;
@ -286,9 +287,11 @@ public class GuiKeyboard extends WDScreen {
protected void mouse(double mouseX, double mouseY, Consumer<Vector2i> func) {
float pct = Minecraft.getInstance().getPartialTick();
double fov = Minecraft.getInstance().gameRenderer.getFov(
ViewportEvent.ComputeFov fov = new ViewportEvent.ComputeFov(
Minecraft.getInstance().gameRenderer,
Minecraft.getInstance().getEntityRenderDispatcher().camera,
pct, true
pct, Minecraft.getInstance().options.fov().get(),
true
);
mouseX /= width;
@ -298,7 +301,7 @@ public class GuiKeyboard extends WDScreen {
mouseY -= 0.5;
mouseY = -mouseY;
Matrix4f proj = Minecraft.getInstance().gameRenderer.getProjectionMatrix(fov);
Matrix4f proj = Minecraft.getInstance().gameRenderer.getProjectionMatrix(fov.getFOV());
Entity e = Minecraft.getInstance().getEntityRenderDispatcher().camera.getEntity();
@ -307,12 +310,14 @@ public class GuiKeyboard extends WDScreen {
camera.mulPose(Axis.XP.rotationDegrees(angle[0]));
camera.mulPose(Axis.YP.rotationDegrees(angle[1] + 180.0F));
Vector4f coord = new Vector4f(2f * (float) mouseX, 2 * (float) mouseY, 0, 1f);
coord.add(proj.invert().transform(coord));
Vector4f coord = new Vector4f(0, 0, 0, 0);
coord.add(proj.invert().transform(new Vector4f(2f * (float) mouseX, 2 * (float) mouseY, 0, 1f)));
coord = camera.last().pose().invert().transform(coord);
coord.w = 0;
coord.normalize();
Vec3 vec3 = e.getEyePosition(pct);
Vec3 vec31 = new Vec3(coord.x, coord.y, coord.z).normalize();
Vec3 vec31 = new Vec3(coord.x, coord.y, coord.z);
BlockHitResult result = tes.trace(side, vec3, vec31);
if (result.getType() != HitResult.Type.MISS) {
@ -338,8 +343,6 @@ public class GuiKeyboard extends WDScreen {
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(tes, side, hit, button));
});
KeyboardCamera.setMouse(button, true);
return super.mouseClicked(mouseX, mouseY, button);
}
@ -351,8 +354,6 @@ public class GuiKeyboard extends WDScreen {
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserUp(tes, side, button));
});
KeyboardCamera.setMouse(button, false);
return super.mouseReleased(mouseX, mouseY, button);
}

View File

@ -30,10 +30,6 @@ public class KeyboardCamera {
private static double nextX = -1;
private static double nextY = -1;
private static double focalX = -1;
private static double focalY = -1;
private static final boolean[] mouseStatus = new boolean[2];
protected static Vec2 pxToHit(ScreenData scr, Vec2 dst) {
float cx, cy;
@ -86,20 +82,14 @@ public class KeyboardCamera {
if (scr != null) {
Vec2 c;
if (!mouseStatus[0] && !mouseStatus[1]) {
if (lock.hasFocused()) {
if (ClientConfig.Input.keyboardCamera) {
nextX = lock.getX();
nextY = lock.getY();
if (lock.hasFocused()) {
if (ClientConfig.Input.keyboardCamera) {
nextX = lock.getX();
nextY = lock.getY();
c = pxToHit(scr, new Vec2((float) nextX, (float) nextY));
} else c = new Vec2(scr.size.x / 2f, scr.size.y / 2f);
c = pxToHit(scr, new Vec2((float) nextX, (float) nextY));
} else c = new Vec2(scr.size.x / 2f, scr.size.y / 2f);
// } else c = new Vec2((float) focalX, (float) focalY);
} else return;
focalX = c.x;
focalY = c.y;
} else c = new Vec2(scr.size.x / 2f, scr.size.y / 2f);
nextX = c.x;
nextY = c.y;
@ -168,10 +158,6 @@ public class KeyboardCamera {
return angle;
}
public static void setMouse(int side, boolean pressed) {
mouseStatus[side] = pressed;
}
public static void updateCamera(ViewportEvent.ComputeCameraAngles event) {
if (tes == null) {
xCrd = -1;
@ -213,11 +199,6 @@ public class KeyboardCamera {
protected static int delay = 8;
public static void gameTick(TickEvent.ClientTickEvent event) {
if (mouseStatus[0] || mouseStatus[1]) {
oxCrd = Mth.lerp(0.5, oxCrd, xCrd);
oyCrd = Mth.lerp(0.5, oyCrd, yCrd);
return;
}
if (event.phase.equals(TickEvent.Phase.END)) {
if (side == null) {
delay = 1;

View File

@ -28,6 +28,7 @@ import net.minecraftforge.network.PacketDistributor;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.block.ScreenBlock;
import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.client.audio.WDAudioSource;
import net.montoyo.wd.config.CommonConfig;
import net.montoyo.wd.controls.builtin.ClickControl;
import net.montoyo.wd.core.DefaultUpgrade;
@ -1143,6 +1144,15 @@ public class ScreenBlockEntity extends BlockEntity {
return bhr;
}
public WDAudioSource getSoundSource(CefBrowser cefBrowser) {
for (ScreenData screen : screens) {
if (screen.browser == cefBrowser) {
return screen.audioSource;
}
}
return null;
}
// @Override
// public boolean shouldRefresh(Level world, BlockPos pos, @Nonnull BlockState oldState, @Nonnull BlockState newState) {

View File

@ -3,6 +3,7 @@ package net.montoyo.wd.entity;
import com.cinemamod.mcef.MCEF;
import com.cinemamod.mcef.MCEFBrowser;
import com.cinemamod.mcef.listeners.MCEFCursorChangeListener;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -13,6 +14,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.client.audio.WDAudioSource;
import net.montoyo.wd.config.CommonConfig;
import net.montoyo.wd.core.ScreenRights;
import net.montoyo.wd.utilities.*;
@ -33,6 +35,7 @@ public class ScreenData {
public Vector2i resolution;
public Rotation rotation = Rotation.ROT_0;
public String url;
public WDAudioSource audioSource;
protected VideoType videoType;
public NameUUIDPair owner;
public ArrayList<NameUUIDPair> friends;
@ -206,6 +209,12 @@ public class ScreenData {
doTurnOnAnim = doAnim;
turnOnTime = System.currentTimeMillis();
audioSource = new WDAudioSource(
be,
this
);
Minecraft.getInstance().getSoundManager().play(audioSource);
}
}
}

View File

@ -0,0 +1,48 @@
package net.montoyo.wd.mixins.audio;
import com.mojang.blaze3d.audio.Channel;
import net.minecraft.client.sounds.AudioStream;
import net.montoyo.wd.client.audio.WDExtendedAudioStream;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import javax.annotation.Nullable;
import javax.sound.sampled.AudioFormat;
@Mixin(Channel.class)
public class AudioChannelMixin {
@Shadow
@Nullable
private AudioStream stream;
@Shadow private int streamingBufferSize;
@Inject(at = @At("HEAD"), method = "attachBufferStream")
public void postAttach(AudioStream pStream, CallbackInfo ci) {
((WDExtendedAudioStream) pStream).attach((Channel) (Object) this);
}
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/audio/Channel;pumpBuffers(I)V", shift = At.Shift.BEFORE), method = "attachBufferStream")
public void postComputeSize(AudioStream pStream, CallbackInfo ci) {
streamingBufferSize = ((WDExtendedAudioStream) pStream).computeSize(
pStream.getFormat(), streamingBufferSize
);
}
@ModifyVariable(argsOnly = true, ordinal = 0, at = @At("HEAD"), method = "pumpBuffers")
public int prePump(int defaultAmount) {
return ((WDExtendedAudioStream) stream).getPumpCount(defaultAmount);
}
@Inject(at = @At("HEAD"), method = "stopped", cancellable = true)
public void preCheckStopped(CallbackInfoReturnable<Boolean> cir) {
if (stream != null)
if (!((WDExtendedAudioStream) stream).canStop())
cir.setReturnValue(false);
}
}

View File

@ -0,0 +1,9 @@
package net.montoyo.wd.mixins.audio;
import net.minecraft.client.sounds.AudioStream;
import net.montoyo.wd.client.audio.WDExtendedAudioStream;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(AudioStream.class)
public interface AudioStreamMixin extends WDExtendedAudioStream {
}

View File

@ -7,8 +7,4 @@ public-f net.minecraft.world.phys.AABB f_82289_
public-f net.minecraft.world.phys.AABB f_82290_
public-f net.minecraft.world.phys.AABB f_82291_
public-f net.minecraft.world.phys.AABB f_82292_
public-f net.minecraft.world.phys.AABB f_82293_
# GameRenderer
public net.minecraft.client.renderer.GameRenderer m_109141_(Lnet/minecraft/client/Camera;FZ)D # getFov
public-f net.minecraft.world.phys.AABB f_82293_

View File

@ -8,7 +8,9 @@
],
"client": [
"MouseHandlerMixin",
"OverlayMixin"
"OverlayMixin",
"audio.AudioChannelMixin",
"audio.AudioStreamMixin"
],
"injectors": {
"defaultRequire": 1