Compare commits
1 Commits
main
...
initial-id
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3390e9d50a |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
||||
build
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,4 +0,0 @@
|
||||
{
|
||||
"deno.enable": true,
|
||||
"deno.unstable": true
|
||||
}
|
25
README.md
25
README.md
@ -1,25 +1,2 @@
|
||||
# Faux
|
||||
# fantasy-console
|
||||
|
||||
This is a custom fantasy-console (like Pico 8) written in Deno/Typescript.
|
||||
|
||||
Go to the [Releases](https://git.playbox.link/dylan/fantasy-console/releases) page to find downloadable executables.
|
||||
|
||||
NOTE: If you are running Faux on Linux, you will need to have `xsel` installed.
|
||||
|
||||
## Developing
|
||||
|
||||
Faux is written in [TypeScript](https://www.typescriptlang.org/) to be run or compiled by [Deno](https://deno.com/runtime).
|
||||
|
||||
If you want to build from source, you should have Deno installed, clone this repo, and then...
|
||||
|
||||
To run:
|
||||
```
|
||||
deno task run
|
||||
```
|
||||
|
||||
To compile:
|
||||
```
|
||||
deno task build_all
|
||||
```
|
||||
|
||||
NOTE: Development is happening solely on Linux, so some build commands may fail if you are not on Linux or do not have some build dependencies installed.
|
@ -1 +0,0 @@
|
||||
[{"sheet_type":"code","value":""},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null}]
|
File diff suppressed because one or more lines are too long
707
carts/test.faux
707
carts/test.faux
@ -1,707 +0,0 @@
|
||||
[
|
||||
{
|
||||
"sheet_type": "code",
|
||||
"value": "x = code(1);\nreturn {\n\tinit: () => {y = 0},\n\tupdate: () => {\n\t\ty += speed;\n\t\tif (y > 127) {\n\t\t\ty = -6\n\t\t}\n\t},\n\tdraw: () => {\n\t\tcls();\n\t\ttxt(x, y, 'hello world')\n\t}\n}"
|
||||
},
|
||||
{
|
||||
"sheet_type": "code",
|
||||
"value": "sprsht(15);\nspeed = 2;\nreturn 8;"
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "none",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"sheet_type": "spritesheet",
|
||||
"value": [
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 2, 0, 0, 2, 0, 0,
|
||||
0, 0, 0, 2, 2, 0, 0, 0,
|
||||
0, 0, 0, 2, 2, 0, 0, 0,
|
||||
0, 0, 2, 0, 0, 2, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 3, 3, 1, 1, 3, 3, 1,
|
||||
1, 3, 3, 1, 1, 3, 3, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 3, 3, 1, 1, 3, 3, 1,
|
||||
1, 3, 3, 1, 1, 3, 3, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1
|
||||
],
|
||||
[
|
||||
6, 6, 6, 4, 4, 4, 5, 5,
|
||||
6, 6, 4, 4, 4, 5, 5, 5,
|
||||
6, 4, 4, 4, 5, 5, 5, 6,
|
||||
4, 4, 4, 5, 5, 5, 6, 6,
|
||||
4, 4, 5, 5, 5, 6, 6, 6,
|
||||
4, 5, 5, 5, 6, 6, 6, 4,
|
||||
5, 5, 5, 6, 6, 6, 4, 4,
|
||||
5, 5, 6, 6, 6, 4, 4, 4
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
158
colors.html
Normal file
158
colors.html
Normal file
@ -0,0 +1,158 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<style>
|
||||
.swatch {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: hsl(var(--hue), var(--saturation), var(--lightness));
|
||||
}
|
||||
|
||||
.h1p {
|
||||
--hue: 310;
|
||||
}
|
||||
.h1 {
|
||||
--hue: 340;
|
||||
}
|
||||
.h1s {
|
||||
--hue: 335;
|
||||
}
|
||||
.h2d {
|
||||
--hue: 50;
|
||||
}
|
||||
.h2 {
|
||||
--hue: 37;
|
||||
}
|
||||
.h2s {
|
||||
--hue: 30;
|
||||
}
|
||||
.h2h {
|
||||
--hue: 57;
|
||||
}
|
||||
.h3 {
|
||||
--hue: 130;
|
||||
}
|
||||
.h3s {
|
||||
--hue: 145;
|
||||
}
|
||||
.h3h {
|
||||
--hue: 203;
|
||||
}
|
||||
.h4 {
|
||||
--hue: 224;
|
||||
}
|
||||
/* .h4hs {
|
||||
--hue: 228;
|
||||
}
|
||||
.h4s {
|
||||
--hue: 235;
|
||||
} */
|
||||
.h4hs {
|
||||
--hue: 235;
|
||||
}
|
||||
.h4s {
|
||||
--hue: 240;
|
||||
}
|
||||
.h5 {
|
||||
--hue: 250;
|
||||
}
|
||||
.h6 {
|
||||
--hue: 230;
|
||||
}
|
||||
.h7 {
|
||||
--hue: 30;
|
||||
}
|
||||
|
||||
.sp {
|
||||
--saturation: 90%;
|
||||
}
|
||||
.s1 {
|
||||
--saturation: 85%;
|
||||
}
|
||||
.s1x {
|
||||
--saturation: 75%;
|
||||
}
|
||||
.sx {
|
||||
--saturation: 65%;
|
||||
}
|
||||
.smx {
|
||||
--saturation: 60%;
|
||||
}
|
||||
.sm {
|
||||
--saturation: 55%;
|
||||
}
|
||||
.smm {
|
||||
--saturation: 50%;
|
||||
}
|
||||
.s2 {
|
||||
--saturation: 45%;
|
||||
}
|
||||
.ss {
|
||||
--saturation: 40%;
|
||||
}
|
||||
.sl {
|
||||
--saturation: 25%;
|
||||
}
|
||||
.s3 {
|
||||
--saturation: 13%;
|
||||
}
|
||||
|
||||
.l0 {
|
||||
--lightness: 95%;
|
||||
}
|
||||
.l1 {
|
||||
--lightness: 82%;
|
||||
}
|
||||
.l1h {
|
||||
--lightness: 75%;
|
||||
}
|
||||
.l1hh {
|
||||
--lightness: 70%;
|
||||
}
|
||||
.l2 {
|
||||
--lightness: 67%;
|
||||
}
|
||||
.l2m {
|
||||
--lightness: 62%;
|
||||
}
|
||||
.lm {
|
||||
--lightness: 58%;
|
||||
}
|
||||
.l3 {
|
||||
--lightness: 50%;
|
||||
}
|
||||
.l3h {
|
||||
--lightness: 40%;
|
||||
}
|
||||
.l4 {
|
||||
--lightness: 30%;
|
||||
}
|
||||
.l4h {
|
||||
--lightness: 25%;
|
||||
}
|
||||
.l5 {
|
||||
--lightness: 20%;
|
||||
}
|
||||
.l6 {
|
||||
--lightness: 5%;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#palette {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="palette"></div>
|
||||
<script src="colors.js"></script>
|
||||
<script>
|
||||
const div = document.getElementById("palette");
|
||||
div.innerHTML = palette.map(c => `<div class="swatch" style="background-color: hsl(${c[0]}, ${c[1]}%, ${c[2]}%);"></div>`).join("");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
54
colors.js
Normal file
54
colors.js
Normal file
@ -0,0 +1,54 @@
|
||||
const hue_gray = 230;
|
||||
const hue_brown = 30;
|
||||
const hue_orange = 37;
|
||||
const hue_purple = 250;
|
||||
const hue_pink = 310;
|
||||
const hue_red = 340;
|
||||
const hue_red_shade = 335;
|
||||
const hue_yellow = 57;
|
||||
const hue_green = 130;
|
||||
const hue_green_shade = 145;
|
||||
const hue_sky = 203;
|
||||
const hue_blue = 224;
|
||||
const hue_blue_shade = 235;
|
||||
const hue_blue_shade_2 = 240;
|
||||
|
||||
const saturation_max = 90;
|
||||
const saturation_normal = 60;
|
||||
const saturation_low = 40;
|
||||
const saturation_min = 13;
|
||||
|
||||
const lightness_max = 95;
|
||||
const lightness_light = 67;
|
||||
const lightness_mediumlight = 62;
|
||||
const lightness_medium = 50;
|
||||
const lightness_mediumdark = 40;
|
||||
const lightness_dark = 30;
|
||||
const lightness_almostverydark = 25;
|
||||
const lightness_verydark = 20;
|
||||
const lightness_min = 5;
|
||||
|
||||
const hsl = (h, s, l) => [h, s, l];
|
||||
|
||||
const palette = [
|
||||
hsl(hue_gray, saturation_min, lightness_max),
|
||||
hsl(hue_gray, saturation_min, lightness_light),
|
||||
hsl(hue_gray, saturation_min, lightness_dark),
|
||||
hsl(hue_gray, saturation_min, lightness_min),
|
||||
hsl(hue_orange, saturation_normal, lightness_medium),
|
||||
hsl(hue_brown, saturation_low, lightness_light),
|
||||
hsl(hue_brown, saturation_low, lightness_mediumdark),
|
||||
hsl(hue_brown, saturation_low, lightness_almostverydark),
|
||||
hsl(hue_purple, saturation_normal, lightness_light),
|
||||
hsl(hue_pink, saturation_normal, lightness_light),
|
||||
hsl(hue_red, saturation_normal, lightness_medium),
|
||||
hsl(hue_red_shade, saturation_normal, lightness_dark),
|
||||
hsl(hue_yellow, saturation_max, lightness_mediumlight),
|
||||
hsl(hue_green, saturation_normal, lightness_medium),
|
||||
hsl(hue_green_shade, saturation_normal, lightness_dark),
|
||||
hsl(hue_green_shade, saturation_normal, lightness_verydark),
|
||||
hsl(hue_sky, saturation_max, lightness_light),
|
||||
hsl(hue_blue, saturation_normal, lightness_medium),
|
||||
hsl(hue_blue_shade, saturation_normal, lightness_mediumdark),
|
||||
hsl(hue_blue_shade_2, saturation_normal, lightness_dark),
|
||||
]
|
54
colors2.js
Normal file
54
colors2.js
Normal file
@ -0,0 +1,54 @@
|
||||
const hue_gray = 230;
|
||||
const hue_brown = 25;
|
||||
const hue_brown_shade = 10;
|
||||
const hue_orange = 37;
|
||||
const hue_purple = 250;
|
||||
const hue_pink = 310;
|
||||
const hue_red = 340;
|
||||
const hue_red_shade = 335;
|
||||
const hue_redbrown_dark = 0;
|
||||
const hue_yellow = 57;
|
||||
const hue_green = 140;
|
||||
const hue_green_shade = 145;
|
||||
const hue_sky = 203;
|
||||
const hue_blue = 240;
|
||||
const hue_blue_shade = 235;
|
||||
const hue_blue_shade_2 = 240;
|
||||
const hue_bluegreen_dark = 215;
|
||||
|
||||
const saturation_max = 90;
|
||||
const saturation_normal = 60;
|
||||
const saturation_low = 40;
|
||||
const saturation_min = 13;
|
||||
|
||||
const lightness_max = 95;
|
||||
const lightness_light = 67;
|
||||
const lightness_mediumlight = 62;
|
||||
const lightness_medium = 50;
|
||||
const lightness_mediumdark = 40;
|
||||
const lightness_dark = 30;
|
||||
const lightness_almostverydark = 25;
|
||||
const lightness_verydark = 20;
|
||||
const lightness_min = 5;
|
||||
|
||||
const hsl = (h, s, l) => [h, s, l];
|
||||
|
||||
const palette = [
|
||||
hsl(hue_gray, saturation_min, lightness_max),
|
||||
hsl(hue_gray, saturation_min, lightness_light),
|
||||
hsl(hue_gray, saturation_min, lightness_dark),
|
||||
hsl(hue_gray, saturation_min, lightness_min),
|
||||
hsl(hue_orange, saturation_normal, lightness_medium),
|
||||
hsl(hue_brown, saturation_low, lightness_light),
|
||||
hsl(hue_brown_shade, saturation_low, lightness_mediumdark),
|
||||
hsl(hue_pink, saturation_normal, lightness_light),
|
||||
hsl(hue_red, saturation_normal, lightness_medium),
|
||||
hsl(hue_red_shade, saturation_normal, lightness_dark),
|
||||
hsl(hue_yellow, saturation_max, lightness_mediumlight),
|
||||
hsl(hue_green, saturation_normal, lightness_medium),
|
||||
hsl(hue_green_shade, saturation_normal, lightness_dark),
|
||||
hsl(hue_sky, saturation_max, lightness_light),
|
||||
hsl(hue_blue, saturation_normal, lightness_mediumlight),
|
||||
hsl(hue_blue_shade, saturation_normal, lightness_mediumdark),
|
||||
hsl(hue_bluegreen_dark, saturation_normal, lightness_verydark),
|
||||
]
|
119
data/colors.ts
119
data/colors.ts
@ -1,119 +0,0 @@
|
||||
const hue_gray = 230;
|
||||
const hue_brown = 30;
|
||||
const hue_orange = 37;
|
||||
const hue_purple = 280;
|
||||
const hue_pink = 310;
|
||||
const hue_red = 340;
|
||||
const hue_red_shade = 335;
|
||||
const hue_yellow = 57;
|
||||
const hue_green = 130;
|
||||
const hue_green_shade = 145;
|
||||
const hue_sky = 203;
|
||||
const hue_blue = 224;
|
||||
const hue_blue_shade = 235;
|
||||
const hue_blue_shade_2 = 240;
|
||||
|
||||
const saturation_max = 90;
|
||||
const saturation_normal = 60;
|
||||
const saturation_low = 40;
|
||||
const saturation_min = 13;
|
||||
|
||||
const lightness_max = 95;
|
||||
const lightness_light = 67;
|
||||
const lightness_mediumlight = 62;
|
||||
const lightness_medium = 50;
|
||||
const lightness_mediumdark = 40;
|
||||
const lightness_dark = 30;
|
||||
const lightness_almostverydark = 25;
|
||||
const lightness_verydark = 20;
|
||||
const lightness_min = 5;
|
||||
|
||||
/**
|
||||
* Converts an HSL color value to RGB. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes h, s, and l are contained in the set [0, 1] and
|
||||
* returns r, g, and b in the set [0, 255].
|
||||
*
|
||||
* @param Number h The hue
|
||||
* @param Number s The saturation
|
||||
* @param Number l The lightness
|
||||
* @return Array The RGB representation
|
||||
*/
|
||||
function hsl(h: number, s: number, l: number): [number, number, number] {
|
||||
h = h / 360;
|
||||
s = s/100;
|
||||
l = l/100;
|
||||
let r, g, b;
|
||||
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
const hue2rgb = (p: number, q: number, t: number) => {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return [ r , g , b ];
|
||||
}
|
||||
|
||||
const colors = {
|
||||
TRANSPARENT: [0, 0, 0],
|
||||
BLACK2: [0, 0, 0],
|
||||
BLACK3: [0, 0, 0],
|
||||
BLACK4: [0, 0, 0],
|
||||
WHITE: hsl(hue_gray, saturation_min, lightness_max),
|
||||
LIGHTGRAY: hsl(hue_gray, saturation_min, lightness_light),
|
||||
DARKGRAY: hsl(hue_gray, saturation_min, lightness_dark),
|
||||
BLACK: hsl(hue_gray, saturation_min, lightness_min),
|
||||
ORANGE: hsl(hue_orange, saturation_normal, lightness_medium),
|
||||
TAN: hsl(hue_brown, saturation_low, lightness_light),
|
||||
BROWN: hsl(hue_brown, saturation_low, lightness_mediumdark),
|
||||
DARKBROWN: hsl(hue_brown, saturation_low, lightness_almostverydark),
|
||||
PURPLE: hsl(hue_purple, saturation_normal, lightness_medium),
|
||||
PINK: hsl(hue_pink, saturation_normal, lightness_light),
|
||||
RED: hsl(hue_red, saturation_normal, lightness_medium),
|
||||
DARKRED: hsl(hue_red_shade, saturation_normal, lightness_dark),
|
||||
YELLOW: hsl(hue_yellow, saturation_max, lightness_mediumlight),
|
||||
GREEN: hsl(hue_green, saturation_normal, lightness_medium),
|
||||
DARKGREEN: hsl(hue_green_shade, saturation_normal, lightness_dark),
|
||||
DARKERGREEN: hsl(hue_green_shade, saturation_normal, lightness_verydark),
|
||||
CYAN: hsl(hue_sky, saturation_max, lightness_light),
|
||||
BLUE: hsl(hue_blue, saturation_normal, lightness_medium),
|
||||
DARKBLUE: hsl(hue_blue_shade, saturation_normal, lightness_mediumdark),
|
||||
DARKERBLUE: hsl(hue_blue_shade_2, saturation_normal, lightness_dark),
|
||||
} as const;
|
||||
|
||||
// const colors = {
|
||||
// TRANSPARENT: [0, 0, 0],
|
||||
// BLACK: [0, 0, 0],
|
||||
// WHITE: [1, 1, 1],
|
||||
// RED: [1, 0, 0],
|
||||
// YELLOW: [1, 1, 0],
|
||||
// GREEN: [0, 1, 0],
|
||||
// BLUE: [0.1, 0.5, 1],
|
||||
// DARKBLUE: [0.05, 0.1, 0.3],
|
||||
// BROWN: [0.6, 0.5, 0.4],
|
||||
// GRAY: [0.5, 0.5, 0.5],
|
||||
// PURPLE: [0.7, 0.1, 0.85],
|
||||
// ORANGE: [0.95, 0.75, 0.25],
|
||||
// CYAN: [0, 0.9, 0.9],
|
||||
// LIGHTGRAY: [0.75, 0.75, 0.75],
|
||||
// REDDISH: [216/255, 59/255, 113/255],
|
||||
// DARKGREEN: [0, 0.6, 0.2],
|
||||
// } as const;
|
||||
|
||||
export const palette: Array<[number, number, number, number]> = Object.values(colors).map(val => [...val, 1]);
|
||||
|
||||
export const COLOR = Object.fromEntries(Object.keys(colors).map((name, i) => [name, Number(i)])) as {[key in keyof typeof colors]: number};
|
854
data/font.ts
854
data/font.ts
@ -1,854 +0,0 @@
|
||||
/**
|
||||
* Perhaps fonts can be their own type of sheet. By the calculation below, we can fit ~4 fonts per fontsheet
|
||||
*
|
||||
* 3 bits for height
|
||||
* 5 more metadata bits
|
||||
* = 1 byte
|
||||
*
|
||||
* Per character:
|
||||
* - 3 bits for width
|
||||
* - 5 bits for metadata
|
||||
* - 64 bits for pixels
|
||||
* = 9 bytes per character
|
||||
*
|
||||
* 96 chars * 9 bytes =
|
||||
*/
|
||||
|
||||
// export const fontWidth = 4;
|
||||
// export const fontHeight = 6;
|
||||
|
||||
export const CHAR = {
|
||||
UP: "À",
|
||||
LEFT: "Á",
|
||||
DOWN: "Â",
|
||||
RIGHT: "Ã",
|
||||
PI: "π"
|
||||
}
|
||||
|
||||
export type Font = {
|
||||
height: 6,
|
||||
chars: {[key: string]: Array<number>},
|
||||
};
|
||||
|
||||
// deno-fmt-ignore
|
||||
export const font: Font = {
|
||||
height: 6,
|
||||
chars: {
|
||||
"A": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"B": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"C": [
|
||||
0, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"D": [
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"E": [
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"F": [
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"G": [
|
||||
0, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"H": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"I": [
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"J": [
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"K": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"L": [
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"M": [
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"N": [
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"O": [
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"P": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"Q": [
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"R": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"S": [
|
||||
0, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"T": [
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"U": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"V": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"W": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"X": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"Y": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"Z": [
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"a": [
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"b": [
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"c": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"d": [
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"e": [
|
||||
0, 0, 0,
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"f": [
|
||||
0, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"g": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 1,
|
||||
1, 1, 0,
|
||||
],
|
||||
"h": [
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"i": [
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"j": [
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
],
|
||||
"k": [
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"l": [
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"m": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"n": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"o": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"p": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
],
|
||||
"q": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
],
|
||||
"r": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"s": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"t": [
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"u": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"v": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"w": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"x": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"y": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
],
|
||||
"z": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
",": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
],
|
||||
".": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
" ": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"\t": [
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
"\n": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"<": [
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
">": [
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"=": [
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"(": [
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
")": [
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"[": [
|
||||
0, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"]": [
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"{": [
|
||||
0, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"}": [
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
":": [
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
";": [
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
],
|
||||
"'": [
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
'"': [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"1": [
|
||||
0, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"2": [
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"3": [
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"4": [
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"5": [
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"6": [
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"7": [
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"8": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"9": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"0": [
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"+": [
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"-": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"_": [
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"`": [
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"~": [
|
||||
0, 0, 0,
|
||||
0, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"/": [
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"?": [
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"\\": [
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"|": [
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"!": [
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"@": [
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"#": [
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"$": [
|
||||
1, 1, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"%": [
|
||||
1, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"^": [
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
"&": [
|
||||
1, 1, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 0,
|
||||
],
|
||||
"*": [
|
||||
0, 1, 0,
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
],
|
||||
[CHAR.UP]: [
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 1, 0, 1, 1, 1,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
[CHAR.LEFT]: [
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 1, 0, 0, 1, 1,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
[CHAR.DOWN]: [
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 0, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
[CHAR.RIGHT]: [
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 0, 0, 1, 1, 1,
|
||||
1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 0, 0, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
[CHAR.PI]: [
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
0, 1, 0, 1, 0,
|
||||
0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
],
|
||||
}
|
||||
};
|
@ -1,54 +0,0 @@
|
||||
export const codeIcon = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 1, 0, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 1, 0, 0, 0, 0, 1, 0,
|
||||
0, 1, 0, 0, 0, 0, 1, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 0, 1, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
export const spriteIcon = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 1, 1, 1, 0, 0,
|
||||
0, 1, 1, 0, 1, 1, 1, 0,
|
||||
0, 1, 1, 1, 1, 0, 0, 0,
|
||||
0, 1, 1, 1, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
export const mapIcon = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0,
|
||||
0, 1, 0, 1, 0, 0, 1, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 0,
|
||||
0, 1, 1, 1, 0, 0, 1, 0,
|
||||
0, 1, 0, 1, 0, 0, 1, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
export const sheetsIcon = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
export const trashIcon = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 1, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
@ -1 +0,0 @@
|
||||
[{"sheet_type":"code","value":"// Sample\n\nreturn {\n\tinit() {},\n\tupdate() {},\n\tdraw() {\n\t\tcls();\n\t\ttxt(10,10,\"Hello, World!\");\n\t}\n}"},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null},{"sheet_type":"none","value":null}]
|
12
deno.json
12
deno.json
@ -1,12 +0,0 @@
|
||||
{
|
||||
"fmt": {
|
||||
"useTabs": true
|
||||
},
|
||||
"tasks": {
|
||||
"run": "deno run -A --unstable index.ts",
|
||||
"build": "deno compile --output build/faux -A --unstable index.ts",
|
||||
"build_linux": "mkdir -p ./build/zips ; mkdir -p ./build/linux ; cp ./manual.md ./build/linux/README.md ; deno compile --output build/linux/faux --target x86_64-unknown-linux-gnu -A --unstable index.ts ; cd ./build/linux ; zip -r ../zips/faux_linux.zip . ; cd ../..",
|
||||
"build_windows": "mkdir -p ./build/zips ; mkdir -p ./build/windows ; cp ./manual.md ./build/windows/README.md ; deno compile --output build/windows/faux --target x86_64-pc-windows-msvc -A --unstable index.ts ; cd ./build/windows ; zip -r ../zips/faux_windows.zip . ; cd ../..",
|
||||
"build_all": "deno task build_linux & deno task build_windows"
|
||||
}
|
||||
}
|
73
deno.lock
generated
73
deno.lock
generated
@ -1,73 +0,0 @@
|
||||
{
|
||||
"version": "2",
|
||||
"remote": {
|
||||
"https://deno.land/std@0.186.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
|
||||
"https://deno.land/std@0.186.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
|
||||
"https://deno.land/std@0.186.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
|
||||
"https://deno.land/std@0.186.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
|
||||
"https://deno.land/std@0.186.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
|
||||
"https://deno.land/std@0.186.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
|
||||
"https://deno.land/std@0.186.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
|
||||
"https://deno.land/std@0.186.0/path/mod.ts": "ee161baec5ded6510ee1d1fb6a75a0f5e4b41f3f3301c92c716ecbdf7dae910d",
|
||||
"https://deno.land/std@0.186.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
|
||||
"https://deno.land/std@0.186.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
|
||||
"https://deno.land/std@0.186.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
|
||||
"https://deno.land/std@0.97.0/_util/assert.ts": "2f868145a042a11d5ad0a3c748dcf580add8a0dbc0e876eaa0026303a5488f58",
|
||||
"https://deno.land/std@0.97.0/_util/os.ts": "e282950a0eaa96760c0cf11e7463e66babd15ec9157d4c9ed49cc0925686f6a7",
|
||||
"https://deno.land/std@0.97.0/encoding/base64.ts": "eecae390f1f1d1cae6f6c6d732ede5276bf4b9cd29b1d281678c054dc5cc009e",
|
||||
"https://deno.land/std@0.97.0/encoding/hex.ts": "f952e0727bddb3b2fd2e6889d104eacbd62e92091f540ebd6459317a61932d9b",
|
||||
"https://deno.land/std@0.97.0/fs/_util.ts": "f2ce811350236ea8c28450ed822a5f42a0892316515b1cd61321dec13569c56b",
|
||||
"https://deno.land/std@0.97.0/fs/ensure_dir.ts": "b7c103dc41a3d1dbbb522bf183c519c37065fdc234831a4a0f7d671b1ed5fea7",
|
||||
"https://deno.land/std@0.97.0/fs/exists.ts": "b0d2e31654819cc2a8d37df45d6b14686c0cc1d802e9ff09e902a63e98b85a00",
|
||||
"https://deno.land/std@0.97.0/hash/_wasm/hash.ts": "cb6ad1ab429f8ac9d6eae48f3286e08236d662e1a2e5cfd681ba1c0f17375895",
|
||||
"https://deno.land/std@0.97.0/hash/_wasm/wasm.js": "94b1b997ae6fb4e6d2156bcea8f79cfcd1e512a91252b08800a92071e5e84e1a",
|
||||
"https://deno.land/std@0.97.0/hash/hasher.ts": "57a9ec05dd48a9eceed319ac53463d9873490feea3832d58679df6eec51c176b",
|
||||
"https://deno.land/std@0.97.0/hash/mod.ts": "5d032bd34186cda2f8d17fc122d621430953a6030d4b3f11172004715e3e2441",
|
||||
"https://deno.land/std@0.97.0/path/_constants.ts": "1247fee4a79b70c89f23499691ef169b41b6ccf01887a0abd131009c5581b853",
|
||||
"https://deno.land/std@0.97.0/path/_interface.ts": "1fa73b02aaa24867e481a48492b44f2598cd9dfa513c7b34001437007d3642e4",
|
||||
"https://deno.land/std@0.97.0/path/_util.ts": "2e06a3b9e79beaf62687196bd4b60a4c391d862cfa007a20fc3a39f778ba073b",
|
||||
"https://deno.land/std@0.97.0/path/common.ts": "eaf03d08b569e8a87e674e4e265e099f237472b6fd135b3cbeae5827035ea14a",
|
||||
"https://deno.land/std@0.97.0/path/glob.ts": "314ad9ff263b895795208cdd4d5e35a44618ca3c6dd155e226fb15d065008652",
|
||||
"https://deno.land/std@0.97.0/path/mod.ts": "4465dc494f271b02569edbb4a18d727063b5dbd6ed84283ff906260970a15d12",
|
||||
"https://deno.land/std@0.97.0/path/posix.ts": "f56c3c99feb47f30a40ce9d252ef6f00296fa7c0fcb6dd81211bdb3b8b99ca3b",
|
||||
"https://deno.land/std@0.97.0/path/separator.ts": "8fdcf289b1b76fd726a508f57d3370ca029ae6976fcde5044007f062e643ff1c",
|
||||
"https://deno.land/std@0.97.0/path/win32.ts": "77f7b3604e0de40f3a7c698e8a79e7f601dc187035a1c21cb1e596666ce112f8",
|
||||
"https://deno.land/x/cache@0.2.13/deps.ts": "6f14e76a1a09f329e3f3830c6e72bd10b53a89a75769d5ea886e5d8603e503e6",
|
||||
"https://deno.land/x/cache@0.2.13/directories.ts": "ef48531cab3f827252e248596d15cede0de179a2fb15392ae24cf8034519994f",
|
||||
"https://deno.land/x/dwm@0.3.3/mod.ts": "8a8ca602442d250eaa7cef67c14245a41aa7dc8de2fa337008e433a2ed1fe2f1",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/common.ts": "dd4cd26f45fca187c5a6192bfb7b3b4a01a23c66dddf64e19e013de7748f988d",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/event.ts": "715cce309021e9dcd45b7e3f41bddea961d4b157dcf6f29a21e910825aae90a8",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/mod.ts": "4c54848365ea17b67e65d4d58c7c94378c9bbc6ea2a59d7d11f1d701e6a5483a",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/monitor.ts": "b291ebad386095285fb7c430990be0a9f1f5f81fbcb338058ce72a538a75d667",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/platform.ts": "6cab5f575198848673204673fe82d242c9c87549c16cbed9a64c838eb99dd2d4",
|
||||
"https://deno.land/x/dwm@0.3.3/src/core/window.ts": "1ccd738d6e4e28836327a76480c3c47855f617fa7ed7552a035f2d7bf0fd6c6d",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/constants.ts": "832295fa6a4bd66aea638bd09ad2cc48b3756daff814c7c0ae2a544f228be9e5",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/ffi.ts": "0c6a521a8374aa8c912417edfa5c263423286363f4a7c827d4d26ead8b954ee6",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/monitor.ts": "05506c5d21c527a6ea456d24e00f88a01a9292a68f45a845499137ecb6fb80c7",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/platform.ts": "cca2684151f34be392e74a9828f89f8c3ed46db25e59aec1f638b4ccf82535e9",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/scancode_win.json": "711ee525f88fe92129acd7d66fd6a5665b68ce6a60f590ae24de67e1ee916b8f",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/glfw/window.ts": "a6dd426a95cd93ba4905da151a0d06e9376becca273ee8bc8d1c9a7bd16e0d81",
|
||||
"https://deno.land/x/dwm@0.3.3/src/platform/mod.ts": "20572d937c62ec543e0ca87cf8ed32cd15505d254f97a6fae98b936e480f2157",
|
||||
"https://deno.land/x/gluten@0.1.6/api/gles23.2.ts": "99cad13b74938ff987a1a707f73d72a82ddf66935e45b59d1980928cd3af3495",
|
||||
"https://esm.sh/js-tokens@8.0.1": "7b08a51f91034b720edcde4f0b4314abc39ee14da57861e3e676f1ed1f4fb4ab",
|
||||
"https://esm.sh/v119/js-tokens@8.0.1/deno/js-tokens.mjs": "0fa55e76fa97785f8f938db8ea55e0db57825ea81cdcad20bd925f9902f678c1",
|
||||
"https://esm.sh/v119/js-tokens@8.0.1/index.d.ts": "9b178631a934bd5e4832b478d4f74083d4dc357615a0d1a632357dfafe898cdb",
|
||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_darwin.js": "48911f26fff723a9c5f2f38e39be42fc65ed8dea6f2ba1f1acb464d3f0aa435b",
|
||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_darwin_aarch64.js": "ae4d795d93830b8a27714ab6c20b69b67f3d4ad3544c50e344558756cf2e92f3",
|
||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_linux.js": "b064aedb175fee1a977937f07584238f313a1958f9869273e7e672c42f09932d",
|
||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_windows.js": "6ac603e03520c8c333e1475cb00f982adb1f8a99de7f4bb0b8953da66f210159",
|
||||
"https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts": "85282325a499c75c6f9ed3603fc5f8baf4bf661a616add43b4e6f033def52680",
|
||||
"https://unpkg.com/js-tokens@8.0.1/index.js": "322c95254ceef0ac195f4e71adac2a90adf379a2d67fbb948402295a780fdbc0"
|
||||
},
|
||||
"npm": {
|
||||
"specifiers": {
|
||||
"js-tokens": "js-tokens@8.0.1"
|
||||
},
|
||||
"packages": {
|
||||
"js-tokens@8.0.1": {
|
||||
"integrity": "sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==",
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
deps.ts
43
deps.ts
@ -1,43 +0,0 @@
|
||||
// dwm
|
||||
export {
|
||||
createWindow,
|
||||
getProcAddress,
|
||||
mainloop,
|
||||
} from "https://deno.land/x/dwm@0.3.3/mod.ts";
|
||||
export * as gl from "https://deno.land/x/gluten@0.1.6/api/gles23.2.ts";
|
||||
|
||||
// jsTokens
|
||||
import jsTokens from "https://esm.sh/js-tokens@8.0.1";
|
||||
export function tokenize(input: string): Iterable<Token> {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
return (jsTokens as any)(input);
|
||||
}
|
||||
type Token =
|
||||
| { type: "StringLiteral"; value: string; closed: boolean }
|
||||
| { type: "NoSubstitutionTemplate"; value: string; closed: boolean }
|
||||
| { type: "TemplateHead"; value: string }
|
||||
| { type: "TemplateMiddle"; value: string }
|
||||
| { type: "TemplateTail"; value: string; closed: boolean }
|
||||
| { type: "RegularExpressionLiteral"; value: string; closed: boolean }
|
||||
| { type: "MultiLineComment"; value: string; closed: boolean }
|
||||
| { type: "SingleLineComment"; value: string }
|
||||
| { type: "IdentifierName"; value: string }
|
||||
| { type: "PrivateIdentifier"; value: string }
|
||||
| { type: "NumericLiteral"; value: string }
|
||||
| { type: "Punctuator"; value: string }
|
||||
| { type: "WhiteSpace"; value: string }
|
||||
| { type: "LineTerminatorSequence"; value: string }
|
||||
| { type: "Invalid"; value: string };
|
||||
|
||||
// clipboard
|
||||
import { clipboard } from "https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts";
|
||||
export { clipboard } from "https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts";
|
||||
try {
|
||||
await clipboard.readText();
|
||||
} catch (err) {
|
||||
console.log("If you are running this on linux, please make sure you have 'xsel' installed.");
|
||||
throw err;
|
||||
}
|
||||
|
||||
// path
|
||||
export * as path from "https://deno.land/std@0.186.0/path/mod.ts";
|
134
docs/manual.md
134
docs/manual.md
@ -1,134 +0,0 @@
|
||||
# Faux Manual
|
||||
|
||||
This document is up-to-date as of May 14, 2023.
|
||||
|
||||
Faux is a [fantasy console](https://en.wikipedia.org/wiki/Fantasy_video_game_console) heavily inspired by [PICO-8](https://www.lexaloffle.com/pico-8.php), but with several alternative design choices. It is probably nowhere near as resource efficient either.
|
||||
|
||||
This console being in its infancy, this document is literally the only documentation that exists. As such, anything not found in this documentation should be asked of the author, or assumed to be similar to PICO-8.
|
||||
|
||||
## What's different from PICO-8?
|
||||
|
||||
Glad you asked.
|
||||
|
||||
Probably the most important difference is that cartridges are written in JavaScript rather than Lua.
|
||||
|
||||
Another huge design difference is that rather than having a fixed amount of sprite/map/music data, a Faux cartridge is made up of up to 16 "sheets". Each sheet can store a certain amount of data in a specific format. Sheets can be used to hold sprite data, map data, code, and eventually music/sfx, fonts, and other types of data. The first sheet must always be a code sheet and must return an object with three properties: `init`, `update`, and `draw`, each of which should be a function.
|
||||
|
||||
## Code
|
||||
|
||||
The code used in faux cartridges is JavaScript, but without a lot of the language built-ins. Instead, faux provides it's own api to accomplish things like drawing sprites, etc.
|
||||
|
||||
In the code editor, a few special characters can be inserted by holding alt while pressing another key. Currently, the characters that can be added in this way are:
|
||||
|
||||
Symbols for arrows:
|
||||
|
||||
- `⬆️` (Alt+W)
|
||||
- `⬅️` (Alt+A)
|
||||
- `⬇️` (Alt+S)
|
||||
- `➡️` (Alt+D)
|
||||
|
||||
And math symbols:
|
||||
|
||||
- `π` (Alt+P)
|
||||
|
||||
### Graphics
|
||||
|
||||
- `cls(color?: number)` clears the screen to the given color if provided, otherwise, black.
|
||||
- `camera(x: number, y: number)` draws everything from here on with an offset of (-x, -y).
|
||||
- `sprsht(sheet: number)` sets the current spritesheet used for drawing sprites with the `spr` function below.
|
||||
- `spr(x: number, y: number, sprite: number)` draws the given sprite from the current spritesheet at (x,y).
|
||||
- `txt(x: number, y: number, text: string, color?: number)` draws the given text at (x,y) in the provided color (or white if none provided).
|
||||
- `rectfill(x: number, y: number, w: number, h: number, color: number)` fills a rectangle with the given color with a top-left corner at (x,y) and a width of w and a height of h.
|
||||
- `rect(x: number, y: number, w: number, h: number, color: number)` outlines a rectangle with the given color with a top-left corner at (x,y) and a width of w and a height of h.
|
||||
- `circfill(x: number, y: number, r: number, color: number)` fills a circle with the given color with a center at (x,y) and a radius of r.
|
||||
- `circ(x: number, y: number, r: number, color: number)` outlines a circle with the given color with a center at (x,y) and a radius of r.
|
||||
- `ovalfill(x0: number, y0: number, x1: number, y1: number, color: number)` fills an ellipse with the given color whose bounding box has a top-left corner at (x0,y0) and a bottom-right corner at (x1,y1).
|
||||
- `oval(x0: number, y0: number, x1: number, y1: number, color: number)` outlines an ellipse with the given color whose bounding box has a top-left corner at (x0,y0) and a bottom-right corner at (x1,y1).
|
||||
- `pset(x: number, y: number, color: number)` sets the color of the pixel at (x,y) to the given color.
|
||||
- `map(mapSheet: number, tileX: number, tileY: number, screenX: number, screenY: number, tileW: number, tileH: number)` draws the map of the given sheet to the screen at (screenX,screenY) beginning from from the tile at (tileX,tileY) and drawing tileW many tiles across, and tileH many tiles down.
|
||||
|
||||
### Map
|
||||
|
||||
- `mgetsht(mapSheet: number, x: number, y: number)` returns the sheet number of the sprite at tile (x,y) in the given map
|
||||
- `mgetspr(mapSheet: number, x: number, y: number)` returns the sprite number within it's sheet of the sprite at tile (x,y) in the given map
|
||||
- `mset(mapSheet: number, x: number, y: number, sprSheet: number, spr: number)` sets the sprite at tile (x,y) in the given map to the given sprite of the given spritesheet. **(THIS FUNCTION IS TEMPORARILY UNAVAILABLE.)**
|
||||
|
||||
### Input
|
||||
|
||||
- `btn(key: string | number)` returns a boolean indicating whether the given key is currently held down.
|
||||
- `btnp(key: string | number)` returns a boolean indicating whether the given key has just been pressed. Fires repeatedly after a time, as when typing.
|
||||
- `btnr(key: string | number)` returns a boolean indicating whether the given key has just been released.
|
||||
|
||||
There are also values:
|
||||
|
||||
- `⬆️` a number that corresponds to the up arrow.
|
||||
- `⬅️` a number that corresponds to the left arrow.
|
||||
- `⬇️` a number that corresponds to the down arrow.
|
||||
- `➡️` a number that corresponds to the right arrow.
|
||||
|
||||
### System
|
||||
|
||||
- `save(name: string)` saves the cartridge
|
||||
- `load(name: string)` loads the cartridge
|
||||
- `play()` plays the cartridge
|
||||
|
||||
### Misc.
|
||||
|
||||
- `code(sheet: number)` executes the code in the given sheet as a function and returns any return value.
|
||||
- `log(...args: any)` logs the given args to the stdout of faux.
|
||||
|
||||
### REPL Only
|
||||
|
||||
- `print(val: any)` only really should be used in the repl.
|
||||
- `printVal(val: any)` only really should be used in the repl.
|
||||
|
||||
### Math functions
|
||||
|
||||
These are all identical to what Javascript typically has under the [`Math`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math) namespace:
|
||||
|
||||
- `max`
|
||||
- `min`
|
||||
- `floor`
|
||||
- `ceil`
|
||||
- `sin`
|
||||
- `cos`
|
||||
- `atan2`
|
||||
- `sqrt`
|
||||
- `abs`
|
||||
- `rand`
|
||||
|
||||
Faux also provides:
|
||||
|
||||
- `π` which is just `Math.PI` in regular JS.
|
||||
|
||||
### JS Objects
|
||||
|
||||
The following JS objects/functions/value are exactly provided as is in a typical JS environment:
|
||||
|
||||
- [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||
- [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
|
||||
- [`Boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)
|
||||
- [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
|
||||
- [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
|
||||
- [`Function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
|
||||
- [`Infinity`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity)
|
||||
- [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)
|
||||
- [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
|
||||
- [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)
|
||||
- [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)
|
||||
- [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
|
||||
- [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
|
||||
- [`Proxy`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
|
||||
- [`Reflect`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect)
|
||||
- [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)
|
||||
- [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
|
||||
- [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
|
||||
- [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
|
||||
- [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
|
||||
- [`WeakRef`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef)
|
||||
- [`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet)
|
||||
- [`isFinite`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
|
||||
- [`isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN)
|
||||
- [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
|
||||
- [`parseFloat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat)
|
||||
- [`parseInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
|
@ -1,130 +0,0 @@
|
||||
- [x] load
|
||||
- [x] save
|
||||
- [ ] folder
|
||||
- [ ] ls (cd?)
|
||||
- [x] run
|
||||
- [ ] stop
|
||||
- [ ] resume
|
||||
- [ ] assert
|
||||
- [ ] reboot
|
||||
- [ ] reset
|
||||
- [ ] info
|
||||
- [ ] flip
|
||||
- [x] printh (as `log`)
|
||||
- [ ] time/t
|
||||
- [ ] stat
|
||||
- [ ] extcmd
|
||||
|
||||
- [ ] clip
|
||||
- [x] pset
|
||||
- [ ] pget
|
||||
- [ ] sget
|
||||
- [ ] sset
|
||||
- [ ] fget
|
||||
- [ ] fset
|
||||
- [?] print
|
||||
- [ ] cursor
|
||||
- [ ] color
|
||||
- [x] cls
|
||||
- [x] camera
|
||||
- [x] circ
|
||||
- [x] circfill
|
||||
- [x] oval
|
||||
- [x] ovalfill
|
||||
- [ ] line
|
||||
- [x] rect
|
||||
- [x] rectfill
|
||||
- [ ] pal
|
||||
- [ ] palt
|
||||
- [x] spr
|
||||
- [ ] sspr
|
||||
- [ ] fillp
|
||||
|
||||
- [x] btn
|
||||
- [x] btnp
|
||||
|
||||
- [ ] sfx
|
||||
- [ ] music
|
||||
|
||||
- [x] mget
|
||||
- [x] mset
|
||||
- [x] map
|
||||
- [ ] tline
|
||||
|
||||
- [ ] peek
|
||||
- [ ] poke
|
||||
- [ ] peek2
|
||||
- [ ] poke2
|
||||
- [ ] peek4
|
||||
- [ ] poke4
|
||||
- [ ] memcpy
|
||||
- [ ] reload
|
||||
- [ ] cstore
|
||||
- [ ] memset
|
||||
|
||||
- [ ] menuitem
|
||||
|
||||
- [ ] cartdata
|
||||
- [ ] dget
|
||||
- [ ] dset
|
||||
|
||||
- [ ] serial
|
||||
|
||||
- [ ] setmetatable
|
||||
- [ ] getmetatable
|
||||
- [ ] rawset
|
||||
- [ ] rawget
|
||||
- [ ] rawequal
|
||||
- [ ] rawlen
|
||||
|
||||
|
||||
== most things below here handled by js or easily included.
|
||||
|
||||
-- js Array has most things we want here
|
||||
- [ ] add
|
||||
- [ ] del
|
||||
- [ ] deli
|
||||
- [ ] count
|
||||
- [ ] all
|
||||
- [ ] foreach
|
||||
- [ ] pairs
|
||||
|
||||
- [x] max
|
||||
- [x] min
|
||||
- [ ] mid
|
||||
- [x] flr
|
||||
- [x] ceil
|
||||
- [x] cos
|
||||
- [x] sin
|
||||
- [x] atan2
|
||||
- [x] sqrt
|
||||
- [x] abs
|
||||
- [x] rnd
|
||||
- [ ] srand
|
||||
|
||||
-- skipping these in favor of bitwise operations if needed
|
||||
- [ ] band
|
||||
- [ ] bor
|
||||
- [ ] bxor
|
||||
- [ ] bnot
|
||||
- [ ] shl
|
||||
- [ ] shr
|
||||
- [ ] lshr
|
||||
- [ ] rotl
|
||||
- [ ] rotr
|
||||
|
||||
-- js comes with stuff here (String, Number, typeof, etc.)
|
||||
- [ ] tostr
|
||||
- [ ] tonum
|
||||
- [ ] chr
|
||||
- [ ] ord
|
||||
- [ ] sub
|
||||
- [ ] split
|
||||
- [ ] type
|
||||
|
||||
-- js comes with stuff here
|
||||
- [ ] cocreate
|
||||
- [ ] coresume
|
||||
- [ ] assert
|
||||
- [ ] costatus
|
||||
- [ ] yield
|
@ -1,694 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { CHAR, font } from "../data/font.ts";
|
||||
import { drawText, measureText } from "../runtime/builtins.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getCodeSheet, setSheet } from "../io/sheet.ts";
|
||||
import { K, ctrlKeyDown, getKeyboardString, keyPressed, shiftKeyDown } from "../io/keyboard.ts";
|
||||
import { clipboard, tokenize } from "../deps.ts";
|
||||
import { getBuiltins } from "../runtime/runcode.ts";
|
||||
import { page } from "./viewsheets.ts";
|
||||
import { mouseDown, mouseHeld, mousePos } from "../io/mouse.ts";
|
||||
|
||||
const historyDebounceFrames = 20;
|
||||
|
||||
const fontHeight = font.height;
|
||||
|
||||
const keywords = [
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"export",
|
||||
"extends",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
"let",
|
||||
"static",
|
||||
"yield",
|
||||
"await",
|
||||
"enum",
|
||||
"implements",
|
||||
"interface",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"=>",
|
||||
];
|
||||
const values = [
|
||||
"false",
|
||||
"null",
|
||||
"true",
|
||||
"undefined",
|
||||
"NaN",
|
||||
"Infinity",
|
||||
CHAR.PI,
|
||||
];
|
||||
const operator = [
|
||||
"&&",
|
||||
"||",
|
||||
"??",
|
||||
"--",
|
||||
"++",
|
||||
".",
|
||||
"?.",
|
||||
"<",
|
||||
"<=",
|
||||
">",
|
||||
">=",
|
||||
"!=",
|
||||
"!==",
|
||||
"==",
|
||||
"===",
|
||||
"+",
|
||||
"-",
|
||||
"%",
|
||||
"&",
|
||||
"|",
|
||||
"^",
|
||||
"/",
|
||||
"*",
|
||||
"**",
|
||||
"<<",
|
||||
">>",
|
||||
">>>",
|
||||
"=",
|
||||
"+=",
|
||||
"-=",
|
||||
"%=",
|
||||
"&=",
|
||||
"|=",
|
||||
"^=",
|
||||
"/=",
|
||||
"*=",
|
||||
"**=",
|
||||
"<<=",
|
||||
">>=",
|
||||
">>>=",
|
||||
"!",
|
||||
"?",
|
||||
"~",
|
||||
"...",
|
||||
];
|
||||
const punctuation = [
|
||||
"(",
|
||||
")",
|
||||
"[",
|
||||
"]",
|
||||
"{",
|
||||
"}",
|
||||
".",
|
||||
":",
|
||||
";",
|
||||
",",
|
||||
];
|
||||
|
||||
const builtinColor = COLOR.BLUE;
|
||||
const keywordColor = COLOR.PURPLE;
|
||||
const operatorColor = COLOR.CYAN;
|
||||
const valueColor = COLOR.ORANGE;
|
||||
const stringColor = COLOR.GREEN;
|
||||
const regexColor = COLOR.PINK;
|
||||
const punctuationColor = COLOR.LIGHTGRAY;
|
||||
const commentColor = COLOR.DARKGREEN;
|
||||
const identifierColor = COLOR.YELLOW;
|
||||
const invalidColor = COLOR.RED;
|
||||
|
||||
const caretColor = COLOR.WHITE;
|
||||
const selectionColor = COLOR.DARKBLUE;
|
||||
|
||||
const backgroundColor = COLOR.DARKERBLUE;
|
||||
|
||||
const tokenColors = {
|
||||
"StringLiteral": stringColor,
|
||||
"NoSubstitutionTemplate": stringColor,
|
||||
"TemplateHead": stringColor,
|
||||
"TemplateMiddle": stringColor,
|
||||
"TemplateTail": stringColor,
|
||||
"RegularExpressionLiteral": regexColor,
|
||||
"MultiLineComment": commentColor,
|
||||
"SingleLineComment": commentColor,
|
||||
"IdentifierName": identifierColor,
|
||||
"PrivateIdentifier": identifierColor,
|
||||
"NumericLiteral": valueColor,
|
||||
"Punctuator": punctuationColor,
|
||||
"WhiteSpace": punctuationColor,
|
||||
"LineTerminatorSequence": punctuationColor,
|
||||
"Invalid": invalidColor,
|
||||
}
|
||||
|
||||
const transformForCopy = (text: string) => {
|
||||
text = text.replaceAll(CHAR.UP, "⬆️");
|
||||
text = text.replaceAll(CHAR.LEFT, "⬅️");
|
||||
text = text.replaceAll(CHAR.DOWN, "⬇️");
|
||||
text = text.replaceAll(CHAR.RIGHT, "➡️");
|
||||
return text;
|
||||
}
|
||||
|
||||
const transformForPaste = (text: string) => {
|
||||
let newstr = "";
|
||||
text = text.replaceAll("⬆️", CHAR.UP);
|
||||
text = text.replaceAll("⬅️", CHAR.LEFT);
|
||||
text = text.replaceAll("⬇️", CHAR.DOWN);
|
||||
text = text.replaceAll("➡️", CHAR.RIGHT);
|
||||
for (const char of text) {
|
||||
if (char in font.chars) {
|
||||
newstr += char;
|
||||
}
|
||||
}
|
||||
return newstr;
|
||||
}
|
||||
|
||||
const state = {
|
||||
doubleClickTimer: 0,
|
||||
history: [] as Array<{code: string, anchor: number, focus: number}>,
|
||||
historyDebounce: 0,
|
||||
historyIndex: 0,
|
||||
undo() {
|
||||
console.log('undoing');
|
||||
if (this.historyIndex === this.history.length && this.historyDebounce > 0) {
|
||||
this.snapshot();
|
||||
}
|
||||
console.log('historyIndex', this.historyIndex);
|
||||
if (this.historyIndex > 0) {
|
||||
this.historyIndex -= 1;
|
||||
const snap = this.history[this.historyIndex];
|
||||
console.log('historyIndex', this.historyIndex);
|
||||
this.code = snap.code;
|
||||
this.setSelection(snap.anchor, snap.focus);
|
||||
}
|
||||
},
|
||||
redo() {
|
||||
console.log('redoing');
|
||||
if (this.historyIndex < this.history.length-1) {
|
||||
this.historyIndex += 1;
|
||||
const snap = this.history[this.historyIndex];
|
||||
this.code = snap.code;
|
||||
this.setSelection(snap.anchor, snap.focus);
|
||||
}
|
||||
},
|
||||
snapshot() {
|
||||
const snap = {
|
||||
code: this.code,
|
||||
anchor: this.anchor,
|
||||
focus: this.focus,
|
||||
};
|
||||
this.history.push(snap);
|
||||
console.log('took snapshot', this.historyIndex, snap);
|
||||
},
|
||||
startSnapping() {
|
||||
console.log('start snapping', this.historyIndex);
|
||||
if (this.historyDebounce <= 0) {
|
||||
this.historyIndex += 1;
|
||||
}
|
||||
if (this.history.length > this.historyIndex) {
|
||||
this.history.length = this.historyIndex;
|
||||
}
|
||||
this.historyDebounce = historyDebounceFrames;
|
||||
},
|
||||
wordMode: false,
|
||||
scrollX: 0,
|
||||
scrollY: 0,
|
||||
anchor: 0,
|
||||
focus: 0,
|
||||
get focusX() {return indexToGrid(this.code, this.focus).x;},
|
||||
get focusY() {return indexToGrid(this.code, this.focus).y;},
|
||||
get anchorX() {return indexToGrid(this.code, this.anchor).x;},
|
||||
get anchorY() {return indexToGrid(this.code, this.anchor).y;},
|
||||
get focusPixelX() {return indexToRect(this.code, this.focus).x;},
|
||||
get focusPixelY() {return indexToRect(this.code, this.focus).y;},
|
||||
get anchorPixelX() {return indexToRect(this.code, this.anchor).x;},
|
||||
get anchorPixelY() {return indexToRect(this.code, this.anchor).y;},
|
||||
isCollapsed() {
|
||||
return this.anchor === this.focus;
|
||||
},
|
||||
clampInRange(n: number) {
|
||||
return Math.max(0, Math.min(n, this.code.length))
|
||||
},
|
||||
findNearestWordBoundaryLeft(index: number) {
|
||||
if (index === this.code.length-1) {
|
||||
return index;
|
||||
}
|
||||
const words1 = this.code.slice(0, index+1).split(/\b/g);
|
||||
if (words1[words1.length-1].length === 1) {
|
||||
return index;
|
||||
}
|
||||
const words = this.code.slice(0, index).split(/\b/g);
|
||||
if (!words.length) {
|
||||
return 0;
|
||||
}
|
||||
return index-words[words.length-1].length;
|
||||
},
|
||||
findNearestWordBoundaryRight(index: number) {
|
||||
if (index === 0) {
|
||||
return index;
|
||||
}
|
||||
const words1 = this.code.slice(index-1).split(/\b/g);
|
||||
if (words1[0].length === 1) {
|
||||
return index;
|
||||
}
|
||||
const words = this.code.slice(index).split(/\b/g);
|
||||
if (!words.length) {
|
||||
return this.code.length;
|
||||
}
|
||||
return index+words[0].length;
|
||||
},
|
||||
setSelection(anchor: number | {x: number, y: number}, focus?: number | {x: number, y: number}) {
|
||||
if (typeof anchor !== "number") {
|
||||
anchor = gridToIndex(this.code, anchor.x, anchor.y);
|
||||
}
|
||||
focus = focus ?? anchor;
|
||||
if (typeof focus !== "number") {
|
||||
focus = gridToIndex(this.code, focus.x, focus.y);
|
||||
}
|
||||
this.anchor = this.clampInRange(anchor);
|
||||
this.focus = this.clampInRange(focus);
|
||||
if (this.wordMode) {
|
||||
console.log('word mode', this.anchor, this.focus, this.findNearestWordBoundaryLeft(this.anchor), this.findNearestWordBoundaryRight(this.focus));
|
||||
if (this.anchor <= this.focus) {
|
||||
this.anchor = this.findNearestWordBoundaryLeft(this.anchor);
|
||||
this.focus = this.findNearestWordBoundaryRight(this.focus);
|
||||
} else {
|
||||
this.anchor = this.findNearestWordBoundaryRight(this.anchor);
|
||||
this.focus = this.findNearestWordBoundaryLeft(this.focus);
|
||||
}
|
||||
}
|
||||
this.anchor = this.clampInRange(this.anchor);
|
||||
this.focus = this.clampInRange(this.focus);
|
||||
},
|
||||
setFocus(focus: number | {x: number, y: number}) {
|
||||
if (typeof focus !== "number") {
|
||||
focus = gridToIndex(this.code, focus.x, focus.y);
|
||||
}
|
||||
this.focus = this.clampInRange(focus);
|
||||
if (this.wordMode) {
|
||||
if (this.anchor <= this.focus) {
|
||||
this.anchor = this.findNearestWordBoundaryLeft(this.anchor);
|
||||
this.focus = this.findNearestWordBoundaryRight(this.focus);
|
||||
} else {
|
||||
this.anchor = this.findNearestWordBoundaryRight(this.anchor);
|
||||
this.focus = this.findNearestWordBoundaryLeft(this.focus);
|
||||
}
|
||||
}
|
||||
this.focus = this.clampInRange(this.focus);
|
||||
},
|
||||
insertText(text: string) {
|
||||
const {code, anchor, focus} = this;
|
||||
this.code = code.slice(0, Math.min(anchor, focus)) + text + code.slice(Math.max(anchor, focus));
|
||||
this.setSelection(Math.min(anchor, focus) + text.length);
|
||||
this.startSnapping();
|
||||
},
|
||||
toggleComment() {
|
||||
const lines = this.code.split("\n");
|
||||
const {focusX, focusY, anchorX, anchorY} = this;
|
||||
const lineInSelection = (i: number) => i >= Math.min(focusY, anchorY) && i <= Math.max(focusY, anchorY);
|
||||
const allLinesAreCommented = lines.every((line, i) => {
|
||||
if (lineInSelection(i) && !line.trim().startsWith("// ")) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const newLines = lines.map((line, i) => {
|
||||
if (lineInSelection(i)) {
|
||||
if (allLinesAreCommented) {
|
||||
return line.slice(3);
|
||||
} else {
|
||||
return "// "+line;
|
||||
}
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
});
|
||||
this.code = newLines.join("\n");
|
||||
const shiftBy = allLinesAreCommented ? -3 : 3;
|
||||
this.setSelection({x: anchorX+shiftBy, y: anchorY}, {x: focusX+shiftBy, y: focusY});
|
||||
this.startSnapping();
|
||||
},
|
||||
indent(indentString: string) {
|
||||
const lines = this.code.split("\n");
|
||||
const {focusX, focusY, anchorX, anchorY} = this;
|
||||
const newLines = lines.map((line, i) => {
|
||||
if (i >= Math.min(focusY, anchorY) && i <= Math.max(focusY, anchorY)) {
|
||||
return indentString+line;
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
});
|
||||
this.code = newLines.join("\n");
|
||||
this.setSelection({x: anchorX+1, y: anchorY}, {x: focusX+1, y: focusY});
|
||||
this.startSnapping();
|
||||
},
|
||||
outdent(outdentRegex: RegExp) {
|
||||
const lines = this.code.split("\n");
|
||||
const {focusX, focusY, anchorX, anchorY} = this;
|
||||
const newLines = lines.map((line, i) => {
|
||||
const match = line.match(outdentRegex);
|
||||
if (i >= Math.min(focusY, anchorY) && i <= Math.max(focusY, anchorY) && match) {
|
||||
return line.slice(match[0].length);
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
});
|
||||
this.code = newLines.join("\n");
|
||||
this.setSelection({x: Math.max(0,anchorX-1), y: anchorY}, {x: Math.max(0,focusX-1), y: focusY});
|
||||
this.startSnapping();
|
||||
},
|
||||
backspace() {
|
||||
const {code, focus} = this;
|
||||
if (this.isCollapsed()) {
|
||||
if (focus > 0) {
|
||||
this.code = code.slice(0, focus-1) + code.slice(focus);
|
||||
this.setSelection(focus-1);
|
||||
this.startSnapping();
|
||||
}
|
||||
} else {
|
||||
this.insertText("");
|
||||
}
|
||||
},
|
||||
delete() {
|
||||
const {code, focus} = this;
|
||||
if (this.isCollapsed()) {
|
||||
if (focus < code.length) {
|
||||
this.code = code.slice(0, focus) + code.slice(1+focus);
|
||||
this.startSnapping();
|
||||
}
|
||||
} else {
|
||||
this.insertText("");
|
||||
}
|
||||
},
|
||||
async copy() {
|
||||
const {code, anchor, focus} = this;
|
||||
const selected = code.slice(Math.min(anchor,focus), Math.max(anchor,focus));
|
||||
await clipboard.writeText(transformForCopy(selected));
|
||||
},
|
||||
async cut() {
|
||||
await this.copy();
|
||||
this.insertText("");
|
||||
},
|
||||
async paste() {
|
||||
this.insertText(transformForPaste(await clipboard.readText()));
|
||||
},
|
||||
scrollToCursor() {
|
||||
const {focusY, scrollY, scrollX, focus} = this;
|
||||
const fh = fontHeight + 1;
|
||||
const rect = indexToRect(this.code, focus);
|
||||
if (focusY*fh < scrollY) {
|
||||
this.scrollY = focusY*fh;
|
||||
}
|
||||
if (focusY*fh > scrollY+112-fh) {
|
||||
this.scrollY = focusY*fh-112+fh;
|
||||
}
|
||||
if (rect.x < scrollX) {
|
||||
this.scrollX = rect.x;
|
||||
}
|
||||
if (rect.x+rect.w > scrollX+128) {
|
||||
this.scrollX = rect.x-128+rect.w+1;
|
||||
}
|
||||
},
|
||||
currentIndentation() {
|
||||
const lines = this.code.slice(0, this.focus).split("\n");
|
||||
const line = lines[lines.length-1];
|
||||
const match = line.match(/^\s*/);
|
||||
if (!match) {
|
||||
return "";
|
||||
}
|
||||
return match[0];
|
||||
},
|
||||
get code() {
|
||||
return getCodeSheet(page.activeSheet);
|
||||
},
|
||||
set code(val) {
|
||||
setSheet(page.activeSheet, "code", val);
|
||||
}
|
||||
}
|
||||
|
||||
const indexToGrid = (str: string, index: number) => {
|
||||
const linesUpTo = str.slice(0,index).split("\n");
|
||||
return {
|
||||
x: linesUpTo[linesUpTo.length-1].length,
|
||||
y: linesUpTo.length - 1,
|
||||
}
|
||||
}
|
||||
|
||||
const gridToIndex = (str: string, x: number, y: number) => {
|
||||
const lines = str.split("\n");
|
||||
if (y < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (y >= lines.length) {
|
||||
return str.length;
|
||||
}
|
||||
return lines.slice(0, y).join("\n").length+Math.min(x, lines[y].length)+(y === 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
const indexToRect = (str: string, index: number) => {
|
||||
const linesUpTo = str.slice(0,index).split("\n");
|
||||
let extra = 0;
|
||||
if (linesUpTo[linesUpTo.length-1].length > 0) {
|
||||
extra = 1;
|
||||
}
|
||||
return {
|
||||
x: measureText(linesUpTo[linesUpTo.length-1]) + extra,
|
||||
y: (fontHeight + 1)*(linesUpTo.length - 1),
|
||||
w: measureText(str[index] ?? "\n"),
|
||||
h: fontHeight+1,
|
||||
}
|
||||
}
|
||||
|
||||
const pixelToIndex = (str: string, x: number, y: number) => {
|
||||
const lines = str.split("\n");
|
||||
if (y < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (y >= (fontHeight+1)*lines.length) {
|
||||
return str.length;
|
||||
}
|
||||
const yy = Math.floor(y/(fontHeight+1));
|
||||
const prefix = lines.slice(0, yy).join("\n").length+(yy === 0 ? 0 : 1);
|
||||
const line = lines[yy];
|
||||
let j = 0;
|
||||
while (measureText(line.slice(0, j)) < x && j < line.length) {
|
||||
j+=1;
|
||||
}
|
||||
if (measureText(line) < x) {
|
||||
j+=1;
|
||||
}
|
||||
return prefix + Math.max(0, j-1);
|
||||
}
|
||||
|
||||
const update = async () => {
|
||||
const { focus } = state;
|
||||
if (state.history.length === 0) {
|
||||
state.snapshot();
|
||||
}
|
||||
if (state.historyDebounce > 0) {
|
||||
state.historyDebounce -= 1;
|
||||
if (state.historyDebounce <= 0) {
|
||||
state.snapshot();
|
||||
}
|
||||
}
|
||||
if (state.doubleClickTimer > 0) {
|
||||
state.doubleClickTimer -= 1;
|
||||
}
|
||||
|
||||
if (mouseDown() && !shiftKeyDown()) {
|
||||
if (state.doubleClickTimer > 0) {
|
||||
state.wordMode = true;
|
||||
} else {
|
||||
state.doubleClickTimer = 10;
|
||||
}
|
||||
const {x, y} = mousePos();
|
||||
state.setSelection(pixelToIndex(state.code, x+state.scrollX, y+state.scrollY-8));
|
||||
state.scrollToCursor();
|
||||
} else if (mouseHeld()) {
|
||||
const {x, y} = mousePos();
|
||||
state.setFocus(pixelToIndex(state.code, x+state.scrollX, y+state.scrollY-8));
|
||||
state.scrollToCursor();
|
||||
} else {
|
||||
state.wordMode = false;
|
||||
}
|
||||
|
||||
const keyboardString = getKeyboardString();
|
||||
if (keyboardString) {
|
||||
state.insertText(keyboardString);
|
||||
state.scrollToCursor();
|
||||
}
|
||||
|
||||
if (keyPressed(K.ENTER)) {
|
||||
state.insertText("\n"+state.currentIndentation());
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.TAB)) {
|
||||
if (!shiftKeyDown()) {
|
||||
if (state.isCollapsed()) {
|
||||
state.insertText("\t");
|
||||
} else {
|
||||
state.indent("\t");
|
||||
}
|
||||
} else {
|
||||
state.outdent(/^(\t| )/);
|
||||
}
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.BACKSPACE)) {
|
||||
state.backspace();
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.DELETE)) {
|
||||
state.delete();
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.ARROW_RIGHT)) {
|
||||
if (shiftKeyDown()) {
|
||||
state.setFocus(focus+1);
|
||||
} else {
|
||||
state.setSelection(focus+1);
|
||||
}
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.ARROW_LEFT)) {
|
||||
if (shiftKeyDown()) {
|
||||
state.setFocus(focus-1);
|
||||
} else {
|
||||
state.setSelection(focus-1);
|
||||
}
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.ARROW_DOWN)) {
|
||||
const rect = indexToRect(state.code, focus);
|
||||
const newIndex = pixelToIndex(state.code, rect.x, rect.y+rect.h+1+1);
|
||||
if (shiftKeyDown()) {
|
||||
state.setFocus(newIndex);
|
||||
} else {
|
||||
state.setSelection(newIndex);
|
||||
}
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed(K.ARROW_UP)) {
|
||||
const rect = indexToRect(state.code, focus);
|
||||
const newIndex = pixelToIndex(state.code, rect.x, rect.y-1-1);
|
||||
if (shiftKeyDown()) {
|
||||
state.setFocus(newIndex);
|
||||
} else {
|
||||
state.setSelection(newIndex);
|
||||
}
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed("C") && ctrlKeyDown()) {
|
||||
await state.copy();
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed("X") && ctrlKeyDown()) {
|
||||
await state.cut();
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed("V") && ctrlKeyDown()) {
|
||||
await state.paste();
|
||||
state.scrollToCursor();
|
||||
}
|
||||
if (keyPressed("Z") && ctrlKeyDown()) {
|
||||
if (shiftKeyDown()) {
|
||||
state.redo();
|
||||
} else {
|
||||
state.undo();
|
||||
}
|
||||
}
|
||||
if (keyPressed("Y") && ctrlKeyDown()) {
|
||||
state.redo();
|
||||
}
|
||||
if (keyPressed("/") && ctrlKeyDown()) {
|
||||
state.toggleComment();
|
||||
}
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
clearScreen();
|
||||
const {
|
||||
scrollX,
|
||||
scrollY,
|
||||
anchor,
|
||||
focus,
|
||||
code,
|
||||
} = state;
|
||||
const x = 0;
|
||||
const y = 8;
|
||||
const w = 128;
|
||||
const h = 112;
|
||||
fillRect(x, y, w, h, backgroundColor);
|
||||
if (anchor !== focus) {
|
||||
for (let i = Math.min(anchor, focus); i < Math.max(anchor, focus); i++) {
|
||||
const sel = indexToRect(code, i);
|
||||
fillRect(x+sel.x-scrollX, y+sel.y-scrollY, sel.w+2, sel.h, selectionColor);
|
||||
}
|
||||
}
|
||||
const rect = indexToRect(code, focus);
|
||||
fillRect(x+rect.x-scrollX, y+rect.y-scrollY, 1, rect.h, caretColor);
|
||||
|
||||
const builtins = Object.keys(getBuiltins());
|
||||
const tokens = [...tokenize(code)];
|
||||
let cx = 0;
|
||||
let cy = 0;
|
||||
tokens.forEach((token) => {
|
||||
if (token.type === "LineTerminatorSequence") {
|
||||
cx=0;
|
||||
cy+=fontHeight+1;
|
||||
return;
|
||||
}
|
||||
const lines = token.value.split("\n");
|
||||
lines.forEach((line, i) => {
|
||||
let color = tokenColors[token.type];
|
||||
if (builtins.includes(token.value)) {
|
||||
color = builtinColor;
|
||||
}
|
||||
if (keywords.includes(token.value)) {
|
||||
color = keywordColor;
|
||||
}
|
||||
if (values.includes(token.value)) {
|
||||
color = valueColor;
|
||||
}
|
||||
if (operator.includes(token.value)) {
|
||||
color = operatorColor;
|
||||
}
|
||||
if (punctuation.includes(token.value)) {
|
||||
color = punctuationColor;
|
||||
}
|
||||
drawText(1+x+cx-scrollX, 1+y+cy-scrollY, line, color);
|
||||
if (i === lines.length-1) {
|
||||
cx += measureText(line)+1;
|
||||
} else {
|
||||
cx=0;
|
||||
cy+=fontHeight+1;
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export const codetab = {
|
||||
update,
|
||||
draw,
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { codetab } from "./codetab.ts";
|
||||
import { spritetab } from "./spritetab.ts";
|
||||
import { viewsheets, page } from "./viewsheets.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { mouseClick, mousePos } from "../io/mouse.ts";
|
||||
import { drawIcon } from "../runtime/builtins.ts";
|
||||
import { inRect } from "../util/util.ts";
|
||||
import { sheetsIcon, trashIcon } from "../data/icons.ts";
|
||||
import { SheetType, setSheet } from "../io/sheet.ts";
|
||||
import { nonetab } from "./nonetab.ts";
|
||||
import { maptab } from "./maptab.ts";
|
||||
|
||||
type TabName = SheetType; // "code" | "sprite" | "map" | "sfx" | "music" | "sheet";
|
||||
|
||||
const buttons: Array<{update: () => void, draw: () => void}> = [];
|
||||
const makeTabButton = (tabname: TabName | "sheet", x: number, y: number, icon: Array<number>) => {
|
||||
buttons.push({
|
||||
update() {
|
||||
if (mouseClick()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
if (inRect(mouseX, mouseY, x, y, 8, 8)) {
|
||||
page.tab = tabname;
|
||||
}
|
||||
}
|
||||
},
|
||||
draw() {
|
||||
drawIcon(x, y, icon, page.tab === tabname ? COLOR.YELLOW : COLOR.WHITE);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const makeTrashButton = (x: number, y: number, icon: Array<number>) => {
|
||||
buttons.push({
|
||||
update() {
|
||||
if (page.tab !== "sheet") {
|
||||
return
|
||||
}
|
||||
if (mouseClick()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
if (inRect(mouseX, mouseY, x, y, 8, 8)) {
|
||||
setSheet(page.activeSheet, "none", null);
|
||||
page.tab = "sheet";
|
||||
}
|
||||
}
|
||||
},
|
||||
draw() {
|
||||
if (page.tab !== "sheet") {
|
||||
return
|
||||
}
|
||||
drawIcon(x, y, icon, COLOR.BLACK);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
makeTabButton("sheet", 120, 0, sheetsIcon);
|
||||
makeTrashButton(0, 0, trashIcon);
|
||||
|
||||
const update = () => {
|
||||
buttons.forEach(button => button.update());
|
||||
if (page.tab === "code") {
|
||||
codetab.update();
|
||||
} else if (page.tab === "spritesheet") {
|
||||
spritetab.update();
|
||||
} else if (page.tab === "map") {
|
||||
maptab.update();
|
||||
} else if (page.tab === "sheet") {
|
||||
viewsheets.update();
|
||||
} else if (page.tab === "none") {
|
||||
nonetab.update();
|
||||
}
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
clearScreen();
|
||||
if (page.tab === "code") {
|
||||
codetab.draw();
|
||||
} else if (page.tab === "spritesheet") {
|
||||
spritetab.draw();
|
||||
} else if (page.tab === "map") {
|
||||
maptab.draw();
|
||||
} else if (page.tab === "sheet") {
|
||||
viewsheets.draw();
|
||||
} else if (page.tab === "none") {
|
||||
nonetab.draw();
|
||||
}
|
||||
fillRect(0, 0, 128, 8, COLOR.RED);
|
||||
fillRect(0, 120, 128, 8, COLOR.RED);
|
||||
buttons.forEach(button => button.draw());
|
||||
}
|
||||
|
||||
export const editmode = {
|
||||
update,
|
||||
draw,
|
||||
}
|
213
editor/maptab.ts
213
editor/maptab.ts
@ -1,213 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { drawSprite, drawText, useSpritesheet } from "../runtime/builtins.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getMapSheet, getSheet, setSheet } from "../io/sheet.ts";
|
||||
import { M, mouseClick, mouseDown, mouseHeld, mousePos } from "../io/mouse.ts";
|
||||
import { drawTransparentRect, drawVoidRect, inRect, reGrid } from "../util/util.ts";
|
||||
import { page } from "./viewsheets.ts";
|
||||
import { keyPressed, K } from "../io/keyboard.ts";
|
||||
|
||||
const state = {
|
||||
selectedSpriteSheet: 0,
|
||||
selectedSprite: 0,
|
||||
viewX: 0,
|
||||
viewY: 0,
|
||||
dragging: false,
|
||||
dragFromViewX: 0,
|
||||
dragFromViewY: 0,
|
||||
dragFromX: 0,
|
||||
dragFromY: 0,
|
||||
get spriteSheetPage() {
|
||||
return Math.floor(this.selectedSprite/64);
|
||||
},
|
||||
set spriteSheetPage(val) {
|
||||
this.selectedSprite = 64*val+this.spriteWithinPage;
|
||||
},
|
||||
get spriteWithinPage() {
|
||||
return this.selectedSprite%64;
|
||||
},
|
||||
set spriteWithinPage(val) {
|
||||
this.selectedSprite = 64*this.spriteSheetPage+val;
|
||||
},
|
||||
get map() {
|
||||
return getMapSheet(page.activeSheet);
|
||||
},
|
||||
set map(val) {
|
||||
setSheet(page.activeSheet, "map", val);
|
||||
},
|
||||
setInPatch(i: number, sprsheet: number, sprite: number) {
|
||||
const cellVal = this.map.subgrid(this.viewX, this.viewY, patchW, patchH).values[i];
|
||||
if (cellVal) {
|
||||
cellVal[0] = sprsheet
|
||||
cellVal[1] = sprite;
|
||||
}
|
||||
},
|
||||
get patch() {
|
||||
return this.map.subgrid(this.viewX, this.viewY, patchW, patchH);
|
||||
}
|
||||
}
|
||||
|
||||
const patchX = 0;
|
||||
const patchY = 8;
|
||||
const patchW = 16;
|
||||
const patchH = 9;
|
||||
|
||||
const spriteW = 8;
|
||||
const spriteH = 8;
|
||||
|
||||
const spriteSheetX = 0;
|
||||
const spriteSheetY = 88;
|
||||
const spriteSheetW = 16;
|
||||
const spriteSheetH = 4;
|
||||
|
||||
const spriteSheetPickerX = 0;
|
||||
const spriteSheetPickerY = 81;
|
||||
const spriteSheetPickerW = 16;
|
||||
const spriteSheetPickerH = 1;
|
||||
const spriteSheetPickerTabW = 7;
|
||||
const spriteSheetPickerTabH = 7;
|
||||
|
||||
const spriteSheetPageSwapX = 121;
|
||||
const spriteSheetPageSwapY = 81;
|
||||
const spriteSheetPageSwapW = 7;
|
||||
const spriteSheetPageSwapH = 7;
|
||||
|
||||
const update = () => {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
const inPatch = inRect(mouseX, mouseY, patchX, patchY, patchW*spriteW, patchH*spriteH - 2);
|
||||
const inSpriteSheetPicker = inRect(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerW*spriteSheetPickerTabW, spriteSheetPickerH*spriteSheetPickerTabH);
|
||||
const inSpriteSheet = inRect(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteSheetW*spriteW, spriteSheetH*spriteH);
|
||||
const inSpriteSheetPageSwap = inRect(mouseX, mouseY, spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH);
|
||||
if (mouseHeld()) {
|
||||
if (inPatch) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
||||
const cellNumber = patchW*y+x;
|
||||
state.setInPatch(cellNumber, state.selectedSpriteSheet, state.selectedSprite);
|
||||
}
|
||||
if (inSpriteSheetPicker) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW, spriteSheetPickerTabH);
|
||||
state.selectedSpriteSheet = spriteSheetPickerW*y+x;
|
||||
}
|
||||
if (inSpriteSheet) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteW, spriteH);
|
||||
state.spriteWithinPage = spriteSheetW*y+x;
|
||||
}
|
||||
} else if (mouseDown(M.MIDDLE)) {
|
||||
if (inPatch) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
||||
state.dragging = true;
|
||||
state.dragFromX = x;
|
||||
state.dragFromY = y;
|
||||
state.dragFromViewX = state.viewX;
|
||||
state.dragFromViewY = state.viewY;
|
||||
}
|
||||
} else if (mouseHeld(M.MIDDLE)) {
|
||||
if (state.dragging) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
||||
state.viewX = state.dragFromViewX - x + state.dragFromX;
|
||||
state.viewY = state.dragFromViewY - y + state.dragFromY;
|
||||
}
|
||||
} else if (mouseClick(M.MIDDLE)) {
|
||||
state.dragging = false;
|
||||
} else if (mouseClick()) {
|
||||
if (inSpriteSheetPageSwap) {
|
||||
state.spriteSheetPage = (1+state.spriteSheetPage)%2;
|
||||
}
|
||||
}
|
||||
if (keyPressed(K.ARROW_RIGHT)) {
|
||||
state.viewX += 1;
|
||||
}
|
||||
if (keyPressed(K.ARROW_LEFT)) {
|
||||
state.viewX -= 1;
|
||||
}
|
||||
if (keyPressed(K.ARROW_UP)) {
|
||||
state.viewY -= 1;
|
||||
}
|
||||
if (keyPressed(K.ARROW_DOWN)) {
|
||||
state.viewY += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const outlineRect = (x: number, y: number, w: number, h: number, color: number) => {
|
||||
fillRect(x, y, w, 1, color);
|
||||
fillRect(x, y, 1, h, color);
|
||||
fillRect(x+w-1, y, 1, h, color);
|
||||
fillRect(x, y+h-1, w, 1, color);
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
const {
|
||||
selectedSpriteSheet,
|
||||
spriteWithinPage,
|
||||
spriteSheetPage,
|
||||
} = state;
|
||||
clearScreen();
|
||||
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
||||
|
||||
// Draw the current patch
|
||||
drawVoidRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2);
|
||||
state.patch.values.forEach((val, i) => {
|
||||
const spriteX = patchX+spriteW*(i%patchW);
|
||||
const spriteY = patchY+spriteH*Math.floor(i/patchW);
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
const [sprsheet, sprite] = val;
|
||||
drawTransparentRect(spriteX, spriteY, 8, 8);
|
||||
if (getSheet(sprsheet).sheet_type === "spritesheet") {
|
||||
useSpritesheet(sprsheet);
|
||||
drawSprite(spriteX, spriteY, sprite);
|
||||
}
|
||||
});
|
||||
|
||||
// Draw the bar
|
||||
fillRect(spriteSheetPickerX, spriteSheetPickerY-1, 128, 1, COLOR.BLACK);
|
||||
fillRect(spriteSheetPickerX, spriteSheetPickerY, 128, 7, COLOR.DARKGRAY);
|
||||
|
||||
// Draw the spritesheet picker
|
||||
fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK);
|
||||
Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => {
|
||||
const tabX = spriteSheetPickerX+spriteSheetPickerTabW*(i%spriteSheetPickerW);
|
||||
const tabY = spriteSheetPickerY+spriteSheetPickerTabH*Math.floor(i/spriteSheetPickerW);
|
||||
let color = COLOR.DARKGREEN;
|
||||
if (getSheet(i).sheet_type !== "spritesheet") {
|
||||
color = COLOR.BROWN;
|
||||
}
|
||||
if (i === page.activeSheet) {
|
||||
color = COLOR.PURPLE;
|
||||
}
|
||||
if (i === selectedSpriteSheet) {
|
||||
color = {
|
||||
[COLOR.BROWN]: COLOR.TAN,
|
||||
[COLOR.DARKGREEN]: COLOR.GREEN,
|
||||
[COLOR.PURPLE]: COLOR.PINK,
|
||||
}[color];
|
||||
}
|
||||
fillRect(tabX, tabY, spriteSheetPickerTabW, spriteSheetPickerTabH, color);
|
||||
drawText(tabX+2, tabY+1, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"][i]);
|
||||
});
|
||||
|
||||
// Draw the spritesheet page swap button
|
||||
fillRect(spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH, COLOR.BLUE);
|
||||
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
||||
|
||||
// Draw the spritesheet
|
||||
fillRect(spriteSheetX, spriteSheetY, (spriteSheetW*spriteW), (spriteSheetH*spriteH), COLOR.BLACK);
|
||||
if (getSheet(selectedSpriteSheet).sheet_type === "spritesheet") {
|
||||
useSpritesheet(selectedSpriteSheet);
|
||||
Array(64).fill(0).forEach((_, i) => {
|
||||
const sprI = i+64*spriteSheetPage;
|
||||
const sprX = spriteSheetX+spriteW*(i%spriteSheetW);
|
||||
const sprY = spriteSheetY+spriteH*Math.floor(i/spriteSheetW);
|
||||
drawSprite(sprX, sprY, sprI);
|
||||
if (i === spriteWithinPage) {
|
||||
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const maptab = {
|
||||
update,
|
||||
draw,
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { drawIcon, drawText, useSpritesheet } from "../runtime/builtins.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getSheet, setSheet } from "../io/sheet.ts";
|
||||
import { mouseClick, mousePos } from "../io/mouse.ts";
|
||||
import { reGridWithGap } from "../util/util.ts";
|
||||
import { page } from "./viewsheets.ts";
|
||||
import { codeIcon, mapIcon, spriteIcon } from "../data/icons.ts";
|
||||
|
||||
const gridX = 8;
|
||||
const gridY = 40;
|
||||
const cellW = 8;
|
||||
const cellH = 8;
|
||||
const gapX = 8;
|
||||
const gapY = 8;
|
||||
|
||||
const sheetTypes = ["code", "spritesheet", "map"] as const;
|
||||
const defaultSheetVal = {
|
||||
code: () => "",
|
||||
spritesheet: () => Array(128).fill(0).map(() => Array(64).fill(0)),
|
||||
map: () => Array(64*64).fill(0).map(() => [0, 0]),
|
||||
none: () =>null,
|
||||
}
|
||||
|
||||
const update = () => {
|
||||
if (mouseClick()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
const g = reGridWithGap(mouseX, mouseY, gridX, gridY, cellW, cellH, gapX, gapY);
|
||||
if (g) {
|
||||
const {x, y: _y} = g;
|
||||
const sheetType = sheetTypes[x];
|
||||
setSheet(page.activeSheet, sheetType, defaultSheetVal[sheetType]());
|
||||
page.tab = getSheet(page.activeSheet).sheet_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
const draw = () => {
|
||||
clearScreen();
|
||||
useSpritesheet(page.activeSheet);
|
||||
fillRect(0, 8, 128, 112, COLOR.BLACK);
|
||||
|
||||
drawText(4, 16, "Click an icon below to choose");
|
||||
drawText(4, 16+7, "this sheet's type...");
|
||||
|
||||
// Draw the spritesheet
|
||||
sheetTypes.forEach((sheetType, i) => {
|
||||
const sx = gridX+(cellW+gapX)*(i%6);
|
||||
const sy = gridY+(cellH+gapY)*Math.floor(i/6);
|
||||
const icon = {
|
||||
code: codeIcon,
|
||||
spritesheet: spriteIcon,
|
||||
map: mapIcon,
|
||||
none: null,
|
||||
}[sheetType];
|
||||
drawIcon(sx, sy, icon, COLOR.BLUE);
|
||||
});
|
||||
}
|
||||
|
||||
export const nonetab = {
|
||||
update,
|
||||
draw,
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { drawSprite, drawText, useSpritesheet } from "../runtime/builtins.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getSpriteSheet, setSheet } from "../io/sheet.ts";
|
||||
import { mouseClick, mouseHeld, mousePos } from "../io/mouse.ts";
|
||||
import { drawTransparentRect, inRect, outlineRect, reGrid } from "../util/util.ts";
|
||||
import { page } from "./viewsheets.ts";
|
||||
|
||||
const state = {
|
||||
selectedSprite: 0,
|
||||
selectedColor: 0,
|
||||
get spriteSheetPage() {
|
||||
return Math.floor(this.selectedSprite/64);
|
||||
},
|
||||
set spriteSheetPage(val) {
|
||||
this.selectedSprite = 64*val+this.spriteWithinPage;
|
||||
},
|
||||
get spriteWithinPage() {
|
||||
return this.selectedSprite%64;
|
||||
},
|
||||
set spriteWithinPage(val) {
|
||||
this.selectedSprite = 64*this.spriteSheetPage+val;
|
||||
},
|
||||
get sprites() {
|
||||
return getSpriteSheet(page.activeSheet);
|
||||
},
|
||||
set sprites(val) {
|
||||
setSheet(page.activeSheet, "spritesheet", val);
|
||||
}
|
||||
}
|
||||
|
||||
const paletteX = 88;
|
||||
const paletteY = 16;
|
||||
const swatchW = 8;
|
||||
const swatchH = 8;
|
||||
const paletteW = 4;
|
||||
const paletteH = 6;
|
||||
|
||||
const spriteX = 8;
|
||||
const spriteY = 16;
|
||||
const pixelW = 8;
|
||||
const pixelH = 8;
|
||||
|
||||
const spriteW = 8;
|
||||
const spriteH = 8;
|
||||
|
||||
const sheetX = 0;
|
||||
const sheetY = 88;
|
||||
const sheetW = 16;
|
||||
const sheetH = 4;
|
||||
|
||||
const spriteSheetPageSwapX = 121;
|
||||
const spriteSheetPageSwapY = 80;
|
||||
const spriteSheetPageSwapW = 7;
|
||||
const spriteSheetPageSwapH = 7;
|
||||
|
||||
const update = () => {
|
||||
if (mouseHeld()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
const inPalette = inRect(mouseX, mouseY, paletteX, paletteY, paletteW*swatchW, paletteH*swatchH);
|
||||
const inSprite = inRect(mouseX, mouseY, spriteX, spriteY, spriteW*pixelW, spriteH*pixelH);
|
||||
const inSheet = inRect(mouseX, mouseY, sheetX, sheetY, sheetW*spriteW, sheetH*spriteH);
|
||||
if (inPalette) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, paletteX, paletteY, swatchW, swatchH);
|
||||
state.selectedColor = paletteW*y+x;
|
||||
}
|
||||
if (inSprite) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, spriteX, spriteY, pixelW, pixelH);
|
||||
const pixelNumber = spriteW*y+x;
|
||||
state.sprites[state.selectedSprite][pixelNumber] = state.selectedColor;
|
||||
}
|
||||
if (inSheet) {
|
||||
const {x, y} = reGrid(mouseX, mouseY, sheetX, sheetY, spriteW, spriteH);
|
||||
state.spriteWithinPage = sheetW*y+x;
|
||||
}
|
||||
} else if (mouseClick()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
const inSpriteSheetPageSwap = inRect(mouseX, mouseY, spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH);
|
||||
if (inSpriteSheetPageSwap) {
|
||||
state.spriteSheetPage = (1+state.spriteSheetPage)%2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
const {sprites, selectedSprite, selectedColor} = state;
|
||||
clearScreen();
|
||||
useSpritesheet(page.activeSheet);
|
||||
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
||||
|
||||
// Draw the palette
|
||||
fillRect(paletteX-1, paletteY-1, (paletteW*swatchW)+2, (paletteH*swatchH)+2, COLOR.BLACK);
|
||||
Object.keys(COLOR).forEach((name, i) => {
|
||||
const swatchX = paletteX+swatchW*(i%paletteW);
|
||||
const swatchY = paletteY+swatchH*Math.floor(i/paletteW);
|
||||
fillRect(swatchX, swatchY, swatchW, swatchH, COLOR[name as keyof typeof COLOR]);
|
||||
if (name == "TRANSPARENT") {
|
||||
// transparent
|
||||
drawTransparentRect(swatchX, swatchY, swatchW, swatchH);
|
||||
}
|
||||
if (i === selectedColor) {
|
||||
outlineRect(swatchX, swatchY, swatchW, swatchH, name === "WHITE" ? COLOR.BLACK : COLOR.WHITE);
|
||||
}
|
||||
});
|
||||
|
||||
// Draw the current sprite
|
||||
fillRect(spriteX-1, spriteY-1, (spriteW*pixelW)+2, (spriteH*pixelH)+2, COLOR.BLACK);
|
||||
drawTransparentRect(spriteX, spriteY, (spriteW*pixelW), (spriteH*pixelH));
|
||||
sprites[selectedSprite].forEach((pix, i) => {
|
||||
fillRect(spriteX+pixelW*(i%spriteW), spriteY+pixelH*Math.floor(i/spriteW), pixelW, pixelH, pix);
|
||||
});
|
||||
|
||||
// Draw the spritesheet page swap button
|
||||
fillRect(spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH, COLOR.BLUE);
|
||||
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
||||
|
||||
// Draw the spritesheet
|
||||
fillRect(sheetX, sheetY-1, (sheetW*spriteW), (sheetH*spriteH)+1, COLOR.BLACK);
|
||||
Array(64).fill(0).forEach((_, i) => {
|
||||
const sprI = i+64*state.spriteSheetPage;
|
||||
const sprX = sheetX+spriteW*(i%sheetW);
|
||||
const sprY = sheetY+spriteH*Math.floor(i/sheetW);
|
||||
drawSprite(sprX, sprY, sprI);
|
||||
if (i === state.spriteWithinPage) {
|
||||
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const spritetab = {
|
||||
update,
|
||||
draw,
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { drawIcon, drawText } from "../runtime/builtins.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getSheet } from "../io/sheet.ts";
|
||||
import { mouseClick, mousePos } from "../io/mouse.ts";
|
||||
import { getCart } from "../io/cart.ts";
|
||||
import { font } from "../data/font.ts";
|
||||
import { codeIcon, spriteIcon, mapIcon } from "../data/icons.ts";
|
||||
import { reGridWithGap } from "../util/util.ts";
|
||||
|
||||
const fontHeight = font.height;
|
||||
|
||||
export const page = {activeSheet: 0, tab: "sheet"};
|
||||
|
||||
const gridX = 8;
|
||||
const gridY = 20;
|
||||
const cellW = 22;
|
||||
const cellH = 16;
|
||||
const gapX = 8;
|
||||
const gapY = 8;
|
||||
|
||||
const update = () => {
|
||||
if (mouseClick()) {
|
||||
const {x: mouseX, y: mouseY} = mousePos();
|
||||
const g = reGridWithGap(mouseX, mouseY, gridX, gridY, cellW, cellH, gapX, gapY);
|
||||
if (g) {
|
||||
const {x, y} = g;
|
||||
page.activeSheet = 4*y+x;
|
||||
const sheet = getSheet(page.activeSheet);
|
||||
if (!sheet) {
|
||||
console.log(x, y, g);
|
||||
}
|
||||
page.tab = getSheet(page.activeSheet).sheet_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
clearScreen();
|
||||
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
||||
|
||||
// Draw the sheet grid
|
||||
getCart().forEach((sheet, i) => {
|
||||
const x = gridX+(cellW+gapX)*(i%4);
|
||||
const y = gridY+(cellH+gapY)*Math.floor(i/4);
|
||||
fillRect(x, y, cellW, cellH, i===page.activeSheet ? COLOR.PURPLE : COLOR.BLACK);
|
||||
drawText(x+(cellW)/2, y+(cellH-fontHeight)/2, i.toString().padStart(2,"0"));
|
||||
const icon = {
|
||||
code: codeIcon,
|
||||
spritesheet: spriteIcon,
|
||||
map: mapIcon,
|
||||
none: null,
|
||||
}[sheet.sheet_type];
|
||||
if (icon) {
|
||||
drawIcon(x+2, y+4, icon, COLOR.WHITE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const viewsheets = {
|
||||
update,
|
||||
draw,
|
||||
}
|
133
femto-lang/faux/faux.ts
Normal file
133
femto-lang/faux/faux.ts
Normal file
@ -0,0 +1,133 @@
|
||||
// const STR = (s: string): StringValue => ({type: "string", value: s});
|
||||
// const FN = (f: FunctionValue["value"]): FunctionValue => ({type: "function", value: f});
|
||||
// const SYM = (s: string): SymbolValue => ({type: "symbol", value: s});
|
||||
// const UNDEF = (): UndefinedValue => ({type: "undefined", value: null});
|
||||
// const CODE = (p: CodeBlockValue["value"]): CodeBlockValue => ({type: "code", value: p});
|
||||
// const THUNK = (t: ThunkValue["value"]): ThunkValue => ({type: "thunk", value: t});
|
||||
// const BOOL = (b: boolean): BooleanValue => ({type: "boolean", value: b});
|
||||
|
||||
// console.log("HELLO");
|
||||
|
||||
// type SymbolValue = {
|
||||
// type: "symbol",
|
||||
// value: string,
|
||||
// }
|
||||
|
||||
// type FunctionValue = {
|
||||
// type: "function",
|
||||
// value: (arg: Value, env: Environment, passalong: Passalong) => Result,
|
||||
// }
|
||||
|
||||
// type StringValue = {
|
||||
// type: "string",
|
||||
// value: string,
|
||||
// }
|
||||
|
||||
// type BooleanValue = {
|
||||
// type: "boolean",
|
||||
// value: boolean,
|
||||
// }
|
||||
|
||||
// type UndefinedValue = {
|
||||
// type: "undefined",
|
||||
// value: null,
|
||||
// }
|
||||
|
||||
// type CodeBlockValue = {
|
||||
// type: "code",
|
||||
// value: Array<Value>,
|
||||
// }
|
||||
|
||||
// type ThunkValue = {
|
||||
// type: "thunk",
|
||||
// value: Array<Value>,
|
||||
// }
|
||||
|
||||
// type Value =
|
||||
// | SymbolValue
|
||||
// | FunctionValue
|
||||
// | StringValue
|
||||
// | UndefinedValue
|
||||
// | CodeBlockValue
|
||||
// | ThunkValue
|
||||
// | BooleanValue
|
||||
|
||||
// type Passalong = Value;
|
||||
|
||||
// type Result<V extends Value = Value> = {
|
||||
// result: V,
|
||||
// passalong: any,
|
||||
// }
|
||||
|
||||
// type Environment = {[key: string]: Value}
|
||||
|
||||
// const evaluate_codeblock = (codeBlock: CodeBlockValue, env: Environment): Result => {
|
||||
// let result: Result = {
|
||||
// result: UNDEF(),
|
||||
// passalong: UNDEF(),
|
||||
// };
|
||||
// const terms = [...codeBlock.value];
|
||||
// while (terms.length) {
|
||||
// console.log('evaluating phrase', terms);
|
||||
// result = evaluate_phrase(terms, env, result.passalong);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// const evaluate_phrase = (terms: Array<Value>, env: Environment, passalong: Passalong): Result => {
|
||||
// let head: Result = evaluate_term(terms.shift() as Value, env, passalong);
|
||||
// let pa = passalong;
|
||||
// while (head.result.type === "function") {
|
||||
// if (!terms.length) {
|
||||
// throw 'Runtime Error: head function has no argument to be called with';
|
||||
// }
|
||||
// const tail: Result = evaluate_term(terms.shift() as Value, env, UNDEF());
|
||||
// head = head.result.value(tail.result, env, pa);
|
||||
// pa = head.passalong;
|
||||
// }
|
||||
// return head;
|
||||
// }
|
||||
|
||||
// const evaluate_term = (term: Value, env: Environment, passalong: Passalong): Result => {
|
||||
// if (term.type === "symbol") {
|
||||
// return {
|
||||
// result: env[term.value],
|
||||
// passalong: UNDEF(), // TODO: this should include term.value as a "name"
|
||||
// }
|
||||
// } else if (term.type === "string") {
|
||||
// return {
|
||||
// result: term,
|
||||
// passalong: UNDEF(),
|
||||
// }
|
||||
// } else if (term.type === "function") {
|
||||
// return {
|
||||
// result: term,
|
||||
// passalong: UNDEF(),
|
||||
// }
|
||||
// } else if (term.type === "boolean") {
|
||||
// return {
|
||||
// result: term,
|
||||
// passalong: UNDEF(),
|
||||
// }
|
||||
// }
|
||||
// return {
|
||||
// result: UNDEF(),
|
||||
// passalong: UNDEF(),
|
||||
// }
|
||||
// }
|
||||
|
||||
// const my_env: Environment = {
|
||||
// print: FN((arg, env, passalong) => {
|
||||
// console.log(arg);
|
||||
// return {
|
||||
// result: UNDEF(),
|
||||
// passalong: UNDEF(),
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// const my_prog: CodeBlockValue = CODE([
|
||||
// SYM("print"), STR("hi"),
|
||||
// ]);
|
||||
|
||||
// console.log(evaluate_codeblock(my_prog, my_env));
|
141
femto-lang/faux/trying.js
Normal file
141
femto-lang/faux/trying.js
Normal file
@ -0,0 +1,141 @@
|
||||
const STR = (s) => ({type: "string", value: s});
|
||||
const FN = (f) => ({type: "function", value: f});
|
||||
const SYM = (s) => ({type: "symbol", value: s});
|
||||
const UNDEF = () => ({type: "undefined", value: null});
|
||||
const CODE = (p) => ({type: "code", value: p});
|
||||
const THUNK = (t) => ({type: "thunk", value: t});
|
||||
const BOOL = (b) => ({type: "boolean", value: b});
|
||||
|
||||
const evaluate_codeblock = (codeBlock, env) => {
|
||||
let result = {
|
||||
result: UNDEF(),
|
||||
passalong: {},
|
||||
};
|
||||
const terms = [...codeBlock.value];
|
||||
while (terms.length) {
|
||||
// console.log('evaluating phrase', terms);
|
||||
result = evaluate_phrase(terms, env, result.passalong);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const evaluate_phrase = (terms, env, passalong) => {
|
||||
let head = evaluate_term(terms.shift(), env, passalong);
|
||||
let pa = passalong;
|
||||
while (head.result.type === "function") {
|
||||
if (!terms.length) {
|
||||
throw 'Runtime Error: head function has no argument to be called with';
|
||||
}
|
||||
const tail = evaluate_term(terms.shift(), env, {});
|
||||
head = head.result.value(tail.result, env, pa);
|
||||
pa = head.passalong;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
const evaluate_term = (term, env, passalong) => {
|
||||
if (term.type === "symbol") {
|
||||
return {
|
||||
result: env[term.value],
|
||||
passalong: {name: STR(term.value)}, // TODO: this should include term.value as a "name"
|
||||
}
|
||||
} else if (term.type === "string") {
|
||||
return {
|
||||
result: term,
|
||||
passalong: {},
|
||||
}
|
||||
} else if (term.type === "function") {
|
||||
return {
|
||||
result: term,
|
||||
passalong: {},
|
||||
}
|
||||
} else if (term.type === "boolean") {
|
||||
return {
|
||||
result: term,
|
||||
passalong: {},
|
||||
}
|
||||
} else if (term.type === "thunk") {
|
||||
return {
|
||||
result: term,
|
||||
passalong: {},
|
||||
}
|
||||
}
|
||||
return {
|
||||
result: UNDEF(),
|
||||
passalong: {},
|
||||
}
|
||||
}
|
||||
|
||||
const my_env = {
|
||||
print: FN((arg, env, passalong) => {
|
||||
console.log('PRINT', arg);
|
||||
return {
|
||||
result: UNDEF(),
|
||||
passalong: {},
|
||||
}
|
||||
}),
|
||||
if: FN((arg, env, passalong) => {
|
||||
return {
|
||||
result: FN((thunk, e2, pa) => {
|
||||
if (arg.type === "boolean" && arg.value) {
|
||||
return {
|
||||
result: evaluate_codeblock(thunk, e2),
|
||||
passalong: {handled: true},
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
result: UNDEF(),
|
||||
passalong: {handled: false},
|
||||
}
|
||||
}
|
||||
}),
|
||||
passalong: {},
|
||||
}
|
||||
}),
|
||||
else: FN((thunk, env, passalong) => {
|
||||
if (!passalong.handled) {
|
||||
return {
|
||||
result: evaluate_codeblock(thunk, env),
|
||||
passalong: {handled: true},
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
result: UNDEF(),
|
||||
passalong: {handled: true},
|
||||
}
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
`
|
||||
print "hi"
|
||||
if false {
|
||||
print "hi2"
|
||||
} else {
|
||||
print "hi3"
|
||||
}
|
||||
set x = 10
|
||||
set y = 20
|
||||
set f = fn h => {
|
||||
print h
|
||||
print h
|
||||
}
|
||||
f x
|
||||
|
||||
for value in obj {
|
||||
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
const my_prog = CODE([
|
||||
SYM("print"), STR("hi"),
|
||||
SYM("if"), BOOL(false), THUNK([
|
||||
SYM("print"), STR("hi2"),
|
||||
]),
|
||||
SYM("else"), THUNK([
|
||||
SYM("print"), STR("hi3"),
|
||||
]),
|
||||
]);
|
||||
|
||||
console.log(evaluate_codeblock(my_prog, my_env));
|
150
femto-lang/lexer.ts
Normal file
150
femto-lang/lexer.ts
Normal file
@ -0,0 +1,150 @@
|
||||
|
||||
|
||||
// type Token = {
|
||||
// type: "paren",
|
||||
// value: 1 | -1,
|
||||
// } | {
|
||||
// type: "bracket",
|
||||
// value: 1 | -1,
|
||||
// } | {
|
||||
// type: "brace",
|
||||
// value: 1 | -1,
|
||||
// } | {
|
||||
// type: "number",
|
||||
// value: number,
|
||||
// } | {
|
||||
// type: "keyword",
|
||||
// value: (typeof KEYWORDS)[number],
|
||||
// } | {
|
||||
// type: "identifier",
|
||||
// value: string,
|
||||
// } | {
|
||||
// type: "string",
|
||||
// value: string,
|
||||
// } | {
|
||||
// type: "assignment-op",
|
||||
// value: "=",
|
||||
// }
|
||||
|
||||
|
||||
// const KEYWORDS = [
|
||||
// "let",
|
||||
// "if",
|
||||
// ] as const;
|
||||
|
||||
// const isKeyword = (str: string): str is (typeof KEYWORDS)[number] => {
|
||||
// return KEYWORDS.includes(str as any);
|
||||
// }
|
||||
|
||||
// const isMatchNestChar = (char: string): char is "(" | ")" | "[" | "]" | "{" | "}" => {
|
||||
// return char === "(" || char === ")" || char === "[" || char === "]" || char === "{" || char === "}";
|
||||
// }
|
||||
|
||||
// const matchNestType = {
|
||||
// "(": "paren",
|
||||
// ")": "paren",
|
||||
// "[": "bracket",
|
||||
// "]": "bracket",
|
||||
// "{": "brace",
|
||||
// "}": "brace",
|
||||
// } as const
|
||||
|
||||
// const matchNestValue = {
|
||||
// "(": 1,
|
||||
// ")": -1,
|
||||
// "[": 1,
|
||||
// "]": -1,
|
||||
// "{": 1,
|
||||
// "}": -1,
|
||||
// } as const
|
||||
|
||||
// const isSkippableChar = (char: string) => {
|
||||
// return [" ", "\n", "\t", ";"].includes(char);
|
||||
// }
|
||||
|
||||
// const isAlpha = (char: string) => {
|
||||
// return /^[a-z]$/.test(char);
|
||||
// }
|
||||
|
||||
// const isNumeric = (char: string) => {
|
||||
// return /^\d$/.test(char);
|
||||
// }
|
||||
|
||||
// const isAlphaNumeric = (char: string) => {
|
||||
// return isAlpha(char) || isNumeric(char);
|
||||
// }
|
||||
|
||||
// const tokenize = (source: string) => {
|
||||
// const tokens: Array<Token> = [];
|
||||
// let src = [...source];
|
||||
// while (src.length) {
|
||||
// const char = src[0];
|
||||
// if (isMatchNestChar(char)) {
|
||||
// const token = {type: matchNestType[char], value: matchNestValue[char]};
|
||||
// tokens.push(token);
|
||||
// src.shift();
|
||||
// } else if (char === "=") {
|
||||
// const token = {type: "assignment-op", value: "="} as const;
|
||||
// tokens.push(token);
|
||||
// src.shift();
|
||||
// } else {
|
||||
// if (isSkippableChar(char)) {
|
||||
// src.shift();
|
||||
// } else if (isNumeric(char)) {
|
||||
// let num = "";
|
||||
// while (src.length && isNumeric(src[0])) {
|
||||
// num += src.shift();
|
||||
// }
|
||||
// const token = {type: "number" as const, value: Number(num)};
|
||||
// tokens.push(token);
|
||||
// } else if (isAlpha(char)) {
|
||||
// let ident = "";
|
||||
// while (src.length && isAlphaNumeric(src[0])) {
|
||||
// ident += src.shift();
|
||||
// }
|
||||
// if (isKeyword(ident)) {
|
||||
// const token = {type: "keyword" as const, value: ident};
|
||||
// tokens.push(token);
|
||||
// } else {
|
||||
// const token = {type: "identifier" as const, value: ident};
|
||||
// tokens.push(token);
|
||||
// }
|
||||
// } else if (char === '"' || char === "'") {
|
||||
// console.log('lexing a string');
|
||||
// const q = char;
|
||||
// src.shift();
|
||||
// let s = "";
|
||||
// while (src.length && src[0] !== q) {
|
||||
// const c = src.shift();
|
||||
// console.log(`c: "${c}"`);
|
||||
// if (c === "\\") {
|
||||
// s += src.shift();
|
||||
// } else {
|
||||
// s += c;
|
||||
// }
|
||||
// }
|
||||
// if (src.length) {
|
||||
// src.shift();
|
||||
// }
|
||||
// const token = {type: "string" as const, value: s};
|
||||
// tokens.push(token);
|
||||
// } else {
|
||||
// throw `Unrecognized character: '${char}'`
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return tokens;
|
||||
// }
|
||||
|
||||
|
||||
// const code = `
|
||||
// let x = 45;
|
||||
// let y = ( 10 );
|
||||
// if (y) {
|
||||
// let z = (x = y);
|
||||
// }
|
||||
// let say = "Hello, \\"world\\"!";
|
||||
|
||||
// `
|
||||
|
||||
// console.log(tokenize(code));
|
107
femto-lang/oddlang.js
Normal file
107
femto-lang/oddlang.js
Normal file
@ -0,0 +1,107 @@
|
||||
// const STR = (s) => ({type: "string", value: s});
|
||||
// const FN = (f) => ({type: "function", value: f});
|
||||
// const NUL = () => ({type: "null", value: null});
|
||||
// const SYM = (s) => ({type: "symbol", value: s});
|
||||
// const UNDEF = () => ({type: "undefined", value: null});
|
||||
// const PROG = (p) => ({type: "program", value: p});
|
||||
// const THUNK = (t) => ({type: "thunk", value: t});
|
||||
// const BOOL = (b) => ({type: "boolean", value: b});
|
||||
|
||||
// const my_prog = [
|
||||
// SYM("print"), STR("hi"),
|
||||
// SYM("if"), BOOL(false), THUNK([
|
||||
// SYM("print"), STR("hi2"),
|
||||
// ]),
|
||||
// SYM("else"), THUNK([
|
||||
// SYM("print"), STR("hi3"),
|
||||
// ]),
|
||||
// ];
|
||||
|
||||
// const my_env = {
|
||||
// print: FN((arg) => {
|
||||
// console.log(arg.value);
|
||||
// return {result: UNDEF()};
|
||||
// }),
|
||||
// if: FN((arg) => {
|
||||
// if (arg.type === "boolean" && arg.value) {
|
||||
// return {
|
||||
// result: FN((thunk) => {
|
||||
// return {
|
||||
// result: eval_program(thunk.value, my_env).result,
|
||||
// handled: BOOL(true),
|
||||
// };
|
||||
// })
|
||||
// };
|
||||
// }
|
||||
// return {
|
||||
// result: UNDEF(),
|
||||
// handled: BOOL(false),
|
||||
// };
|
||||
// }),
|
||||
// else: FN((arg, passalong) => {
|
||||
// console.log('ELSE', arg, passalong);
|
||||
// if (passalong.handled === false) {
|
||||
// return {
|
||||
// result: eval_program(arg.value, my_env).result,
|
||||
// };
|
||||
// }
|
||||
// return {
|
||||
// result: UNDEF(),
|
||||
// };
|
||||
// }),
|
||||
// }
|
||||
|
||||
// const debugLog = (...args) => {
|
||||
// // console.log(args);
|
||||
// }
|
||||
|
||||
// const eval_program = (program, env) => {
|
||||
// debugLog('evaluating program');
|
||||
// let val = {result: UNDEF()};
|
||||
// while (program.length) {
|
||||
// val = eval_phrase(program, env, val);
|
||||
// }
|
||||
// debugLog('program evaluated to', val);
|
||||
// return val;
|
||||
// }
|
||||
|
||||
// const eval_phrase = (program, env, passalong) => {
|
||||
// debugLog('evaluating phrase');
|
||||
// const phraseStart = program.shift();
|
||||
// let head = eval_expression(phraseStart, env, passalong);
|
||||
// while (program.length && head.result.type === "function") {
|
||||
// debugLog('head', head);
|
||||
// const tail = eval_expression(program.shift(), env, head);
|
||||
// debugLog('tail', tail);
|
||||
// head = head.result.value(tail.result, passalong, tail);
|
||||
// }
|
||||
// debugLog('end of phrase, result:', head, 'start:', phraseStart);
|
||||
// return head;
|
||||
// }
|
||||
|
||||
// const eval_expression = (expr, env) => {
|
||||
// debugLog('evaluating expression', expr);
|
||||
// let result = {result: UNDEF()};
|
||||
// if (expr.type === "symbol") {
|
||||
// result = {
|
||||
// result: env[expr.value],
|
||||
// name: STR(expr.value),
|
||||
// }
|
||||
// } else if (expr.type === "string") {
|
||||
// result = {
|
||||
// result: expr,
|
||||
// }
|
||||
// } else if (expr.type === "boolean") {
|
||||
// result = {
|
||||
// result: expr,
|
||||
// }
|
||||
// } else if (expr.type === "thunk") {
|
||||
// result = {
|
||||
// result: expr,
|
||||
// }
|
||||
// }
|
||||
// debugLog('expression evaluated to', result);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// console.log(eval_program(my_prog, my_env));
|
233
ideas.md
Normal file
233
ideas.md
Normal file
@ -0,0 +1,233 @@
|
||||
A game is comprised of up to 16 "bags", each bag being exactly 8196 characters (8 kibibytes)
|
||||
The first bag is the "core" of the game, and is what executes on startup.
|
||||
It may include code from other bags.
|
||||
bags can contain arbitrary data, but the built-in system allows convenient usage of data in specific forms.
|
||||
The main uses of data are:
|
||||
1. code
|
||||
2. planar grid (sprites, maps, etc.)
|
||||
3. sounds
|
||||
|
||||
(5.5 colors * 1.5 saturations + 1 gray) * 3.5 brightnesses
|
||||
|
||||
red 2 3
|
||||
yellow/orange 2 4
|
||||
green 2 3
|
||||
blue 2 3
|
||||
purple 1 3
|
||||
gray 1 4
|
||||
|
||||
6 + 8 + 6 + 6 + 3 + 4 = 33
|
||||
|
||||
"data" can refer to a sprite or a sound
|
||||
|
||||
## In PICO
|
||||
|
||||
A sprite is:
|
||||
- an 8x8 grid of values each of which is: 4 bits,
|
||||
- and 8 1-bit flags
|
||||
that is: 64x4 = 32x8 = 32 bytes
|
||||
|
||||
A sound is:
|
||||
- an array of 32 notes each of which is: pitch(0-63), volume(0-7), instrument(0-15?), effect(0-7),
|
||||
- 5 flags: 0-1, 0-1, 0-2, 0-2, 0-2
|
||||
that is: 32x(6+3+4+3) = 32x16 = 64x8 = 64 bytes
|
||||
|
||||
## In FEMTO
|
||||
|
||||
A sprite is:
|
||||
- an 8x8 grid of values each of which is: color(0-31), 3 unused bits
|
||||
that is: 64x8 = 64 bytes
|
||||
|
||||
A sound is:
|
||||
- an array of 16 notes each of which is: pitch(0-63), volume(0-7), instrument(0-15?), effect(0-7),
|
||||
that is: 16(6+3+4+3) = 16x16 = 32x8 = 32 bytes
|
||||
|
||||
A "block" is 64 bytes = 0x40
|
||||
|
||||
A "sheet" is 64 blocks = 4096 bytes = 4KiB = 0x1000
|
||||
|
||||
A sound-sheet, a sprite-sheet, a code-sheet, a map-sheet
|
||||
|
||||
A full map is:
|
||||
- 128x128 with values from 0-255
|
||||
|
||||
A quarter-map is:
|
||||
- 64x64 grid of values each of which is 8 bits
|
||||
This is equivalent to a "sheet": the "blocks" are 8x8 regions
|
||||
|
||||
|
||||
What if we allow a "meta-sheet" which contains metadata for other blocks.
|
||||
Each block in a different sheet is associated with a single byte here.
|
||||
That means this has 64 sheets' worth of metadata.
|
||||
|
||||
A meta-sheet is:
|
||||
- each block is 64 bytes: one byte for each block of a different sheet. -- the hooking up happens separately
|
||||
|
||||
Your package can be comprised of up to 64 sheets (= 256KiB = 0.25MiB)
|
||||
|
||||
Each sheet can be accessed by an id 0-63. Each block in a sheet can be accessed by an id 0-63.
|
||||
|
||||
Sheet 0 is the entrypoint and is the code that starts running.
|
||||
|
||||
draw_sprite(sheet_id, block_id)
|
||||
play_sound(sheet_id, block_id)
|
||||
map_get(sheet_id, block_id, x, y)
|
||||
|
||||
|
||||
## The Language
|
||||
|
||||
Considering a functional language idea.
|
||||
|
||||
We have an IO "monad"?
|
||||
|
||||
type systems seem complicated... so we'll skip that for now.
|
||||
|
||||
functions are variables.
|
||||
|
||||
```
|
||||
// JSON5 + arrow functions
|
||||
|
||||
set {succ: (n) => {
|
||||
for (key: value in obj) {
|
||||
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
// do stuff
|
||||
}
|
||||
elseif (cond2) {
|
||||
// different stuff
|
||||
}
|
||||
else {
|
||||
// more stuff
|
||||
}
|
||||
return +(n, 1)
|
||||
}}
|
||||
|
||||
```
|
||||
|
||||
If a function is called with the
|
||||
|
||||
```
|
||||
funcname (arg1, arg2) {
|
||||
// block here
|
||||
}
|
||||
```
|
||||
|
||||
syntax, then contents of the block can be called by calling `thunk()`.
|
||||
|
||||
Each function can also prepare for a chain, by calling `passalong(value)`, and the very next function call can read it with `passalong()`.
|
||||
|
||||
```
|
||||
:x 40
|
||||
:x 50
|
||||
|
||||
obj = {
|
||||
abc: "def",
|
||||
ghi: "jkl"
|
||||
}
|
||||
|
||||
arr = [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
|
||||
succ = (n) => +(n, 1)
|
||||
|
||||
succ(n)
|
||||
|
||||
myif = (cond) => if(cond, thunk)
|
||||
|
||||
|
||||
map(obj, (key, value) =>
|
||||
if(eq(key, "abc"),
|
||||
"overridden",
|
||||
value
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
Maybe just use lua, js, or lisp after all.
|
||||
|
||||
Main downsides of lua: I don't love the function syntax and lack of curly braces.
|
||||
|
||||
Downsides of lisp: syntax is hard to get used to.
|
||||
|
||||
Maybe: js-like.
|
||||
|
||||
So:
|
||||
- arrow functions
|
||||
- JSON5 object syntax
|
||||
- if/else with js syntax
|
||||
- for with `for (key: value in obj)` OR `for (value in obj)` OR `for (key: in obj)`
|
||||
- break and continue
|
||||
- while with js syntax
|
||||
|
||||
No `this`.
|
||||
|
||||
```
|
||||
x = 5;
|
||||
while(condition, () => {
|
||||
// do stuff
|
||||
});
|
||||
if(equal(x, 5), () => {
|
||||
x = +(x, 1);
|
||||
});
|
||||
foreach(obj, (value, key) => {
|
||||
// do stuff
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
if cond {
|
||||
|
||||
}
|
||||
elseif cond2 {
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Eval strategy: eval current thing. If current thing is function, then eval next thing, and apply the func to that next thing. If current thing is function, eval next thing, and apply the func to that next thing. repeat. Do that if `return-and-call` was used, otherwise, if just `return` was used, move on to evaluate the next thing.
|
||||
|
||||
You can pass along certain things, e.g. "if" can say "i ran" or "i didn't run", and the "else" can pick that up and run with it.
|
||||
|
||||
You can also set a flag that says "I'm the end of this statement"
|
||||
|
||||
The pass-along can also be used to implement setting a variable, like `x = 5`, since the `x` can pass along its name, then the `=` can set it, and end after the `5`.
|
||||
|
||||
In general, anything infix can work that way, but precedence won't be right. E.g. `x = x + 5` will set `x = x`, and then add 5 to the result of that assignment, and return, but without updating `x`.
|
||||
|
||||
```
|
||||
for val in obj {
|
||||
|
||||
}
|
||||
|
||||
for key : val in obj {
|
||||
|
||||
}
|
||||
|
||||
for key : in obj {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Functions are created with `fn var thunk`, or `var => thunk`
|
||||
|
||||
Properties can be accessed and set with `obj . prop`
|
||||
|
||||
Command is:
|
||||
```
|
||||
set x = 5
|
||||
if condition {
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
250
index.html
Normal file
250
index.html
Normal file
@ -0,0 +1,250 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<style>
|
||||
.swatch {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: hsl(var(--hue), var(--saturation), var(--lightness));
|
||||
}
|
||||
|
||||
.h1p {
|
||||
--hue: 310;
|
||||
}
|
||||
.h1 {
|
||||
--hue: 340;
|
||||
}
|
||||
.h1s {
|
||||
--hue: 335;
|
||||
}
|
||||
.h2d {
|
||||
--hue: 50;
|
||||
}
|
||||
.h2 {
|
||||
--hue: 37;
|
||||
}
|
||||
.h2s {
|
||||
--hue: 30;
|
||||
}
|
||||
.h2h {
|
||||
--hue: 57;
|
||||
}
|
||||
.h3 {
|
||||
--hue: 130;
|
||||
}
|
||||
.h3s {
|
||||
--hue: 145;
|
||||
}
|
||||
.h3h {
|
||||
--hue: 203;
|
||||
}
|
||||
.h4 {
|
||||
--hue: 224;
|
||||
}
|
||||
/* .h4hs {
|
||||
--hue: 228;
|
||||
}
|
||||
.h4s {
|
||||
--hue: 235;
|
||||
} */
|
||||
.h4hs {
|
||||
--hue: 235;
|
||||
}
|
||||
.h4s {
|
||||
--hue: 240;
|
||||
}
|
||||
.h5 {
|
||||
--hue: 250;
|
||||
}
|
||||
.h6 {
|
||||
--hue: 230;
|
||||
}
|
||||
.h7 {
|
||||
--hue: 30;
|
||||
}
|
||||
|
||||
.sp {
|
||||
--saturation: 90%;
|
||||
}
|
||||
.s1 {
|
||||
--saturation: 85%;
|
||||
}
|
||||
.s1x {
|
||||
--saturation: 75%;
|
||||
}
|
||||
.sx {
|
||||
--saturation: 65%;
|
||||
}
|
||||
.smx {
|
||||
--saturation: 60%;
|
||||
}
|
||||
.sm {
|
||||
--saturation: 55%;
|
||||
}
|
||||
.smm {
|
||||
--saturation: 50%;
|
||||
}
|
||||
.s2 {
|
||||
--saturation: 45%;
|
||||
}
|
||||
.ss {
|
||||
--saturation: 40%;
|
||||
}
|
||||
.sl {
|
||||
--saturation: 25%;
|
||||
}
|
||||
.s3 {
|
||||
--saturation: 13%;
|
||||
}
|
||||
|
||||
.l0 {
|
||||
--lightness: 95%;
|
||||
}
|
||||
.l1 {
|
||||
--lightness: 82%;
|
||||
}
|
||||
.l1h {
|
||||
--lightness: 75%;
|
||||
}
|
||||
.l1hh {
|
||||
--lightness: 70%;
|
||||
}
|
||||
.l2 {
|
||||
--lightness: 67%;
|
||||
}
|
||||
.l2m {
|
||||
--lightness: 62%;
|
||||
}
|
||||
.lm {
|
||||
--lightness: 58%;
|
||||
}
|
||||
.l3 {
|
||||
--lightness: 50%;
|
||||
}
|
||||
.l3h {
|
||||
--lightness: 40%;
|
||||
}
|
||||
.l4 {
|
||||
--lightness: 30%;
|
||||
}
|
||||
.l4h {
|
||||
--lightness: 25%;
|
||||
}
|
||||
.l5 {
|
||||
--lightness: 20%;
|
||||
}
|
||||
.l6 {
|
||||
--lightness: 5%;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<div class="swatch h6 s3 l0"></div>
|
||||
<div class="swatch h6 s3 l2"></div>
|
||||
<div class="swatch h6 s3 l4"></div>
|
||||
<div class="swatch h6 s3 l6"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h2 smx l3"></div>
|
||||
<div class="swatch h7 ss l2"></div>
|
||||
<div class="swatch h7 ss l3h"></div>
|
||||
<div class="swatch h7 ss l4h"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h5 smx l2"></div>
|
||||
<div class="swatch h1p smx l2"></div>
|
||||
<div class="swatch h1 smx l3"></div>
|
||||
<div class="swatch h1s smx l4"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h2h sp l2m"></div>
|
||||
<div class="swatch h3 smx l3"></div>
|
||||
<div class="swatch h3s smx l4"></div>
|
||||
<div class="swatch h3s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h3h sp l2"></div>
|
||||
<div class="swatch h4 smx l3"></div>
|
||||
<div class="swatch h4hs smx l3h"></div>
|
||||
<div class="swatch h4s smx l4"></div>
|
||||
</div>
|
||||
<!-- -->
|
||||
<!-- <div class="row">
|
||||
<div class="swatch h1 smx l3"></div>
|
||||
<div class="swatch h1s smx l4"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h2h sx lm"></div>
|
||||
<div class="swatch h3 smx l3"></div>
|
||||
<div class="swatch h3s smx l4"></div>
|
||||
<div class="swatch h3s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h4 smx l3"></div>
|
||||
<div class="swatch h4hs smx l3h"></div>
|
||||
<div class="swatch h4s smx l4"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h7 ss l4h"></div>
|
||||
<div class="swatch h2s ss l3h"></div>
|
||||
<div class="swatch h2s ss l2"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h6 s3 l0"></div>
|
||||
<div class="swatch h6 s3 l2"></div>
|
||||
<div class="swatch h6 s3 l4"></div>
|
||||
<div class="swatch h6 s3 l6"></div>
|
||||
</div> -->
|
||||
<!-- -->
|
||||
<!-- <div class="row">
|
||||
<div class="swatch h1 smx l2"></div>
|
||||
<div class="swatch h1 smx l3"></div>
|
||||
<div class="swatch h1s smx l4"></div>
|
||||
<div class="swatch h1s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h2 smx l2"></div>
|
||||
<div class="swatch h2 smx l3"></div>
|
||||
<div class="swatch h2s smx l4"></div>
|
||||
<div class="swatch h2s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h3 smx l2"></div>
|
||||
<div class="swatch h3 smx l3"></div>
|
||||
<div class="swatch h3s smx l4"></div>
|
||||
<div class="swatch h3s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h4 smx l2"></div>
|
||||
<div class="swatch h4 smx l3"></div>
|
||||
<div class="swatch h4s smx l4"></div>
|
||||
<div class="swatch h4s smx l5"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h5 sl lm"></div>
|
||||
<div class="swatch h5 sl l3h"></div>
|
||||
<div class="swatch h5 sl l4h"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h6 s3 l0"></div>
|
||||
<div class="swatch h6 s3 l1"></div>
|
||||
<div class="swatch h6 s3 l2"></div>
|
||||
<div class="swatch h6 s3 l3"></div>
|
||||
<div class="swatch h6 s3 l4"></div>
|
||||
<div class="swatch h6 s3 l5"></div>
|
||||
<div class="swatch h6 s3 l6"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="swatch h7 ss l1"></div>
|
||||
<div class="swatch h7 ss l2"></div>
|
||||
<div class="swatch h7 ss l3"></div>
|
||||
<div class="swatch h7 ss l4"></div>
|
||||
<div class="swatch h7 ss l5"></div>
|
||||
</div> -->
|
||||
</body>
|
||||
</html>
|
64
index.ts
64
index.ts
@ -1,64 +0,0 @@
|
||||
import {
|
||||
mainloop,
|
||||
frame,
|
||||
clearScreen,
|
||||
} from "./io/window.ts";
|
||||
import { runCode } from "./runtime/runcode.ts";
|
||||
import { getCodeSheet } from "./io/sheet.ts";
|
||||
import { refreshKeyboard, keyPressed, K } from "./io/keyboard.ts";
|
||||
import { repl, resetRepl } from "./repl/repl.ts";
|
||||
import { addToContext } from "./runtime/runcode.ts";
|
||||
import { editmode } from "./editor/editmode.ts";
|
||||
import { refreshMouse } from "./io/mouse.ts";
|
||||
import { camera } from "./runtime/builtins.ts";
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
let game: any = null;
|
||||
|
||||
let mode: "play" | "edit" | "repl" = "repl";
|
||||
|
||||
addToContext("play", async () => {
|
||||
game = await runCode(getCodeSheet(0));
|
||||
mode = "play";
|
||||
game.init();
|
||||
});
|
||||
|
||||
clearScreen();
|
||||
|
||||
await mainloop(async (_t) => {
|
||||
// TODO: use t
|
||||
if (keyPressed(K.ESCAPE)) {
|
||||
const modeTo = ({
|
||||
play: "repl",
|
||||
edit: "repl",
|
||||
repl: "edit",
|
||||
} as const)[mode];
|
||||
if (mode === "play") {
|
||||
resetRepl();
|
||||
}
|
||||
if (mode === "edit") {
|
||||
clearScreen();
|
||||
}
|
||||
mode = modeTo;
|
||||
} else {
|
||||
if (mode === "play") {
|
||||
if (game) {
|
||||
await game.update();
|
||||
await game.draw();
|
||||
}
|
||||
frame();
|
||||
} else if (mode === "repl") {
|
||||
repl.update();
|
||||
camera(0, 0);
|
||||
repl.draw();
|
||||
frame();
|
||||
} else if (mode === "edit") {
|
||||
await editmode.update();
|
||||
camera(0, 0);
|
||||
editmode.draw();
|
||||
frame();
|
||||
}
|
||||
}
|
||||
refreshKeyboard();
|
||||
refreshMouse();
|
||||
}, false);
|
28
io/cart.ts
28
io/cart.ts
@ -1,28 +0,0 @@
|
||||
import { path } from "../deps.ts";
|
||||
import initialCart from "../data/initialCart.json" assert { type: "json" };
|
||||
import { Sheet } from "./sheet.ts";
|
||||
|
||||
const extension = ".faux";
|
||||
|
||||
let staticCart = initialCart as Array<Sheet>;
|
||||
let cart: Array<Sheet> = JSON.parse(JSON.stringify(staticCart));
|
||||
|
||||
const virtualPathToRealPath = (virtualFname: string) => {
|
||||
const vfname = virtualFname + extension;
|
||||
const realPath = path.join(".", "carts", ...vfname.split("/"));
|
||||
return realPath;
|
||||
}
|
||||
|
||||
export const saveCart = async (fname: string) => {
|
||||
await Deno.writeTextFile(virtualPathToRealPath(fname), JSON.stringify(getCart()));
|
||||
}
|
||||
|
||||
export const loadCart = async (fname: string) => {
|
||||
const json = await Deno.readTextFile(virtualPathToRealPath(fname));
|
||||
staticCart = JSON.parse(json);
|
||||
cart = JSON.parse(json);
|
||||
}
|
||||
|
||||
export const getCart = () => {
|
||||
return cart;
|
||||
}
|
174
io/keyboard.ts
174
io/keyboard.ts
@ -1,174 +0,0 @@
|
||||
import { font, CHAR } from "../data/font.ts";
|
||||
|
||||
const keyboard = new Map<number, {first: boolean, repeat: boolean, held: boolean}>();
|
||||
|
||||
export const K = {
|
||||
ESCAPE: 256,
|
||||
ENTER: 257,
|
||||
TAB: 258,
|
||||
BACKSPACE: 259,
|
||||
INSERT: 260,
|
||||
DELETE: 261,
|
||||
ARROW_RIGHT: 262,
|
||||
ARROW_LEFT: 263,
|
||||
ARROW_DOWN: 264,
|
||||
ARROW_UP: 265,
|
||||
PAGE_UP: 266,
|
||||
PAGE_DOWN: 267,
|
||||
HOME: 268,
|
||||
END: 269,
|
||||
CAPS_LOCK: 280,
|
||||
F1: 290,
|
||||
F2: 291,
|
||||
F3: 292,
|
||||
F4: 293,
|
||||
F5: 294,
|
||||
F6: 295,
|
||||
F7: 296,
|
||||
F8: 297,
|
||||
F9: 298,
|
||||
F10: 299,
|
||||
F11: 300,
|
||||
F12: 301,
|
||||
SHIFT_LEFT: 340,
|
||||
CTRL_LEFT: 341,
|
||||
ALT_LEFT: 342,
|
||||
SHIFT_RIGHT: 344,
|
||||
CTRL_RIGHT: 345,
|
||||
ALT_RIGHT: 346,
|
||||
}
|
||||
|
||||
export const shiftMap = {
|
||||
"1": "!",
|
||||
"2": "@",
|
||||
"3": "#",
|
||||
"4": "$",
|
||||
"5": "%",
|
||||
"6": "^",
|
||||
"7": "&",
|
||||
"8": "*",
|
||||
"9": "(",
|
||||
"0": ")",
|
||||
"`": "~",
|
||||
"-": "_",
|
||||
"=": "+",
|
||||
"[": "{",
|
||||
"]": "}",
|
||||
"\\": "|",
|
||||
";": ":",
|
||||
"'": '"',
|
||||
",": "<",
|
||||
".": ">",
|
||||
"/": "?",
|
||||
}
|
||||
|
||||
export const altMap = {
|
||||
"w": CHAR.UP,
|
||||
"a": CHAR.LEFT,
|
||||
"s": CHAR.DOWN,
|
||||
"d": CHAR.RIGHT,
|
||||
"p": CHAR.PI,
|
||||
}
|
||||
|
||||
addEventListener("keydown", (evt) => {
|
||||
// console.log("keydown", evt.key, evt.key.charCodeAt(0));
|
||||
const key = evt.key.charCodeAt(0);
|
||||
const isRepeat = keyboard.has(key) && keyboard.get(key)?.held!;
|
||||
keyboard.set(key, {
|
||||
first: !isRepeat,
|
||||
repeat: isRepeat,
|
||||
held: true,
|
||||
});
|
||||
});
|
||||
|
||||
addEventListener("keyup", (evt) => {
|
||||
// console.log("keyup", evt.key, evt.key.charCodeAt(0));
|
||||
const key = evt.key.charCodeAt(0);
|
||||
keyboard.set(key, {
|
||||
first: false,
|
||||
repeat: false,
|
||||
held: false,
|
||||
});
|
||||
});
|
||||
|
||||
export const refreshKeyboard = () => {
|
||||
keyboard.forEach(({held}, key) => {
|
||||
if (!held) {
|
||||
keyboard.delete(key);
|
||||
} else {
|
||||
keyboard.set(key, {
|
||||
first: false,
|
||||
repeat: false,
|
||||
held: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const keyPressed = (key: string | number) => {
|
||||
if (typeof key === "string") {
|
||||
key = key.toUpperCase().charCodeAt(0);
|
||||
}
|
||||
return keyboard.has(key) && (keyboard.get(key)?.first! || keyboard.get(key)?.repeat!);
|
||||
}
|
||||
|
||||
export const keyDown = (key: string | number) => {
|
||||
if (typeof key === "string") {
|
||||
key = key.toUpperCase().charCodeAt(0);
|
||||
}
|
||||
return keyboard.has(key) && keyboard.get(key)?.held!;
|
||||
}
|
||||
|
||||
export const shiftKeyDown = () => {
|
||||
return keyDown(K.SHIFT_LEFT) || keyDown(K.SHIFT_RIGHT);
|
||||
}
|
||||
|
||||
export const ctrlKeyDown = () => {
|
||||
return keyDown(K.CTRL_LEFT) || keyDown(K.CTRL_RIGHT);
|
||||
}
|
||||
|
||||
export const altKeyDown = () => {
|
||||
return keyDown(K.ALT_LEFT) || keyDown(K.ALT_RIGHT);
|
||||
}
|
||||
|
||||
export const keyReleased = (key: string | number) => {
|
||||
if (typeof key === "string") {
|
||||
key = key.toUpperCase().charCodeAt(0);
|
||||
}
|
||||
return keyboard.has(key) && !keyboard.get(key)?.held!;
|
||||
}
|
||||
|
||||
export const getKeysPressed = () => {
|
||||
const result = [...keyboard.entries()].filter(([_key, value]) => {
|
||||
return value.first || value.repeat;
|
||||
}).map(([key]) => key);
|
||||
return result;
|
||||
}
|
||||
|
||||
export const getKeyboardString = () => {
|
||||
let str = "";
|
||||
if (ctrlKeyDown()) {
|
||||
return str;
|
||||
}
|
||||
for (const key of getKeysPressed()) {
|
||||
let char = String.fromCharCode(key).toLowerCase();
|
||||
if (shiftKeyDown()) {
|
||||
if (char in shiftMap) {
|
||||
char = shiftMap[char as keyof typeof shiftMap];
|
||||
} else {
|
||||
char = char.toUpperCase();
|
||||
}
|
||||
}
|
||||
if (altKeyDown()) {
|
||||
if (char in altMap) {
|
||||
char = altMap[char as keyof typeof altMap];
|
||||
} else {
|
||||
char = char.toUpperCase();
|
||||
}
|
||||
}
|
||||
if (char in font.chars) {
|
||||
str += char;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
121
io/mouse.ts
121
io/mouse.ts
@ -1,121 +0,0 @@
|
||||
import { WindowMouseEvent } from "https://deno.land/x/dwm@0.3.3/mod.ts";
|
||||
import { gameWindow } from "./window.ts";
|
||||
|
||||
export const M = {
|
||||
NONE: -1,
|
||||
LEFT: 0,
|
||||
RIGHT: 1,
|
||||
MIDDLE: 2,
|
||||
}
|
||||
|
||||
const mouseButtonsDown = {
|
||||
[M.LEFT]: false,
|
||||
[M.RIGHT]: false,
|
||||
[M.MIDDLE]: false,
|
||||
};
|
||||
|
||||
type MouseEventType = "click" | "down" | "up" | "move" | "dblclick";
|
||||
|
||||
const mouseEvents: Array<{
|
||||
type: MouseEventType,
|
||||
button: typeof M[keyof typeof M],
|
||||
x: number,
|
||||
y: number,
|
||||
prevX?: number,
|
||||
prevY?: number
|
||||
}> = [];
|
||||
|
||||
let mouseX = 0;
|
||||
let mouseY = 0;
|
||||
|
||||
const eventPixelCoords = (evt: WindowMouseEvent) => {
|
||||
const {width, height} = gameWindow.size;
|
||||
const min = Math.min(width, height);
|
||||
const pixX = Math.floor(128*(evt.clientX-(width-min)/2)/min);
|
||||
const pixY = Math.floor(128*(evt.clientY-(height-min)/2)/min);
|
||||
if (pixX < 0 || pixX > 128 || pixY < 0 || pixY > 128) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
x: pixX,
|
||||
y: pixY,
|
||||
}
|
||||
}
|
||||
|
||||
const pushEvent = (type: MouseEventType, evt: WindowMouseEvent, extra?: Partial<typeof mouseEvents[0]>) => {
|
||||
const coords = eventPixelCoords(evt);
|
||||
if (!coords) {
|
||||
return
|
||||
}
|
||||
mouseEvents.push({type, button: evt.button, ...coords, ...(extra ?? {})});
|
||||
}
|
||||
|
||||
const evtInBounds = (evt: WindowMouseEvent) => {
|
||||
return !!eventPixelCoords(evt);
|
||||
}
|
||||
|
||||
addEventListener("dblclick", (evt) => {
|
||||
pushEvent("dblclick", evt);
|
||||
});
|
||||
|
||||
addEventListener("click", (evt) => {
|
||||
pushEvent("click", evt);
|
||||
});
|
||||
|
||||
addEventListener("mousedown", (evt) => {
|
||||
if (evtInBounds(evt)) {
|
||||
mouseButtonsDown[evt.button] = true;
|
||||
}
|
||||
pushEvent("down", evt);
|
||||
});
|
||||
|
||||
addEventListener("mouseup", (evt) => {
|
||||
if (evtInBounds(evt)) {
|
||||
mouseButtonsDown[evt.button] = false;
|
||||
}
|
||||
pushEvent("up", evt);
|
||||
});
|
||||
|
||||
addEventListener("mousemove", (evt) => {
|
||||
const coords = eventPixelCoords(evt);
|
||||
pushEvent("up", evt, {prevX: mouseX, prevY: mouseY});
|
||||
if (coords) {
|
||||
mouseX = coords.x;
|
||||
mouseY = coords.y;
|
||||
}
|
||||
});
|
||||
|
||||
export const mousePos = () => {
|
||||
return {
|
||||
x: mouseX,
|
||||
y: mouseY,
|
||||
}
|
||||
}
|
||||
|
||||
export const getMouseX = () => {
|
||||
return mouseX;
|
||||
}
|
||||
|
||||
export const getMouseY = () => {
|
||||
return mouseY;
|
||||
}
|
||||
|
||||
export const refreshMouse = () => {
|
||||
mouseEvents.length = 0;
|
||||
}
|
||||
|
||||
export const mouseDown = (button: number = M.LEFT) => {
|
||||
return mouseEvents.some(ev => ev.button === button && ev.type === "down");
|
||||
}
|
||||
|
||||
export const mouseClick = (button: number = M.LEFT) => {
|
||||
return mouseEvents.some(ev => ev.button === button && ev.type === "click");
|
||||
}
|
||||
|
||||
export const mouseDoubleClick = (button: number = M.LEFT) => {
|
||||
return mouseEvents.some(ev => ev.button === button && ev.type === "dblclick");
|
||||
}
|
||||
|
||||
export const mouseHeld = (button: number = M.LEFT) => {
|
||||
return mouseButtonsDown[button];
|
||||
}
|
56
io/sheet.ts
56
io/sheet.ts
@ -1,56 +0,0 @@
|
||||
import { getCart } from "./cart.ts";
|
||||
import { LinearGrid } from "../util/util.ts";
|
||||
// import { runCode, addToContext } from "./runcode.ts";
|
||||
|
||||
// "code" | "spritesheet" | "map" | "sfx" | "patterns" | "fonts"
|
||||
export type Sheet = {
|
||||
sheet_type: "code",
|
||||
value: string,
|
||||
} | {
|
||||
sheet_type: "spritesheet",
|
||||
value: Array<Array<number>>,
|
||||
} | {
|
||||
sheet_type: "map",
|
||||
value: Array<[number, number]>,
|
||||
} | {
|
||||
sheet_type: "none",
|
||||
value: null,
|
||||
}
|
||||
export type SheetType = Sheet["sheet_type"];
|
||||
|
||||
export const getSheet = (n: number): Sheet => {
|
||||
return getCart()[n];
|
||||
}
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
export const setSheet = (n: number, type: SheetType, value: any) => {
|
||||
return getCart()[n] = {sheet_type: type, value};
|
||||
}
|
||||
|
||||
export const getCodeSheet = (sheet: number) => {
|
||||
const {sheet_type, value} = getSheet(sheet);
|
||||
if (sheet_type !== "code") {
|
||||
throw "Trying to use a non-code sheet as code."
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export const getSpriteSheet = (sheet: number) => {
|
||||
const {sheet_type, value} = getSheet(sheet);
|
||||
if (sheet_type !== "spritesheet") {
|
||||
throw Error("Trying to use a non-sprite sheet as a spritesheet.");
|
||||
}
|
||||
while (value.length < 128) {
|
||||
value.push(Array(64).fill(0));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export const getMapSheet = (sheet: number) => {
|
||||
const {sheet_type, value} = getSheet(sheet);
|
||||
if (sheet_type !== "map") {
|
||||
throw "Trying to use a non-map sheet as a map."
|
||||
}
|
||||
sheet_type
|
||||
return LinearGrid(value, 64);
|
||||
}
|
256
io/window.ts
256
io/window.ts
@ -1,256 +0,0 @@
|
||||
import {
|
||||
createWindow,
|
||||
getProcAddress,
|
||||
gl,
|
||||
} from "../deps.ts";
|
||||
export {mainloop} from "../deps.ts";
|
||||
import { COLOR, palette } from "../data/colors.ts";
|
||||
|
||||
export const gameWindow = createWindow({
|
||||
title: "Faux",
|
||||
width: 512,
|
||||
height: 512,
|
||||
resizable: true,
|
||||
glVersion: [3, 2],
|
||||
gles: true,
|
||||
});
|
||||
|
||||
gl.load(getProcAddress);
|
||||
|
||||
function loadShader(type: number, src: string) {
|
||||
const shader = gl.CreateShader(type);
|
||||
gl.ShaderSource(
|
||||
shader,
|
||||
1,
|
||||
new Uint8Array(
|
||||
new BigUint64Array([
|
||||
BigInt(
|
||||
Deno.UnsafePointer.value(
|
||||
Deno.UnsafePointer.of(new TextEncoder().encode(src)),
|
||||
),
|
||||
),
|
||||
]).buffer,
|
||||
),
|
||||
new Int32Array([src.length]),
|
||||
);
|
||||
gl.CompileShader(shader);
|
||||
const status = new Int32Array(1);
|
||||
gl.GetShaderiv(shader, gl.COMPILE_STATUS, status);
|
||||
if (status[0] === gl.FALSE) {
|
||||
const logLength = new Int32Array(1);
|
||||
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, logLength);
|
||||
const log = new Uint8Array(logLength[0]);
|
||||
gl.GetShaderInfoLog(shader, logLength[0], logLength, log);
|
||||
console.log(new TextDecoder().decode(log));
|
||||
gl.DeleteShader(shader);
|
||||
return 0;
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
const vShaderSrc = `
|
||||
attribute vec4 vPosition;
|
||||
attribute vec4 vCol;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
color = vCol;
|
||||
}
|
||||
`;
|
||||
|
||||
const fShaderSrc = `
|
||||
precision mediump float;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_FragColor = color;
|
||||
}
|
||||
`;
|
||||
|
||||
const vShader = loadShader(gl.VERTEX_SHADER, vShaderSrc);
|
||||
const fShader = loadShader(gl.FRAGMENT_SHADER, fShaderSrc);
|
||||
|
||||
const program = gl.CreateProgram();
|
||||
gl.AttachShader(program, vShader);
|
||||
gl.AttachShader(program, fShader);
|
||||
|
||||
gl.BindAttribLocation(program, 0, new TextEncoder().encode("vPosition\0"));
|
||||
gl.BindAttribLocation(program, 1, new TextEncoder().encode("vCol\0"));
|
||||
|
||||
gl.LinkProgram(program);
|
||||
|
||||
const status = new Int32Array(1);
|
||||
gl.GetProgramiv(program, gl.LINK_STATUS, status);
|
||||
if (status[0] === gl.FALSE) {
|
||||
const logLength = new Int32Array(1);
|
||||
gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, logLength);
|
||||
const log = new Uint8Array(logLength[0]);
|
||||
gl.GetProgramInfoLog(program, logLength[0], logLength, log);
|
||||
console.log(new TextDecoder().decode(log));
|
||||
gl.DeleteProgram(program);
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
gl.ClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
const pixelsPerRow = 128;
|
||||
|
||||
const top = 1;
|
||||
const left = -1;
|
||||
const cell = 2/pixelsPerRow;
|
||||
|
||||
const getHalfAsInt = (n: number) => Number(parseInt(Math.floor(n/2).toString()));
|
||||
|
||||
addEventListener("resize", (event) => {
|
||||
const {width, height} = event;
|
||||
const min = Math.min(width, height);
|
||||
gl.Viewport(getHalfAsInt(width-min), getHalfAsInt(height-min), min, min);
|
||||
});
|
||||
|
||||
const px = (x: number, y: number) => {
|
||||
// deno-fmt-ignore
|
||||
return [
|
||||
left + x*cell, top - y*cell, 0,
|
||||
left + (x+1)*cell, top - y*cell, 0,
|
||||
left + x*cell, top - (y+1)*cell, 0,
|
||||
left + (x+1)*cell, top - y*cell, 0,
|
||||
left + x*cell, top - (y+1)*cell, 0,
|
||||
left + (x+1)*cell, top - (y+1)*cell, 0,
|
||||
];
|
||||
}
|
||||
|
||||
const paletteX6 = palette.map(rgba => [...rgba, ...rgba, ...rgba, ...rgba, ...rgba, ...rgba]);
|
||||
|
||||
const c = (n: number) => {
|
||||
return paletteX6[n];
|
||||
}
|
||||
|
||||
const allPixelTriangles = new Float32Array(
|
||||
Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap((_, i) => px(i%pixelsPerRow,Math.floor(i/pixelsPerRow)))
|
||||
)
|
||||
|
||||
const allPixelColors = new Float32Array(
|
||||
Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap(() => c(1))
|
||||
)
|
||||
|
||||
export const cameraPos = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
|
||||
export const setPixelColorRaw = (x: number, y: number, color: number) => {
|
||||
if (x < 0 || y < 0 || x > 127 || y > 127) {
|
||||
return;
|
||||
}
|
||||
if (color !== 0) {
|
||||
const col = c(color);
|
||||
allPixelColors.set(col, 4*6*(128*y+x));
|
||||
}
|
||||
}
|
||||
|
||||
export const setPixelColor = (x: number, y: number, color: number) => {
|
||||
return setPixelColorRaw(Math.floor(x - cameraPos.x), Math.floor(y - cameraPos.y), color);
|
||||
}
|
||||
|
||||
export const setPixelsInRect = (x: number, y: number, w: number, pixels: Array<number>) => {
|
||||
for (let i = 0; i < pixels.length; i++) {
|
||||
setPixelColor(x+i%w, y+Math.floor(i/w), pixels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
export const setPixelsInRectRaw = (x: number, y: number, w: number, pixels: Array<number>) => {
|
||||
for (let i = 0; i < pixels.length; i++) {
|
||||
setPixelColorRaw(x+i%w, y+Math.floor(i/w), pixels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
export const fillRect = (x: number, y: number, w: number, h: number, color: number) => {
|
||||
setPixelsInRect(x, y, w, Array(w*h).fill(color));
|
||||
}
|
||||
|
||||
export const fillCircle = (x: number, y: number, r: number, color: number) => {
|
||||
const left = Math.floor(x-r-1);
|
||||
const top = Math.floor(y-r-1);
|
||||
for (let i = left; i <= Math.ceil(x+r+1); i ++) {
|
||||
for (let j = top; j <= Math.ceil(y+r+1); j ++) {
|
||||
if (Math.sqrt((x-i)**2 + (y-j)**2) <= r+0.5) {
|
||||
setPixelColor(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const outlineCircle = (x: number, y: number, r: number, color: number) => {
|
||||
const left = Math.floor(x-r-1);
|
||||
const top = Math.floor(y-r-1);
|
||||
const inR = (d: number) => d <= r+0.5 && d > r-0.5;
|
||||
for (let i = left; i <= Math.ceil(x+r+1); i ++) {
|
||||
for (let j = top; j <= Math.ceil(y+r+1); j ++) {
|
||||
const d = Math.sqrt((x-i)**2 + (y-j)**2);
|
||||
if (inR(d)) {
|
||||
const dh = Math.sqrt((x-(i+Math.sign(i-x)))**2 + (y-j)**2);
|
||||
const dv = Math.sqrt((x-i)**2 + (y-(j+Math.sign(j-y)))**2);
|
||||
const h = Math.abs(x-i) > Math.abs(y-j);
|
||||
if (!inR(h ? dh : dv)) {
|
||||
setPixelColor(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const fillEllipse = (x0: number, y0: number, x1: number, y1: number, color: number) => {
|
||||
const x = 0.5*(x0 + x1);
|
||||
const y = 0.5*(y0 + y1);
|
||||
const rx = Math.abs(x0-x1)/2;
|
||||
const ry = Math.abs(y0-y1)/2;
|
||||
const left = Math.floor(x-rx-1);
|
||||
const top = Math.floor(y-ry-1);
|
||||
for (let i = left; i <= Math.ceil(x+rx+1); i ++) {
|
||||
for (let j = top; j <= Math.ceil(y+ry+1); j ++) {
|
||||
if (Math.sqrt(((x-i)/rx)**2 + ((y-j)/ry)**2) <= 1+(1/(rx+ry))) {
|
||||
setPixelColor(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const outlineEllipse = (x0: number, y0: number, x1: number, y1: number, color: number) => {
|
||||
const x = 0.5*(x0 + x1);
|
||||
const y = 0.5*(y0 + y1);
|
||||
const rx = Math.abs(x0-x1)/2;
|
||||
const ry = Math.abs(y0-y1)/2;
|
||||
const left = Math.floor(x-rx-1);
|
||||
const top = Math.floor(y-ry-1);
|
||||
const inR = (d: number) => d <= 1+1/(rx+ry);
|
||||
for (let i = left; i <= Math.ceil(x+rx+1); i ++) {
|
||||
for (let j = top; j <= Math.ceil(y+ry+1); j ++) {
|
||||
const d = Math.sqrt(((x-i)/rx)**2 + ((y-j)/ry)**2);
|
||||
if (inR(d)) {
|
||||
const dh = Math.sqrt(((x-(i+Math.sign(i-x)))/rx)**2 + ((y-j)/ry)**2);
|
||||
const dv = Math.sqrt(((x-i)/rx)**2 + ((y-(j+Math.sign(j-y)))/ry)**2);
|
||||
if (!inR(dh) || !inR(dv)) {
|
||||
setPixelColor(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const fillRectRaw = (x: number, y: number, w: number, h: number, color: number) => {
|
||||
setPixelsInRectRaw(x, y, w, Array(w*h).fill(color));
|
||||
}
|
||||
|
||||
export const clearScreen = (color?: number) => {
|
||||
fillRectRaw(0, 0, 128, 128, color ?? COLOR.BLACK);
|
||||
}
|
||||
|
||||
export const frame = () => {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.UseProgram(program);
|
||||
gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, allPixelTriangles);
|
||||
gl.VertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, 0, allPixelColors);
|
||||
gl.EnableVertexAttribArray(0);
|
||||
gl.EnableVertexAttribArray(1);
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6*pixelsPerRow*pixelsPerRow);
|
||||
gameWindow.swapBuffers();
|
||||
}
|
54
lang2/lexer.ts
Normal file
54
lang2/lexer.ts
Normal file
@ -0,0 +1,54 @@
|
||||
type Token<T extends string> = {
|
||||
type: T,
|
||||
string: string,
|
||||
}
|
||||
|
||||
type LexerProps<T extends string> = {
|
||||
rules: {
|
||||
[key in T]: RegExp;
|
||||
},
|
||||
// postprocess?: (token: Token<T>) =>
|
||||
}
|
||||
|
||||
const entries = <K extends string, V>(obj: {[key in K]: V}) => {
|
||||
return Object.entries(obj) as Array<[K, V]>;
|
||||
}
|
||||
|
||||
const lexer = <T extends string>(props: LexerProps<T>) => {
|
||||
const {rules} = props;
|
||||
return (string: string): Array<Token<T>> => {
|
||||
const tokens: Array<Token<T>> = [];
|
||||
let str = string;
|
||||
while (str.length) {
|
||||
let matched = false;
|
||||
for (const [type, matcher] of entries(rules)) {
|
||||
const match = str.match(matcher);
|
||||
if (match && match.index === 0) {
|
||||
if (type !== "_skip") {
|
||||
tokens.push({type, string: match[0]});
|
||||
}
|
||||
str = str.slice(match[0].length);
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
console.log(tokens);
|
||||
console.log(str);
|
||||
throw 'Infinite Loop';
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
|
||||
const my_lexer = lexer({
|
||||
rules: {
|
||||
symbol: /\w+/,
|
||||
punctuation: /[\.,:;()[\]{}]/,
|
||||
string_literal: /"([^"\\]|\\.)*"/,
|
||||
_skip: /\s+/,
|
||||
}
|
||||
});
|
||||
|
||||
console.log(my_lexer(`abc def { ghi } "string literal!" "with \\"escaped\\" quote marks"`));
|
28
lang2/peg.js
Normal file
28
lang2/peg.js
Normal file
@ -0,0 +1,28 @@
|
||||
const Expression = rule(
|
||||
[{head: Term}, {tail: star([_, slash("+", "-"), _, Term])}],
|
||||
({head, tail}) => {
|
||||
return tail.reduce(function(result, element) {
|
||||
if (element[1] === "+") { return result + element[3]; }
|
||||
if (element[1] === "-") { return result - element[3]; }
|
||||
}, head);
|
||||
}
|
||||
);
|
||||
|
||||
const Term = rule(
|
||||
[{head: Factor}, {tail: star([_, slash("*", "/"), _, Factor])}],
|
||||
({head, tail}) => {
|
||||
return tail.reduce(function(result, element) {
|
||||
if (element[1] === "*") { return result * element[3]; }
|
||||
if (element[1] === "/") { return result / element[3]; }
|
||||
}, head);
|
||||
}
|
||||
);
|
||||
|
||||
const Factor = slash(
|
||||
rule(["(", _, {expr: Expression}, _, ")"], ({expr}) => expr),
|
||||
Integer
|
||||
);
|
||||
|
||||
const Integer = rule([_, /[0-9]+/], () => { return parseInt(text(), 10); });
|
||||
|
||||
const _ = /[ \t\n\r]*/;
|
130
repl/repl.ts
130
repl/repl.ts
@ -1,130 +0,0 @@
|
||||
import { drawText} from "../runtime/builtins.ts";
|
||||
import { getKeysPressed, shiftKeyDown, shiftMap, K } from "../io/keyboard.ts";
|
||||
import { font } from "../data/font.ts";
|
||||
import { addToContext, evalCode } from "../runtime/runcode.ts";
|
||||
import { clearScreen, fillRect } from "../io/window.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
|
||||
const lineHeight = 6;
|
||||
|
||||
const history: Array<string> = [];
|
||||
let historyIndex = history.length;
|
||||
let textLinesAbove: Array<string> = [];
|
||||
let maxLineLen = 0;
|
||||
let currentLine = "";
|
||||
let index = 0;
|
||||
|
||||
export const resetRepl = () => {
|
||||
historyIndex = history.length;
|
||||
textLinesAbove.length = 0;
|
||||
maxLineLen = 0;
|
||||
currentLine = "";
|
||||
index = 0;
|
||||
}
|
||||
|
||||
const print = (arg: unknown) => {
|
||||
textLinesAbove.push(...String(arg).split("\n").flatMap((line)=>{
|
||||
const wrap = [];
|
||||
while (line.length) {
|
||||
wrap.push(line.slice(0,32));
|
||||
line = line.slice(32);
|
||||
}
|
||||
return wrap;
|
||||
}));
|
||||
textLinesAbove = textLinesAbove.slice(-20);
|
||||
}
|
||||
|
||||
const printVal = (arg: unknown) => {
|
||||
print(JSON.stringify(arg));
|
||||
}
|
||||
|
||||
addToContext("print", print);
|
||||
addToContext("printVal", printVal);
|
||||
|
||||
const update = () => {
|
||||
// TODO: model this after the newer editmode.ts version using getKeyboardString
|
||||
for (const key of getKeysPressed()) {
|
||||
let char = String.fromCharCode(key).toLowerCase();
|
||||
if (shiftKeyDown()) {
|
||||
if (char in shiftMap) {
|
||||
char = shiftMap[char as keyof typeof shiftMap];
|
||||
} else {
|
||||
char = char.toUpperCase();
|
||||
}
|
||||
}
|
||||
if (char in font.chars) {
|
||||
currentLine = currentLine.slice(0, index)+char+currentLine.slice(index);
|
||||
index += 1;
|
||||
} else if (key === K.BACKSPACE) {
|
||||
if (index > 0) {
|
||||
currentLine = currentLine.slice(0, index-1)+currentLine.slice(index);
|
||||
index -= 1;
|
||||
}
|
||||
} else if (key === K.ARROW_LEFT) {
|
||||
index -= 1;
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
} else if (key === K.ARROW_RIGHT) {
|
||||
index += 1;
|
||||
if (index > currentLine.length) {
|
||||
index = currentLine.length;
|
||||
}
|
||||
} else if (key === K.ARROW_UP) {
|
||||
historyIndex -= 1;
|
||||
if (historyIndex < 0) {
|
||||
historyIndex = -1;
|
||||
}
|
||||
const lineAtHistory = history[historyIndex] ?? "";
|
||||
currentLine = lineAtHistory;
|
||||
index = currentLine.length;
|
||||
} else if (key === K.ARROW_DOWN) {
|
||||
historyIndex += 1;
|
||||
if (historyIndex > history.length) {
|
||||
historyIndex = history.length;
|
||||
}
|
||||
const lineAtHistory = history[historyIndex] ?? "";
|
||||
currentLine = lineAtHistory;
|
||||
index = currentLine.length;
|
||||
} else if (key === K.ENTER) {
|
||||
if (currentLine) {
|
||||
history.push(currentLine);
|
||||
historyIndex = history.length;
|
||||
}
|
||||
print("> "+currentLine);
|
||||
try {
|
||||
const ran = evalCode(currentLine);
|
||||
if (ran !== undefined) {
|
||||
printVal(ran);
|
||||
}
|
||||
} catch (err) {
|
||||
print(err.name+":\n"+err.message);
|
||||
}
|
||||
maxLineLen = 0;
|
||||
currentLine = "";
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
maxLineLen = Math.max(maxLineLen, currentLine.length);
|
||||
}
|
||||
|
||||
const drawTextAbove = () => {
|
||||
textLinesAbove.forEach((line, i) => {
|
||||
fillRect(0, 1+i*lineHeight, 4*(line.length+1)+1, lineHeight+1, COLOR.BLACK);
|
||||
drawText(0, 1+i*lineHeight, line);
|
||||
});
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
clearScreen();
|
||||
|
||||
drawTextAbove();
|
||||
|
||||
fillRect(0, 1+textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, COLOR.BLACK);
|
||||
fillRect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, COLOR.RED);
|
||||
drawText(0, 1+textLinesAbove.length*lineHeight, "> "+currentLine);
|
||||
}
|
||||
|
||||
export const repl = {
|
||||
update, draw
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
import {
|
||||
setPixelsInRect,
|
||||
clearScreen,
|
||||
fillRect,
|
||||
cameraPos,
|
||||
fillCircle,
|
||||
outlineCircle,
|
||||
fillEllipse,
|
||||
outlineEllipse,
|
||||
setPixelColor,
|
||||
} from "../io/window.ts";
|
||||
import { CHAR, Font, font } from "../data/font.ts";
|
||||
import { K, keyDown, keyPressed, keyReleased } from "../io/keyboard.ts";
|
||||
import { addToContext, runCode } from "./runcode.ts";
|
||||
import { resetRepl } from "../repl/repl.ts";
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { getSheet, getCodeSheet, getMapSheet } from "../io/sheet.ts";
|
||||
import { saveCart, loadCart } from "../io/cart.ts";
|
||||
import { outlineRect } from "../util/util.ts";
|
||||
|
||||
let spritesheet: number | null = null;
|
||||
|
||||
export const getSpritesheet = () => {
|
||||
return spritesheet;
|
||||
}
|
||||
|
||||
export const useSpritesheet = (sheet: number) => {
|
||||
spritesheet = sheet;
|
||||
}
|
||||
|
||||
export const drawSprite = (x: number, y: number, spr: number) => {
|
||||
if (!spritesheet) {
|
||||
return;
|
||||
}
|
||||
const {sheet_type, value: sprites} = getSheet(spritesheet);
|
||||
if (sheet_type !== "spritesheet") {
|
||||
throw "Trying to run a non-code sheet as code."
|
||||
}
|
||||
setPixelsInRect(x, y, 8, sprites[spr]);
|
||||
}
|
||||
|
||||
export const drawIcon = (x: number, y: number, icon: Array<number>, color: number) => {
|
||||
setPixelsInRect(x, y, 8, icon.map(n => n*color));
|
||||
}
|
||||
|
||||
export const measureCharFont = (char: string, fnt: Font) => {
|
||||
return (fnt.chars[char]?.length ?? 0)/fnt.height;
|
||||
}
|
||||
|
||||
export const drawCharFont = (x: number, y: number, char: string, fnt: Font, color: number) => {
|
||||
const w = measureCharFont(char, fnt);
|
||||
if (!fnt.chars[char]) {
|
||||
return 0;
|
||||
}
|
||||
setPixelsInRect(x, y, w, fnt.chars[char].map(n => n*color));
|
||||
return w;
|
||||
}
|
||||
|
||||
export const drawTextFont = (x: number, y: number, text: string, fnt: Font, color?: number) => {
|
||||
let dx = 0;
|
||||
[...text].forEach((char) => {
|
||||
dx += 1+drawCharFont(x+dx, y, char, fnt, color ?? COLOR.WHITE);
|
||||
});
|
||||
return dx-1;
|
||||
}
|
||||
|
||||
export const measureTextFont = (text: string, fnt: Font) => {
|
||||
let w = 0;
|
||||
[...text].forEach((char) => {
|
||||
w += measureCharFont(char, fnt)+1;
|
||||
});
|
||||
return Math.max(0, w-1);
|
||||
}
|
||||
|
||||
export const drawText = (x: number, y: number, text: string, color?: number) => {
|
||||
return drawTextFont(x, y, text, font, color);
|
||||
}
|
||||
|
||||
export const measureText = (text: string) => {
|
||||
return measureTextFont(text, font);
|
||||
}
|
||||
|
||||
export const camera = (x: number, y: number) => {
|
||||
cameraPos.x = x;
|
||||
cameraPos.y = y;
|
||||
};
|
||||
|
||||
const faux = {
|
||||
// Graphics
|
||||
cls: () => {
|
||||
resetRepl();
|
||||
clearScreen();
|
||||
},
|
||||
camera,
|
||||
sprsht: useSpritesheet,
|
||||
spr: drawSprite,
|
||||
txt: drawText,
|
||||
rectfill: fillRect,
|
||||
rect: outlineRect,
|
||||
circfill: fillCircle,
|
||||
circ: outlineCircle,
|
||||
ovalfill: fillEllipse,
|
||||
oval: outlineEllipse,
|
||||
pset: setPixelColor,
|
||||
map: (mapSheet: number, tileX: number, tileY: number, screenX: number, screenY: number, tileW: number, tileH: number) => {
|
||||
const originalSpritesheet = getSpritesheet() ?? 0;
|
||||
getMapSheet(mapSheet).values.forEach(([sprSheet, spr], i) => {
|
||||
const x = i%64;
|
||||
const y = Math.floor(i/64);
|
||||
if (x >= tileX && y >= tileY && x < tileX + tileW && y < tileY + tileH) {
|
||||
useSpritesheet(sprSheet);
|
||||
drawSprite(screenX + (x-tileX)*8, screenY + (y-tileY)*8, spr);
|
||||
}
|
||||
});
|
||||
useSpritesheet(originalSpritesheet);
|
||||
},
|
||||
// Map
|
||||
mgetsht: (mapSheet: number, x: number, y: number) => {
|
||||
if (x < 0 || x >= 64 || y < 0 || y >= 64) {
|
||||
return undefined;
|
||||
}
|
||||
return getMapSheet(mapSheet).get(x, y)[0];
|
||||
},
|
||||
mgetspr: (mapSheet: number, x: number, y: number) => {
|
||||
if (x < 0 || x >= 64 || y < 0 || y >= 64) {
|
||||
return undefined;
|
||||
}
|
||||
return getMapSheet(mapSheet).get(x, y)[1];
|
||||
},
|
||||
// Temporarily removing mset, since it would overwrite static cart data
|
||||
// mset: (mapSheet: number, x: number, y: number, sprSheet: number, spr: number) => {
|
||||
// if (x < 0 || x >= 64 || y < 0 || y >= 64) {
|
||||
// return;
|
||||
// }
|
||||
// getMapSheet(mapSheet).set(x, y, [sprSheet, spr]);
|
||||
// },
|
||||
// Input
|
||||
[CHAR.UP]: K.ARROW_UP,
|
||||
[CHAR.DOWN]: K.ARROW_DOWN,
|
||||
[CHAR.LEFT]: K.ARROW_LEFT,
|
||||
[CHAR.RIGHT]: K.ARROW_RIGHT,
|
||||
btn: keyDown,
|
||||
btnp: keyPressed,
|
||||
btnr: keyReleased,
|
||||
// Cart
|
||||
save: saveCart,
|
||||
load: loadCart,
|
||||
// JS
|
||||
Array,
|
||||
BigInt: BigInt,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Infinity: Infinity,
|
||||
JSON: JSON,
|
||||
Map,
|
||||
NaN: NaN,
|
||||
Number,
|
||||
Object,
|
||||
Promise,
|
||||
Proxy,
|
||||
Reflect: Reflect,
|
||||
RegExp,
|
||||
Set,
|
||||
String,
|
||||
Symbol: Symbol,
|
||||
WeakMap,
|
||||
WeakRef,
|
||||
WeakSet,
|
||||
isFinite,
|
||||
isNaN,
|
||||
parseFloat,
|
||||
parseInt,
|
||||
// Math
|
||||
max: Math.max,
|
||||
min: Math.min,
|
||||
floor: Math.floor,
|
||||
ceil: Math.ceil,
|
||||
sin: Math.sin,
|
||||
cos: Math.cos,
|
||||
atan2: Math.atan2,
|
||||
sqrt: Math.sqrt,
|
||||
abs: Math.abs,
|
||||
rand: Math.random,
|
||||
[CHAR.PI]: Math.PI,
|
||||
// Other
|
||||
code: (n: number) => {
|
||||
return runCode(getCodeSheet(n));
|
||||
},
|
||||
log: console.log,
|
||||
};
|
||||
|
||||
for (const key in faux) {
|
||||
addToContext(key, faux[key as keyof typeof faux]);
|
||||
}
|
||||
|
||||
export default faux;
|
@ -1,61 +0,0 @@
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const builtins: any = {};
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const G: any = {};
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
export const addToContext = (name: string, value: any) => {
|
||||
builtins[name] = value;
|
||||
}
|
||||
|
||||
export const getBuiltins = () => {
|
||||
return builtins;
|
||||
}
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const AsyncFunction = (async function () {}).constructor as any;
|
||||
|
||||
addToContext("eval", eval);
|
||||
|
||||
const context = new Proxy(G, {
|
||||
get: (target, prop) => {
|
||||
if (prop in builtins) {
|
||||
return builtins[prop as keyof typeof builtins];
|
||||
}
|
||||
return target[prop];
|
||||
},
|
||||
set: (target, prop, value) => {
|
||||
target[prop] = value;
|
||||
return true;
|
||||
},
|
||||
has: () => {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
export const runCode = async (code: string) => {
|
||||
try {
|
||||
new AsyncFunction(code);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
const fn = new AsyncFunction("context", `
|
||||
with (context) {
|
||||
${code}
|
||||
}
|
||||
`);
|
||||
return await fn(context);
|
||||
}
|
||||
|
||||
export const evalCode = (code: string) => {
|
||||
try {
|
||||
return runCode(`return eval("(${code.replaceAll('"', '\\"')})");`);
|
||||
} catch (err) {
|
||||
if (err.name === "SyntaxError") {
|
||||
return runCode(`return eval("${code.replaceAll('"', '\\"')}");`);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
98
util/util.ts
98
util/util.ts
@ -1,98 +0,0 @@
|
||||
import { COLOR } from "../data/colors.ts";
|
||||
import { fillRect, setPixelColor } from "../io/window.ts";
|
||||
|
||||
export const inRect = (x: number, y: number, rectX: number, rectY: number, rectW: number, rectH: number) => {
|
||||
return (
|
||||
x >= rectX &&
|
||||
x < rectX+rectW &&
|
||||
y >= rectY &&
|
||||
y < rectY+rectH
|
||||
)
|
||||
}
|
||||
|
||||
export function reGridWithGap (x: number, y: number, gridX: number, gridY: number, cellW: number, cellH: number, gapX: number, gapY: number): {x: number, y: number} | null {
|
||||
const gx = Math.floor((x-gridX)/(cellW+gapX));
|
||||
const gy = Math.floor((y-gridY)/(cellH+gapY));
|
||||
if (x >= gridX+(cellW+gapX)*gx+cellW || y >= gridY+(cellH+gapY)*gy+cellH) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
x: Math.floor((x-gridX)/(cellW+gapX)),
|
||||
y: Math.floor((y-gridY)/(cellH+gapY)),
|
||||
}
|
||||
}
|
||||
|
||||
export function reGrid (x: number, y: number, gridX: number, gridY: number, cellW: number, cellH: number): {x: number, y: number} {
|
||||
const gx = Math.floor((x-gridX)/(cellW));
|
||||
const gy = Math.floor((y-gridY)/(cellH));
|
||||
return {
|
||||
x: gx,
|
||||
y: gy,
|
||||
}
|
||||
}
|
||||
|
||||
export const outlineRect = (x: number, y: number, w: number, h: number, color: number) => {
|
||||
fillRect(x, y, w, 1, color);
|
||||
fillRect(x, y, 1, h, color);
|
||||
fillRect(x+w-1, y, 1, h, color);
|
||||
fillRect(x, y+h-1, w, 1, color);
|
||||
}
|
||||
|
||||
export const drawTransparentRect = (x: number, y: number, w: number, h: number) => {
|
||||
Array(w*h).fill(0).map((_z, j) => {
|
||||
const jx = j%w;
|
||||
const jy = Math.floor(j/w);
|
||||
setPixelColor(x+jx, y+jy, (jx+jy)%2 ? COLOR.BLACK : COLOR.DARKGRAY);
|
||||
})
|
||||
}
|
||||
|
||||
export const drawVoidRect = (x: number, y: number, w: number, h: number) => {
|
||||
Array(w*h).fill(0).map((_z, j) => {
|
||||
const jx = j%w;
|
||||
const jy = Math.floor(j/w);
|
||||
setPixelColor(x+jx, y+jy, (jx+jy)%2 ? COLOR.BLACK : COLOR.DARKERBLUE);
|
||||
})
|
||||
}
|
||||
|
||||
export const subgrid = <T>(array: Array<T>, gridW: number, x: number, y: number, w: number, h: number): Array<T|undefined> => {
|
||||
return Array(h).fill(0).flatMap((_, i) => {
|
||||
if (y+i < 0 || y+i > array.length/gridW) {
|
||||
return Array(w).fill(undefined);
|
||||
}
|
||||
const x0 = Math.max(0, x);
|
||||
const x1 = Math.min(x+w, gridW);
|
||||
const start = (y+i)*gridW+x0;
|
||||
const end = (y+i)*gridW+x1;
|
||||
const before = Array(x0 - x).fill(undefined);
|
||||
const after = Array((x+w) - x1).fill(undefined);
|
||||
const middle = array.slice(start, end);
|
||||
return [...before, ...middle, ...after];
|
||||
})
|
||||
}
|
||||
|
||||
export const LinearGrid = <T>(array: Array<T>, gridW: number) => {
|
||||
return {
|
||||
get(x: number, y: number) {
|
||||
return array[this.coordsToIndex(x, y)]
|
||||
},
|
||||
getIndex(i: number) {
|
||||
return array[i];
|
||||
},
|
||||
set(x: number, y: number, value: T) {
|
||||
array[this.coordsToIndex(x, y)] = value;
|
||||
},
|
||||
setIndex(i: number, value: T) {
|
||||
array[i] = value;
|
||||
},
|
||||
values: array,
|
||||
indexToCoords: (i: number) => {
|
||||
return [i%gridW, Math.floor(i/gridW)];
|
||||
},
|
||||
coordsToIndex: (x: number, y: number) => {
|
||||
return y*gridW+x;
|
||||
},
|
||||
// TODO: make alterations to subgrid affect parent grid
|
||||
subgrid: (x: number, y: number, w: number, h: number) => LinearGrid(subgrid(array, gridW, x, y, w, h), w),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user