Skip to content

Commit

Permalink
support x,y indexing
Browse files Browse the repository at this point in the history
  • Loading branch information
Herringway committed Aug 15, 2022
1 parent 65cddef commit d0f5aa1
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 52 deletions.
25 changes: 22 additions & 3 deletions source/pixelatrix/bpp1.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ align(1) struct Simple1BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID] |= cast(ubyte)((col == 1) << (row.length - 1 - colID));
this[rowID, colID] = !!col;
}
}
}
Expand All @@ -27,12 +27,18 @@ align(1) struct Simple1BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
((raw[x]&(1<<y))>>y);
output[x][y] = this[x, y];
}
}
return output;
}
bool opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], x * 8 + y);
}
bool opIndexAssign(bool val, size_t x, size_t y) @safe pure {
setBit(raw[], x * 8 + y, val);
return val;
}
}
///
@safe pure unittest {
Expand All @@ -49,4 +55,17 @@ align(1) struct Simple1BPP {
[0, 0, 0, 1, 1, 1, 1, 0]];
assert(data.pixelMatrix() == finaldata);
assert(Simple1BPP(data.pixelMatrix()) == data);
foreach (x; 0 .. 8) {
foreach (y; 0 .. 8) {
assert(data[x, y] == finaldata[x][y]);
}
}
Simple1BPP data2 = data;
assert(data2[3, 3]);
assert(!data2[3, 4]);
data2[3, 4] = true;
assert(data2[3, 4]);
data2[3, 4] = false;
assert(!data2[3, 4]);
assert(data2 == data);
}
34 changes: 24 additions & 10 deletions source/pixelatrix/bpp2.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ align(1) struct Linear2BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID] |= cast(ubyte)((col & 1) << (row.length - 1 - colID));
raw[rowID + 8] |= cast(ubyte)(((col & 2) >> 1) << (row.length - 1 - colID));
this[rowID, colID] = col;
}
}
}
Expand All @@ -29,13 +28,19 @@ align(1) struct Linear2BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
(((raw[x]&(1<<y))>>y) +
(((raw[x+8]&(1<<y))>>y)<<1));
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], x * 8 + y) | (getBit(raw[], (x + 8) * 8 + y) << 1);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
setBit(raw[], x * 8 + y, val & 1);
setBit(raw[], (x + 8) * 8 + y, (val >> 1) & 1);
return val;
}
}
///
@safe pure unittest {
Expand All @@ -50,8 +55,12 @@ align(1) struct Linear2BPP {
[0, 3, 0, 3, 3, 3, 3, 3],
[0, 0, 3, 0, 1, 1, 3, 3],
[0, 0, 0, 3, 1, 1, 3, 2]];
assert(data[0, 1] == 3);
assert(data.pixelMatrix() == finaldata);
assert(Linear2BPP(data.pixelMatrix()) == data);
Linear2BPP data2 = data;
data2[0, 1] = 2;
assert(data2[0, 1] == 2);
}

