194 lines
5.9 KiB
Go
194 lines
5.9 KiB
Go
package interpreters
|
|
|
|
import (
|
|
"math"
|
|
)
|
|
|
|
// RawValueFormatter provides the format function for given value.
|
|
// If nothing special is to be displayed, an empty string should be returned.
|
|
// The handler is responsible for adding the number value representation.
|
|
type RawValueFormatter func(value int) string
|
|
|
|
// RawValueHandler is for a simple value range.
|
|
type RawValueHandler func(minValue, maxValue int64, formatter RawValueFormatter)
|
|
|
|
// EnumValueHandler is for enumerated (mapped) values.
|
|
type EnumValueHandler func(values map[uint32]string)
|
|
|
|
// BitfieldHandler is for bitfields.
|
|
type BitfieldHandler func(values map[uint32]string)
|
|
|
|
// ObjectIDHandler is for object identifier in a level.
|
|
type ObjectIDHandler func()
|
|
|
|
// SpecialHandler is for rare occasions.
|
|
type SpecialHandler func()
|
|
|
|
// RotationHandler is for circular values.
|
|
type RotationHandler func(minValue, maxValue int64)
|
|
|
|
func basicToString(value int) string {
|
|
return ""
|
|
}
|
|
|
|
// RangedValue creates a field range for specific minimum and maximum values.
|
|
func RangedValue(minValue, maxValue int64) FieldRange {
|
|
return FormattedRangedValue(minValue, maxValue, basicToString)
|
|
}
|
|
|
|
// FormattedRangedValue is similar to RangedValue, and adds a formatting function.
|
|
func FormattedRangedValue(minValue, maxValue int64, formatter RawValueFormatter) FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.rangedValue(minValue, maxValue, formatter)
|
|
}
|
|
}
|
|
|
|
// EnumValue creates a field range describing enumerated values.
|
|
func EnumValue(values map[uint32]string) FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.enumValue(values)
|
|
}
|
|
}
|
|
|
|
// Bitfield creates a field range describing bitfield values.
|
|
func Bitfield(values map[uint32]string) FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.bitfield(values)
|
|
}
|
|
}
|
|
|
|
// ObjectID creates a field range describing object identifier.
|
|
func ObjectID() FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.objectIndex()
|
|
}
|
|
}
|
|
|
|
// RotationValue creates a field range for a rotational property.
|
|
func RotationValue(minValue, maxValue int64) FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.rotation(minValue, maxValue)
|
|
}
|
|
}
|
|
|
|
// SpecialValue creates a field range for special fields.
|
|
// Currently known special values:
|
|
// * BinaryCodedDecimal - for keypads storing their number as BCD
|
|
// * LevelTexture - index value into level texture list
|
|
// * MaterialOrLevelTexture - index value into level texture list, or material (bit 7 toggles)
|
|
// * VariableKey - for actions
|
|
// * VariableCondition - for action conditions
|
|
// * ObjectTriple - for 0x00CCSSTT selection
|
|
// * ObjectHeight - for level height value 0..255
|
|
// * MoveTileHeight - for change tile height action
|
|
// * TileHeight - tile heights
|
|
// * TileType - tile types
|
|
// * Unknown - It is unclear whether this field would have any effect, none identified so far
|
|
// * Ignored - Although values have been found in this field, they don't appear to have any effect
|
|
// * Mistake - It is assumed that these values should have been placed somewhere else. Typical example: Container content
|
|
// * Internal - Fields that are handled mainly by the engine and shouldn't be modified.
|
|
func SpecialValue(specialType string) FieldRange {
|
|
return func(simpl *Simplifier) bool {
|
|
return simpl.specialValue(specialType)
|
|
}
|
|
}
|
|
|
|
// Simplifier forwards descriptions in a way the requester can use.
|
|
type Simplifier struct {
|
|
rawValueHandler RawValueHandler
|
|
enumValueHandler EnumValueHandler
|
|
bitfieldHandler BitfieldHandler
|
|
objectIDHandler ObjectIDHandler
|
|
rotationHandler RotationHandler
|
|
specialHandler map[string]SpecialHandler
|
|
}
|
|
|
|
// NewSimplifier returns a new instance of a simplifier, with the minimal
|
|
// handler set.
|
|
func NewSimplifier(rawValueHandler RawValueHandler) *Simplifier {
|
|
return &Simplifier{
|
|
rawValueHandler: rawValueHandler,
|
|
specialHandler: make(map[string]SpecialHandler)}
|
|
}
|
|
|
|
func (simpl *Simplifier) rawValue(e *entry) {
|
|
max := int64(math.Pow(2, float64(e.count*8)))
|
|
if max == 256 {
|
|
simpl.rawValueHandler(0, 255, basicToString)
|
|
} else {
|
|
half := max / 2
|
|
simpl.rawValueHandler(-1, half-1, basicToString)
|
|
}
|
|
}
|
|
|
|
func (simpl *Simplifier) rangedValue(minValue, maxValue int64, formatter RawValueFormatter) bool {
|
|
simpl.rawValueHandler(minValue, maxValue, formatter)
|
|
return true
|
|
}
|
|
|
|
// SetEnumValueHandler registers the handler for enumerations.
|
|
func (simpl *Simplifier) SetEnumValueHandler(handler EnumValueHandler) {
|
|
simpl.enumValueHandler = handler
|
|
}
|
|
|
|
func (simpl *Simplifier) enumValue(values map[uint32]string) (result bool) {
|
|
if simpl.enumValueHandler != nil {
|
|
simpl.enumValueHandler(values)
|
|
result = true
|
|
}
|
|
return
|
|
}
|
|
|
|
// SetBitfieldHandler registers the handler for bitfields.
|
|
func (simpl *Simplifier) SetBitfieldHandler(handler BitfieldHandler) {
|
|
simpl.bitfieldHandler = handler
|
|
}
|
|
|
|
func (simpl *Simplifier) bitfield(values map[uint32]string) (result bool) {
|
|
if simpl.bitfieldHandler != nil {
|
|
simpl.bitfieldHandler(values)
|
|
result = true
|
|
}
|
|
return
|
|
}
|
|
|
|
// SetObjectIDHandler registers the handler for object indices.
|
|
func (simpl *Simplifier) SetObjectIDHandler(handler ObjectIDHandler) {
|
|
simpl.objectIDHandler = handler
|
|
}
|
|
|
|
func (simpl *Simplifier) objectIndex() (result bool) {
|
|
if simpl.objectIDHandler != nil {
|
|
simpl.objectIDHandler()
|
|
result = true
|
|
}
|
|
return
|
|
}
|
|
|
|
// SetSpecialHandler registers the handler for special values.
|
|
func (simpl *Simplifier) SetSpecialHandler(specialType string, handler SpecialHandler) {
|
|
simpl.specialHandler[specialType] = handler
|
|
}
|
|
|
|
func (simpl *Simplifier) specialValue(specialType string) (result bool) {
|
|
handler, existing := simpl.specialHandler[specialType]
|
|
if existing && (handler != nil) {
|
|
handler()
|
|
result = true
|
|
}
|
|
return
|
|
}
|
|
|
|
// SetRotationHandler registers the handler for rotation values.
|
|
func (simpl *Simplifier) SetRotationHandler(handler RotationHandler) {
|
|
simpl.rotationHandler = handler
|
|
}
|
|
|
|
func (simpl *Simplifier) rotation(minValue, maxValue int64) (result bool) {
|
|
if simpl.rotationHandler != nil {
|
|
simpl.rotationHandler(minValue, maxValue)
|
|
result = true
|
|
}
|
|
return
|
|
}
|