ChocolateBird/scripts/loaders/snes/graphics.gd

103 lines
3.0 KiB
GDScript

const globals = preload('res://globals.gd') # Make LSP shut up about non-const
var INDEX_FORMAT := globals.INDEX_FORMAT
static func ByteArray(size: int) -> PoolByteArray:
var arr := PoolByteArray()
arr.resize(size)
return arr
static func mode7_to_tile(data: PoolByteArray) -> Image:
# Easy one, it's just straight data left-to-right, top-to-bottom
var tile := Image.new()
tile.create_from_data(8, 8, false, Image.FORMAT_L8, data)
return tile
static func mode7_compressed_to_tile(data: PoolByteArray, tile_palette: int = 0) -> Image:
# 4 bits per pixel.
var tdata := ByteArray(64)
for i in 32:
var b := data[i]
var j: int = i*2
tdata[j] = (b & 0x0F) | tile_palette
tdata[j+1] = (b >> 4) | tile_palette
return mode7_to_tile(tdata)
static func _4plane_to_tile(data: PoolByteArray) -> Image:
var tdata := ByteArray(64)
for i in range(64):
var j = (i/8)*2
var x = 7 - (i%8)
tdata[i] = (data[j] >> x & 1) | ((data[j+1] >> x & 1)<<1) | ((data[j+16] >> x & 1)<<2) | ((data[j+17] >> x & 1)<<3)
var tile := Image.new()
tile.create_from_data(8, 8, false, Image.FORMAT_L8, tdata)
return tile
static func _3plane_to_tile(data: PoolByteArray) -> Image:
var tdata := ByteArray(64)
for i in range(64):
var j = (i/8)*2
var x = 7 - (i%8)
tdata[i] = (data[j] >> x & 1) | ((data[j+1] >> x & 1)<<1) | ((data[(i/8)+16] >> x & 1)<<2)
var tile := Image.new()
tile.create_from_data(8, 8, false, Image.FORMAT_L8, tdata)
return tile
static func _2plane_to_tile(data: PoolByteArray) -> Image:
var tdata := ByteArray(64)
for i in range(64):
var j = (i/8)*2
var x = 7 - (i%8)
tdata[i] = (data[j] >> x & 1) | ((data[j+1] >> x & 1)<<1)
var tile := Image.new()
tile.create_from_data(8, 8, false, Image.FORMAT_L8, tdata)
return tile
static func _1plane_to_tile(data: PoolByteArray) -> Image:
var tdata := ByteArray(64)
for i in range(64):
var x = 7 - (i%8)
tdata[i] = (data[i/8] >> x & 1)
var tile := Image.new()
tile.create_from_data(8, 8, false, Image.FORMAT_L8, tdata)
return tile
static func get_tile(rom: File, offset: int, length: int) -> Image:
rom.seek(offset)
var data := rom.get_buffer(length)
var planes := length / 8
match planes:
4:
return _4plane_to_tile(data)
3:
return _3plane_to_tile(data)
2:
return _2plane_to_tile(data)
_:
return _1plane_to_tile(data)
static func get_tritile(buffer: StreamPeer) -> Image:
# Converts 1bpp planar font tile to 16bpp image for convenience.
var tdata := ByteArray(384) # 16*12*2
for plane in 2:
for row in 12:
var byte = buffer.get_u8()
for bit in 8:
var idx: int = 2 * (bit + (plane*8) + (row*16))
if (byte >> (7-bit)) & 1:
tdata[idx] = 0xFF
tdata[idx+1] = 0xFF
else:
tdata[idx] = 0
tdata[idx+1] = 0
var tile := Image.new()
tile.create_from_data(16, 12, false, Image.FORMAT_LA8, tdata)
return tile
static func bgr555_to_color(short: int) -> Color:
var color = Color()
color.a = 1
color.r = ((short & 0x1F) / 31.0)
color.g = (((short >> 5) & 0x1F) / 31.0)
color.b = (((short >> 10) & 0x1F) / 31.0)
return color