sound cues for buttons

This commit is contained in:
minjaesong
2024-04-01 03:15:57 +09:00
parent f72ed0f706
commit 576e868996
23 changed files with 193 additions and 41 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum;
import com.badlogic.gdx.*;
import com.badlogic.gdx.audio.AudioDevice;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.backends.lwjgl3.TerrarumLwjgl3Application;
import com.badlogic.gdx.controllers.Controllers;
@@ -17,6 +18,8 @@ import kotlin.jvm.functions.Function0;
import kotlin.text.Charsets;
import net.torvald.getcpuname.GetCpuName;
import net.torvald.terrarum.audio.AudioMixer;
import net.torvald.terrarum.audio.MusicContainer;
import net.torvald.terrarum.audio.dsp.BinoPan;
import net.torvald.terrarum.controller.GdxControllerAdapter;
import net.torvald.terrarum.controller.TerrarumController;
import net.torvald.terrarum.controller.XinputControllerAdapter;
@@ -551,6 +554,9 @@ public class App implements ApplicationListener {
CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga")));
CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga")));
CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bop", () -> new MusicContainer("haptic_bop", Gdx.files.internal("./assets/audio/effects/haptic_bop.ogg").file(), false, (Music m) -> { return null; }));
CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bup", () -> new MusicContainer("haptic_bup", Gdx.files.internal("./assets/audio/effects/haptic_bup.ogg").file(), false, (Music m) -> { return null; }));
CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bip", () -> new MusicContainer("haptic_bip", Gdx.files.internal("./assets/audio/effects/haptic_bip.ogg").file(), false, (Music m) -> { highPrioritySoundPlaying = false; return null; }));
// make loading list
CommonResourcePool.INSTANCE.loadAll();
@@ -1959,4 +1965,35 @@ public class App implements ApplicationListener {
setConfig("autosaveinterval", 5 * 60000);
}
}
private static boolean highPrioritySoundPlaying = false;
public static void playGUIsound(MusicContainer sound, double volume, float pan) {
if (!highPrioritySoundPlaying) {
var it = audioMixer.getGuiTrack();
it.stop();
it.setCurrentTrack(sound);
it.setMaxVolumeFun(() -> volume);
it.setVolume(volume);
((BinoPan) Arrays.stream(it.getFilters()).findFirst().get()).setPan(pan);
it.play();
}
}
public static void playGUIsound(MusicContainer sound, double volume) { playGUIsound(sound, volume, 0.0f); }
public static void playGUIsound(MusicContainer sound) { playGUIsound(sound, 1.0, 0.0f); }
public static void playGUIsoundHigh(MusicContainer sound, double volume, float pan) {
// TODO when a sound is played thru this function, other sound play calls thru playGUIsound are ignored until this sound finishes playing
var it = audioMixer.getGuiTrack();
highPrioritySoundPlaying = true;
it.stop();
it.setCurrentTrack(sound);
it.setMaxVolumeFun(() -> volume);
it.setVolume(volume);
((BinoPan) Arrays.stream(it.getFilters()).findFirst().get()).setPan(pan);
it.play();
}
public static void playGUIsoundHigh(MusicContainer sound, double volume) { playGUIsoundHigh(sound, volume, 0.0f); }
public static void playGUIsoundHigh(MusicContainer sound) { playGUIsoundHigh(sound, 1.0, 0.0f); }
}

View File

@@ -341,6 +341,10 @@ Remixed sound from <https://freesound.org/people/j1987> and <https://freesound.o
℗ 2009 Benboncan
Sound from <https://freesound.org/people/Benboncan/>
- effects/haptic_*.ogg
℗ 2024 CuriousTorvald
My own recordings
$BULLET Impulse Responses:

View File

@@ -444,16 +444,6 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
loadedTime_t = App.getTIME_T()
}
open fun playGUIsound(sound: MusicContainer, volume: Double = 1.0, pan: Float = 0f) {
App.audioMixer.guiTrack.let {
it.currentTrack = sound
it.maxVolumeFun= { volume }
it.volume = volume
it.playRequested.set(true)
it.getFilter<BinoPan>().pan = pan
}
}
/**
* Copies most recent `save` to `save.1`, leaving `save` for overwriting, previous `save.1` will be copied to `save.2`
*/

View File

