diff --git a/SMILEBASIC/TEST.txt b/SMILEBASIC/TEST.txt index 6fa6adf..120f75b 100644 --- a/SMILEBASIC/TEST.txt +++ b/SMILEBASIC/TEST.txt @@ -1,3 +1,13 @@ +DEF TESST X,A$ + IF Y<0 THEN Y=28 + IF X<0 THEN X=20-(LEN(A$)/2) + AA + ?X + END + DEF AA + X=999 + END + TESST -1,"AAAAAAAAAAAAAAAAAAAA" ASSERT__ FLOOR(0.5)==0, "FLOOR" ASSERT__ FLOOR(1)==1, "FLOOR" ASSERT__ FLOOR(1.5)==1, "FLOOR" diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 877e26f..071b162 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -706,7 +706,7 @@ class GosubExpr : Code { Value label; vm.pop(label); - if(!label.isString) + if(label.isString) { vm.push(Value(vm.pc)); vm.pc = vm.globalLabel[label.castString] - 1; diff --git a/SMILEBASIC/bg.d b/SMILEBASIC/bg.d index 2e99c1a..ef2b579 100644 --- a/SMILEBASIC/bg.d +++ b/SMILEBASIC/bg.d @@ -132,4 +132,17 @@ class BG { this.r = rot; } + void fill(int x, int y, int x2, int y2, int screendata) + { + import std.algorithm; + int id = screendata & 4095; + if(x > x2) swap(x, x2); + if(y > y2) swap(y, y2); + for(; y <= y2; y++) + chip[x + y * width .. x2 + y * width] = BGChip(id); + /*for(int i = x; i <= x2; i++) + { + chip[i + y * width].i = id; + }*/ + } } diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 89c74f7..d179289 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -274,6 +274,11 @@ class BuiltinFunction color.setDefaultValue(p.gcolor); p.gfill(p.useGRP, x, y, x2, y2, cast(int)color); } + static void GCIRCLE(PetitComputer p, Value[]) + { + //color.setDefaultValue(p.gcolor); + //p.gfill(p.useGRP, x, y, x2, y2, cast(int)color); + } static void GCOLOR(PetitComputer p, int color) { p.gcolor = color; @@ -546,17 +551,49 @@ class BuiltinFunction //TODO:配列 auto args = retro(va_args); int no = args[0].castInteger; - double[] animdata = new double[args.length - 2]; - int i; - foreach(a; args[2..$]) + double[] animdata; + if(args[2].isString) { - animdata[i++] = a.castDouble; + VM vm = p.vm; + vm.pushDataIndex(); + vm.restoreData(args[2].castString); + int keyframe = vm.readData.castInteger; + auto target = p.sprite.getSpriteAnimTarget(args[1].castString); + int item = 2; + if((target & 7) == SpriteAnimTarget.XY || (target & 7) == SpriteAnimTarget.UV) item++; + animdata = new double[item * keyframe + 1]; + int j; + for(int i = 0; i < keyframe; i++) + { + animdata[j] = vm.readData.castDouble; + animdata[j + 1] = vm.readData.castDouble; + if(item == 3) + animdata[j + 2] = vm.readData.castDouble; + j += item; + } + if(args.length > 2) + animdata[j] = args[3].castInteger; + vm.popDataIndex(); + } + else + { + int i; + animdata = new double[args.length - 2]; + foreach(a; args[2..$]) + { + animdata[i++] = a.castDouble; + } } if(args[1].isString) p.sprite.spanim(no, args[1].castString, animdata); if(args[1].isNumber) p.sprite.spanim(no, cast(SpriteAnimTarget)(args[1].castInteger), animdata); } + @StartOptional("W") + static void SPDEF(PetitComputer p, int id, out int U, out int V, out int W, out int H, out int HX, out int HY, out int A) + { + p.sprite.getspdef(id, U, V, W, H, HX, HY, A); + } static void SPDEF(PetitComputer p, Value[] va_args) { switch(va_args.length) @@ -687,6 +724,18 @@ class BuiltinFunction { return p.sprite.sphitsp(id, min, max); } + static void SPVAR(PetitComputer p, int id, int var, double val) + { + p.sprite.spvar(id, var, val); + } + static double SPVAR(PetitComputer p, int id, int var) + { + return p.sprite.spvar(id, var); + } + static int SPCHK(PetitComputer p, int id) + { + return p.sprite.spchk(id); + } static void BGMSTOP(PetitComputer p) { writeln("NOTIMPL:BGMSTOP"); @@ -827,6 +876,10 @@ class BuiltinFunction { p.getBG(layer).rot(rot); } + static void BGFILL(PetitComputer p, int layer, int x, int y, int x2, int y2, int screendata) + { + p.getBG(layer).fill(x, y, x2, y2, screendata); + } static void EFCON() { } diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index c146ef2..d1f84a7 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -213,6 +213,15 @@ class Compiler } void genCodePushVar(wstring name, Scope sc) { + if(sc.func) + { + auto local = sc.func.hasLocalVarIndex(name); + if(local) + { + code ~= new PushL(local); + return; + } + } auto global = hasGlobalVarIndex(name); if(global) { @@ -233,6 +242,15 @@ class Compiler } void genCodePopVar(wstring name, Scope sc) { + if(sc.func) + { + auto local = sc.func.hasLocalVarIndex(name); + if(local) + { + code ~= new PopL(local); + return; + } + } auto global = hasGlobalVarIndex(name); if(global) { @@ -821,7 +839,10 @@ class Compiler auto assign = cast(ArrayAssign)i; compileExpression(assign.assignExpression, s); compileExpression(assign.indexExpression, s); - genCode(new PopArray(getGlobalVarIndex(assign.name), cast(int)assign.indexExpression.expressions.length, !(s.func is null))); + int index; + bool local; + getVarIndex(assign.name, s, index, local); + genCode(new PopArray(index, cast(int)assign.indexExpression.expressions.length, local)); } break; case NodeType.CallFunctionStatement: diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index eee0d1e..4c938ed 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -739,6 +739,14 @@ class Parser void syntaxError() { stderr.writeln("Syntax error (", lex.getLine(), ')', " Mysterious ", lex.front().type); + try + { + throw new Exception("Stacktrace"); + } + catch(Exception e) + { + writeln(e); + } } //statement Statement statement() @@ -768,6 +776,7 @@ class Parser //命令呼び出し auto func = new CallFunctionStatement(name); node = func; + bool oldcomma; while(true) { token = lex.front(); @@ -781,11 +790,12 @@ class Parser else { auto expr = expression(); - if(expr) + if(expr || oldcomma || lex.front.type == TokenType.Comma)//if(expr) func.addArg(expr); } if(lex.front().type == TokenType.Out) break; if(lex.front().type != TokenType.Comma) break; + oldcomma = true; lex.popFront(); } if(lex.front().type == TokenType.Out) @@ -810,8 +820,9 @@ class Parser break; } } + return node; } - break; + //break; case TokenType.Colon: case TokenType.NewLine: break; diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 1a25c46..6372fe0 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -156,6 +156,8 @@ class PetitComputer int consoleHeight; int consoleWidthDisplay1; int consoleHeightDisplay1; + int consoleWidth4; + int consoleHeight4; int consoleHeightC, consoleWidthC; ConsoleCharacter[][] consoleC; int[] consoleColor = @@ -198,6 +200,7 @@ class PetitComputer Button button; ConsoleCharacter[][] console; ConsoleCharacter[][] consoleDisplay1; + ConsoleCharacter[][] console4; bool visibleGRP = true; private int[2] showPage = [0, 1]; private int[2] usePage = [0, 1]; @@ -391,8 +394,11 @@ class PetitComputer consoleHeight = screenHeight / fontHeight; consoleWidthDisplay1 = screenWidthDisplay1 / fontWidth; consoleHeightDisplay1 = screenHeightDisplay1 / fontHeight; + consoleWidth4 = 320 / fontWidth; + consoleHeight4 = 480 / fontHeight; console = new ConsoleCharacter[][consoleHeight]; consoleDisplay1 = new ConsoleCharacter[][consoleHeightDisplay1]; + console4 = new ConsoleCharacter[][consoleHeight4]; consoleForeColor = 15;//#T_WHITE for(int i = 0; i < console.length; i++) { @@ -404,11 +410,23 @@ class PetitComputer consoleDisplay1[i] = new ConsoleCharacter[consoleWidthDisplay1]; consoleDisplay1[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor); } + for(int i = 0; i < console4.length; i++) + { + console4[i] = new ConsoleCharacter[consoleWidth4]; + console4[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor); + } display(0); } void display(int number) { displaynum = number; + if(xscreenmode == 2) + { + consoleHeightC = consoleHeight4; + consoleWidthC = consoleWidth4; + consoleC = console4; + return; + } if(number) { consoleHeightC = consoleHeightDisplay1; @@ -422,9 +440,9 @@ class PetitComputer } void cls() { - for(int i = 0; i < console.length; i++) + for(int i = 0; i < consoleC.length; i++) { - console[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor); + consoleC[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor); } CSRX = 0; CSRY = 0; @@ -721,6 +739,7 @@ class PetitComputer this.bgmax = bg; //BG int mode2 = mode / 2; + xscreenmode = mode2; if(mode2 == 0) { SDL_SetWindowSize(window, 400, 240); @@ -732,8 +751,8 @@ class PetitComputer if(mode == 4) { SDL_SetWindowSize(window, 320, 240 * 2); + display(0); } - xscreenmode = mode2; } BG getBG(int layer) { @@ -768,12 +787,6 @@ class PetitComputer DerelictGL.load(); DerelictGL3.load(); - buttonTable = new Button[SDL_SCANCODE_SLEEP + 1]; - buttonTable[SDL_SCANCODE_UP] = Button.UP; - buttonTable[SDL_SCANCODE_DOWN] = Button.DOWN; - buttonTable[SDL_SCANCODE_LEFT] = Button.LEFT; - buttonTable[SDL_SCANCODE_RIGHT] = Button.RIGHT; - buttonTable[SDL_SCANCODE_SPACE] = Button.A; bool renderprofile;//e = true; try { @@ -787,6 +800,12 @@ class PetitComputer window = SDL_CreateWindow("SMILEBASIC", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 400, 240, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + buttonTable = new Button[SDL_SCANCODE_SLEEP + 1]; + buttonTable[SDL_SCANCODE_UP] = Button.UP; + buttonTable[SDL_SCANCODE_DOWN] = Button.DOWN; + buttonTable[SDL_SCANCODE_LEFT] = Button.LEFT; + buttonTable[SDL_SCANCODE_RIGHT] = Button.RIGHT; + buttonTable[SDL_SCANCODE_SPACE] = Button.A; if(!window) { write("can't create window: "); @@ -1004,6 +1023,7 @@ class PetitComputer catch(Throwable t) { writeln(t); + readln(); } } SDL_Window* window; @@ -1031,11 +1051,11 @@ class PetitComputer { parser = new Parser( //readText("./SYS/GAME6TALK.TXT").to!wstring - //readText("./SYS/GAME4SHOOTER.TXT").to!wstring + readText("./SYS/GAME4SHOOTER.TXT").to!wstring //readText("./SYS/GAME2RPG.TXT").to!wstring //readText("./SYS/GAME1DOTRC.TXT").to!wstring //readText(input("LOAD PROGRAM:", true).to!string).to!wstring - readText("./SYS/EX8TECDEMO.TXT").to!wstring + //readText("./SYS/EX8TECDEMO.TXT").to!wstring //readText("./SYS/EX1TEXT.TXT").to!wstring //readText("FIZZBUZZ.TXT").to!wstring //readText("TEST.TXT").to!wstring @@ -1430,10 +1450,10 @@ class PetitComputer glBindTexture(GL_TEXTURE_2D, GRPF.glTexture); glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); - for(int y = 0; y < consoleHeight; y++) - for(int x = 0; x < consoleWidth; x++) + for(int y = 0; y < consoleHeight4; y++) + for(int x = 0; x < consoleWidth4; x++) { - auto back = consoleColorGL[console[y][x].backColor]; + auto back = consoleColorGL[console4[y][x].backColor]; glColor4ubv(cast(ubyte*)&back); glVertex3f((x * 8) / 160f - 1, 1 - (y * 8 + 8) / 240f, 0.9f); glVertex3f((x * 8) / 160f - 1, 1 - (y * 8) / 240f, 0.9f); @@ -1452,20 +1472,21 @@ class PetitComputer glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); - for(int y = 0; y < consoleHeight; y++) - for(int x = 0; x < consoleWidth; x++) + for(int y = 0; y < consoleHeight4; y++) + for(int x = 0; x < consoleWidth4; x++) { - auto fore = consoleColorGL[console[y][x].foreColor]; - auto rect = &fontTable[console[y][x].character]; + auto fore = consoleColorGL[console4[y][x].foreColor]; + auto rect = &fontTable[console4[y][x].character]; glColor4ubv(cast(ubyte*)&fore); + float z = console4[y][x].z / 1025f; glTexCoord2f((rect.x) / 512f - 1 , (rect.y + 8) / 512f - 1); - glVertex3f((x * 8) / 160f - 1, 1 - (y * 8 + 8) / 240f, 0); + glVertex3f((x * 8) / 160f - 1, 1 - (y * 8 + 8) / 240f, z); glTexCoord2f((rect.x) / 512f - 1, (rect.y) / 512f - 1); - glVertex3f((x * 8) / 160f - 1, 1 - (y * 8) / 240f, 0); + glVertex3f((x * 8) / 160f - 1, 1 - (y * 8) / 240f, z); glTexCoord2f((rect.x + 8) / 512f - 1, (rect.y) / 512f - 1); - glVertex3f((x * 8 + 8) / 160f - 1, 1 - (y * 8) / 240f, 0); + glVertex3f((x * 8 + 8) / 160f - 1, 1 - (y * 8) / 240f, z); glTexCoord2f((rect.x + 8) / 512f - 1, (rect.y +8) / 512f - 1); - glVertex3f((x * 8 + 8) / 160f - 1, 1 - (y * 8 + 8) / 240f, 0); + glVertex3f((x * 8 + 8) / 160f - 1, 1 - (y * 8 + 8) / 240f, z); } glEnd(); return; diff --git a/SMILEBASIC/sprite.d b/SMILEBASIC/sprite.d index 3d818e7..b6e04d7 100644 --- a/SMILEBASIC/sprite.d +++ b/SMILEBASIC/sprite.d @@ -252,10 +252,10 @@ struct SpriteData this.defno = defno; col = SpriteCollision(&this); } - SpriteAnimData[][SpriteAnimTarget.V] anim; - int[SpriteAnimTarget.V] animindex; - int[SpriteAnimTarget.V] animloop; - int[SpriteAnimTarget.V] animloopcnt; + SpriteAnimData[][SpriteAnimTarget.V + 1] anim; + int[SpriteAnimTarget.V + 1] animindex; + int[SpriteAnimTarget.V + 1] animloop; + int[SpriteAnimTarget.V + 1] animloopcnt; void setAnimation(SpriteAnimData[] anim, SpriteAnimTarget sat, int loop) { this.anim[sat] = anim; @@ -321,6 +321,16 @@ class Sprite { this.SPDEFTable[] = (this.defSPDEFTable)[]; } + void getspdef(int id, out int U, out int V, out int W, out int H, out int HX, out int HY, out int A) + { + U = SPDEFTable[id].u; + V = SPDEFTable[id].v; + W = SPDEFTable[id].w; + H = SPDEFTable[id].h; + HX= SPDEFTable[id].hx; + HY= SPDEFTable[id].hy; + A = SPDEFTable[id].a; + } void spchr(int i, int d) { i = spid(i); @@ -702,13 +712,31 @@ class Sprite auto spdef = SpriteDef(u, v, w, h, 0, 0, attr); sprites[id] = SpriteData(id, spdef, 0/*要調査*/); } + int spchk(int id) + { + id = spid(id); + int state; + for(int i = 0; i <= SpriteAnimTarget.V; i++) + { + if(sprites[id].anim[i]) + { + state |= 1 << i; + } + } + return state; + } void spofs(int id, double x, double y) { + //animeとめる id = spid(id); sprites[id].x = x; sprites[id].y = y; sprites[id].linkx = cast(int)(x + (sprites[id].parent ? sprites[id].parent.linkx : 0)); sprites[id].linky = cast(int)(y + (sprites[id].parent ? sprites[id].parent.linky : 0)); + sprites[id].anim[SpriteAnimTarget.XY] = null; + sprites[id].animindex[SpriteAnimTarget.XY] = 0; + sprites[id].animloop[SpriteAnimTarget.XY] = 0; + sprites[id].animloopcnt[SpriteAnimTarget.XY] = 0; } void spofs(int id, double x, double y, int z) { @@ -719,6 +747,10 @@ class Sprite sprites[id].linkx = cast(int)(x + (sprites[id].parent ? sprites[id].parent.linkx : 0)); sprites[id].linky = cast(int)(y + (sprites[id].parent ? sprites[id].parent.linky : 0)); zChange = true; + sprites[id].anim[SpriteAnimTarget.XY] = null; + sprites[id].animindex[SpriteAnimTarget.XY] = 0; + sprites[id].animloop[SpriteAnimTarget.XY] = 0; + sprites[id].animloopcnt[SpriteAnimTarget.XY] = 0; } void getspofs(int id, out double x, out double y, out int z) { @@ -762,6 +794,16 @@ class Sprite "V": SpriteAnimTarget.V, ]; } + SpriteAnimTarget getSpriteAnimTarget(wstring target) + { + bool relative = false; + if(target[$ - 1..$] == "+") + { + target = target[0..$-1]; + relative = true; + } + return spriteAnimTarget[target] | (relative ? SpriteAnimTarget.relative : cast(SpriteAnimTarget)0); + } void spanim(int id, SpriteAnimTarget target, double[] data) { id = spid(id); @@ -916,4 +958,14 @@ class Sprite } return -1; } + void spvar(int id, int var, double val) + { + id = spid(id); + sprites[id].var[var] = val; + } + double spvar(int id, int var) + { + id = spid(id); + return sprites[id].var[var]; + } }