1
0

GAME1が動くようになった

This commit is contained in:
otya128
2015-08-20 20:11:33 +09:00
parent 886be04289
commit 8e0a4e0ae4
8 changed files with 275 additions and 30 deletions

View File

@@ -1,4 +1,5 @@
DIM ARRY[10]
?ARRY[0],FORMAT$("%D",100)
GOSUB@A GOSUB@A
GOTO@B GOTO@B
'A=SIN(B) 'A=SIN(B)

View File

@@ -129,6 +129,7 @@ enum CodeType
GosubS, GosubS,
ReturnSubroutine, ReturnSubroutine,
OnS, OnS,
RestoreCodeS,
} }
abstract class Code abstract class Code
{ {
@@ -898,7 +899,14 @@ class CallBuiltinFunction : Code
result = vm.stack[vm.stacki/* - argcount */+ 1..vm.stacki + 1/* - argcount */+ outcount];//雑; result = vm.stack[vm.stacki/* - argcount */+ 1..vm.stacki + 1/* - argcount */+ outcount];//雑;
} }
func.func(vm.petitcomputer, arg, result); func.func(vm.petitcomputer, arg, result);
vm.stacki -= func.argments.length;// - outcount; if(func.variadic)
{
vm.stacki -= argcount;
}
else
{
vm.stacki -= func.argments.length;// - outcount;
}
////vm.stacki += outcount; ////vm.stacki += outcount;
//vm.stacki = old; //vm.stacki = old;
for(int i = 0; i < result.length; i++) for(int i = 0; i < result.length; i++)
@@ -1151,6 +1159,33 @@ class ReadCode : Code
} }
} }
} }
class RestoreCodeS : Code
{
wstring label;
this(wstring label)
{
this.label = label;
this.type = CodeType.RestoreCodeS;
}
override void execute(VM vm)
{
stderr.writeln("can't execute (compiler bug?)");
}
}
class RestoreCode : Code
{
int label;
DataTable datatable;
this(int label, DataTable datatable)
{
this.label = label;
this.datatable = datatable;
}
override void execute(VM vm)
{
datatable.dataIndex = label;
}
}
class PushSystemVariable : Code class PushSystemVariable : Code
{ {
SystemVariable var; SystemVariable var;

View File

@@ -6,6 +6,7 @@ import std.typetuple;
import std.traits; import std.traits;
import std.stdio; import std.stdio;
import std.ascii; import std.ascii;
import std.range;
import otya.smilebasic.error; import otya.smilebasic.error;
import otya.smilebasic.type; import otya.smilebasic.type;
import otya.smilebasic.petitcomputer; import otya.smilebasic.petitcomputer;
@@ -49,12 +50,15 @@ class BuiltinFunction
ValueType result; ValueType result;
void function(PetitComputer, Value[], Value[]) func; void function(PetitComputer, Value[], Value[]) func;
int startskip; int startskip;
this(BuiltinFunctionArgument[] argments, ValueType result, void function(PetitComputer, Value[], Value[]) func, int startskip) bool variadic;
this(BuiltinFunctionArgument[] argments, ValueType result, void function(PetitComputer, Value[], Value[]) func, int startskip,
bool variadic)
{ {
this.argments = argments; this.argments = argments;
this.result = result; this.result = result;
this.func = func; this.func = func;
this.startskip = startskip; this.startskip = startskip;
this.variadic = variadic;
} }
bool hasSkipArgument() bool hasSkipArgument()
{ {
@@ -67,6 +71,7 @@ class BuiltinFunction
return a < 0 ? -a : a; return a < 0 ? -a : a;
}*/ }*/
static double function(double) ABS = &abs!double; static double function(double) ABS = &abs!double;
static double function(double) SGN = &sgn!double;
static double SIN(double arg1) static double SIN(double arg1)
{ {
return sin(arg1); return sin(arg1);
@@ -148,9 +153,21 @@ class BuiltinFunction
{ {
p.gcolor = color; p.gcolor = color;
} }
static void BEEP(PetitComputer p, DefaultValue!(int, false) display) static void GPRIO(PetitComputer p, int z)
{ {
} }
static void BGMPLAY(PetitComputer p, int music)
{
}
static void BEEP(PetitComputer p, DefaultValue!(int, false) beep, DefaultValue!(int, false) pitch, DefaultValue!(int, false) volume, DefaultValue!(int, false) pan)
{
}
static void STICK(PetitComputer p, DefaultValue!(int, false) mp, out int x, out int y)
{
//JOYSTICK?
x = 0;
y = 0;
}
static int RGB(int R, int G, int B, DefaultValue!(int, false) _) static int RGB(int R, int G, int B, DefaultValue!(int, false) _)
{ {
if(!_.isDefault) if(!_.isDefault)
@@ -189,6 +206,10 @@ class BuiltinFunction
} }
static double VAL(wstring str) static double VAL(wstring str)
{ {
if(str[0..2] == "&H")
{
return str[2..$].to!int(16);
}
double val = str.to!double; double val = str.to!double;
return val; return val;
} }
@@ -201,6 +222,112 @@ class BuiltinFunction
//挙動未定 //挙動未定
return str[i..i + len]; return str[i..i + len];
} }
static void SPSET(PetitComputer p, int id, int defno)
{
p.sprite.spset(id, defno);
}
static void SPHIDE(PetitComputer p, int id)
{
p.sprite.sphide(id);
}
static void SPSHOW(PetitComputer p, int id)
{
p.sprite.spshow(id);
}
static void SPOFS(PetitComputer p, int id, int x, int y, DefaultValue!(int, false) z)
{
p.sprite.spofs(id, x, y);
}
static void SPANIM(PetitComputer p, Value[] va_args)
{
writeln("NOTIMPL:SPANIM");
}
static void BGMSTOP(PetitComputer p)
{
writeln("NOTIMPL:BGMSTOP");
}
static int BGMCHK(PetitComputer p)
{
writeln("NOTIMPL:BGMCHK");
return false;
}
static int CHKCHR(PetitComputer p, int x, int y)
{
return cast(int)(p.console[y][x].character);
}
static wstring FORMAT(PetitComputer p, Value[] va_args)
{
alias retro!(Value[]) VaArgs;
auto args = retro(va_args);
auto format = args[0].castString;
import std.array : appender;
import std.format;
import std.string;
auto w = appender!wstring();
int j = 1;
for(int i = 0; i < format.length; i++)
{
auto f = format[i];
if(f == '%')
{
int d = indexOf(format, 'D', CaseSensitive.yes);
if(d != -1)
{
auto spec = singleSpec(format[i .. d + 1]);
spec.spec = 'd';
formatValue(w, args[j].castInteger, spec);
j++;
i = d;
continue;
}
d = indexOf(format, 'X', CaseSensitive.yes);
if(d != -1)
{
auto spec = singleSpec(format[i .. d + 1]);
spec.spec = 'x';
formatValue(w, args[j].castDouble, spec);
j++;
i = d;
continue;
}
d = indexOf(format, 'S', CaseSensitive.yes);
if(d != -1)
{
auto spec = singleSpec(format[i .. d + 1]);
spec.spec = 's';
formatValue(w, args[j].castString, spec);
j++;
i = d;
continue;
}
d = indexOf(format, 'F', CaseSensitive.yes);
if(d != -1)
{
auto spec = singleSpec(format[i .. d + 1]);
spec.spec = 'f';
formatValue(w, args[j].castDouble, spec);
j++;
i = d;
continue;
}
}
w ~= f;
}
//プチコン互換FOMA
return cast(immutable)w.data();
}
static wstring CHR(int code)
{
return (cast(wchar)code).to!wstring;
}
static double POW(double a1, double a2)
{
return a1 ^^ a2;
}
static double SQR(double a1)
{
return sqrt(a1);
}
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
static BuiltinFunction[wstring] builtinFunctions; static BuiltinFunction[wstring] builtinFunctions;
static this() static this()
@@ -221,6 +348,7 @@ class BuiltinFunction
GetFunctionReturnType!(BuiltinFunction, name), GetFunctionReturnType!(BuiltinFunction, name),
mixin(AddFunc!(BuiltinFunction, name)), mixin(AddFunc!(BuiltinFunction, name)),
GetStartSkip!(BuiltinFunction, name), GetStartSkip!(BuiltinFunction, name),
IsVariadic!(BuiltinFunction, name),
); );
writeln(AddFunc!(BuiltinFunction, name)); writeln(AddFunc!(BuiltinFunction, name));
} }
@@ -367,6 +495,10 @@ template GetFunctionParamType(T, string N)
{ {
const string arg = "ValueType.String, true"; const string arg = "ValueType.String, true";
} }
else static if(is(P[0] == Value[]))
{
const string arg = "";
}
else static if(is(P[0] == PetitComputer)) else static if(is(P[0] == PetitComputer))
{ {
static if(P.length != 0) static if(P.length != 0)
@@ -450,6 +582,10 @@ template AddFuncArg(int L, int N, int M, int O, T, string NAME, P...)
enum outadd = 0; enum outadd = 0;
const string arg = "fromStringToSkip(arg[" ~ I.to!string ~ "])"; const string arg = "fromStringToSkip(arg[" ~ I.to!string ~ "])";
} }
else static if(is(P[0] == Value[]))
{
const string arg = "arg";
}
else else
{ {
enum add = 1; enum add = 1;
@@ -470,28 +606,35 @@ template OutArgsInit(T, string N, int I = 0, int J = 0)
{ {
enum tuple = ParameterStorageClassTuple!(__traits(getMember, T, N))[I]; enum tuple = ParameterStorageClassTuple!(__traits(getMember, T, N))[I];
alias param = ParameterTypeTuple!(__traits(getMember, T, N)); alias param = ParameterTypeTuple!(__traits(getMember, T, N));
static if(tuple & ParameterStorageClass.out_) static if(!param.length)
{ {
enum add = 1; enum OutArgsInit = "";
enum ret1 = "ret[" ~ J.to!string ~ "].type = "; }
static if(is(param[I] == int)) else
{
static if(tuple & ParameterStorageClass.out_)
{ {
enum ret2 = "ValueType.Integer;"; enum add = 1;
enum ret1 = "ret[" ~ J.to!string ~ "].type = ";
static if(is(param[I] == int))
{
enum ret2 = "ValueType.Integer;";
}
enum result = ret1 ~ ret2;
}
else
{
enum add = 0;
enum result = "";
}
static if(param.length > I + 1)
{
enum OutArgsInit = result ~ OutArgsInit!(T, N, I + 1, J + add);
}
else
{
enum OutArgsInit = result;
} }
enum result = ret1 ~ ret2;
}
else
{
enum add = 0;
enum result = "";
}
static if(param.length > I + 1)
{
enum OutArgsInit = result ~ OutArgsInit!(T, N, I + 1, J + add);
}
else
{
enum OutArgsInit = result;
} }
} }
template GetArgumentCount(T, string N, int I = 0) template GetArgumentCount(T, string N, int I = 0)
@@ -522,3 +665,20 @@ template GetArgumentCount(T, string N, int I = 0)
enum GetArgumentCount = add; enum GetArgumentCount = add;
} }
} }
template IsVariadic(T, string N, int I = 0)
{
alias param = ParameterTypeTuple!(__traits(getMember, T, N));
static if(param.length == 0 || param.length <= I)
{
enum IsVariadic = false;
}
else static if(is(param[I] == Value[]))
{
enum IsVariadic = true;
}
else
{
enum IsVariadic = IsVariadic!(T, N, I + 1);
}
}

