Skip to content

Commit

Permalink
Implement object attributes override 🛞.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarty committed May 23, 2024
1 parent 3e45f53 commit c026038
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 10 deletions.
54 changes: 46 additions & 8 deletions src/containers/ScreenCanvasContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,20 @@ const draw = (
crop,
) => {
const { width, height } = room.header;
const { nametableObj, palette } = room.nametable;
const attributes = room.attributes;
const { palette } = room.nametable;
const baseTilesNum = baseTiles?.gfx?.length / 8 / 2;
const nametableObjCopy = nametableObj.map((arr) => arr.slice());
const nametableObj = structuredClone(room.nametable.nametableObj);
const attributes = structuredClone(room.attributes);

// Overwrite tiles with selected object.
// Overwrite tiles and palette with selected object.
// Start with highest id as it is the way it is implemented with overlapping object images.
for (let i = selectedObjects.length - 1; i >= 0; i--) {
const object = room?.objects[i];
const objectImage = room?.objectImages[i];
const x = room?.objects[i]?.x; // Can be 0?
const y = room?.objects[i]?.y; // Can be 0?
const x = object?.x; // Can be 0?
const y = object?.y; // Can be 0?
const width = object?.width;
const height = object?.height;

if (
!selectedObjects[i] ||
Expand All @@ -75,15 +78,50 @@ const draw = (

for (let j = 0; j < objectImage.tiles.length; j++) {
for (let i = 0; i < objectImage.tiles[j].length; i++) {
nametableObjCopy[y + j][x + i + 2] = objectImage.tiles[j][i];
nametableObj[y + j][x + i + 2] = objectImage.tiles[j][i];
}
}

// Port of https://github.com/scummvm/scummvm/blob/master/engines/scumm/gfx.cpp#L3103-L3134
let j = height >> 1;
let ay = y;
let ptr = 0;
while (j) {
let ax = x + 2;
let i = 0;
let adata = 0;
while (i < width >> 1) {
if (!(i & 3)) {
adata = objectImage.attributes[ptr++];
}

let aand = 3;
let aor = adata & 3;
if (ay & 0x02) {
aand <<= 4;
aor <<= 4;
}
if (ax & 0x02) {
aand <<= 2;
aor <<= 2;
}
const attr = attributes[((ay << 2) & 0x30) | ((ax >> 2) & 0xf)];
attributes[((ay << 2) & 0x30) | ((ax >> 2) & 0xf)] =
(~aand & attr) | aor;

adata >>= 2;
ax += 2;
i++;
}
ay += 2;
j--;
}
}

// Now generate the image of the room.
for (let sprY = 0; sprY < height; sprY++) {
for (let sprX = 0; sprX < 62; sprX++) {
let tile = nametableObjCopy[sprY][sprX];
let tile = nametableObj[sprY][sprX];

let gfx = baseTiles?.gfx;
if (tile >= baseTilesNum) {
Expand Down
14 changes: 12 additions & 2 deletions src/lib/parser/parseRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,19 @@ const parseRooms = (arrayBuffer, i = 0, offset = 0, characters = {}) => {
}
}

// @todo Implement attribute changes and mask tables for object images.
// Parse object attrtable override.
const attributes = [];
if (tiles?.length) {
// Is that this length number of bytes to parse?
for (let i = 0; i < (objWidth >> 1) * (objHeight >> 1); i++) {
attributes.push(objectImagesParser.getUint8());
}
}

const objectImage = { tiles, attributes };
objectImages.push(objectImage);

objectImages.push({ tiles });
// @todo Implement mask tables for object images.

// @fixme This does not account for object scripts.
if (objectCodeMap.to < objectOffs + objectImagesParser.pointer) {
Expand Down

0 comments on commit c026038

Please sign in to comment.