Begrudgingly support letter tiles
This commit is contained in:
parent
a2e1a4fd9a
commit
b3a0ff963c
@ -115,13 +115,12 @@ const TILE_ENCODING = {
|
|||||||
// 0x6e: (Unused) :
|
// 0x6e: (Unused) :
|
||||||
// 0x6f: Railroad sign : '#next'
|
// 0x6f: Railroad sign : '#next'
|
||||||
// 0x70: Custom wall (green) : Modifier allows other styles, see below
|
// 0x70: Custom wall (green) : Modifier allows other styles, see below
|
||||||
// TODO needs a preceding modifier but that's not done yet (and should enforce that a modifier is followed by a modifiable tile?)
|
0x71: ['#mod8', 'floor_letter'],
|
||||||
0x71: 'floor_letter',
|
|
||||||
// 0x72: Purple toggle wall :
|
// 0x72: Purple toggle wall :
|
||||||
// 0x73: Purple toggle floor :
|
// 0x73: Purple toggle floor :
|
||||||
// 0x74: (Unused) :
|
// 0x74: (Unused) :
|
||||||
// 0x75: (Unused) :
|
// 0x75: (Unused) :
|
||||||
// 0x76: 8-bit Modifier (see Modifier section below) : 1 modifier byte, Tile Specification for affected tile
|
0x76: ['#mod8', '#next'],
|
||||||
// 0x77: 16-bit Modifier (see Modifier section below) : 2 modifier bytes, Tile Specification for affected tile
|
// 0x77: 16-bit Modifier (see Modifier section below) : 2 modifier bytes, Tile Specification for affected tile
|
||||||
// 0x78: 32-bit Modifier (see Modifier section below) : 4 modifier bytes, Tile Specification for affected tile
|
// 0x78: 32-bit Modifier (see Modifier section below) : 4 modifier bytes, Tile Specification for affected tile
|
||||||
// 0x79: (Unused) : '#direction', '#next'
|
// 0x79: (Unused) : '#direction', '#next'
|
||||||
@ -313,29 +312,49 @@ export function parse_level(buf) {
|
|||||||
level.size_x = width;
|
level.size_x = width;
|
||||||
level.size_y = height;
|
level.size_y = height;
|
||||||
let p = 2;
|
let p = 2;
|
||||||
|
|
||||||
|
function read_spec() {
|
||||||
|
let tile_byte = bytes[p];
|
||||||
|
p++;
|
||||||
|
if (tile_byte >= 0x77 && tile_byte <= 0x78) {
|
||||||
|
// XXX handle these modifier "tiles"
|
||||||
|
p += tile_byte - 0x75;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
let spec = TILE_ENCODING[tile_byte];
|
||||||
|
if (! spec)
|
||||||
|
throw new Error(`Unrecognized tile type 0x${tile_byte.toString(16)}`);
|
||||||
|
|
||||||
|
let name;
|
||||||
|
let args = [];
|
||||||
|
if (spec instanceof Array) {
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [spec];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let n = 0; n < width * height; n++) {
|
for (let n = 0; n < width * height; n++) {
|
||||||
let cell = new util.StoredCell;
|
let cell = new util.StoredCell;
|
||||||
while (true) {
|
while (true) {
|
||||||
let tile_byte = bytes[p];
|
let [name, ...args] = read_spec();
|
||||||
p++;
|
if (name === undefined) continue; // XXX modifier skip hack
|
||||||
if (tile_byte >= 0x76 && tile_byte <= 0x78) {
|
|
||||||
// XXX handle these modifier "tiles"
|
|
||||||
p += tile_byte - 0x75;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let spec = TILE_ENCODING[tile_byte];
|
|
||||||
if (! spec)
|
|
||||||
throw new Error(`Unrecognized tile type 0x${tile_byte.toString(16)}`);
|
|
||||||
|
|
||||||
let name;
|
let modifier;
|
||||||
let args = [];
|
if (name === '#mod8') {
|
||||||
if (spec instanceof Array) {
|
if (args[0] !== '#next')
|
||||||
[name, ...args] = spec;
|
throw new Error(`Tile requires a preceding modifier`);
|
||||||
|
|
||||||
|
modifier = bytes[p];
|
||||||
|
p++;
|
||||||
|
let mod_marker;
|
||||||
|
[mod_marker, name, ...args] = read_spec();
|
||||||
|
if (mod_marker !== '#mod8')
|
||||||
|
throw new Error(`Expected a tile requiring a modifier`);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
name = spec;
|
let tile = {name, modifier};
|
||||||
}
|
|
||||||
let tile = {name};
|
|
||||||
cell.push(tile);
|
cell.push(tile);
|
||||||
let type = TILE_TYPES[name];
|
let type = TILE_TYPES[name];
|
||||||
if (!type) console.error(name);
|
if (!type) console.error(name);
|
||||||
|
|||||||
@ -84,7 +84,11 @@ class Tile {
|
|||||||
static from_template(tile_template, x, y) {
|
static from_template(tile_template, x, y) {
|
||||||
let type = TILE_TYPES[tile_template.name];
|
let type = TILE_TYPES[tile_template.name];
|
||||||
if (! type) console.error(tile_template.name);
|
if (! type) console.error(tile_template.name);
|
||||||
return new this(type, x, y, tile_template.direction);
|
let tile = new this(type, x, y, tile_template.direction);
|
||||||
|
if (type.load) {
|
||||||
|
type.load(tile, tile_template);
|
||||||
|
}
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ignores(name) {
|
ignores(name) {
|
||||||
|
|||||||
@ -1,6 +1,19 @@
|
|||||||
export const CC2_TILESET_LAYOUT = {
|
export const CC2_TILESET_LAYOUT = {
|
||||||
floor: [0, 2],
|
floor: [0, 2],
|
||||||
floor_letter: [2, 2],
|
floor_letter: [2, 2],
|
||||||
|
'floor_letter#ascii': {
|
||||||
|
x0: 0,
|
||||||
|
y0: 0,
|
||||||
|
width: 16,
|
||||||
|
height: 1,
|
||||||
|
},
|
||||||
|
'floor_letter#arrows': {
|
||||||
|
north: [14, 31],
|
||||||
|
east: [14.5, 31],
|
||||||
|
south: [15, 31],
|
||||||
|
west: [15.5, 31],
|
||||||
|
},
|
||||||
|
|
||||||
wall: [1, 2],
|
wall: [1, 2],
|
||||||
|
|
||||||
fire: [
|
fire: [
|
||||||
@ -89,10 +102,10 @@ export const CC2_TILESET_LAYOUT = {
|
|||||||
|
|
||||||
hint: [5, 2],
|
hint: [5, 2],
|
||||||
|
|
||||||
score_10: [14, 1],
|
score_10: [14, 2],
|
||||||
score_100: [13, 1],
|
score_100: [13, 2],
|
||||||
score_1000: [12, 1],
|
score_1000: [12, 2],
|
||||||
score_2x: [15, 1],
|
score_2x: [15, 2],
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX need to specify that you can't use this for cc2 levels, somehow
|
// XXX need to specify that you can't use this for cc2 levels, somehow
|
||||||
@ -247,10 +260,21 @@ export class Tileset {
|
|||||||
this.size_y = size_y;
|
this.size_y = size_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to draw to a canvas using tile coordinates
|
||||||
|
blit(ctx, sx, sy, dx, dy, scale = 1) {
|
||||||
|
let w = this.size_x * scale;
|
||||||
|
let h = this.size_y * scale;
|
||||||
|
ctx.drawImage(
|
||||||
|
this.image,
|
||||||
|
sx * this.size_x, sy * this.size_y, w, h,
|
||||||
|
dx * this.size_x, dy * this.size_y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
draw(tile, ctx, x, y) {
|
draw(tile, ctx, x, y) {
|
||||||
let drawspec = this.layout[tile.type.name];
|
let name = tile.type.name;
|
||||||
|
let drawspec = this.layout[name];
|
||||||
let coords = drawspec;
|
let coords = drawspec;
|
||||||
if (! coords) console.error(tile.type.name);
|
if (! coords) console.error(name);
|
||||||
if (!(coords instanceof Array)) {
|
if (!(coords instanceof Array)) {
|
||||||
// Must be an object of directions
|
// Must be an object of directions
|
||||||
coords = coords[tile.direction ?? 'south'];
|
coords = coords[tile.direction ?? 'south'];
|
||||||
@ -259,9 +283,38 @@ export class Tileset {
|
|||||||
coords = coords[0];
|
coords = coords[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage(
|
this.blit(ctx, coords[0], coords[1], x, y);
|
||||||
this.image,
|
|
||||||
coords[0] * this.size_x, coords[1] * this.size_y, this.size_x, this.size_y,
|
// Special behavior for special objects
|
||||||
x * this.size_x, y * this.size_y, this.size_x, this.size_y);
|
// TODO? hardcode this less?
|
||||||
|
if (name === 'floor_letter') {
|
||||||
|
let n = tile.ascii_code - 32;
|
||||||
|
let scale = 0.5;
|
||||||
|
let sx, sy;
|
||||||
|
if (n < 0) {
|
||||||
|
// Arrows
|
||||||
|
if (n < -4) {
|
||||||
|
// Default to south
|
||||||
|
n = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let direction = ['north', 'east', 'south', 'west'][n + 4];
|
||||||
|
[sx, sy] = this.layout['floor_letter#arrows'][direction];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// ASCII text (only up through uppercase)
|
||||||
|
let letter_spec = this.layout['floor_letter#ascii'];
|
||||||
|
if (n > letter_spec.width / scale * letter_spec.height / scale) {
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
let w = letter_spec.width / scale;
|
||||||
|
sx = (letter_spec.x0 + n % w) * scale;
|
||||||
|
sy = (letter_spec.y0 + Math.floor(n / w)) * scale;
|
||||||
|
}
|
||||||
|
let offset = (1 - scale) / 2;
|
||||||
|
this.blit(
|
||||||
|
ctx, sx, sy,
|
||||||
|
x + offset, y + offset, scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,9 @@ const TILE_TYPES = {
|
|||||||
floor: {
|
floor: {
|
||||||
},
|
},
|
||||||
floor_letter: {
|
floor_letter: {
|
||||||
|
load(me, template) {
|
||||||
|
me.ascii_code = template.modifier;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
wall: {
|
wall: {
|
||||||
blocks: true,
|
blocks: true,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user