node-insim
Version:
An InSim library for NodeJS with TypeScript support
200 lines (199 loc) • 7.58 kB
JavaScript
import { __decorate } from "tslib";
import unicodeToLfs from 'unicode-to-lfs';
import { byte, string } from '../decorators';
import { SendablePacket } from './base';
import { PacketType } from './enums';
/**
* BuTtoN - button header - followed by 0 to 240 characters
*
* You can make up to 240 buttons appear on the host or guests (ID = 0 to 239).
* You should set the {@link InSimFlags.ISF_LOCAL} flag (in {@link IS_ISI}) if
* your program is not a host control system, to make sure your buttons do not
* conflict with any buttons sent by the host.
*
* LFS can display normal buttons in these four screens:
* - main entry screen
* - race setup screen
* - in game
* - SHIFT+U mode
*
* The recommended area for most buttons is defined by:
* - {@link IS_X_MIN}
* - {@link IS_X_MAX}
* - {@link IS_Y_MIN}
* - {@link IS_Y_MAX}
*
* If you draw buttons in this area, the area will be kept clear to avoid
* overlapping LFS buttons with your InSim program's buttons. Buttons outside
* that area will not have a space kept clear. You can also make buttons visible
* in all screens by setting the {@link Inst} property to {@link INST_ALWAYS_ON}.
*/
export class IS_BTN extends SendablePacket {
constructor(data) {
super();
/** 12 + text size (a multiple of 4) */
this.Size = IS_BTN.FIXED_DATA_SIZE;
this.Type = PacketType.ISP_BTN;
/** Non-zero (returned in {@link IS_BTC} and {@link IS_BTT} packets) */
this.ReqI = 1;
/** Connection to display the button (0 = local / 255 = all) */
this.UCID = 0;
/**
* Button ID (0 to 239)
*
* This value is returned in {@link IS_BTC} and {@link IS_BTT} packets.
*
* Host buttons and local buttons are stored separately, so there is no
* chance of a conflict between a host control system and a local system
* (although the buttons could overlap on screen).
*
* Programmers of local InSim programs may wish to consider using a
* configurable button range and possibly screen position, in case their
* users will use more than one local InSim program at once.
*/
this.ClickID = 0;
/**
* Mainly used internally by InSim but also provides some extra user flags
*
* NOTE: You should not use {@link INST_ALWAYS_ON} for most buttons.
* This is a special flag for buttons that really must be on in all screens
* (including the garage and options screens). You will probably need to
* confine these buttons to the top or bottom edge of the screen, to avoid
* overwriting LFS buttons. Most buttons should be defined without this flag,
* and positioned in the recommended area so LFS can keep a space clear in
* the main screens.
*/
this.Inst = 0;
/** Button style flags */
this.BStyle = 0;
/**
* If set, the user can click this button to type in text.
*
* Lowest 7 bits are the maximum number of characters to type in (0 to 95)
* The highest bit (128) can be set to initialise dialog with the button's text
*
* On clicking the button, a text entry dialog will be opened, allowing the
* specified number of characters to be typed in. The caption on the text
* entry dialog is optionally customisable using {@link Text} in the
* {@link IS_BTN} packet. If the first character of IS_BTN's {@link Text}
* field is zero, LFS will read the caption up to the second zero.
* The visible button text then follows that second zero.
*
* Text: 65-66-67-0 would display button text "ABC" and no caption
*
* Text: 0-65-66-67-0-68-69-70-71-0-0-0 would display button text "DEFG" and caption "ABC"
*/
this.TypeIn = 0;
/** Left offset (0 to 200) */
this.L = 0;
/** Top offset (0 to 200) */
this.T = 0;
/** Width (0 to 200) */
this.W = 0;
/** Height (0 to 200) */
this.H = 0;
/** 0 to 240 characters of text */
this.Text = '';
this.initialize(data);
}
pack() {
if (this.ReqI === 0) {
throw new RangeError('IS_BTN - ReqI must be greater than 0');
}
if (this.ClickID > IS_BTN.MAX_CLICK_ID) {
throw new RangeError(`IS_BTN - Invalid ClickID: ${this.ClickID} - must be less than or equal to ${IS_BTN.MAX_CLICK_ID}`);
}
const multiple = 4;
const MAX_LENGTH = 240;
const encodedText = unicodeToLfs(this.Text);
const length = encodedText.length;
const textSize = Math.min(length + (multiple - (length % multiple)), MAX_LENGTH);
this.Size = IS_BTN.FIXED_DATA_SIZE + textSize;
return super.pack({
Text: `${textSize}s`,
});
}
}
IS_BTN.INST_ALWAYS_ON = 128;
IS_BTN.IS_X_MIN = 0;
IS_BTN.IS_X_MAX = 110;
IS_BTN.IS_Y_MIN = 30;
IS_BTN.IS_Y_MAX = 170;
IS_BTN.MAX_CLICK_ID = 239;
IS_BTN.FIXED_DATA_SIZE = 12;
__decorate([
byte()
], IS_BTN.prototype, "Size", void 0);
__decorate([
byte()
], IS_BTN.prototype, "Type", void 0);
__decorate([
byte()
], IS_BTN.prototype, "ReqI", void 0);
__decorate([
byte()
], IS_BTN.prototype, "UCID", void 0);
__decorate([
byte()
], IS_BTN.prototype, "ClickID", void 0);
__decorate([
byte()
], IS_BTN.prototype, "Inst", void 0);
__decorate([
byte()
], IS_BTN.prototype, "BStyle", void 0);
__decorate([
byte()
], IS_BTN.prototype, "TypeIn", void 0);
__decorate([
byte()
], IS_BTN.prototype, "L", void 0);
__decorate([
byte()
], IS_BTN.prototype, "T", void 0);
__decorate([
byte()
], IS_BTN.prototype, "W", void 0);
__decorate([
byte()
], IS_BTN.prototype, "H", void 0);
__decorate([
string(0)
], IS_BTN.prototype, "Text", void 0);
export var ButtonStyle;
(function (ButtonStyle) {
/** Click this button to send {@link IS_BTC} */
ButtonStyle[ButtonStyle["ISB_CLICK"] = 8] = "ISB_CLICK";
/** Light button */
ButtonStyle[ButtonStyle["ISB_LIGHT"] = 16] = "ISB_LIGHT";
/** Dark button */
ButtonStyle[ButtonStyle["ISB_DARK"] = 32] = "ISB_DARK";
/** Align text to left */
ButtonStyle[ButtonStyle["ISB_LEFT"] = 64] = "ISB_LEFT";
/** Align text to right */
ButtonStyle[ButtonStyle["ISB_RIGHT"] = 128] = "ISB_RIGHT";
})(ButtonStyle || (ButtonStyle = {}));
export var ButtonTextColour;
(function (ButtonTextColour) {
/** Not user editable */
ButtonTextColour[ButtonTextColour["LIGHT_GREY"] = 0] = "LIGHT_GREY";
/** Default: yellow */
ButtonTextColour[ButtonTextColour["TITLE_COLOUR"] = 1] = "TITLE_COLOUR";
/** Default: black */
ButtonTextColour[ButtonTextColour["UNSELECTED_TEXT"] = 2] = "UNSELECTED_TEXT";
/** Default: white */
ButtonTextColour[ButtonTextColour["SELECTED_TEXT"] = 3] = "SELECTED_TEXT";
/** Default: green */
ButtonTextColour[ButtonTextColour["OK"] = 4] = "OK";
/** Default: red */
ButtonTextColour[ButtonTextColour["CANCEL"] = 5] = "CANCEL";
/** Default: pale blue */
ButtonTextColour[ButtonTextColour["TEXT_STRING"] = 6] = "TEXT_STRING";
/** Default: grey */
ButtonTextColour[ButtonTextColour["UNAVAILABLE"] = 7] = "UNAVAILABLE";
})(ButtonTextColour || (ButtonTextColour = {}));
export var TypeIn;
(function (TypeIn) {
/** Initialise dialog with the button's text */
TypeIn[TypeIn["INIT_VALUE_BUTTON_TEXT"] = 128] = "INIT_VALUE_BUTTON_TEXT";
})(TypeIn || (TypeIn = {}));