ChocolateBird/scripts/loaders/snes/structs.gd

111 lines
4.2 KiB
GDScript

#warning-ignore-all:shadowed_variable
#warning-ignore-all:unused_argument
const STRUCT := preload('res://scripts/struct.gd')
const GRAPHICS := preload('res://scripts/loaders/snes/graphics.gd')
class TileSNESMode7 extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS.mode7_to_tile(buffer.get_data(64))
class TileSNESMode7c extends STRUCT.StructType:
# Note that this will give a palette offset of 0, you will need to postprocess the values.
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS.mode7_compressed_to_tile(buffer.get_data(32)[1])
class TileSNES4bpp extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS._4plane_to_tile(buffer.get_data(32)[1])
class TileSNES3bpp extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS._3plane_to_tile(buffer.get_data(24)[1])
class TileSNES2bpp extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS._2plane_to_tile(buffer.get_data(16)[1])
class TileSNES1bpp extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS._1plane_to_tile(buffer.get_data(8)[1])
class ColorBGR555 extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
return GRAPHICS.bgr555_to_color(buffer.get_u16())
class PaletteOf555 extends STRUCT.StructType:
var length: int = 16
func _init(length: int):
self.length = length
func get_value(buffer: StreamPeer, leftover_bits: Array):
var array := PoolColorArray()
for i in self.length:
array.append(GRAPHICS.bgr555_to_color(buffer.get_u16()))
return array
class ItemCost extends STRUCT.StructType:
func get_value(buffer: StreamPeer, leftover_bits: Array):
var b0 := buffer.get_u8()
var mantissa := buffer.get_u8()
var exponent := b0 & 0x3F
var is_sellable := (b0 & 0x80) == 0
var is_sellprice_5gil := (b0 & 0x40) == 0x40
var buy_price := mantissa * int(pow(10, exponent))
var sell_price := -1 if not is_sellable else (5 if is_sellprice_5gil else buy_price/2)
return {'buy_price': buy_price, 'sell_price': sell_price}
# Unions aren't covered by my DSL yet
class EquipStatBonus extends STRUCT.StructType:
static func get_stat_bonuses(affected_stats: int, bonus: int, base: int = 0) -> Dictionary:
var stats := {Common.STAT_STR: base, Common.STAT_SPD: base, Common.STAT_VIT: base, Common.STAT_MAG: base}
if affected_stats & 0x1:
stats[Common.STAT_MAG] += bonus
if affected_stats & 0x2:
stats[Common.STAT_VIT] += bonus
if affected_stats & 0x4:
stats[Common.STAT_SPD] += bonus
if affected_stats & 0x8:
stats[Common.STAT_STR] += bonus
return stats
func get_value(buffer: StreamPeer, leftover_bits: Array):
var b0 := buffer.get_u8()
var is_stat_bonus = b0 >> 7
if is_stat_bonus:
var affected_stats := (b0 >> 3) & 0x0F # "0" maryoku, "1": tairyoku, "2": subayasa, "3": chikara
var stats := [{}, {}]
var bonus := b0 & 0x07
match bonus:
0:
return get_stat_bonuses(affected_stats, 1)
1:
return get_stat_bonuses(affected_stats, 2)
2:
return get_stat_bonuses(affected_stats, 3)
3: # unused? "+1/-1/+1/-1"
return {Common.STAT_STR: 1, Common.STAT_SPD: -1, Common.STAT_VIT: 1, Common.STAT_MAG: -1}
4: # unused? "-1 (to unselected stats)"
return get_stat_bonuses(affected_stats, 1, -1)
5: # Giant's Glove: +5 -5 +5 -5
return {Common.STAT_STR: 5, Common.STAT_SPD: -5, Common.STAT_VIT: 5, Common.STAT_MAG: -5}
6: # Bone Mail: -5 to unselected stats
return get_stat_bonuses(affected_stats, 5, -5)
7:
return get_stat_bonuses(affected_stats, 5)
else: # is Element bitfield
return {'elemental_bonus': b0 & 0x7F}
static func get_structtypes() -> Dictionary:
return {
'TileSNESMode7': TileSNESMode7.new(),
'TileSNESMode7c': TileSNESMode7c.new(),
'TileSNES4bpp': TileSNES4bpp.new(),
'TileSNES3bpp': TileSNES3bpp.new(),
'TileSNES2bpp': TileSNES2bpp.new(),
'TileSNES1bpp': TileSNES1bpp.new(),
'ColorBGR555': ColorBGR555.new(),
'Palette16Of555': PaletteOf555.new(16),
'Palette128Of555': PaletteOf555.new(128),
'ItemCost': ItemCost.new(),
'EquipStatBonus': EquipStatBonus.new(),
}