codemirror ecs mode
This commit is contained in:
parent
ce21eb29e5
commit
69cd28aa0e
|
@ -1,279 +0,0 @@
|
||||||
|
|
||||||
component Kernel
|
|
||||||
lines: 0..255
|
|
||||||
bgcolor: 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
component Bitmap
|
|
||||||
bitmapdata: array of 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
component HasBitmap
|
|
||||||
bitmap: [Bitmap]
|
|
||||||
end
|
|
||||||
|
|
||||||
component Colormap
|
|
||||||
colormapdata: array of 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
component HasColormap
|
|
||||||
colormap: [Colormap]
|
|
||||||
end
|
|
||||||
|
|
||||||
component Sprite
|
|
||||||
height: 0..255
|
|
||||||
plyrindex: 0..1
|
|
||||||
end
|
|
||||||
|
|
||||||
component Player end
|
|
||||||
|
|
||||||
component PlayerFlags
|
|
||||||
plyrflags: 0..63
|
|
||||||
end
|
|
||||||
|
|
||||||
component HasXpos
|
|
||||||
xpos: 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
component HasYpos
|
|
||||||
ypos: 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
component HasXYVel
|
|
||||||
xyvel: 0..255
|
|
||||||
end
|
|
||||||
|
|
||||||
system FrameLoop
|
|
||||||
on start do once [Kernel] emit (preframe, kernel, postframe)
|
|
||||||
---
|
|
||||||
{{@NextFrame}}:
|
|
||||||
FRAME_START
|
|
||||||
{{!preframe}}
|
|
||||||
KERNEL_START
|
|
||||||
{{!kernel}}
|
|
||||||
KERNEL_END
|
|
||||||
{{!postframe}}
|
|
||||||
FRAME_END
|
|
||||||
lsr SWCHB ; test Game Reset switch
|
|
||||||
bcs {{@NoStart}}
|
|
||||||
jmp Start
|
|
||||||
{{@NoStart}}:
|
|
||||||
jmp {{@NextFrame}}
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system SimpleKernel
|
|
||||||
locals 12
|
|
||||||
on preframe do each [Sprite,HasBitmap,HasColormap,HasYpos]
|
|
||||||
---
|
|
||||||
lda #192 ; TODO: numlines
|
|
||||||
sec
|
|
||||||
sbc {{<ypos}}
|
|
||||||
sta {{$11}}
|
|
||||||
|
|
||||||
ldy {{<bitmap}} ; deref
|
|
||||||
lda {{<Bitmap.bitmapdata}},y
|
|
||||||
sec
|
|
||||||
sbc {{$11}}
|
|
||||||
sta {{$0}},x
|
|
||||||
lda {{>Bitmap.bitmapdata}},y
|
|
||||||
sbc #0
|
|
||||||
sta {{$2}},x
|
|
||||||
|
|
||||||
ldy {{<colormap}}
|
|
||||||
lda {{<Colormap.colormapdata}},y
|
|
||||||
sec
|
|
||||||
sbc {{$11}}
|
|
||||||
sta {{$4}},x
|
|
||||||
lda {{>Colormap.colormapdata}},y
|
|
||||||
sbc #0
|
|
||||||
sta {{$6}},x
|
|
||||||
|
|
||||||
lda {{<height}}
|
|
||||||
sta {{$8}},x
|
|
||||||
lda {{<ypos}}
|
|
||||||
sta {{$10}},x
|
|
||||||
---
|
|
||||||
on preframe do once [Sprite,HasBitmap,HasColormap,HasYpos]
|
|
||||||
---
|
|
||||||
; L0 L1 H0 H1 -> L0 H0 L1 H1
|
|
||||||
lda {{$1}}
|
|
||||||
ldy {{$2}}
|
|
||||||
sty {{$1}}
|
|
||||||
sta {{$2}}
|
|
||||||
lda {{$5}}
|
|
||||||
ldy {{$6}}
|
|
||||||
sty {{$5}}
|
|
||||||
sta {{$6}}
|
|
||||||
---
|
|
||||||
on kernel do once [Kernel]
|
|
||||||
---
|
|
||||||
lda {{<bgcolor}}
|
|
||||||
sta COLUBK
|
|
||||||
ldy {{<lines}}
|
|
||||||
@LVScan:
|
|
||||||
lda {{$8}} ; height
|
|
||||||
dcp {{$10}} ; ypos
|
|
||||||
bcs @DoDraw1
|
|
||||||
lda #0
|
|
||||||
.byte $2C
|
|
||||||
@DoDraw1:
|
|
||||||
lda ({{$0}}),y
|
|
||||||
sta WSYNC
|
|
||||||
sta GRP0
|
|
||||||
lda ({{$4}}),y
|
|
||||||
sta COLUP0
|
|
||||||
|
|
||||||
lda {{$9}} ; height
|
|
||||||
dcp {{$11}} ; ypos
|
|
||||||
bcs @DoDraw2
|
|
||||||
lda #0
|
|
||||||
.byte $2C
|
|
||||||
@DoDraw2:
|
|
||||||
lda ({{$2}}),y
|
|
||||||
sta GRP1
|
|
||||||
lda ({{$6}}),y
|
|
||||||
sta COLUP1
|
|
||||||
|
|
||||||
dey ; decrement
|
|
||||||
bne @LVScan ; repeat until 192 lines
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system SetXPos
|
|
||||||
on preframe do each [Sprite,HasXpos] emit (SetHorizPos)
|
|
||||||
---
|
|
||||||
lda {{<xpos}}
|
|
||||||
ldy {{<plyrindex}}
|
|
||||||
sta HMCLR
|
|
||||||
jsr {{^SetHorizPos}}
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system SetHorizPos
|
|
||||||
on SetHorizPos do once [HasXpos]
|
|
||||||
---
|
|
||||||
; SetHorizPos routine
|
|
||||||
; A = X coordinate
|
|
||||||
; Y = player number (0 or 1)
|
|
||||||
SetHorizPos:
|
|
||||||
sta WSYNC ; start a new line
|
|
||||||
sec ; set carry flag
|
|
||||||
nop
|
|
||||||
@DivideLoop:
|
|
||||||
sbc #15 ; subtract 15
|
|
||||||
bcs @DivideLoop ; branch until negative
|
|
||||||
eor #7 ; calculate fine offset
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
sta RESP0,y ; fix coarse position
|
|
||||||
sta HMP0,y ; set fine offset
|
|
||||||
sta WSYNC
|
|
||||||
sta HMOVE
|
|
||||||
rts ; return to caller
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system JoyRead
|
|
||||||
locals 1
|
|
||||||
on postframe do once [Player]
|
|
||||||
---
|
|
||||||
lda SWCHA
|
|
||||||
sta {{$0}}
|
|
||||||
---
|
|
||||||
on postframe do each [Player] emit (joyup, joydown, joyleft, joyright, joybutton)
|
|
||||||
---
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveRight}}
|
|
||||||
{{!joyright}}
|
|
||||||
{{@SkipMoveRight}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveLeft}}
|
|
||||||
{{!joyleft}}
|
|
||||||
{{@SkipMoveLeft}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveDown}}
|
|
||||||
{{!joydown}}
|
|
||||||
{{@SkipMoveDown}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveUp}}
|
|
||||||
{{!joyup}}
|
|
||||||
{{@SkipMoveUp}}:
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system MoveJoyX
|
|
||||||
on joyleft do source [HasXpos]
|
|
||||||
---
|
|
||||||
lda {{<xpos}}
|
|
||||||
sec
|
|
||||||
sbc #1
|
|
||||||
bcc {{@nomove}}
|
|
||||||
sta {{<xpos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
---
|
|
||||||
on joyright do source [HasXpos]
|
|
||||||
---
|
|
||||||
lda {{<xpos}}
|
|
||||||
clc
|
|
||||||
adc #1
|
|
||||||
cmp #150
|
|
||||||
bcs {{@nomove}}
|
|
||||||
sta {{<xpos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
system MoveJoyY
|
|
||||||
on joyup do source [HasYpos]
|
|
||||||
---
|
|
||||||
lda {{<ypos}}
|
|
||||||
sec
|
|
||||||
sbc #1
|
|
||||||
bcc {{@nomove}}
|
|
||||||
sta {{<ypos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
---
|
|
||||||
on joydown do source [HasYpos]
|
|
||||||
---
|
|
||||||
lda {{<ypos}}
|
|
||||||
clc
|
|
||||||
adc #1
|
|
||||||
cmp #150
|
|
||||||
bcs {{@nomove}}
|
|
||||||
sta {{<ypos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
---
|
|
||||||
end
|
|
||||||
|
|
||||||
scope Main
|
|
||||||
entity Kernel [Kernel]
|
|
||||||
const lines = 192
|
|
||||||
const bgcolor = 0xa2
|
|
||||||
end
|
|
||||||
entity Bitmap1 [Bitmap]
|
|
||||||
const bitmapdata = [1, 1, 3, 7, 15, 31, 63, 127]
|
|
||||||
end
|
|
||||||
entity Bitmap2 [Bitmap]
|
|
||||||
const bitmapdata = [$18,$3e,$ff,$ff,$ff,$ff,$3e,$18]
|
|
||||||
end
|
|
||||||
entity Colormap1 [Colormap]
|
|
||||||
const colormapdata = [6, 3, 6, 9, 12, 14, 31, 63]
|
|
||||||
end
|
|
||||||
entity Player0 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
|
|
||||||
const plyrindex = 0
|
|
||||||
init height = 8
|
|
||||||
init xpos = 50
|
|
||||||
init ypos = 50
|
|
||||||
end
|
|
||||||
entity Player1 [Sprite,HasBitmap,HasColormap,HasXpos,HasYpos,Player]
|
|
||||||
const plyrindex = 1
|
|
||||||
init height = 8
|
|
||||||
init xpos = 100
|
|
||||||
init ypos = 60
|
|
||||||
init bitmap = #Bitmap2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -540,6 +540,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<script src="src/codemirror/basic.js"></script>
|
<script src="src/codemirror/basic.js"></script>
|
||||||
<script src="src/codemirror/wiz.js"></script>
|
<script src="src/codemirror/wiz.js"></script>
|
||||||
<script src="src/codemirror/vasm.js"></script>
|
<script src="src/codemirror/vasm.js"></script>
|
||||||
|
<script src="src/codemirror/ecs.js"></script>
|
||||||
<link rel="stylesheet" href="css/codemirror.css">
|
<link rel="stylesheet" href="css/codemirror.css">
|
||||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
<script src="codemirror/addon/search/search.js"></script>
|
<script src="codemirror/addon/search/search.js"></script>
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||||
|
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||||
|
|
||||||
|
(function (mod) {
|
||||||
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
|
mod(require("../../lib/codemirror"));
|
||||||
|
else if (typeof define == "function" && define.amd) // AMD
|
||||||
|
define(["../../lib/codemirror"], mod);
|
||||||
|
else // Plain browser env
|
||||||
|
mod(CodeMirror);
|
||||||
|
})(function (CodeMirror) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// 6502 DASM syntax
|
||||||
|
|
||||||
|
CodeMirror.defineMode('ecs', function (_config, parserConfig) {
|
||||||
|
var keywords1, keywords2;
|
||||||
|
|
||||||
|
var directives_list = [
|
||||||
|
'component', 'system', 'entity', 'scope', 'end',
|
||||||
|
'const', 'init', 'locals',
|
||||||
|
'on', 'do', 'emit',
|
||||||
|
'once', 'foreach', 'source',
|
||||||
|
];
|
||||||
|
var keywords_list = [
|
||||||
|
'processor',
|
||||||
|
'byte', 'word', 'long',
|
||||||
|
'include', 'seg', 'dc', 'ds', 'dv', 'hex', 'err', 'org', 'rorg', 'echo', 'rend',
|
||||||
|
'align', 'subroutine', 'equ', 'eqm', 'set', 'mac', 'endm', 'mexit', 'ifconst',
|
||||||
|
'ifnconst', 'if', 'else', 'endif', 'eif', 'repeat', 'repend'
|
||||||
|
];
|
||||||
|
|
||||||
|
var directives = new Map();
|
||||||
|
directives_list.forEach(function (s) { directives.set(s, 'def'); });
|
||||||
|
keywords_list.forEach(function (s) { directives.set(s, 'keyword'); });
|
||||||
|
|
||||||
|
var opcodes = /^[a-z][a-z][a-z]\b/i;
|
||||||
|
var numbers = /^(0x[\da-f]+|[\da-f]+h|[0-7]+o|[01]+b|\d+d?)\b/i;
|
||||||
|
var tags = /^\{\{.*\}\}/;
|
||||||
|
var mlcomment = /^---.+?---\b/i;
|
||||||
|
|
||||||
|
return {
|
||||||
|
startState: function () {
|
||||||
|
return {
|
||||||
|
context: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
token: function (stream, state) {
|
||||||
|
if (stream.eatSpace())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (stream.match(tags)) {
|
||||||
|
return 'meta';
|
||||||
|
}
|
||||||
|
|
||||||
|
var w;
|
||||||
|
if (stream.eatWhile(/\w/)) {
|
||||||
|
w = stream.current();
|
||||||
|
var cur = w.toLowerCase();
|
||||||
|
var style = directives.get(cur);
|
||||||
|
if (style)
|
||||||
|
return style;
|
||||||
|
|
||||||
|
if (opcodes.test(w)) {
|
||||||
|
return 'keyword';
|
||||||
|
} else if (numbers.test(w)) {
|
||||||
|
return 'number';
|
||||||
|
} else if (w == 'comment') {
|
||||||
|
stream.match(mlcomment);
|
||||||
|
return 'comment';
|
||||||
|
}
|
||||||
|
} else if (stream.eat(';')) {
|
||||||
|
stream.skipToEnd();
|
||||||
|
return 'comment';
|
||||||
|
} else if (stream.eat('"')) {
|
||||||
|
while (w = stream.next()) {
|
||||||
|
if (w == '"')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (w == '\\')
|
||||||
|
stream.next();
|
||||||
|
}
|
||||||
|
return 'string';
|
||||||
|
} else if (stream.eat('\'')) {
|
||||||
|
if (stream.match(/\\?.'/))
|
||||||
|
return 'number';
|
||||||
|
} else if (stream.eat('$') || stream.eat('#')) {
|
||||||
|
if (stream.eatWhile(/[^;]/i))
|
||||||
|
return 'number';
|
||||||
|
} else if (stream.eat('%')) {
|
||||||
|
if (stream.eatWhile(/[01]/))
|
||||||
|
return 'number';
|
||||||
|
} else {
|
||||||
|
stream.next();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
CodeMirror.defineMIME("text/x-ecs", "ecs");
|
||||||
|
|
||||||
|
});
|
|
@ -152,7 +152,7 @@ export class ECSCompiler extends Tokenizer {
|
||||||
parseAction(): Action {
|
parseAction(): Action {
|
||||||
let event = this.expectIdent().str;
|
let event = this.expectIdent().str;
|
||||||
this.expectToken('do');
|
this.expectToken('do');
|
||||||
let select = this.expectTokens(['once', 'each', 'source']).str as SelectType; // TODO: type check?
|
let select = this.expectTokens(['once', 'foreach', 'source']).str as SelectType; // TODO: type check?
|
||||||
let query = this.parseQuery();
|
let query = this.parseQuery();
|
||||||
let emits;
|
let emits;
|
||||||
if (this.peekToken().str == 'emit') {
|
if (this.peekToken().str == 'emit') {
|
||||||
|
@ -183,6 +183,7 @@ export class ECSCompiler extends Tokenizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
parseCode(): string {
|
parseCode(): string {
|
||||||
|
// TODO: add $loc
|
||||||
let tok = this.expectTokenTypes([TokenType.CodeFragment]);
|
let tok = this.expectTokenTypes([TokenType.CodeFragment]);
|
||||||
let code = tok.str;
|
let code = tok.str;
|
||||||
let lines = code.split('\n');
|
let lines = code.split('\n');
|
||||||
|
|
|
@ -97,7 +97,7 @@ export interface Action {
|
||||||
emits?: string[];
|
emits?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SelectType = 'once' | 'each' | 'source';
|
export type SelectType = 'once' | 'foreach' | 'source';
|
||||||
|
|
||||||
export type DataValue = number | boolean | Uint8Array | Uint16Array;
|
export type DataValue = number | boolean | Uint8Array | Uint16Array;
|
||||||
|
|
||||||
|
@ -154,11 +154,11 @@ interface ComponentFieldPair {
|
||||||
export class Dialect_CA65 {
|
export class Dialect_CA65 {
|
||||||
readonly ASM_ITERATE_EACH = `
|
readonly ASM_ITERATE_EACH = `
|
||||||
ldx #0
|
ldx #0
|
||||||
{{@__each}}:
|
@__each:
|
||||||
{{code}}
|
{{code}}
|
||||||
inx
|
inx
|
||||||
cpx #{{ecount}}
|
cpx #{{ecount}}
|
||||||
bne {{@__each}}
|
bne @__each
|
||||||
`;
|
`;
|
||||||
readonly INIT_FROM_ARRAY = `
|
readonly INIT_FROM_ARRAY = `
|
||||||
ldy #{{nbytes}}
|
ldy #{{nbytes}}
|
||||||
|
@ -254,13 +254,15 @@ class Segment {
|
||||||
this.codefrags.push(code);
|
this.codefrags.push(code);
|
||||||
}
|
}
|
||||||
allocateBytes(name: string, bytes: number) {
|
allocateBytes(name: string, bytes: number) {
|
||||||
if (this.symbols[name]) return this.symbols[name]; // TODO: check size
|
let ofs = this.symbols[name];
|
||||||
let ofs = this.size;
|
if (ofs == null) {
|
||||||
this.symbols[name] = ofs;
|
ofs = this.size;
|
||||||
if (!this.ofs2sym.has(ofs))
|
this.symbols[name] = ofs;
|
||||||
this.ofs2sym.set(ofs, []);
|
if (!this.ofs2sym.has(ofs))
|
||||||
this.ofs2sym.get(ofs)?.push(name);
|
this.ofs2sym.set(ofs, []);
|
||||||
this.size += bytes;
|
this.ofs2sym.get(ofs)?.push(name);
|
||||||
|
this.size += bytes;
|
||||||
|
}
|
||||||
return ofs;
|
return ofs;
|
||||||
}
|
}
|
||||||
// TODO: optimize shared data
|
// TODO: optimize shared data
|
||||||
|
@ -388,7 +390,7 @@ export class EntityScope {
|
||||||
// variable size? make it a pointer
|
// variable size? make it a pointer
|
||||||
if (bits == 0) bits = 16; // TODO?
|
if (bits == 0) bits = 16; // TODO?
|
||||||
let rangelen = (f.ehi - f.elo + 1);
|
let rangelen = (f.ehi - f.elo + 1);
|
||||||
let bytesperelem = Math.ceil(bits / 8) * rangelen;
|
let bytesperelem = Math.ceil(bits / 8);
|
||||||
// TODO: packing bits
|
// TODO: packing bits
|
||||||
// TODO: split arrays
|
// TODO: split arrays
|
||||||
f.access = [];
|
f.access = [];
|
||||||
|
@ -419,7 +421,7 @@ export class EntityScope {
|
||||||
let hiofs = segment.allocateBytes(ptrhisym, entcount);
|
let hiofs = segment.allocateBytes(ptrhisym, entcount);
|
||||||
segment.initdata[loofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 0 };
|
segment.initdata[loofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 0 };
|
||||||
segment.initdata[hiofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 8 };
|
segment.initdata[hiofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 8 };
|
||||||
// TODO: } else if (v instanceof Uint16Array) {
|
// TODO: } else if (v instanceof Uint16Array) {
|
||||||
} else if (typeof v === 'number') {
|
} else if (typeof v === 'number') {
|
||||||
// more than 1 entity, add an array
|
// more than 1 entity, add an array
|
||||||
// TODO: what if > 8 bits?
|
// TODO: what if > 8 bits?
|
||||||
|
@ -428,6 +430,7 @@ export class EntityScope {
|
||||||
let datasym = this.dialect.fieldsymbol(c, f, 0);
|
let datasym = this.dialect.fieldsymbol(c, f, 0);
|
||||||
let base = segment.allocateBytes(datasym, entcount);
|
let base = segment.allocateBytes(datasym, entcount);
|
||||||
segment.initdata[base + e.id - fieldrange.elo] = v;
|
segment.initdata[base + e.id - fieldrange.elo] = v;
|
||||||
|
//console.error(cfname, datasym, base, e.id, fieldrange.elo, entcount, v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ECSError(`unhandled constant ${e.id}:${cfname}`);
|
throw new ECSError(`unhandled constant ${e.id}:${cfname}`);
|
||||||
|
@ -524,17 +527,20 @@ export class EntityScope {
|
||||||
}
|
}
|
||||||
replaceCode(code: string, sys: System, action: Action): string {
|
replaceCode(code: string, sys: System, action: Action): string {
|
||||||
const re = /\{\{(.+?)\}\}/g;
|
const re = /\{\{(.+?)\}\}/g;
|
||||||
let label = sys.name + '_' + action.event;
|
let label = `${sys.name}__${action.event}`;
|
||||||
let atypes = this.em.archetypesMatching(action.query);
|
let atypes = this.em.archetypesMatching(action.query);
|
||||||
let entities = this.entitiesMatching(atypes);
|
let entities = this.entitiesMatching(atypes);
|
||||||
// TODO: detect cycles
|
// TODO: detect cycles
|
||||||
// TODO: "source"?
|
// TODO: "source"?
|
||||||
// TODO: what if only 1 item?
|
// TODO: what if only 1 item?
|
||||||
if (action.select == 'each') {
|
if (action.select == 'foreach') {
|
||||||
code = this.wrapCodeInLoop(code, sys, action, entities);
|
code = this.wrapCodeInLoop(code, sys, action, entities);
|
||||||
//console.log(sys.name, action.event, ents);
|
//console.log(sys.name, action.event, ents);
|
||||||
//frag = this.iterateCode(frag);
|
//frag = this.iterateCode(frag);
|
||||||
}
|
}
|
||||||
|
// replace @labels
|
||||||
|
code = code.replace(/@(\w+)\b/g, (s: string, a: string) => `${label}__${a}`);
|
||||||
|
// replace {{...}} tags
|
||||||
return code.replace(re, (entire, group: string) => {
|
return code.replace(re, (entire, group: string) => {
|
||||||
let cmd = group.charAt(0);
|
let cmd = group.charAt(0);
|
||||||
let rest = group.substring(1);
|
let rest = group.substring(1);
|
||||||
|
|
|
@ -114,7 +114,8 @@ const TOOL_TO_SOURCE_STYLE = {
|
||||||
'silice': 'verilog',
|
'silice': 'verilog',
|
||||||
'wiz': 'text/x-wiz',
|
'wiz': 'text/x-wiz',
|
||||||
'vasmarm': 'vasm',
|
'vasmarm': 'vasm',
|
||||||
'armips': 'vasm'
|
'armips': 'vasm',
|
||||||
|
'ecs': 'ecs',
|
||||||
}
|
}
|
||||||
|
|
||||||
const TOOL_TO_HELPURL = {
|
const TOOL_TO_HELPURL = {
|
||||||
|
|
|
@ -36,6 +36,7 @@ const MODEDEFS = {
|
||||||
markdown: { lineWrap: true },
|
markdown: { lineWrap: true },
|
||||||
fastbasic: { noGutters: true },
|
fastbasic: { noGutters: true },
|
||||||
basic: { noLineNumbers: true, noGutters: true }, // TODO: not used?
|
basic: { noLineNumbers: true, noGutters: true }, // TODO: not used?
|
||||||
|
ecs: { theme: 'mbo', isAsm: false },
|
||||||
}
|
}
|
||||||
|
|
||||||
export var textMapFunctions = {
|
export var textMapFunctions = {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ECSCompiler } from "../common/ecs/compiler";
|
||||||
import { Dialect_CA65, EntityManager, SourceFileExport } from "../common/ecs/ecs";
|
import { Dialect_CA65, EntityManager, SourceFileExport } from "../common/ecs/ecs";
|
||||||
|
|
||||||
const TEMPLATE1 = `
|
const TEMPLATE1 = `
|
||||||
{{@NextFrame}}:
|
@NextFrame:
|
||||||
FRAME_START
|
FRAME_START
|
||||||
{{!preframe}}
|
{{!preframe}}
|
||||||
KERNEL_START
|
KERNEL_START
|
||||||
|
@ -15,74 +15,12 @@ const TEMPLATE1 = `
|
||||||
bcs @NoStart
|
bcs @NoStart
|
||||||
jmp Start
|
jmp Start
|
||||||
@NoStart:
|
@NoStart:
|
||||||
jmp {{@NextFrame}}
|
jmp @NextFrame
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// TODO: two sticks?
|
|
||||||
const TEMPLATE2_a = `
|
|
||||||
lda SWCHA
|
|
||||||
sta {{$0}}
|
|
||||||
`
|
|
||||||
|
|
||||||
const TEMPLATE2_b = `
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveRight}}
|
|
||||||
{{!joyright}}
|
|
||||||
{{@SkipMoveRight}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveLeft}}
|
|
||||||
{{!joyleft}}
|
|
||||||
{{@SkipMoveLeft}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveDown}}
|
|
||||||
{{!joydown}}
|
|
||||||
{{@SkipMoveDown}}:
|
|
||||||
asl {{$0}}
|
|
||||||
bcs {{@SkipMoveUp}}
|
|
||||||
{{!joyup}}
|
|
||||||
{{@SkipMoveUp}}:
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TEMPLATE3_L = `
|
|
||||||
lda {{<xpos}}
|
|
||||||
sec
|
|
||||||
sbc #1
|
|
||||||
bcc {{@nomove}}
|
|
||||||
sta {{<xpos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TEMPLATE3_R = `
|
|
||||||
lda {{<xpos}}
|
|
||||||
clc
|
|
||||||
adc #1
|
|
||||||
cmp #150
|
|
||||||
bcs {{@nomove}}
|
|
||||||
sta {{<xpos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TEMPLATE3_U = `
|
|
||||||
lda {{<ypos}}
|
|
||||||
sec
|
|
||||||
sbc #1
|
|
||||||
bcc {{@nomove}}
|
|
||||||
sta {{<ypos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TEMPLATE3_D = `
|
|
||||||
lda {{<ypos}}
|
|
||||||
clc
|
|
||||||
adc #1
|
|
||||||
cmp #150
|
|
||||||
bcs {{@nomove}}
|
|
||||||
sta {{<ypos}}
|
|
||||||
{{@nomove}}:
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TEMPLATE4_S1 = `
|
const TEMPLATE4_S1 = `
|
||||||
.macro {{@KernelSetup}} ent,ofs
|
.macro @KernelSetup ent,ofs
|
||||||
lda #192 ; TODO: numlines
|
lda #192 ; TODO: numlines
|
||||||
sec
|
sec
|
||||||
sbc ypos_ypos_b0+ent
|
sbc ypos_ypos_b0+ent
|
||||||
|
@ -113,8 +51,8 @@ const TEMPLATE4_S1 = `
|
||||||
.endmacro
|
.endmacro
|
||||||
`
|
`
|
||||||
const TEMPLATE4_S2 = `
|
const TEMPLATE4_S2 = `
|
||||||
{{@KernelSetup}} 0,0
|
@KernelSetup 0,0
|
||||||
{{@KernelSetup}} 1,6
|
@KernelSetup 1,6
|
||||||
`
|
`
|
||||||
|
|
||||||
// https://atariage.com/forums/topic/75982-skipdraw-and-graphics/?tab=comments#comment-928232
|
// https://atariage.com/forums/topic/75982-skipdraw-and-graphics/?tab=comments#comment-928232
|
||||||
|
@ -261,12 +199,6 @@ function testECS() {
|
||||||
{ name: 'ypos', dtype: 'int', lo: 0, hi: 255 }
|
{ name: 'ypos', dtype: 'int', lo: 0, hi: 255 }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
let c_xyvel = em.defineComponent({
|
|
||||||
name: 'xyvel', fields: [
|
|
||||||
{ name: 'xvel', dtype: 'int', lo: -8, hi: 7 },
|
|
||||||
{ name: 'yvel', dtype: 'int', lo: -8, hi: 7 }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
// init -> [start] -> frameloop
|
// init -> [start] -> frameloop
|
||||||
// frameloop -> [preframe] [kernel] [postframe]
|
// frameloop -> [preframe] [kernel] [postframe]
|
||||||
|
@ -299,7 +231,7 @@ function testECS() {
|
||||||
name: 'set_xpos',
|
name: 'set_xpos',
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
text: SET_XPOS, event: 'preframe', select: 'each', query: {
|
text: SET_XPOS, event: 'preframe', select: 'foreach', query: {
|
||||||
include: ['sprite', 'xpos']
|
include: ['sprite', 'xpos']
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -314,29 +246,6 @@ function testECS() {
|
||||||
emits: ['preframe', 'kernel', 'postframe'] }
|
emits: ['preframe', 'kernel', 'postframe'] }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
em.defineSystem({
|
|
||||||
name: 'joyread',
|
|
||||||
tempbytes: 1,
|
|
||||||
actions: [
|
|
||||||
{ text: TEMPLATE2_a, event: 'postframe', select: 'once', query: { include: ['player'] } },
|
|
||||||
{ text: TEMPLATE2_b, event: 'postframe', select: 'each', query: { include: ['player'] },
|
|
||||||
emits: ['joyup', 'joydown', 'joyleft', 'joyright', 'joybutton'] }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
em.defineSystem({
|
|
||||||
name: 'move_x',
|
|
||||||
actions: [
|
|
||||||
{ text: TEMPLATE3_L, event: 'joyleft', select: 'source', query: { include: ['player', 'xpos'] }, },
|
|
||||||
{ text: TEMPLATE3_R, event: 'joyright', select: 'source', query: { include: ['player', 'xpos'] }, },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
em.defineSystem({
|
|
||||||
name: 'move_y',
|
|
||||||
actions: [
|
|
||||||
{ text: TEMPLATE3_U, event: 'joyup', select: 'source', query: { include: ['player', 'ypos'] } },
|
|
||||||
{ text: TEMPLATE3_D, event: 'joydown', select: 'source', query: { include: ['player', 'ypos'] } },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
em.defineSystem({
|
em.defineSystem({
|
||||||
name: 'SetHorizPos',
|
name: 'SetHorizPos',
|
||||||
actions: [
|
actions: [
|
||||||
|
|
Loading…
Reference in New Issue