Compare commits
3 Commits
1.20
...
audio-hand
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e81b1b7d | ||
|
|
47966aa6d5 | ||
|
|
3b7c4a5bf8 |
221
build.gradle
221
build.gradle
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
BIN
libs/mcef-forge-2.1.5-1.20.1.jar
Normal file
BIN
libs/mcef-forge-2.1.5-1.20.1.jar
Normal file
Binary file not shown.
|
|
@ -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'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
141
src/main/java/net/montoyo/wd/client/audio/WDAudioStream.java
Normal file
141
src/main/java/net/montoyo/wd/client/audio/WDAudioStream.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
}
|
||||
|
|
@ -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_
|
||||
|
|
@ -8,7 +8,9 @@
|
|||
],
|
||||
"client": [
|
||||
"MouseHandlerMixin",
|
||||
"OverlayMixin"
|
||||
"OverlayMixin",
|
||||
"audio.AudioChannelMixin",
|
||||
"audio.AudioStreamMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user