1 module pixelatrix.bpp2; 2 3 import pixelatrix.common; 4 import siryul; 5 6 /++ 7 + 2 bit per pixel tile format with palette. Consists of two bitplanes stored 8 + one after the other. Commonly used by the NES. 9 + 10 + Params: data = a 16 byte array 11 + Returns: a decoded 8x8 tile. 12 +/ 13 deprecated ubyte[8][8] toPixelMatrix(ubyte[] data) @safe pure 14 in(data.length == 8 * 2, "Data length mismatch") 15 out(result; result.isValidBitmap!2) 16 { 17 return Linear2BPP(data[0 .. 8 * 2]).pixelMatrix; 18 } 19 align(1) struct Linear2BPP { 20 align(1): 21 ubyte[16] raw; 22 @SerializationMethod 23 string toBase64() const @safe { 24 import std.base64 : Base64; 25 return Base64.encode(raw[]); 26 } 27 ubyte[8][8] pixelMatrix() const @safe pure 28 out(result; result.isValidBitmap!2) 29 { 30 ubyte[8][8] output; 31 foreach (x; 0..8) { 32 foreach (y; 0..8) { 33 output[x][7-y] = cast(ubyte) 34 (((raw[x]&(1<<y))>>y) + 35 (((raw[x+8]&(1<<y))>>y)<<1)); 36 } 37 } 38 return output; 39 } 40 } 41 /// 42 @safe pure unittest { 43 import std.string : representation; 44 const data = Linear2BPP(import("bpp2-sample1.bin").representation[0 .. 8 * 2]); 45 const ubyte[][] finaldata = [ 46 [0, 3, 2, 2, 2, 2, 3, 2], 47 [0, 0, 3, 2, 2, 2, 2, 2], 48 [0, 0, 3, 3, 3, 0, 3, 3], 49 [0, 3, 3, 3, 0, 0, 0, 3], 50 [0, 3, 0, 3, 3, 3, 3, 3], 51 [0, 3, 0, 3, 3, 3, 3, 3], 52 [0, 0, 3, 0, 1, 1, 3, 3], 53 [0, 0, 0, 3, 1, 1, 3, 2]]; 54 assert(data.pixelMatrix() == finaldata); 55 } 56 57 /++ 58 + 2 bit per pixel tile format with palette. Each row has its bitplanes stored 59 + adjacent to one another. Commonly used by SNES and Gameboy. 60 + 61 + Params: data = a 16 byte array 62 + Returns: a decoded 8x8 tile. 63 +/ 64 deprecated ubyte[8][8] toPixelMatrixIntertwined(ubyte[] data) @safe pure 65 in(data.length == 8 * 2, "Data length mismatch") 66 out(result; result.isValidBitmap!2) 67 { 68 return Intertwined2BPP(data[0 .. 8 * 2]).pixelMatrix; 69 } 70 align(1) struct Intertwined2BPP { 71 align(1): 72 ubyte[16] raw; 73 @SerializationMethod 74 string toBase64() const @safe { 75 import std.base64 : Base64; 76 return Base64.encode(raw[]); 77 } 78 ubyte[8][8] pixelMatrix() const @safe pure 79 out(result; result.isValidBitmap!2) 80 { 81 ubyte[8][8] output; 82 foreach (x; 0..8) { 83 foreach (y; 0..8) { 84 output[x][7-y] = cast(ubyte) 85 (((raw[x*2]&(1<<y))>>y) + 86 (((raw[x*2+1]&(1<<y))>>y)<<1)); 87 } 88 } 89 return output; 90 } 91 } 92 /// 93 @safe pure unittest { 94 import std.string : representation; 95 const data = Intertwined2BPP(import("bpp2-sample2.bin").representation[0 .. 8 * 2]); 96 const ubyte[][] finaldata = [ 97 [0, 3, 2, 2, 2, 2, 3, 2], 98 [0, 0, 3, 2, 2, 2, 2, 2], 99 [0, 0, 3, 3, 3, 0, 3, 3], 100 [0, 3, 3, 3, 0, 0, 0, 3], 101 [0, 3, 0, 3, 3, 3, 3, 3], 102 [0, 3, 0, 3, 3, 3, 3, 3], 103 [0, 0, 3, 0, 1, 1, 3, 3], 104 [0, 0, 0, 3, 1, 1, 3, 2]]; 105 assert(data.pixelMatrix() == finaldata); 106 }