mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-15 08:06:06 +09:00
working vital meter for tool durability
This commit is contained in:
88
src/net/torvald/dataclass/Float16.kt
Normal file
88
src/net/torvald/dataclass/Float16.kt
Normal file
@@ -0,0 +1,88 @@
|
||||
package net.torvald.dataclass
|
||||
|
||||
import kotlin.experimental.or
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/questions/6162651/half-precision-floating-point-in-java#6162687
|
||||
*
|
||||
* Created by SKYHi14 on 2017-04-21.
|
||||
*/
|
||||
typealias Float16Bits = Short
|
||||
|
||||
class Float16() {
|
||||
|
||||
var bits = 0.toShort()
|
||||
private set
|
||||
|
||||
constructor(fval: Float) : this() {
|
||||
fromFloat(fval)
|
||||
}
|
||||
|
||||
fun toFloat() = Float16.toFloat(bits)
|
||||
fun fromFloat(fval: Float) {
|
||||
bits = Float16.fromFloat(fval)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun toFloat(hbits: Short): Float {
|
||||
val hbits = hbits.toInt().and(0xFFFF)
|
||||
|
||||
var mant = hbits and 0x03ff // 10 bits mantissa
|
||||
var exp = hbits and 0x7c00 // 5 bits exponent
|
||||
if (exp == 0x7c00)
|
||||
// NaN/Inf
|
||||
exp = 0x3fc00 // -> NaN/Inf
|
||||
else if (exp != 0)
|
||||
// normalized value
|
||||
{
|
||||
exp += 0x1c000 // exp - 15 + 127
|
||||
if (mant == 0 && exp > 0x1c400)
|
||||
// smooth transition
|
||||
return java.lang.Float.intBitsToFloat(hbits and 0x8000 shl 16 or (exp shl 13) or 0x3ff)
|
||||
}
|
||||
else if (mant != 0)
|
||||
// && exp==0 -> subnormal
|
||||
{
|
||||
exp = 0x1c400 // make it normal
|
||||
do {
|
||||
mant = mant shl 1 // mantissa * 2
|
||||
exp -= 0x400 // decrease exp by 1
|
||||
} while (mant and 0x400 == 0) // while not normal
|
||||
mant = mant and 0x3ff // discard subnormal bit
|
||||
} // else +/-0 -> +/-0
|
||||
return java.lang.Float.intBitsToFloat(// combine all parts
|
||||
hbits and 0x8000 shl 16 or (exp or mant shl 13)) // value << ( 23 - 10 )
|
||||
}
|
||||
|
||||
fun fromFloat(fval: Float): Short {
|
||||
val fbits = java.lang.Float.floatToIntBits(fval)
|
||||
val sign = fbits.ushr(16).and(0x8000).toShort() // sign only
|
||||
var `val` = (fbits and 0x7fffffff) + 0x1000 // rounded value
|
||||
|
||||
if (`val` >= 0x47800000)
|
||||
// might be or become NaN/Inf
|
||||
{ // avoid Inf due to rounding
|
||||
if (fbits and 0x7fffffff >= 0x47800000) { // is or must become NaN/Inf
|
||||
if (`val` < 0x7f800000)
|
||||
// was value but too large
|
||||
return sign or 0x7c00 // make it +/-Inf
|
||||
return sign or 0x7c00 or // remains +/-Inf or NaN
|
||||
(fbits and 0x007fffff).ushr(13).toShort() // keep NaN (and Inf) bits
|
||||
}
|
||||
return sign or 0x7bff.toShort() // unrounded not quite Inf
|
||||
}
|
||||
if (`val` >= 0x38800000)
|
||||
// remains normalized value
|
||||
return sign or (`val` - 0x38000000).ushr(13).toShort() // exp - 127 + 15
|
||||
if (`val` < 0x33000000)
|
||||
// too small for subnormal
|
||||
return sign // becomes +/-0
|
||||
`val` = (fbits and 0x7fffffff).ushr(23) // tmp exp for subnormal calc
|
||||
|
||||
return sign or ((fbits and 0x7fffff or 0x800000) // add subnormal bit
|
||||
+ 0x800000.ushr(`val` - 102) // round depending on cut off
|
||||
).ushr(126 - `val`) // div by 2^(1-(exp-127+15)) and >> 13 | exp=0
|
||||
.toShort()
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/net/torvald/dataclass/HistoryArray.kt
Normal file
58
src/net/torvald/dataclass/HistoryArray.kt
Normal file
@@ -0,0 +1,58 @@
|
||||
package net.torvald.dataclass
|
||||
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
* Simple ArrayList wrapper that acts as history keeper. You can append any data but cannot delete.
|
||||
*
|
||||
* Created by minjaesong on 16-07-13.
|
||||
*/
|
||||
class HistoryArray<T>(val historyMax: Int) {
|
||||
|
||||
val history = ArrayList<T?>(Math.min(historyMax, 256)) // 256: arbitrary set upper bound
|
||||
|
||||
fun add(value: T) {
|
||||
if (history.size == 0) {
|
||||
history.add(value)
|
||||
return
|
||||
}
|
||||
// push existing values to an index
|
||||
else {
|
||||
for (i in history.size - 1 downTo 0) {
|
||||
// if history.size is smaller than historyMax, make room by appending
|
||||
if (i == history.size - 1 && i < historyMax - 1)
|
||||
history.add(history[i])
|
||||
// actually move if we have some room
|
||||
else if (i < historyMax - 1)
|
||||
history[i + 1] = history[i]
|
||||
}
|
||||
}
|
||||
// add new value to the room
|
||||
history[0] = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Get certain index from history. NOTE: index 0 means latest!
|
||||
*/
|
||||
operator fun get(index: Int): T? =
|
||||
if (index >= history.size) null
|
||||
else history[index]
|
||||
|
||||
/**
|
||||
* Iterate from latest to oldest
|
||||
*/
|
||||
fun iterator() = history.iterator()
|
||||
|
||||
/**
|
||||
* Iterate from latest to oldest
|
||||
*/
|
||||
fun forEach(action: (T?) -> Unit) = history.forEach(action)
|
||||
|
||||
val latest: T?
|
||||
get() = this[0]
|
||||
|
||||
val oldest: T?
|
||||
get() = this[history.size - 1]
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user