mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 09:56:37 -04:00
some more color tests and fixes
This commit is contained in:
parent
83c3337f38
commit
a17f75c201
@ -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(),
|
||||
|
@ -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`() {
|
||||
|
@ -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<ChatComponent> = 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
|
||||
}
|
||||
}
|
||||
|
@ -130,12 +130,12 @@ open class TextComponent(
|
||||
}
|
||||
|
||||
fun copy(message: Any? = this.message, color: RGBAColor? = this.color, formatting: BitEnumSet<FormattingCodes> = 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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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")
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user