Skip to content

Commit

Permalink
decal: Add items and API.
Browse files Browse the repository at this point in the history
  • Loading branch information
freezy committed Oct 9, 2019
1 parent d6d7a86 commit a054e7c
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 0 deletions.
80 changes: 80 additions & 0 deletions lib/vpt/decal/decal-api.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import * as chai from 'chai';
import { expect } from 'chai';
import sinonChai = require('sinon-chai');
import { ThreeHelper } from '../../../test/three.helper';
import { Player } from '../../game/player';
import { NodeBinaryReader } from '../../io/binary-reader.node';
import { DecalType, ImageAlignment, SizingType } from '../enums';
import { Table } from '../table/table';

/* tslint:disable:no-unused-expression */
chai.use(sinonChai);
const three = new ThreeHelper();

describe('The VPinball decal API', () => {

let table: Table;
let player: Player;

beforeEach(async () => {
table = await Table.load(new NodeBinaryReader(three.fixturePath('table-decal.vpx')));
player = new Player(table).init();
});

it('should correctly read and write the properties', async () => {
const decal = table.decals.Decal001.getApi();

decal.Rotation = 128;
decal.Image = 'test_pattern';
decal.Width = 1685;
decal.Height = 115;
decal.X = 304;
decal.Y = 1.8;
decal.Surface = 'surface';
decal.Type = DecalType.Image; expect(decal.Type).to.equal(DecalType.Image);
decal.Type = DecalType.Text;
decal.Text = 'Text';
decal.SizingType = SizingType.AutoSize; expect(decal.SizingType).to.equal(SizingType.AutoSize);
decal.SizingType = SizingType.AutoWidth;
decal.FontColor = 0x913a8d;
decal.Material = 'Material';
decal.Font = 'Font';
decal.HasVerticalText = true; expect(decal.HasVerticalText).to.equal(true);
decal.HasVerticalText = false;

expect(decal.Rotation).to.equal(128);
expect(decal.Image).to.equal('test_pattern');
expect(decal.Width).to.equal(1685);
expect(decal.Height).to.equal(115);
expect(decal.X).to.equal(304);
expect(decal.Y).to.be.closeTo(1.8, 0.0001);
expect(decal.Surface).to.equal('surface');
expect(decal.Type).to.equal(DecalType.Text);
expect(decal.Text).to.equal('Text');
expect(decal.SizingType).to.equal(SizingType.AutoWidth);
expect(decal.FontColor).to.equal(0x913a8d);
expect(decal.Material).to.equal('Material');
expect(decal.Font).to.equal('Font');
expect(decal.HasVerticalText).to.equal(false);
});

});
54 changes: 54 additions & 0 deletions lib/vpt/decal/decal-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { ItemApi } from '../item-api';
import { DecalData } from './decal-data';

export class DecalApi extends ItemApi<DecalData> {

get Rotation() { return this.data.rotation; }
set Rotation(v) { this.data.rotation = v; }
get Image() { return this.data.szImage; }
set Image(v) { this._assertNonHdrImage(v); this.data.szImage = v; }
get Width() { return this.data.width; }
set Width(v) { this.data.width = v; }
get Height() { return this.data.height; }
set Height(v) { this.data.height = v; }
get X() { return this.data.center.x; }
set X(v) { this.data.center.x = v; }
get Y() { return this.data.center.y; }
set Y(v) { this.data.center.y = v; }
get Surface() { return this.data.szSurface; }
set Surface(v) { this.data.szSurface = v; }
get Type() { return this.data.decalType; }
set Type(v) { this.data.decalType = v; }
get Text() { return this.data.text; }
set Text(v) { this.data.text = v; }
get SizingType() { return this.data.sizingType; }
set SizingType(v) { this.data.sizingType = v; }
get FontColor() { return this.data.color; }
set FontColor(v) { this.data.color = v; }
get Material() { return this.data.szMaterial; }
set Material(v) { this.data.szMaterial = v; }
get Font() { return this.data.font; }
set Font(v) { this.data.font = v; }
get HasVerticalText() { return this.data.verticalText; }
set HasVerticalText(v) { this.data.verticalText = v; }

}
78 changes: 78 additions & 0 deletions lib/vpt/decal/decal-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { BiffParser } from '../../io/biff-parser';
import { Storage } from '../../io/ole-doc';
import { Vertex2D } from '../../math/vertex2d';
import { DecalType, SizingType } from '../enums';
import { ItemData } from '../item-data';