@@ -255,7 +255,7 @@ object PickaxeCore {
val pan = 1.3 * relX / distFallOff
val vol = MixerTrackProcessor.getVolFun(dist / distFallOff).coerceAtLeast(0.0)
if (!tooltipWasShown && tooltipSet) {
INGAME.playGUIsound(soundCue, 0.25 * vol, pan.toFloat())
App.playGUIsound(soundCue, 0.18 * vol, pan.toFloat())
}
true // just a placeholder

View File

@@ -35,9 +35,16 @@ abstract class UIItemInventoryCellBase(
var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme,
var showTooltip: Boolean = true,
) : UIItem(parentUI, initialX, initialY) {
abstract override fun update(delta: Float)
override fun update(delta: Float) {
suppressHaptic = (item == null)
super.update(delta)
}
abstract override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera)
override var suppressHaptic = false
protected val tooltipHash = System.nanoTime()
/** Custom highlight rule to highlight tihs button to primary accent colour (blue by default).

View File

@@ -51,6 +51,8 @@ open class UIItemInventoryItemGrid(
private val colourTheme: InventoryCellColourTheme = defaultInventoryCellTheme
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = true
// deal with the moving position
//override var oldPosX = posX
//override var oldPosY = posY

View File

@@ -23,6 +23,7 @@ class UIItemListNavBarVertical(
var extraDrawOpOnBottom: (UIItemListNavBarVertical, SpriteBatch) -> Unit = { _,_ -> }
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = true
override val width = UIItemListNavBarVertical.WIDTH
override val mouseUp: Boolean

View File

@@ -496,6 +496,8 @@ class UIItemPlayerCells(
val playerUUID: UUID,
) : UIItem(parent, initialX, initialY) {
override var suppressHaptic = false
override val width = SAVE_CELL_WIDTH
override val height = SAVE_CELL_HEIGHT
@@ -766,6 +768,7 @@ class UIItemWorldCells(
initialY: Int,
val skimmer: DiskSkimmer) : UIItem(parent, initialX, initialY) {
override var suppressHaptic = false
private val metaFile: EntryFile?
private val saveName: String

View File

@@ -3,7 +3,10 @@ package net.torvald.terrarum.ui
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticCursorHovered
/**
@@ -141,15 +144,20 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
*/
open var isActive = true
private var oldMouseUp = false
open var suppressHaptic = true
override fun update(delta: Float) {
if (parentUI.isVisible) {
if (isActive) {
val mU = mouseUp
updateListener.invoke(delta)
mouseOverCall?.update(delta)
if (mouseUp) {
if (mU) {
if (mouseOverCall?.isVisible == true) {
mouseOverCall?.setAsOpen()
}
@@ -168,7 +176,17 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
}
}
if (!oldMouseUp && mU && !suppressHaptic)
playHapticCursorHovered()
oldMouseUp = mU
}
else {
oldMouseUp = false
}
}
else {
oldMouseUp = false
}
}
@@ -233,6 +251,8 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
if (!clickOnceListenerFired && mouseUp && button == App.getConfigInt("config_mouseprimary")) {
clickOnceListener.invoke(itemRelativeMouseX, itemRelativeMouseY)
if (!suppressHaptic)
playHapticPushedDown()
actionDone = true
}
}
@@ -262,3 +282,12 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
abstract override fun dispose()
}
object UIItemAccessibilityUtil {
fun playHapticCursorHovered() {
App.playGUIsound(CommonResourcePool.getAs("sound:haptic_bup"), 0.1666666)
}
fun playHapticPushedDown() {
App.playGUIsoundHigh(CommonResourcePool.getAs("sound:haptic_bip"), 0.5)
}
}

View File

