1
0

関数内でローカル変数やグローバル変数にアクセスできなかった問題を修正,BGFILL,SPCHK,SPVARなど実装

This commit is contained in:
otya128
2015-08-29 16:23:41 +09:00
parent d05166a3b9
commit 4525728dd5
8 changed files with 215 additions and 34 deletions

View File

@@ -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"

View File

@@ -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;

View File

@@ -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;
}*/
}
}

View File

@@ -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()
{
}

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;

View File

@@ -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];
}
}