View File

@@ -33,6 +33,7 @@ class DataTable
{ {
Value[] data; Value[] data;
int[wstring] label; int[wstring] label;
//dataIndexは関数ごとに別じゃないといけない
int dataIndex; int dataIndex;
void addData(Value data) void addData(Value data)
{ {
@@ -714,6 +715,7 @@ class Compiler
{ {
globalLabel[label.label] = code.length; globalLabel[label.label] = code.length;
} }
s.data.addLabel(label.label);
} }
break; break;
case NodeType.Goto: case NodeType.Goto:
@@ -791,6 +793,7 @@ class Compiler
case NodeType.CallFunctionStatement: case NodeType.CallFunctionStatement:
{ {
auto func = cast(CallFunctionStatement)i; auto func = cast(CallFunctionStatement)i;
writeln(func.name);
auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null); auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null);
if(bfun) if(bfun)
{ {
@@ -835,6 +838,9 @@ class Compiler
case NodeType.Read: case NodeType.Read:
compileRead(cast(Read)i, s); compileRead(cast(Read)i, s);
break; break;
case NodeType.Restore:
genCode(new RestoreCodeS((cast(Constant)(cast(Restore)i).label).value.stringValue));
break;
case NodeType.On: case NodeType.On:
compileOn(cast(On)i, s); compileOn(cast(On)i, s);
break; break;
@@ -907,6 +913,11 @@ class Compiler
code[i] = new OnGoto(addresses); code[i] = new OnGoto(addresses);
} }
} }
if(c.type == CodeType.RestoreCodeS)
{
auto restore = cast(RestoreCodeS)c;
code[i] = new RestoreCode(s.data.label[restore.label], s.data);
}
} }
return new VM(code, globalIndex + 1, global, functions, s.data); return new VM(code, globalIndex + 1, global, functions, s.data);
} }