@@ -6,6 +6,8 @@ import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.*
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticCursorHovered
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import kotlin.math.absoluteValue
import kotlin.math.roundToInt
@@ -32,6 +34,8 @@ class UIItemHorzSlider(
private val disposeTexture: Boolean = false
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = false
override val height = 24
private var mouseOnHandle = false
@@ -50,6 +54,7 @@ class UIItemHorzSlider(
// update handle position and value
if (mouseUp && Terrarum.mouseDown || mouseLatched) {
if (!mouseLatched) playHapticPushedDown()
mouseLatched = true
handlePos = (itemRelativeMouseX - handleWidth/2.0).coerceIn(0.0, handleTravelDist.toDouble())
value = interpolateLinear(handlePos / handleTravelDist, min, max)

View File

@@ -51,6 +51,8 @@ open class UIItemImageButton(
val imageDrawHeight: Int = image.regionHeight,
) : UIItem(parent, initialX, initialY) {
override var suppressHaptic = false
var highlighted = false
var extraDrawOp: (UIItem, SpriteBatch) -> Unit = { _,_ -> }

View File

@@ -41,7 +41,9 @@ class UIItemInventoryElemSimple(
var emptyCellIconColour: Color = Color(0xdddddd7f.toInt()),
val updateOnNull: Boolean = false,
) : UIItemInventoryCellBase(parentUI, initialX, initialY, item, amount, itemImage, quickslot, equippedSlot, keyDownFun, touchDownFun, wheelFun, extraInfo, highlightEquippedItem, colourTheme) {
override var suppressHaptic = false
companion object {
val height = UIItemInventoryElemWide.height
}
@@ -60,9 +62,6 @@ class UIItemInventoryElemSimple(
private val emptyCellIconOffsetX = (this.height - (emptyCellIcon?.regionWidth ?: 0)).div(2).toFloat()
private val emptyCellIconOffsetY = (this.height - (emptyCellIcon?.regionHeight ?: 0)).div(2).toFloat()
override fun update(delta: Float) {
}
private var highlightToMainCol = false
private var highlightToSubCol = false

View File

@@ -41,6 +41,8 @@ class UIItemInventoryElemWide(
var showItemCount: Boolean = true,
) : UIItemInventoryCellBase(parentUI, initialX, initialY, item, amount, itemImage, quickslot, equippedSlot, keyDownFun, touchDownFun, wheelFun, extraInfo, highlightEquippedItem, colourTheme) {
override var suppressHaptic = false
companion object {
val height = 48
val UNIQUE_ITEM_HAS_NO_AMOUNT = -1L
@@ -65,11 +67,6 @@ class UIItemInventoryElemWide(
private val durabilityBarOffY = 35
override fun update(delta: Float) {
}
private var highlightToMainCol = false
private var highlightToSubCol = false

View File

@@ -6,6 +6,8 @@ import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.ceilToInt
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticCursorHovered
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import kotlin.math.absoluteValue
/**
@@ -26,6 +28,8 @@ class UIItemSpinner(
private val numberToTextFunction: (Number) -> String = { "$it" }
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = false
// to alleviate floating point errors adding up as the spinner is being used
private val values = DoubleArray(1 + ((max.toDouble() - min.toDouble()).div(step.toDouble())).ceilToInt()) {
// printdbg(this, "$min..$max step $step; index [$it] = ${min.toDouble() + (step.toDouble() * it)}")
@@ -89,6 +93,8 @@ class UIItemSpinner(
fboUpdateLatch = true
}
private var oldMouseOnButton = 0
override fun update(delta: Float) {
super.update(delta)
@@ -106,7 +112,14 @@ class UIItemSpinner(
changeValueBy((mouseOnButton * 2) - 3)
fboUpdateLatch = true
selectionChangeListener(value)
playHapticPushedDown()
}
if (mouseOnButton > 0 && mouseOnButton != oldMouseOnButton) {
playHapticCursorHovered()
}
oldMouseOnButton = mouseOnButton
}
private var textCache = ""
@@ -199,6 +212,7 @@ class UIItemSpinner(
selectionChangeListener(value)
fboUpdateLatch = true
playHapticPushedDown()
return true
}
else {

View File

@@ -51,6 +51,8 @@ open class UIItemTextButton(
val tags: Array<String> = arrayOf("")
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = false
companion object {
val font = App.fontGame
val height = 24

View File

@@ -1,11 +1,11 @@
package net.torvald.terrarum.ui
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
@@ -86,22 +86,22 @@ class UIItemTextButtonList(
// if (!kinematic) {
UIItemTextButton(
parentUI, if (readFromLang) ld1 else ld0,
initialX = posX,
initialY = posY + vertOff,
width = width,
activeCol = activeCol,
activeBackCol = activeBackCol,
activeBackBlendMode = activeBackBlendMode,
highlightCol = highlightCol,
highlightBackCol = highlightBackCol,
highlightBackBlendMode = highlightBackBlendMode,
inactiveCol = inactiveCol,
paddingLeft = pregap,
paddingRight = postgap,
alignment = alignment,
hitboxSize = itemHitboxSize,
tags = tagsCollection[i]
parentUI, if (readFromLang) ld1 else ld0,
initialX = posX,
initialY = posY + vertOff,
width = width,
activeCol = activeCol,
activeBackCol = activeBackCol,
activeBackBlendMode = activeBackBlendMode,
highlightCol = highlightCol,
highlightBackCol = highlightBackCol,
highlightBackBlendMode = highlightBackBlendMode,
inactiveCol = inactiveCol,
paddingLeft = pregap,
paddingRight = postgap,
alignment = alignment,
hitboxSize = itemHitboxSize,
tags = tagsCollection[i],
)
// }
// else {
@@ -211,6 +211,7 @@ class UIItemTextButtonList(
// }
selectionChangeListener?.invoke(oldIndex, index)
playHapticPushedDown()
}
btn.highlighted = (index == selectedIndex) // forcibly highlight if this.highlighted != null
}

View File

@@ -10,6 +10,8 @@ import com.ibm.icu.text.Normalizer2
import com.jme3.math.FastMath
import net.torvald.terrarum.*
import net.torvald.terrarum.gamecontroller.*
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticCursorHovered
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import net.torvald.terrarum.utils.Clipboard
import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
import net.torvald.unicode.toJavaString
@@ -433,6 +435,8 @@ class UIItemTextLineInput(
}
}
private var oldButtonStatus: Int? = null
override fun update(delta: Float) {
if (mouseoverUpdateLatch) {
super.update(delta)
@@ -443,7 +447,10 @@ class UIItemTextLineInput(
isEnabled = mouseUp
if (oldEnabled && !isEnabled) TerrarumGlobalState.HAS_KEYBOARD_INPUT_FOCUS.unset()
if (!oldEnabled && isEnabled) TerrarumGlobalState.HAS_KEYBOARD_INPUT_FOCUS.set()
if (!oldEnabled && isEnabled) {
TerrarumGlobalState.HAS_KEYBOARD_INPUT_FOCUS.set()
playHapticPushedDown()
}
}
if (App.getConfigString("inputmethod") == "none") imeOn = false
@@ -468,6 +475,23 @@ class UIItemTextLineInput(
}
imeOn = KeyToggler.isOn(ControlPresets.getKey("control_key_toggleime"))
val buttonStatus = if (mouseUpOnIMEButton)
0
else if (mouseUpOnPasteButton)
2
else if (mouseUpOnTextArea)
1
else
null
if (buttonStatus != null && buttonStatus != oldButtonStatus)
playHapticCursorHovered()
oldButtonStatus = buttonStatus
}
}

View File

@@ -10,6 +10,8 @@ import com.badlogic.gdx.graphics.glutils.FrameBuffer
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticCursorHovered
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap
/**
@@ -71,6 +73,9 @@ class UIItemTextSelector(
fboUpdateLatch = true
}
private var oldMouseOnButton = 0
private var oldMouseOnPaletteItem: Int? = null
override fun update(delta: Float) {
super.update(delta)
@@ -99,7 +104,7 @@ class UIItemTextSelector(
mouseLatch.latch {
if (paletteShowing && mouseOnPaletteItem != null ) {
if (paletteShowing && mouseOnPaletteItem != null) {
selection = mouseOnPaletteItem!!
fboUpdateLatch = true
selectionChangeListener(selection)
@@ -125,7 +130,22 @@ class UIItemTextSelector(
else {
paletteShowing = false
}
if (mouseOnButton > 0 && (clickToShowPalette || mouseOnButton != 3)) {
playHapticPushedDown()
}
}
if (mouseOnButton > 0 && mouseOnButton != oldMouseOnButton) {
if (drawBorder || mouseOnButton != 2)
playHapticCursorHovered()
}
else if (mouseOnPaletteItem != null && mouseOnPaletteItem != oldMouseOnPaletteItem) {
playHapticCursorHovered()
}
oldMouseOnButton = mouseOnButton
oldMouseOnPaletteItem = mouseOnPaletteItem
}
private val leftIcon = if (useSpinnerButtons) labels.get(9,2) else labels.get(16,0)
@@ -255,6 +275,7 @@ class UIItemTextSelector(
selectionChangeListener(selection)
fboUpdateLatch = true
playHapticPushedDown()
return true
}
else {

View File

@@ -24,6 +24,7 @@ class UIItemToggleButton(
private var status: Boolean = false,
) : UIItem(parent, initialX, initialY) {
override var suppressHaptic = false
init {
CommonResourcePool.addToLoadingList("gui_toggler_icons") {

View File

@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.ui.UIItemAccessibilityUtil.playHapticPushedDown
import kotlin.math.roundToInt
/**
@@ -23,6 +24,8 @@ class UIItemVertSlider(
private val disposeTexture: Boolean = false
) : UIItem(parentUI, initialX, initialY) {
override var suppressHaptic = false
companion object {
const val WIDTH = 16
}
@@ -49,6 +52,7 @@ class UIItemVertSlider(
// update handle position and value
if (mouseUp && Terrarum.mouseDown || mouseLatched) {
if (!mouseLatched) playHapticPushedDown()
mouseLatched = true
handlePos = (itemRelativeMouseY - handleHeight/2.0).coerceIn(0.0, handleTravelDist.toDouble())
value = interpolateLinear(handlePos / handleTravelDist, min, max)