From 79afda73ddad7d1440ccc0b80f4ca39fb8ad9780 Mon Sep 17 00:00:00 2001 From: Simon Cambier Date: Sun, 14 Dec 2025 14:20:25 +0100 Subject: [PATCH] First commit --- .gitignore | 2 + README.md | 54 ++++++ _G.d.ts | 466 +++++++++++++++++++++++++++++++++++++++++++++++++ game.p64 | 47 +++++ package.json | 12 ++ pnpm-lock.yaml | 136 +++++++++++++++ src/main.ts | 12 ++ src/utils.d.ts | 9 + src/utils.lua | 8 + tsconfig.json | 18 ++ 10 files changed, 764 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 _G.d.ts create mode 100644 game.p64 create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/main.ts create mode 100644 src/utils.d.ts create mode 100644 src/utils.lua create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4a754d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +build/bundle.lua \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..290cb29 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# TypeScript for Picotron + +This is a template project to mix-and-match TypeScript and Lua for your Picotron projects. + +## Setup + +### Requirements + +- [NodeJS](https://nodejs.org/en/download) +- [pnpm](https://pnpm.io/installation) + +### Create your project + +- Create a new project (i.e. `my-project`) from this template +- Clone `my-project` in your Picotron's `drive` folder +- `cd my-project` then `pnpm install` +- Inside Picotron: + - Open the terminal, `cd my-project` then `load game` + - Edit `main.lua` to fix the path + - Run the game + +## Development + +- `pnpm dev` will watch and rebuild your **TypeScript** code. +- `pnpm build` is required when you change **Lua** code. + +The resulting code is a single `build/bundle.lua` file. + +## Publish + +**In Picotron** + +``` +> cd my-project +> load game +``` + +- Open the code inside Picotron +- Comment the `cd()` line in main.lua +- Save + +**On the host** + +`pnpm build` + +**In Picotron** + +Open the terminal: + +``` +> cp -f /my-project/build/src /ram/cart/build/src +> save +> export my-project.bin +``` diff --git a/_G.d.ts b/_G.d.ts new file mode 100644 index 0000000..9991b10 --- /dev/null +++ b/_G.d.ts @@ -0,0 +1,466 @@ +// Picotron v0.2.1e Global API Type Definitions + +// Userdata types +type UserdataType = "u8" | "i16" | "i32" | "i64" | "f64"; + +// Userdata interface +interface Userdata { + // Dimension methods + width(): number; + height(): number | null; + attribs(): LuaMultiReturn<[number, number, T, number]>; + + // Element access + get(x: number, n?: number): LuaMultiReturn; + get(x: number, y: number, n?: number): LuaMultiReturn; + set(x: number, ...values: number[]): void; + set(x: number, y: number, ...values: number[]): void; + + // Row/Column access (2d only) + row(i: number): Userdata | null; + column(i: number): Userdata | null; + + // Binary operations + add( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + sub( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + mul( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + div( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + mod( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + pow( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + + // Bitwise operations + band( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + bor( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + bxor( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + + // Min/Max operations + max( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + min( + src: Userdata | number, + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + + // Unary operations + copy( + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + abs( + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + sgn( + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + sgn0( + dest?: Userdata | true, + src_offset?: number, + dest_offset?: number, + len?: number, + src_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + + // Lookup table copy + take( + idx: Userdata<"i32">, + dest?: Userdata, + idx_offset?: number, + dest_offset?: number, + span_len?: number, + idx_stride?: number, + dest_stride?: number, + spans?: number + ): Userdata; + + // Blit operation + blit( + dest?: Userdata, + src_x?: number, + src_y?: number, + dest_x?: number, + dest_y?: number, + width?: number, + height?: number + ): void; + + // Mutation and conversion + mutate(data_type: UserdataType, width?: number, height?: number): void; + convert(data_type: UserdataType, dest?: Userdata): Userdata; + + // Interpolation + lerp(offset?: number, len?: number, el_stride?: number, num_lerps?: number, lerp_stride?: number): Userdata; + + // Sorting (2d only) + sort(index?: number, descending?: boolean): void; + + // Memory operations + peek(addr: number, offset?: number, elements?: number): void; + poke(addr: number, offset?: number, elements?: number): void; + + // Matrix/Vector operations (f64 only) + matmul(m: Userdata<"f64">, m_out?: Userdata<"f64">, batch_height?: number): Userdata<"f64">; + matmul3d(m: Userdata<"f64">, m_out?: Userdata<"f64">, batch_height?: number): Userdata<"f64">; + transpose(m_out?: Userdata | true): Userdata; + + // Vector operations (f64 only) + magnitude(): number; + distance(v: Userdata<"f64">): number; + dot(v: Userdata<"f64">): number; + cross(v: Userdata<"f64">, v_out?: Userdata<"f64"> | true): Userdata<"f64">; +} + +// ===================== +// Math Functions +// ===================== +declare function abs(x: number): number; +declare function atan2(dx: number, dy: number): number; +declare function cos(x: number): number; +declare function flr(x: number): number; +declare function max(x: number, ...args: number[]): number; +declare function mid(x: number, y: number, z: number): number; +declare function min(x: number, ...args: number[]): number; +declare function rnd(x?: number): number; +declare function sgn(x: number): number; +declare function sin(x: number): number; +declare function sqrt(x: number): number; +declare function srand(seed: number): void; + +// Bitwise operations +declare function band(x: number, ...args: number[]): number; +declare function bnot(x: number): number; +declare function bor(x: number, ...args: number[]): number; +declare function bxor(x: number, ...args: number[]): number; +declare function rotl(x: number, n: number): number; +declare function rotr(x: number, n: number): number; +declare function shl(x: number, n: number): number; +declare function shr(x: number, n: number): number; + +// ===================== +// Graphics API +// ===================== +declare function cls(color?: number): void; +declare function camera(x?: number, y?: number): void; +declare function clip(x?: number, y?: number, w?: number, h?: number): void; +declare function color(c: number): void; +declare function pal(c0?: number, c1?: number, p?: number): void; +declare function palt(c?: number, t?: boolean): void; +declare function fillp(pattern?: number): void; +declare function pget(x: number, y: number): number; +declare function pset(x: number, y: number, c?: number): void; +declare function cursor(x?: number, y?: number, c?: number): void; +declare function print(text?: any, x?: number, y?: number, color?: number): number; +declare function line(x1: number, y1: number, x2?: number, y2?: number, color?: number): void; +declare function line(userdata: Userdata): void; +declare function rect(x0: number, y0: number, x1: number, y1: number, c?: number): void; +declare function rect(userdata: Userdata): void; +declare function rectfill(x0: number, y0: number, x1: number, y1: number, c?: number): void; +declare function rectfill(userdata: Userdata): void; +declare function circ(x: number, y: number, r: number, c?: number): void; +declare function circfill(x: number, y: number, r: number, c?: number): void; +declare function circfill(userdata: Userdata): void; +declare function oval(x: number, y: number, rx: number, ry: number, c?: number): void; +declare function ovalfill(x: number, y: number, rx: number, ry: number, c?: number): void; +declare function rrect(x: number, y: number, width: number, height: number, radius?: number, c?: number): void; +declare function rrectfill(x: number, y: number, width: number, height: number, radius?: number, c?: number): void; +declare function fget(n: number, f?: number): number | boolean; +declare function fset(n: number, f?: number, val?: boolean): void; +declare function get_spr(index: number): Userdata<"u8">; +declare function set_spr(index: number, ud: Userdata<"u8">): void; +declare function spr(sprite: number | Userdata, x: number, y: number, w?: number, h?: number, flip_x?: boolean, flip_y?: boolean): void; +declare function sspr(sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw?: number, dh?: number, flip_x?: boolean, flip_y?: boolean): void; + +// ===================== +// Map API +// ===================== +declare function map(cel_x?: number, cel_y?: number, sx?: number, sy?: number, cel_w?: number, cel_h?: number, layer?: number): void; +declare function map(src: Userdata<"i16">, cel_x?: number, cel_y?: number, sx?: number, sy?: number, cel_w?: number, cel_h?: number, layer?: number, tile_w?: number, tile_h?: number): void; +declare function mget(cel_x: number, cel_y: number): number; +declare function mset(cel_x: number, cel_y: number, sprite_number: number): void; +declare function tline3d(src: number | Userdata<"u8"> | Userdata<"i16">, x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number, w0?: number, w1?: number, flags?: number): void; +declare function tline3d(x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number, w0?: number, w1?: number, flags?: number): void; + +// ===================== +// Audio API +// ===================== +declare function sfx(id: number, channel?: number, offset?: number, length?: number, mix_volume?: number): void; +declare function music(id?: number, fade_len?: number, channel_mask?: number, base_addr?: number, tick_offset?: number): void; +declare function note(pitch?: number, inst?: number, vol?: number, effect?: number, effect_p?: number, channel?: number, retrig?: boolean, panning?: number): void; + +// ===================== +// Input API +// ===================== +declare function btn(i?: number, player?: number): number | boolean; +declare function btnp(i?: number, player?: number): number | boolean; +declare function key(k?: string, raw?: boolean): boolean; +declare function keyp(k?: string, raw?: boolean): boolean; +declare function peektext(): boolean; +declare function readtext(clear?: boolean): string; +declare function mouse(): LuaMultiReturn<[number, number, number, number, number]>; +declare function mouselock(lock: boolean, event_sensitivity?: number, move_sensitivity?: number): LuaMultiReturn<[number, number]>; +declare function input(prompt?: string, flags?: number): string | null; + +// ===================== +// String API +// ===================== +declare function chr(...values: number[]): string; +declare function ord(str: string, index?: number, num_results?: number): number | LuaMultiReturn; +declare function sub(str: string, pos0: number, pos1?: number | boolean): string; +declare function split(str: string, delimiter?: string | number, convert_numbers?: boolean): string[]; +declare function type(val: any): string; +declare function tostr(val: any, format?: string): string; +declare function tonum(str: string): number | null; +declare function create_delta(str0: string, str1: string): string; +declare function apply_delta(str0: string, delta: string): string | null; + +// ===================== +// Tables API +// ===================== +declare function add(t: any[], item: any, index?: number): void; +declare function del(t: any[], item: any): void; +declare function deli(t: any[], index: number): any; +declare function count(t: any[]): number; +declare function all(t: any[]): () => any | undefined; +declare function foreach(t: any[], fn: (item: any) => void): void; +declare function pairs(t: any): LuaMultiReturn<[(t: any, k?: any) => LuaMultiReturn<[any, any]>, any, any]>; +declare function next(t: any, k?: any): LuaMultiReturn<[any, any]>; + +// ===================== +// PODs API +// ===================== +declare function pod(val: any, flags?: number, metadata?: any): string; +declare function unpod(str: string): LuaMultiReturn<[any, any]>; +declare function store(path: string, val: any): void; +declare function fetch(path: string): any; + +// ===================== +// Files API +// ===================== +declare function store(filename: string, obj: any, metadata?: any): void; +declare function fetch(filename: string, options?: any): LuaMultiReturn<[any, any]>; +declare function store_metadata(filename: string, metadata: any): void; +declare function fetch_metadata(filename: string): any; +declare function include(path: string): void; +declare function cd(path: string): void; +declare function ls(path?: string): string[]; +declare function mkdir(path: string): void; +declare function rm(path: string): void; +declare function mv(src: string, dest: string): void; +declare function cp(src: string, dest: string): void; +declare function pwd(): string; +declare function fullpath(filename: string): string; +declare function fstat(path: string): LuaMultiReturn<[string, number, string]>; + +// ===================== +// System API +// ===================== +declare function load(path: string): void; +declare function save(path: string): void; +declare function run(): void; +declare function stop(message?: string): void; +declare function resume(): void; +declare function reset(cart?: string): void; +declare function stat(v: number, ...args: any[]): any; +declare function env(): any; +declare function time(): number; +declare function t(): number; +declare function date(format?: string, t?: string | number, delta?: number): string; +declare function exit(): void; +declare function printh(text: any, file_path?: string, overwrite?: boolean, terminal?: boolean): void; +declare function error(description?: string): void; +declare function assert(condition: any, message?: string): void; +declare function get_clipboard(): string; +declare function set_clipboard(text: string): void; +declare function create_process(filename: string, ...args: any[]): number; +declare function pid(): number; +declare function signal(proc_id: number, signal: string): void; +declare function send_message(proc_id: number, msg: any, reply?: boolean | ((msg: any) => void)): any; +declare function on_event(event: string, func: (msg: any) => boolean | void): void; + +// ===================== +// Memory API +// ===================== +declare function peek(addr: number, count?: number): number | LuaMultiReturn; +declare function poke(addr: number, ...values: number[]): void; +declare function peek2(addr: number): number; +declare function poke2(addr: number, val: number): void; +declare function peek4(addr: number): number; +declare function poke4(addr: number, val: number): void; +declare function peek8(addr: number): number; +declare function poke8(addr: number, val: number): void; +declare function memcpy(dest_addr: number, src_addr: number, count: number): void; +declare function memset(addr: number, value: number, count: number): void; +declare function reload(dest_addr: number, src_addr: number, count: number, filename?: string): void; +declare function memmap(ud: Userdata, addr: number): void; + +// ===================== +// Userdata API +// ===================== +declare function userdata(data_type: UserdataType, width: number, height?: number, data?: string): Userdata; +declare function userdata(gfx_string: string): Userdata<"u8">; +declare function vec(...values: number[]): Userdata<"f64">; +declare function get(u: Userdata | null | undefined, x: number, n?: number): LuaMultiReturn; +declare function get(u: Userdata | null | undefined, x: number, y: number, n?: number): LuaMultiReturn; +declare function set(u: Userdata | null | undefined, x: number, ...values: number[]): void; +declare function set(u: Userdata | null | undefined, x: number, y: number, ...values: number[]): void; +declare function blit(src?: Userdata, dest?: Userdata, src_x?: number, src_y?: number, dest_x?: number, dest_y?: number, width?: number, height?: number): void; +declare function matmul(m0: Userdata<"f64">, m1: Userdata<"f64">, m_out?: Userdata<"f64">, batch_height?: number): Userdata<"f64">; +declare function matmul3d(m0: Userdata<"f64">, m1: Userdata<"f64">, m_out?: Userdata<"f64">, batch_height?: number): Userdata<"f64">; + +// ===================== +// Window API +// ===================== +declare function window(attributes?: any): any; +declare function window(width: number, height: number): any; +declare function get_display(): Userdata<"u8">; +declare function set_draw_target(ud?: Userdata<"u8">): void; +declare function get_draw_target(): Userdata<"u8">; +declare function vid(mode: number): void; + +// ===================== +// Undo Stacks +// ===================== +interface UndoStack { + checkpoint(extra?: any): void; + undo(peek?: boolean): any; + redo(peek?: boolean): any; +} +declare function create_undo_stack(save: (item?: any) => any, load: (dat: any, item?: any) => void, pod_flags?: number, item?: any): UndoStack; + +// ===================== +// Sockets +// ===================== +interface Socket { + read(): string | LuaMultiReturn<[null, string]>; + write(str: string): number | LuaMultiReturn<[null, string]>; + close(): void; + status(): "ready" | "listening" | "closed" | "closed by peer" | "disconnected"; + accept(): Socket | null; +} +declare function socket(addr: string): Socket | null; + +// ===================== +// Userdata Memory +// ===================== +declare function unmap(ud: Userdata, addr?: number): void; + +// ===================== +// Main Loop Callbacks +// ===================== +declare var _init: () => void; +declare var _draw: () => void; +declare var _update: () => void; +declare var _update60: () => void; diff --git a/game.p64 b/game.p64 new file mode 100644 index 0000000..4f44884 --- /dev/null +++ b/game.p64 @@ -0,0 +1,47 @@ +picotron cartridge // www.picotron.net +version 2 + +:: gfx/ +:: map/ +:: sfx/ +:: src/ +:: main.lua +--[[pod_format="raw",created="2025-12-14 12:54:34",modified="2025-12-14 13:05:20",revision=1]] +-- /!\ FIX THE PATH /!\ +-- and comment this line before publishing +cd("/picotron-typescript-template/build") + + +include("bundle.lua") +:: src/main.lua +function _draw() + cls(4) +end + +:: .info.pod +--[[pod,created="2025-11-13 21:07:43",modified="2025-12-14 13:05:20",runtime=24,workspaces={{location="main.lua#5",workspace_index=1},{location="gfx/0.gfx",workspace_index=2},{location="map/0.map",workspace_index=3},{location="sfx/0.sfx",workspace_index=4}}]] +:: gfx/.info.pod +--[[pod,created="2025-11-13 21:07:43",modified="2025-12-14 13:05:20"]] +:: gfx/0.gfx +b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI1LTAxLTE3IDEwOjM1OjQ4Iixtb2RpZmllZD0iMjAyNS0w +MS0xNyAxMDozNzo0NCIscmV2aXNpb249Ml1dbHo0AH4AAAASMQAA8yF7WzBdPXtibXA9cHh1AEMg +EBAE8FYHEAfAF9AXwAcQB-BWLGZsYWdzPTAscGFuX3gIAMt5PTAsem9vbT04fSw_AB-wMQD----- +-----------------------------------------------------------XUG09OH19 +:: map/.info.pod +--[[pod,created="2025-11-13 21:07:43",modified="2025-12-14 13:05:20"]] +:: map/0.map +b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI1LTAxLTE3IDEwOjM1OjQ4Iixtb2RpZmllZD0iMjAyNS0x +Mi0xNCAxMjo1MzowNSIscmV2aXNpb249Ml1dbHo0AEwAAABQAAAA8Rx7e2JtcD1weHUATIAgIAD- +AAD---8DLGhpZGRlbj1mYWxzZSxwYW5feD0wCADSeT0wLHRpbGVfaD0xNgoAEHcKAIB6b29tPTF9 +fQ== +:: sfx/.info.pod +--[[pod,created="2025-11-13 21:07:43",modified="2025-12-14 13:05:20"]] +:: sfx/0.sfx +b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI1LTA3LTMxIDA4OjMwOjI4Iixtb2RpZmllZD0iMjAyNS0w +Ny0zMSAwODozMDoyOCIscmV2aXNpb249MF1dbHo0AKAAAAALCgAA-zBweHUAAygAAAQABA9AEAIO +AAGgASACoA4ADxAADfDKAQIDQA8PkAQFBgdADJAICQoLQAyQDwwPDQ8ODEAM8P8BAOv-J6oBEAYP +MBABIAEgAfAAAhACDhABIA8hIAEwD0Dwww8oD--wxg-4Cg--D4AP9w8NAfAJARAGDjAA------_9 +H-8BAKzPyA9AAA8QQP--sPD-AQD-6lD-----KQ== +:: src/.info.pod +--[[pod,created="2025-11-26 19:06:38",modified="2025-12-14 13:05:20"]] +:: [eoc] diff --git a/package.json b/package.json new file mode 100644 index 0000000..56f3253 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "scripts": { + "build": "tstl", + "dev": "tstl --watch" + }, + "devDependencies": { + "@typescript-to-lua/language-extensions": "^1.19.0", + "prettier": "^3.7.0", + "typescript": "^5.9.3", + "typescript-to-lua": "^1.33.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..181b592 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,136 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@typescript-to-lua/language-extensions': + specifier: ^1.19.0 + version: 1.19.0 + prettier: + specifier: ^3.7.0 + version: 3.7.4 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-to-lua: + specifier: ^1.33.0 + version: 1.33.0(typescript@5.9.3) + +packages: + + '@typescript-to-lua/language-extensions@1.19.0': + resolution: {integrity: sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==} + + enhanced-resolve@5.8.2: + resolution: {integrity: sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==} + engines: {node: '>=10.13.0'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + engines: {node: '>=14'} + hasBin: true + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + typescript-to-lua@1.33.0: + resolution: {integrity: sha512-fFJjP2iJ3NFOSQzAvmFOf8MCsaev531YWYAA9N+RJO/XRV0Moewq+zY7Rg5hFlMFxAJpqrk7E8nb7QcwxCy3XQ==} + engines: {node: '>=16.10.0'} + hasBin: true + peerDependencies: + typescript: 5.9.3 + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + +snapshots: + + '@typescript-to-lua/language-extensions@1.19.0': {} + + enhanced-resolve@5.8.2: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + function-bind@1.1.2: {} + + graceful-fs@4.2.11: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + path-parse@1.0.7: {} + + picomatch@2.3.1: {} + + prettier@3.7.4: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + source-map@0.7.6: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + tapable@2.3.0: {} + + typescript-to-lua@1.33.0(typescript@5.9.3): + dependencies: + '@typescript-to-lua/language-extensions': 1.19.0 + enhanced-resolve: 5.8.2 + picomatch: 2.3.1 + resolve: 1.22.11 + source-map: 0.7.6 + typescript: 5.9.3 + + typescript@5.9.3: {} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..2d36cbe --- /dev/null +++ b/src/main.ts @@ -0,0 +1,12 @@ +import { printBorder } from "./utils" + +let f = 0 + +_update = () => { + ++f +} + +_draw = () => { + cls(3) + printBorder(`Hello World! ${f}`, 8, 8, 7) +} diff --git a/src/utils.d.ts b/src/utils.d.ts new file mode 100644 index 0000000..b6b7b3d --- /dev/null +++ b/src/utils.d.ts @@ -0,0 +1,9 @@ +/** + * + * @param text + * @param x + * @param y + * @param color + * @param borderColor pseudo-hexadecimal string of the color index + */ +export function printBorder(text: string, x: number, y: number, color: number, borderColor?: string): void; diff --git a/src/utils.lua b/src/utils.lua new file mode 100644 index 0000000..4d8e8d1 --- /dev/null +++ b/src/utils.lua @@ -0,0 +1,8 @@ +local utils = {} + +function utils.printBorder(text, x, y, color, borderColor) + borderColor = borderColor or "0" + print("\^o"..borderColor.."ff"..text, x, y, color) +end + +return utils \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a3e8b46 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "target": "ESNext", + "lib": ["ESNext"], + "moduleResolution": "Node", + "types": ["@typescript-to-lua/language-extensions"], + "strict": true, + "outDir": "build" + }, + "tstl": { + "luaTarget": "5.4", + "noImplicitSelf": true, + "luaLibImport": "require-minimal", + "luaBundleEntry": "src/main.ts", + "luaBundle": "bundle.lua" + } +}