Planar Pics¶
These are only used for a few graphics, and are an artifact from the Doom beta era. They are laid out in an order that is very odd to modern graphics programmers, as it was explicitly designed to match the VGA's internal memory at the time, making loading fullscreen graphics as "simple" as a single memcopy. That being said, decoding the data isn't that hard once you know what to do.
Example of loading a planar pic in Odin
load_planar_pic :: proc(data: []byte, allocator := context.allocator, loc := #caller_location) -> (planar_pic: Planar_Pic) {
planar_pic.quarter_width = data[0]
planar_pic.height = data[1]
planar_pic.data = make([]byte, int(planar_pic.quarter_width) * 4 * int(planar_pic.height), allocator, loc)
image_data := data[2:][:int(planar_pic.quarter_width) * 4 * int(planar_pic.height)]
for part, i in image_data {
position := [2]int {i % int(planar_pic.quarter_width), (i / (int(planar_pic.quarter_width) * 4)) % (int(planar_pic.height) / 4)}
tile_pos := [2]int {(i / int(planar_pic.quarter_width)) % 4, i / (int(planar_pic.quarter_width) * 4 * (int(planar_pic.height) / 4))}
overall_pos := (position * 4) + {tile_pos.y, tile_pos.x}
index := (overall_pos.y * int(planar_pic.quarter_width) * 4) + overall_pos.x
planar_pic.data[index] = part
}
return
}
unload_snea :: proc(planar_pic: Planar_Pic, allocator := context.allocator, loc := #caller_location) {
delete(planar_pic.data, allocator, loc)
}