Begrudgingly support letter tiles

This commit is contained in:
Eevee (Evelyn Woods) 2020-08-29 02:10:27 -06:00
parent a2e1a4fd9a
commit b3a0ff963c
4 changed files with 111 additions and 32 deletions

View File

@ -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,15 +312,14 @@ 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;
for (let n = 0; n < width * height; n++) {
let cell = new util.StoredCell; function read_spec() {
while (true) {
let tile_byte = bytes[p]; let tile_byte = bytes[p];
p++; p++;
if (tile_byte >= 0x76 && tile_byte <= 0x78) { if (tile_byte >= 0x77 && tile_byte <= 0x78) {
// XXX handle these modifier "tiles" // XXX handle these modifier "tiles"
p += tile_byte - 0x75; p += tile_byte - 0x75;
continue; return [];
} }
let spec = TILE_ENCODING[tile_byte]; let spec = TILE_ENCODING[tile_byte];
if (! spec) if (! spec)
@ -330,12 +328,33 @@ export function parse_level(buf) {
let name; let name;
let args = []; let args = [];
if (spec instanceof Array) { if (spec instanceof Array) {
[name, ...args] = spec; return spec;
} }
else { else {
name = spec; return [spec];
} }
let tile = {name}; }
for (let n = 0; n < width * height; n++) {
let cell = new util.StoredCell;
while (true) {
let [name, ...args] = read_spec();
if (name === undefined) continue; // XXX modifier skip hack
let modifier;
if (name === '#mod8') {
if (args[0] !== '#next')
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`);
}
let tile = {name, modifier};
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);

View File

@ -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) {

View File

@ -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);
}
} }
} }

View File

@ -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,