View File

@@ -964,12 +964,27 @@ class Parser
auto token = lex.front(); auto token = lex.front();
while(true) while(true)
{ {
bool minusflag;
//TODO:constexpression()関数作る
if(token.type == TokenType.Minus)
{
lex.popFront();
token = lex.front();
minusflag = true;
}
if(token.type != TokenType.String && token.type != TokenType.Integer) if(token.type != TokenType.String && token.type != TokenType.Integer)
{ {
syntaxError(); syntaxError();
return null; return null;
} }
data.addData(token.value); if(minusflag)
{
data.addData(Value(-token.value.castDouble));
}
else
{
data.addData(token.value);
}
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
if(token.type == TokenType.Comma) if(token.type == TokenType.Comma)

View File

@@ -13,6 +13,7 @@ import otya.smilebasic.parser;
import otya.smilebasic.sprite; import otya.smilebasic.sprite;
enum Button enum Button
{ {
NONE = 0,
UP = 1, UP = 1,
DOWN = 2, DOWN = 2,
LEFT = 4, LEFT = 4,
@@ -129,7 +130,7 @@ class PetitComputer
} }
struct ConsoleCharacter struct ConsoleCharacter
{ {
wchar charater; wchar character;
int foreColor; int foreColor;
int backColor; int backColor;
byte attr; byte attr;
@@ -554,7 +555,6 @@ class PetitComputer
glAlphaFunc(GL_GEQUAL, 0.5); glAlphaFunc(GL_GEQUAL, 0.5);
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
draw = new otya.smilebasic.draw.Draw(this); draw = new otya.smilebasic.draw.Draw(this);
sprite = new Sprite(this);
sprite.spset(0, 0); sprite.spset(0, 0);
sprite.spofs(0, 9, 8); sprite.spofs(0, 9, 8);
while(true) while(true)
@@ -658,12 +658,13 @@ class PetitComputer
consolem = new Mutex(); consolem = new Mutex();
keybuffermutex = new Mutex(); keybuffermutex = new Mutex();
grpmutex = new Mutex(); grpmutex = new Mutex();
sprite = new Sprite(this);
core.thread.Thread thread = new core.thread.Thread(&render); core.thread.Thread thread = new core.thread.Thread(&render);
thread.start(); thread.start();
auto startTicks = SDL_GetTicks(); auto startTicks = SDL_GetTicks();
//とりあえず //とりあえず
auto parser = new Parser( auto parser = new Parser(
readText("./SYS/EX7ALIEN.TXT").to!wstring readText("./SYS/GAME1DOTRC.TXT").to!wstring
//readText(input("LOAD PROGRAM:", true).to!string).to!wstring //readText(input("LOAD PROGRAM:", true).to!string).to!wstring
//readText("./SYS/EX1TEXT.TXT").to!wstring //readText("./SYS/EX1TEXT.TXT").to!wstring
//readText("FIZZBUZZ.TXT").to!wstring //readText("FIZZBUZZ.TXT").to!wstring
@@ -730,6 +731,7 @@ class PetitComputer
try try
{ {
printConsole(sbe.to!string); printConsole(sbe.to!string);
writeln(sbe.to!string);
} }
catch catch
{ {
@@ -741,6 +743,7 @@ class PetitComputer
try try
{ {
printConsole(t.to!string); printConsole(t.to!string);
writeln(t);
} }
catch catch
{ {
@@ -993,7 +996,7 @@ class PetitComputer
for(int x = 0; x < consoleWidth; x++) for(int x = 0; x < consoleWidth; x++)
{ {
auto fore = consoleColorGL[console[y][x].foreColor]; auto fore = consoleColorGL[console[y][x].foreColor];
auto rect = &fontTable[console[y][x].charater]; auto rect = &fontTable[console[y][x].character];
glColor4ubv(cast(ubyte*)&fore); glColor4ubv(cast(ubyte*)&fore);
glTexCoord2f((rect.x) / 512f - 1 , (rect.y + 8) / 512f - 1); glTexCoord2f((rect.x) / 512f - 1 , (rect.y + 8) / 512f - 1);
glVertex3f((x * 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 0); glVertex3f((x * 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 0);
@@ -1027,7 +1030,7 @@ class PetitComputer
} }
if(c != '\r' && c != '\n') if(c != '\r' && c != '\n')
{ {
console[CSRY][CSRX].charater = c; console[CSRY][CSRX].character = c;
console[CSRY][CSRX].foreColor = consoleForeColor; console[CSRY][CSRX].foreColor = consoleForeColor;
console[CSRY][CSRX].backColor = consoleBackColor; console[CSRY][CSRX].backColor = consoleBackColor;
} }

View File

@@ -49,7 +49,7 @@ class Sprite
PetitComputer petitcom; PetitComputer petitcom;
void initUVTable() void initUVTable()
{ {
UVTable[0] = SDL_Rect(0, 0, 16, 16);//Ichigo UVTable[] = SDL_Rect(0, 0, 16, 16);//Ichigo
} }
this(PetitComputer petitcom) this(PetitComputer petitcom)
{ {
@@ -89,6 +89,10 @@ class Sprite
} }
void spset(int id, int defno) void spset(int id, int defno)
{ {
if(defno >= 2048 && defno < 4096)
{
defno -= 2048;
}
sprites[id] = SpriteData(id, UVTable[defno].x, UVTable[defno].y, UVTable[defno].w, UVTable[defno].h); sprites[id] = SpriteData(id, UVTable[defno].x, UVTable[defno].y, UVTable[defno].w, UVTable[defno].h);
} }
void spofs(int id, int x, int y) void spofs(int id, int x, int y)
@@ -96,4 +100,12 @@ class Sprite
sprites[id].x = x; sprites[id].x = x;
sprites[id].y = y; sprites[id].y = y;
} }
void sphide(int id)
{
sprites[id].attr ^= SpriteAttr.show;
}
void spshow(int id)
{
sprites[id].attr |= SpriteAttr.show;
}
} }

View File

@@ -124,6 +124,10 @@ class Array(T)
dim[2] = 0; dim[2] = 0;
dim[3] = 0; dim[3] = 0;
array = new T[len]; array = new T[len];
static if(is(T == double))
{
array[] = 0;
}
dimCount = 1; dimCount = 1;
} }
this(int[] dim) this(int[] dim)
@@ -135,6 +139,10 @@ class Array(T)
this.dim[i] = dim[i]; this.dim[i] = dim[i];
} }
array = new T[len]; array = new T[len];
static if(is(T == double))
{
array[] = 0;
}
dimCount = dim.length; dimCount = dim.length;
} }
T opIndexAssign(T v, int[] dim) T opIndexAssign(T v, int[] dim)