export class DecalData extends ItemData {

public center!: Vertex2D;
public width: number = 100.0;
public height: number = 100.0;
public rotation: number = 0.0;
public szImage?: string;
public szSurface?: string;
public text?: string;
public decalType: number = DecalType.Image;
public sizingType: number = SizingType.ManualSize;
public color: number = 0x000000;
public szMaterial?: string;
public verticalText: boolean = false;
private backglass: boolean = false;

public font: string = '';

public static async fromStorage(storage: Storage, itemName: string): Promise<DecalData> {
const decalData = new DecalData(itemName);
await storage.streamFiltered(itemName, 4, BiffParser.stream(decalData.fromTag.bind(decalData), {
streamedTags: [ 'FONT' ],
}));
return decalData;
}

private constructor(itemName: string) {
super(itemName);
}

private async fromTag(buffer: Buffer, tag: string, offset: number, len: number): Promise<number> {
switch (tag) {
case 'VCEN': this.center = Vertex2D.get(buffer); break;
case 'WDTH': this.width = this.getFloat(buffer); break;
case 'HIGH': this.height = this.getFloat(buffer); break;
case 'ROTA': this.rotation = this.getFloat(buffer); break;
case 'IMAG': this.szImage = this.getString(buffer, len); break;
case 'SURF': this.szSurface = this.getString(buffer, len); break;
case 'TEXT': this.text = this.getString(buffer, len); break;
case 'TYPE': this.decalType = this.getInt(buffer); break;
case 'SIZE': this.sizingType = this.getInt(buffer); break;
case 'COLR': this.color = BiffParser.bgrToRgb(this.getInt(buffer)); break;
case 'MATR': this.szMaterial = this.getString(buffer, len); break;
case 'VERT': this.verticalText = this.getBool(buffer); break;
case 'BGLS': this.backglass = this.getBool(buffer); break;
case 'FONT': break; // don't care for now
default:
this.getCommonBlock(buffer, tag, len);
break;
}
return 0;
}
}
54 changes: 54 additions & 0 deletions lib/vpt/decal/decal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { EventProxy } from '../../game/event-proxy';
import { IScriptable } from '../../game/iscriptable';
import { Player } from '../../game/player';
import { Storage } from '../../io/ole-doc';
import { Item } from '../item';
import { Table } from '../table/table';
import { DecalApi } from './decal-api';
import { DecalData } from './decal-data';

export class Decal extends Item<DecalData> implements IScriptable<DecalApi> {

private api?: DecalApi;

public static async fromStorage(storage: Storage, itemName: string): Promise<Decal> {
const data = await DecalData.fromStorage(storage, itemName);
return new Decal(data);
}

private constructor(data: DecalData) {
super(data);
}

public setupPlayer(player: Player, table: Table): void {
this.events = new EventProxy(this);
this.api = new DecalApi(this.data, this.events, player, table);
}

public getApi(): DecalApi {
return this.api!;
}

public getEventNames(): string[] {
return [];
}
}
11 changes: 11 additions & 0 deletions lib/vpt/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,14 @@ export class TextAlignment {
public static readonly Center = 1;
public static readonly Right = 2;
}

export class DecalType {
public static readonly Text = 0;
public static readonly Image = 1;
}

export class SizingType {
public static readonly AutoSize = 0;
public static readonly AutoWidth = 1;
public static readonly ManualSize = 2;
}
9 changes: 9 additions & 0 deletions lib/vpt/table/table-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { Timer } from '../timer/timer';
import { Trigger } from '../trigger/trigger';
import { TableLoadOptions } from './table';
import { TableData } from './table-data';
import { Decal } from '../decal/decal';

export class TableLoader {

Expand Down Expand Up @@ -124,6 +125,7 @@ export class TableLoader {
loadedTable.timers = [];
loadedTable.plungers = [];
loadedTable.textBoxes = [];
loadedTable.decals = [];

// go through all game items
for (let i = 0; i < numItems; i++) {
Expand Down Expand Up @@ -246,6 +248,12 @@ export class TableLoader {
return item;
}

case ItemType.Decal: {
const item = await Decal.fromStorage(storage, itemName);
loadedTable.decals!.push(item);
return item;
}

default:
// ignore the rest for now
return null;
Expand Down Expand Up @@ -307,6 +315,7 @@ export interface LoadedTable {
spinners?: Spinner[];
plungers?: Plunger[];
textBoxes?: Textbox[];
decals?: Decal[];

timers?: Timer[];
}
3 changes: 3 additions & 0 deletions lib/vpt/table/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { TableExportOptions } from './table-exporter';
import { TableHitGenerator } from './table-hit-generator';
import { LoadedTable, TableLoader } from './table-loader';
import { TableMeshGenerator } from './table-mesh-generator';
import { Decal } from '../decal/decal';

/**
* A Visual Pinball table.
Expand Down Expand Up @@ -100,6 +101,7 @@ export class Table implements IScriptable<TableApi> {
public readonly textboxes: { [key: string]: Textbox } = {};
public readonly timers: { [key: string]: Timer } = {};
public readonly triggers: { [key: string]: Trigger } = {};
public readonly decals: { [key: string]: Decal } = {};

private readonly meshGenerator?: TableMeshGenerator;
private readonly hitGenerator?: TableHitGenerator;
Expand Down Expand Up @@ -147,6 +149,7 @@ export class Table implements IScriptable<TableApi> {
[loadedTable.textBoxes, this.textboxes],
[loadedTable.timers, this.timers],
[loadedTable.triggers, this.triggers],
[loadedTable.decals, this.decals],
];
for (const m of mapping) {
if (isLoaded(m[0])) {
Expand Down
Binary file added test/fixtures/table-decal.vpx
Binary file not shown.

0 comments on commit a054e7c

Please sign in to comment.