2022-11-09 04:29:26 +07:00
|
|
|
class_name RWRaster
|
|
|
|
extends RWChunk
|
|
|
|
|
2022-11-09 05:55:25 +07:00
|
|
|
enum {
|
|
|
|
FORMAT_DEFAULT = 0x0000,
|
|
|
|
FORMAT_1555 = 0x0100,
|
|
|
|
FORMAT_565 = 0x0200,
|
|
|
|
FORMAT_4444 = 0x0300,
|
|
|
|
FORMAT_LUM8 = 0x0400,
|
|
|
|
FORMAT_8888 = 0x0500,
|
|
|
|
FORMAT_888 = 0x0600,
|
|
|
|
FORMAT_555 = 0x0A00,
|
|
|
|
FORMAT_EXT_AUTO_MIPMAP = 0x1000,
|
|
|
|
FORMAT_EXT_PAL8 = 0x2000,
|
|
|
|
FORMAT_EXT_PAL4 = 0x4000,
|
|
|
|
FORMAT_EXT_MIPMAP = 0x8000
|
|
|
|
}
|
|
|
|
|
2022-11-09 04:29:26 +07:00
|
|
|
var platform_id: int
|
|
|
|
var filter_mode: int
|
|
|
|
var u_addressing: int
|
|
|
|
var v_addressing: int
|
|
|
|
var name: String
|
|
|
|
var mask_name: String
|
|
|
|
var raster_format: int
|
|
|
|
var has_alpha: bool
|
|
|
|
var width: int
|
|
|
|
var height: int
|
|
|
|
var depth: int
|
|
|
|
var num_levels: int
|
|
|
|
var raster_type: int
|
|
|
|
var compression: int
|
2022-11-11 03:37:25 +07:00
|
|
|
var _file: FileAccess
|
|
|
|
var _image_start: int
|
|
|
|
var image: Image: get = _load_image
|
2022-11-09 05:55:25 +07:00
|
|
|
|
2022-11-09 04:29:26 +07:00
|
|
|
func _init(file: FileAccess):
|
|
|
|
super(file)
|
2022-11-19 04:19:09 +07:00
|
|
|
assert(type == ChunkType.RASTER)
|
2022-11-09 04:29:26 +07:00
|
|
|
RWChunk.new(file)
|
|
|
|
platform_id = file.get_32()
|
|
|
|
filter_mode = file.get_8()
|
|
|
|
var uv_addressing = file.get_8()
|
|
|
|
u_addressing = uv_addressing >> 4
|
|
|
|
v_addressing = uv_addressing & 0xf
|
|
|
|
file.get_16()
|
|
|
|
name = file.get_buffer(32).get_string_from_ascii()
|
|
|
|
mask_name = file.get_buffer(32).get_string_from_ascii()
|
|
|
|
raster_format = file.get_32()
|
|
|
|
has_alpha = (true if file.get_32() > 0 else false)
|
|
|
|
width = file.get_16()
|
|
|
|
height = file.get_16()
|
|
|
|
depth = file.get_8()
|
|
|
|
num_levels = file.get_8()
|
|
|
|
raster_type = file.get_8()
|
|
|
|
compression = file.get_8()
|
2022-11-11 03:37:25 +07:00
|
|
|
_file = file
|
|
|
|
_image_start = file.get_position()
|
|
|
|
skip(file)
|
|
|
|
|
|
|
|
func _load_image():
|
2022-11-18 09:37:51 +07:00
|
|
|
_file.seek(_image_start)
|
|
|
|
var result: Image
|
|
|
|
var format: Image.Format
|
|
|
|
var read: int
|
|
|
|
match raster_format & 0x0f00:
|
|
|
|
# FORMAT_1555:
|
|
|
|
# format = FORMAT_1555
|
|
|
|
# read = 2
|
2022-11-18 11:31:04 +07:00
|
|
|
# FORMAT_565:
|
|
|
|
# format = Image.FORMAT_RGB565
|
|
|
|
# read = 2
|
|
|
|
# FORMAT_4444:
|
|
|
|
# format = Image.FORMAT_RGBA4444
|
|
|
|
# read = 2
|
|
|
|
FORMAT_8888:
|
|
|
|
format = Image.FORMAT_RGBA8
|
|
|
|
read = 4
|
|
|
|
FORMAT_888:
|
|
|
|
format = Image.FORMAT_RGB8
|
|
|
|
read = 3
|
2022-11-18 09:37:51 +07:00
|
|
|
_:
|
|
|
|
assert(false)
|
|
|
|
if raster_format & (FORMAT_EXT_PAL8 | FORMAT_EXT_PAL4):
|
|
|
|
var psize := (16 if raster_format & FORMAT_EXT_PAL4 else 256)
|
|
|
|
var palette := Image.create_from_data(psize, 1, false, format, _unpad(psize, read))
|
|
|
|
result = Image.create(width, height, raster_format & 0x8000, format)
|
|
|
|
_file.get_32()
|
|
|
|
for i in width * height:
|
|
|
|
var x := int(i % width)
|
|
|
|
var y := int(i / width)
|
|
|
|
var color := palette.get_pixel(_file.get_8(), 0)
|
|
|
|
result.set_pixel(x, y, color)
|
|
|
|
# elif format == FORMAT_1555:
|
|
|
|
# result = Image.create(width, height, raster_format & 0x8000, Image.FORMAT_RGBA8)
|
2022-11-18 11:31:04 +07:00
|
|
|
# _file.get_32()
|
2022-11-18 09:37:51 +07:00
|
|
|
# var unpadded := _unpad(width * height, read)
|
|
|
|
# var data := PackedInt32Array()
|
|
|
|
# for i in unpadded.size() / 2:
|
|
|
|
# var x := int(i % width)
|
|
|
|
# var y := int(i / width)
|
|
|
|
# var pixel := unpadded[i] | unpadded[i + 1] << 16
|
|
|
|
# var a := (pixel & 0x8000) >> 15
|
|
|
|
# var r := (pixel & 0x7c00) >> 10
|
|
|
|
# var g := (pixel & 0x03e0) >> 5
|
|
|
|
# var b := pixel & 0x001f
|
|
|
|
# result.set_pixel(
|
|
|
|
# x, y, Color(
|
|
|
|
# r / 0x1f,
|
|
|
|
# g / 0x1f,
|
|
|
|
# b / 0x1f,
|
|
|
|
# a
|
|
|
|
# )
|
|
|
|
# )
|
|
|
|
else:
|
2022-11-18 11:31:04 +07:00
|
|
|
var data := PackedByteArray()
|
2022-11-19 02:45:16 +07:00
|
|
|
var mip_width := width
|
|
|
|
var mip_height := height
|
2022-11-18 11:31:04 +07:00
|
|
|
for i in num_levels:
|
|
|
|
var raster_size := _file.get_32()
|
2022-11-19 02:45:16 +07:00
|
|
|
data.append_array(_unpad(mip_width * mip_height, read))
|
|
|
|
mip_width /= 2
|
|
|
|
mip_height /= 2
|
2022-11-18 11:31:04 +07:00
|
|
|
result = Image.create_from_data(width, height, raster_format & FORMAT_EXT_MIPMAP, format, data)
|
|
|
|
if raster_format & FORMAT_EXT_AUTO_MIPMAP:
|
|
|
|
image.generate_mipmaps()
|
2022-11-18 09:37:51 +07:00
|
|
|
# Perform color conversion
|
|
|
|
for i in width * height:
|
|
|
|
var x := int(i % width)
|
|
|
|
var y := int(i / width)
|
|
|
|
var old := result.get_pixel(x, y)
|
|
|
|
result.set_pixel(x, y, Color(old.b, old.g, old.r, old.a))
|
|
|
|
return result
|
|
|
|
|
|
|
|
func _unpad(length: int, read: int) -> PackedByteArray:
|
|
|
|
var result := PackedByteArray()
|
|
|
|
for i in length:
|
|
|
|
for j in read:
|
|
|
|
result.append(_file.get_8())
|
|
|
|
for j in 4 - read:
|
|
|
|
_file.get_8()
|
|
|
|
return result
|