diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntityTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntityTest.kt index b543d1b37..28cc7f83c 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntityTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntityTest.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2024 Moritz Zwerger + * Copyright (C) 2020-2025 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -70,6 +70,7 @@ class SignBlockEntityTest { assertEquals(entity.back.color, ChatColors.BLUE) assertEquals(entity.back.text, arrayOf(ChatComponent.of("This is the back"), ChatComponent.of("text"), ChatComponent.of("of"), ChatComponent.of("this sign."))) } + fun `nbt 1_20_4`() { val nbt = mapOf( "is_waxed" to 1.toByte(), diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/textures/TextureReadingTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/textures/TextureReadingTest.kt index 0c6697a1b..861ebe469 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/textures/TextureReadingTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/textures/TextureReadingTest.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2024 Moritz Zwerger + * Copyright (C) 2020-2025 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.textures import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kutil.stream.InputStreamUtil.readAll import de.bixilon.kutil.unsafe.UnsafeUtil.setUnsafeAccessible +import de.bixilon.minosoft.data.text.formatting.color.RGBAColor import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGB8Buffer import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGBA8Buffer import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer @@ -69,10 +70,9 @@ class TextureReadingTest { } private fun TextureBuffer.assertSand() { - assertEquals(getRGBA(0, 0), 0xE7E4BBFF.toInt()) - assertEquals(getRGBA(1, 0), 0xDACFA3FF.toInt()) - assertEquals(getRGBA(0, 1), 0xD5C496FF.toInt()) - + assertEquals(getRGBA(0, 0), RGBAColor(0xE7, 0xE4, 0xBB)) + assertEquals(getRGBA(1, 0), RGBAColor(0xDA, 0xCF, 0xA3)) + assertEquals(getRGBA(0, 1), RGBAColor(0xD5, 0xC4, 0x96)) } fun `read1 sand rgba`() { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntity.kt index 7ae970b67..9ec2208be 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/sign/SignBlockEntity.kt @@ -24,7 +24,7 @@ import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.EmptyComponent import de.bixilon.minosoft.data.text.formatting.color.ChatColors -import de.bixilon.minosoft.data.text.formatting.color.RGBColor +import de.bixilon.minosoft.data.text.formatting.color.RGBAColor import de.bixilon.minosoft.protocol.network.session.play.PlaySession class SignBlockEntity(session: PlaySession) : BlockEntity(session) { @@ -56,7 +56,7 @@ class SignBlockEntity(session: PlaySession) : BlockEntity(session) { class SignTextProperties( var glowing: Boolean = false, - var color: RGBColor? = null, + var color: RGBAColor? = null, val text: Array = Array(LINES) { EmptyComponent }, ) { @@ -78,7 +78,7 @@ class SignBlockEntity(session: PlaySession) : BlockEntity(session) { } fun update(color: Any?, glowing: Any?) { - this.color = color?.toString()?.lowercase()?.let { ChatColors.NAME_MAP[it]?.rgb() } + this.color = color?.toString()?.lowercase()?.let { ChatColors.NAME_MAP[it] } this.glowing = glowing?.toBoolean() ?: false } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index 43ef1bfac..c7f3aa439 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -130,12 +130,12 @@ open class TextComponent( } fun copy(message: Any? = this.message, color: RGBAColor? = this.color, formatting: BitEnumSet = this.formatting, clickEvent: ClickEvent? = this.clickEvent, hoverEvent: HoverEvent? = this.hoverEvent) = TextComponent( - message = message, - color = color, - formatting = formatting, - clickEvent = clickEvent, - hoverEvent = hoverEvent, - ) + message = message, + color = color, + formatting = formatting, + clickEvent = clickEvent, + hoverEvent = hoverEvent, + ) override val length: Int get() = message.length diff --git a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAArray.kt b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAArray.kt index fc0dbc314..9a5d0b544 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAArray.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAArray.kt @@ -17,12 +17,12 @@ package de.bixilon.minosoft.data.text.formatting.color value class RGBAArray(val array: IntArray) { constructor(size: Int) : this(IntArray(size)) - constructor(size: Int, init: (Int) -> RGBAColor) : this(IntArray(size) { init.invoke(it).argb }) + constructor(size: Int, init: (Int) -> RGBAColor) : this(IntArray(size) { init.invoke(it).rgba }) operator fun get(index: Int) = RGBAColor(array[index]) inline fun getOrNull(index: Int) = array.getOrNull(index)?.let { RGBAColor(it) } operator fun set(index: Int, value: RGBAColor) { - array[index] = value.rgb + array[index] = value.rgba } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColor.kt b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColor.kt index 91b1baff7..676a88a0f 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColor.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColor.kt @@ -27,7 +27,7 @@ import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.clamp @JvmInline -value class RGBAColor(val argb: Int) : Color, TextFormattable { +value class RGBAColor(val rgba: Int) : Color, TextFormattable { constructor(red: Int, green: Int, blue: Int) : this(red, green, blue, MAX) constructor(red: Int, green: Int, blue: Int, alpha: Int) : this(((alpha.clamp() and MASK) shl ALPHA_SHIFT) or ((red.clamp() and MASK) shl RED_SHIFT) or ((green.clamp() and MASK) shl GREEN_SHIFT) or ((blue.clamp() and MASK) shl BLUE_SHIFT)) @@ -35,10 +35,10 @@ value class RGBAColor(val argb: Int) : Color, TextFormattable { constructor(red: Float, green: Float, blue: Float) : this(Color.fromFloat(red), Color.fromFloat(green), Color.fromFloat(blue)) constructor(red: Float, green: Float, blue: Float, alpha: Float) : this(Color.fromFloat(red), Color.fromFloat(green), Color.fromFloat(blue), Color.fromFloat(alpha)) - override inline val red: Int get() = (argb ushr RED_SHIFT) and MASK - override inline val green: Int get() = (argb ushr GREEN_SHIFT) and MASK - override inline val blue: Int get() = (argb ushr BLUE_SHIFT) and MASK - inline val alpha: Int get() = (argb ushr ALPHA_SHIFT) and MASK + override inline val red: Int get() = (rgba ushr RED_SHIFT) and MASK + override inline val green: Int get() = (rgba ushr GREEN_SHIFT) and MASK + override inline val blue: Int get() = (rgba ushr BLUE_SHIFT) and MASK + inline val alpha: Int get() = (rgba ushr ALPHA_SHIFT) and MASK override inline val redf get() = Color.toFloat(red) @@ -46,8 +46,8 @@ value class RGBAColor(val argb: Int) : Color, TextFormattable { override inline val bluef get() = Color.toFloat(blue) inline val alphaf get() = Color.toFloat(alpha) - override inline val rgb get() = argb and ((MASK shl RED_SHIFT) or (MASK shl GREEN_SHIFT) or (MASK shl BLUE_SHIFT)) - inline val rgba get() = (argb shl BITS) or alpha + override inline val rgb get() = rgba ushr BITS + inline val argb get() = (rgba ushr BITS) or (rgba shl 3 * BITS) inline operator fun plus(value: Int) = plus(RGBAColor(value, value, value, value)) @@ -93,22 +93,21 @@ value class RGBAColor(val argb: Int) : Color, TextFormattable { companion object { - const val ALPHA_SHIFT = 3 * BITS - const val RED_SHIFT = 2 * BITS - const val GREEN_SHIFT = 1 * BITS - const val BLUE_SHIFT = 0 * BITS + const val RED_SHIFT = 3 * BITS + const val GREEN_SHIFT = 2 * BITS + const val BLUE_SHIFT = 1 * BITS + const val ALPHA_SHIFT = 0 * BITS fun Vec4.color() = RGBAColor(r, g, b, a) - inline fun Int.rgba() = RGBAColor(this shr BITS or (this and BITS shl (BITS * 3))) - inline fun Int.argb() = RGBColor(this) + inline fun Int.rgba() = RGBAColor(this) fun String.rgba(): RGBAColor { val string = this.removePrefix("#") val int = Integer.parseUnsignedInt(string, 16) return when (string.length) { - 6 -> RGBAColor(int or (MASK shl ALPHA_SHIFT)) + 6 -> ((int shl BITS) or (MASK shl ALPHA_SHIFT)).rgba() 8 -> int.rgba() else -> throw IllegalArgumentException("Invalid color string: $this") } diff --git a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBArray.kt b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBArray.kt index 7fe745de4..9ca8d54bd 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBArray.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBArray.kt @@ -13,6 +13,8 @@ package de.bixilon.minosoft.data.text.formatting.color +import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.rgb + @JvmInline value class RGBArray(val array: IntArray) { @@ -21,8 +23,8 @@ value class RGBArray(val array: IntArray) { inline val size get() = array.size - inline operator fun get(index: Int) = RGBColor(array[index]) - inline fun getOrNull(index: Int) = array.getOrNull(index)?.let { RGBColor(it) } + inline operator fun get(index: Int) = array[index].rgb() + inline fun getOrNull(index: Int) = array.getOrNull(index)?.rgb() inline operator fun set(index: Int, value: RGBColor) { array[index] = value.rgb } diff --git a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBColor.kt b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBColor.kt index 4011ca089..01a2bd709 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBColor.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/RGBColor.kt @@ -20,11 +20,12 @@ import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.BITS import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.MASK import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.MAX import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.TIMES +import de.bixilon.minosoft.data.text.formatting.color.Color.Companion.clamp @JvmInline value class RGBColor(override val rgb: Int) : Color, TextFormattable { - constructor(red: Int, green: Int, blue: Int) : this(((red and MASK) shl RED_SHIFT) or ((green and MASK) shl GREEN_SHIFT) or ((blue and MASK) shl BLUE_SHIFT)) + constructor(red: Int, green: Int, blue: Int) : this(((red.clamp() and MASK) shl RED_SHIFT) or ((green.clamp() and MASK) shl GREEN_SHIFT) or ((blue.clamp() and MASK) shl BLUE_SHIFT)) constructor(red: Float, green: Float, blue: Float) : this(Color.fromFloat(red), Color.fromFloat(green), Color.fromFloat(blue)) constructor(rgb: Vec3) : this(rgb.r, rgb.g, rgb.b) @@ -87,7 +88,7 @@ value class RGBColor(override val rgb: Int) : Color, TextFormattable { val int = Integer.parseUnsignedInt(string, 16) val rgb = when (string.length) { 6 -> int - 8 -> int ushr BITS // rgba + 8 -> int ushr BITS else -> throw IllegalArgumentException("Invalid color string: $this") } return RGBColor(rgb) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/NativeShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/NativeShader.kt index 6de1c32c7..1839158f2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/NativeShader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/NativeShader.kt @@ -76,6 +76,7 @@ interface NativeShader { is Vec3 -> setVec3(uniformName, data) is Vec2 -> setVec2(uniformName, data) is RGBColor -> setRGBColor(uniformName, data) + is RGBAColor -> setRGBAColor(uniformName, data) is UniformBuffer -> setUniformBuffer(uniformName, data) // ToDo: PNGTexture is Boolean -> setBoolean(uniformName, data) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/SkinManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/SkinManager.kt index 9b2950378..70541c8a8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/SkinManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/SkinManager.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2024 Moritz Zwerger + * Copyright (C) 2020-2025 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -105,7 +105,7 @@ class SkinManager(private val textures: TextureManager) { } private fun TextureBuffer.isReallyWide(): Boolean { - // check if pixel at arm (wide, not slim) is black. If not, its a wide skinn + // check if pixel at arm (wide, not slim) is black. If not, its a wide skin if (!this[50, 16].isBlack()) return true // left arm slim if (!this[42, 48].isBlack()) return true // right arm slim diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt index a66877bcf..48bd2c383 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt @@ -75,9 +75,9 @@ object TextureUtil { var rgba = RGBAColor(image.raster.getSample(x, y, samples[0]), image.raster.getSample(x, y, samples[1]), image.raster.getSample(x, y, samples[2])) if (samples.size > 3) { - rgba = rgba.with(image.raster.getSample(x, y, samples[3])) + rgba = rgba.with(alpha = image.raster.getSample(x, y, samples[3])) } else { - rgba = rgba.with(image.alphaRaster?.getSample(x, y, 0) ?: 0xFF) + rgba = rgba.with(alpha = image.alphaRaster?.getSample(x, y, 0) ?: 0xFF) } buffer.setRGBA(x, y, rgba) } diff --git a/src/test/java/de/bixilon/minosoft/data/text/formatting/color/ChatColorsTest.kt b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/ChatColorsTest.kt new file mode 100644 index 000000000..54929f446 --- /dev/null +++ b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/ChatColorsTest.kt @@ -0,0 +1,40 @@ +/* + * Minosoft + * Copyright (C) 2020-2025 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.text.formatting.color + +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class ChatColorsTest { + + @Test + fun `get yellow`() { + assertEquals(ChatColors["yellow"], RGBAColor(255, 255, 85)) + } + + @Test + fun `get name of gold`() { + assertEquals(ChatColors.NAME_MAP.getKey(RGBAColor(255, 170, 0)), "gold") + } + + @Test + fun `get a`() { + assertEquals(ChatColors.VALUES.getOrNull(Character.digit('a', 16)), RGBAColor(85, 255, 85)) + } + + @Test + fun `get char of red`() { + assertEquals(ChatColors.getChar(RGBAColor(170, 0, 0)), "4") + } +} diff --git a/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColorTest.kt b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColorTest.kt index 615d0a483..0a8eba9bf 100644 --- a/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColorTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBAColorTest.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.data.text.formatting.color +import de.bixilon.minosoft.data.text.formatting.color.RGBAColor.Companion.rgba import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -85,5 +86,16 @@ class RGBAColorTest { assertEquals(color.rgb(), RGBColor(0x12, 0x34, 0x56)) } - // TODO: operations (plus, times), conversion, toString, Int::rgb, Int::rgba, mix + @Test + fun `int to rgba`() { + assertEquals(0x12345678.rgba(), RGBAColor(0x12, 0x34, 0x56, 0x78)) + } + + @Test + fun `string to rgba`() { + assertEquals("#123456".rgba(), RGBAColor(0x12, 0x34, 0x56)) + assertEquals("#12345678".rgba(), RGBAColor(0x12, 0x34, 0x56, 0x78)) + } + + // TODO: operations (plus, times), toString, mix } diff --git a/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBColorTest.kt b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBColorTest.kt index 4268aa724..575b98a06 100644 --- a/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBColorTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/text/formatting/color/RGBColorTest.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.data.text.formatting.color +import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.rgb import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -73,5 +74,16 @@ class RGBColorTest { assertEquals(color.rgba(), RGBAColor(0x12, 0x34, 0x56, 0xFF)) } - // TODO: operations (plus, times), conversion, toString, Int::rgb, Int::rgba, mix + @Test + fun `int to rgb`() { + assertEquals(0x123456.rgb(), RGBColor(0x12, 0x34, 0x56)) + } + + @Test + fun `string to rgb`() { + assertEquals("#123456".rgb(), RGBColor(0x12, 0x34, 0x56)) + assertEquals("#12345678".rgb(), RGBColor(0x12, 0x34, 0x56)) + } + + // TODO: operations (plus, times), toString, Int::rgb, Int::rgba, mix }