/++
Expand All @@ -70,8 +79,7 @@ align(1) struct Intertwined2BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * 2] |= cast(ubyte)((col & 1) << (row.length - 1 - colID));
raw[(rowID * 2) + 1] |= cast(ubyte)(((col & 2) >> 1) << (row.length - 1 - colID));
this[rowID, colID] = col;
}
}
}
Expand All @@ -81,13 +89,19 @@ align(1) struct Intertwined2BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
(((raw[x*2]&(1<<y))>>y) +
(((raw[x*2+1]&(1<<y))>>y)<<1));
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], (x * 2) * 8 + y) | (getBit(raw[], (x * 2 + 1) * 8 + y) << 1);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
setBit(raw[], (x * 2) * 8 + y, val & 1);
setBit(raw[], ((x * 2) + 1) * 8 + y, (val >> 1) & 1);
return val;
}
}
///
@safe pure unittest {
Expand Down
20 changes: 13 additions & 7 deletions source/pixelatrix/bpp3.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ align(1) struct Intertwined3BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * 2] |= cast(ubyte)((col & 1) << (row.length - 1 - colID));
raw[(rowID * 2) + 1] |= cast(ubyte)(((col & 2) >> 1) << (row.length - 1 - colID));
raw[rowID + 16] |= cast(ubyte)(((col & 4) >> 2) << (row.length - 1 - colID));
this[rowID, colID] = col;
}
}
}
Expand All @@ -27,14 +25,22 @@ align(1) struct Intertwined3BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
(((raw[x*2]&(1<<y))>>y) +
(((raw[x*2+1]&(1<<y))>>y)<<1) +
(((raw[16 + x]&(1<<y))>>y)<<2));
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], (x * 2) * 8 + y) |
(getBit(raw[], ((x * 2) + 1) * 8 + y) << 1) |
(getBit(raw[], (x + 16) * 8 + y) << 2);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
setBit(raw[], (x * 2) * 8 + y, val & 1);
setBit(raw[], ((x * 2) + 1) * 8 + y, (val >> 1) & 1);
setBit(raw[], (x + 16) * 8 + y, (val >> 2) & 1);
return val;
}
}
///
@safe pure unittest {
Expand Down
42 changes: 29 additions & 13 deletions source/pixelatrix/bpp4.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ align(1) struct Intertwined4BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * 2] |= cast(ubyte)((col & 1) << (row.length - 1 - colID));
raw[(rowID * 2) + 1] |= cast(ubyte)(((col & 2) >> 1) << (row.length - 1 - colID));
raw[16 + (rowID * 2)] |= cast(ubyte)(((col & 4) >> 2) << (row.length - 1 - colID));
raw[16 + (rowID * 2) + 1] |= cast(ubyte)(((col & 8) >> 3) << (row.length - 1 - colID));
this[rowID, colID] = col;
}
}
}
Expand All @@ -28,15 +25,24 @@ align(1) struct Intertwined4BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
(((raw[x*2]&(1<<y))>>y) +
(((raw[x*2+1]&(1<<y))>>y)<<1) +
(((raw[16 + x*2]&(1<<y))>>y)<<2) +
(((raw[16 + x*2 + 1]&(1<<y))>>y)<<3));
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], (x * 2) * 8 + y) |
(getBit(raw[], ((x * 2) + 1) * 8 + y) << 1) |
(getBit(raw[], ((x * 2) + 16) * 8 + y) << 2) |
(getBit(raw[], ((x * 2) + 1 + 16) * 8 + y) << 3);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
setBit(raw[], (x * 2) * 8 + y, val & 1);
setBit(raw[], ((x * 2) + 1) * 8 + y, (val >> 1) & 1);
setBit(raw[], ((x * 2) + 16) * 8 + y, (val >> 2) & 1);
setBit(raw[], ((x * 2) + 1 + 16) * 8 + y, (val >> 3) & 1);
return val;
}
}
///
@safe pure unittest {
Expand Down Expand Up @@ -69,20 +75,30 @@ align(1) struct GBA4BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * row.length / 2 + colID / 2] |= cast(ubyte)((col & 0xF) << (4 * (colID % 2)));
this[rowID, colID] = col;
}
}
}
ubyte[8][8] pixelMatrix() const @safe pure
out(result; result.isValidBitmap!4)
{
ubyte[8][8] output;
foreach (i, b; raw) {
output[i / 4][(i % 4) * 2] = b&0xF;
output[i / 4][(i % 4) * 2 + 1] = (b&0xF0) >> 4;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return (raw[x * 4 + y / 2] & (0xF << ((y & 1) * 4))) >> ((y & 1) * 4);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
const mask = (0xF << ((~y & 1) * 4)) >> ((~y & 1) * 4);
const newBit = (val & 0xF) << ((y & 1) * 4);
raw[x * 4 + y / 2] = (raw[x * 4 + y / 2] & mask) | newBit;
return val;
}
}
///
@safe pure unittest {
Expand Down
46 changes: 27 additions & 19 deletions source/pixelatrix/bpp8.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ align(1) struct Linear8BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * row.length + colID] = col;
this[rowID, colID] = col;
}
}
}
Expand All @@ -28,6 +28,9 @@ align(1) struct Linear8BPP {
}
return output;
}
ref inout(ubyte) opIndex(size_t x, size_t y) inout @safe pure return {
return raw[x * 8 + y];
}
}
///
@safe pure unittest {
Expand Down Expand Up @@ -59,14 +62,7 @@ align(1) struct Intertwined8BPP {
this(in ubyte[8][8] tile) @safe pure {
foreach (rowID, row; tile) {
foreach (colID, col; row) {
raw[rowID * 2] |= cast(ubyte)((col & 1) << (row.length - 1 - colID));
raw[(rowID * 2) + 1] |= cast(ubyte)(((col & 2) >> 1) << (row.length - 1 - colID));
raw[16 + (rowID * 2)] |= cast(ubyte)(((col & 4) >> 2) << (row.length - 1 - colID));
raw[16 + (rowID * 2) + 1] |= cast(ubyte)(((col & 8) >> 3) << (row.length - 1 - colID));
raw[32 + (rowID * 2)] |= cast(ubyte)(((col & 16) >> 4) << (row.length - 1 - colID));
raw[32 + (rowID * 2) + 1] |= cast(ubyte)(((col & 32) >> 5) << (row.length - 1 - colID));
raw[48 + (rowID * 2)] |= cast(ubyte)(((col & 64) >> 6) << (row.length - 1 - colID));
raw[48 + (rowID * 2) + 1] |= cast(ubyte)(((col & 128) >> 7) << (row.length - 1 - colID));
this[rowID, colID] = col;
}
}
}
Expand All @@ -76,20 +72,32 @@ align(1) struct Intertwined8BPP {
ubyte[8][8] output;
foreach (x; 0..8) {
foreach (y; 0..8) {
output[x][7-y] = cast(ubyte)
(((raw[(8 * 0) + x*2]&(1<<y))>>y) +
(((raw[(8 * 0) + x*2+1]&(1<<y))>>y)<<1) +
(((raw[(8 * 2) + x*2]&(1<<y))>>y)<<2) +
(((raw[(8 * 2) + x*2 + 1]&(1<<y))>>y)<<3) +
(((raw[(8 * 4) + x*2]&(1<<y))>>y)<<4) +
(((raw[(8 * 4) + x*2 + 1]&(1<<y))>>y)<<5) +
(((raw[(8 * 6) + x*2]&(1<<y))>>y)<<6) +
(((raw[(8 * 6) + x*2 + 1]&(1<<y))>>y)<<7)
);
output[x][y] = this[x, y];
}
}
return output;
}
ubyte opIndex(size_t x, size_t y) const @safe pure {
return getBit(raw[], (x * 2) * 8 + y) |
(getBit(raw[], ((x * 2) + 1) * 8 + y) << 1) |
(getBit(raw[], ((x * 2) + 16) * 8 + y) << 2) |
(getBit(raw[], ((x * 2) + 1 + 16) * 8 + y) << 3) |
(getBit(raw[], ((x * 2) + 32) * 8 + y) << 4) |
(getBit(raw[], ((x * 2) + 32 + 1) * 8 + y) << 5) |
(getBit(raw[], ((x * 2) + 48) * 8 + y) << 6) |
(getBit(raw[], ((x * 2) + 1 + 48) * 8 + y) << 7);
}
ubyte opIndexAssign(ubyte val, size_t x, size_t y) @safe pure {
setBit(raw[], (x * 2) * 8 + y, val & 1);
setBit(raw[], ((x * 2) + 1) * 8 + y, (val >> 1) & 1);
setBit(raw[], ((x * 2) + 16) * 8 + y, (val >> 2) & 1);
setBit(raw[], ((x * 2) + 1 + 16) * 8 + y, (val >> 3) & 1);
setBit(raw[], ((x * 2) + 32) * 8 + y, (val >> 4) & 1);
setBit(raw[], ((x * 2) + 1 + 32) * 8 + y, (val >> 5) & 1);
setBit(raw[], ((x * 2) + 48) * 8 + y, (val >> 6) & 1);
setBit(raw[], ((x * 2) + 1 + 48) * 8 + y, (val >> 7) & 1);
return val;
}
}
///
@safe pure unittest {
Expand Down
9 changes: 9 additions & 0 deletions source/pixelatrix/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,12 @@ ubyte[8][8][] pixelMatrices(const ubyte[] data, TileFormat format) @safe pure {
return fromFormat!GBA4BPP(data);
}
}

package void setBit(scope ubyte[] bytes, size_t index, bool value) @safe pure {
const mask = ~(1 << (7 - (index % 8)));
const newBit = value << (7 - (index % 8));
bytes[index / 8] = cast(ubyte)((bytes[index / 8] & mask) | newBit);
}
package bool getBit(in ubyte[] bytes, size_t index) @safe pure {
return !!(bytes[index / 8] & (1 << (7 - (index % 8))));
}

0 comments on commit d0f5aa1

Please sign in to comment.