変数の使えないダイレクトモードを実装
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
<vtls>0</vtls>
|
<vtls>0</vtls>
|
||||||
<vgc>0</vgc>
|
<vgc>0</vgc>
|
||||||
<symdebug>1</symdebug>
|
<symdebug>2</symdebug>
|
||||||
<optimize>0</optimize>
|
<optimize>0</optimize>
|
||||||
<cpu>0</cpu>
|
<cpu>0</cpu>
|
||||||
<isX86_64>0</isX86_64>
|
<isX86_64>0</isX86_64>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids />
|
<debugids />
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>NDirectMode</versionids>
|
<versionids />
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class VM
|
|||||||
void directSlot(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/,
|
void directSlot(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/,
|
||||||
int[wstring] globalLabel, DebugInfo dinfo)
|
int[wstring] globalLabel, DebugInfo dinfo)
|
||||||
{
|
{
|
||||||
|
this.pc = currentSlot.code.length;
|
||||||
this.currentSlot.code ~= code;
|
this.currentSlot.code ~= code;
|
||||||
}
|
}
|
||||||
void loadSlot(int slot, Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/,
|
void loadSlot(int slot, Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/,
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ class Function
|
|||||||
}
|
}
|
||||||
class Compiler
|
class Compiler
|
||||||
{
|
{
|
||||||
|
bool isDirectMode;
|
||||||
ValueType getType(wstring name)
|
ValueType getType(wstring name)
|
||||||
{
|
{
|
||||||
wchar s = name[name.length - 1];
|
wchar s = name[name.length - 1];
|
||||||
@@ -1050,8 +1051,15 @@ class Compiler
|
|||||||
genCode(new EndVM());
|
genCode(new EndVM());
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
void compileDirectMode(VM vm)
|
||||||
|
{
|
||||||
|
isDirectMode = true;
|
||||||
|
compileProgram();
|
||||||
|
vm.directSlot(code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo);
|
||||||
|
}
|
||||||
VM compile()
|
VM compile()
|
||||||
{
|
{
|
||||||
|
isDirectMode = false;
|
||||||
compileProgram();
|
compileProgram();
|
||||||
VM vm = new VM();
|
VM vm = new VM();
|
||||||
vm.loadSlot(0, code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo);
|
vm.loadSlot(0, code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo);
|
||||||
|
|||||||
@@ -233,8 +233,8 @@ class PetitComputer
|
|||||||
rect.y = 0;
|
rect.y = 0;
|
||||||
rect.w = src.w;
|
rect.w = src.w;
|
||||||
rect.h = src.h;
|
rect.h = src.h;
|
||||||
// SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
|
// SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
|
||||||
// SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
|
// SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
ubyte sr, sg, sb, sa;
|
ubyte sr, sg, sb, sa;
|
||||||
SDL_GetRGBA((cast(uint*)src.pixels)[0], src.format, &sr, &sg, &sb, &sa);
|
SDL_GetRGBA((cast(uint*)src.pixels)[0], src.format, &sr, &sg, &sb, &sa);
|
||||||
@@ -347,7 +347,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
// DerelictGL.load();
|
// DerelictGL.load();
|
||||||
for(int i = 0; i < consoleColor.length; i++)
|
for(int i = 0; i < consoleColor.length; i++)
|
||||||
consoleColorGL[i] = toGLColor(consoleColor[i]);
|
consoleColorGL[i] = toGLColor(consoleColor[i]);
|
||||||
if(!exists(resourcePath))
|
if(!exists(resourcePath))
|
||||||
@@ -727,7 +727,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
dt = dm.type;
|
dt = dm.type;
|
||||||
}
|
}
|
||||||
brk:
|
brk:
|
||||||
if(i == len)
|
if(i == len)
|
||||||
{
|
{
|
||||||
renderstartpos = 0;
|
renderstartpos = 0;
|
||||||
@@ -740,7 +740,6 @@ class PetitComputer
|
|||||||
glBindFramebufferEXT(GL_FRAMEBUFFER, old);
|
glBindFramebufferEXT(GL_FRAMEBUFFER, old);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
drawflag = false;
|
drawflag = false;
|
||||||
this.chScreen(0, 0, 400, 240);
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
Button[] buttonTable;
|
Button[] buttonTable;
|
||||||
@@ -802,7 +801,7 @@ class PetitComputer
|
|||||||
|
|
||||||
DerelictGL.load();
|
DerelictGL.load();
|
||||||
DerelictGL3.load();
|
DerelictGL3.load();
|
||||||
bool renderprofile = true;
|
bool renderprofile;// = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
version(Windows)
|
version(Windows)
|
||||||
@@ -894,6 +893,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
renderGraphic();
|
renderGraphic();
|
||||||
|
chScreen(0, 0, 400, 240);
|
||||||
if(xscreenmode == 1)
|
if(xscreenmode == 1)
|
||||||
{
|
{
|
||||||
chScreen(0, 240, 400, 240);
|
chScreen(0, 240, 400, 240);
|
||||||
@@ -1029,7 +1029,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
long delay = (1000/60) - (cast(long)SDL_GetTicks() - profile);
|
long delay = (1000/60) - (cast(long)SDL_GetTicks() - profile);
|
||||||
if(delay > 0)
|
if(delay > 0)
|
||||||
SDL_Delay(cast(uint)delay);
|
SDL_Delay(cast(uint)delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Throwable t)
|
catch(Throwable t)
|
||||||
@@ -1058,59 +1058,60 @@ class PetitComputer
|
|||||||
Parser parser;
|
Parser parser;
|
||||||
otya.smilebasic.vm.VM vm;
|
otya.smilebasic.vm.VM vm;
|
||||||
bool running;
|
bool running;
|
||||||
|
bool directMode = false;
|
||||||
//デバッグ用
|
//デバッグ用
|
||||||
version(NDirectMode)
|
version(NDirectMode)
|
||||||
{
|
{
|
||||||
parser = new Parser(
|
parser = new Parser(
|
||||||
//readText("./SYS/GAME6TALK.TXT").to!wstring
|
//readText("./SYS/GAME6TALK.TXT").to!wstring
|
||||||
//readText("./SYS/GAME7EXPAD.TXT").to!wstring
|
//readText("./SYS/GAME7EXPAD.TXT").to!wstring
|
||||||
//readText("./SYS/GAME4SHOOTER.TXT").to!wstring
|
//readText("./SYS/GAME4SHOOTER.TXT").to!wstring
|
||||||
//readText("./SYS/GAME2RPG.TXT").to!wstring
|
//readText("./SYS/GAME2RPG.TXT").to!wstring
|
||||||
//readText("./SYS/GAME1DOTRC.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/EX8TECDEMO.TXT").to!wstring
|
readText("./SYS/EX8TECDEMO.TXT").to!wstring
|
||||||
//readText("./SYS/EX1TEXT.TXT").to!wstring
|
//readText("./SYS/EX1TEXT.TXT").to!wstring
|
||||||
//readText("FIZZBUZZ.TXT").to!wstring
|
//readText("FIZZBUZZ.TXT").to!wstring
|
||||||
//readText("TEST.TXT").to!wstring
|
//readText("TEST.TXT").to!wstring
|
||||||
/*"?ABS(-1)
|
/*"?ABS(-1)
|
||||||
LOCATE 0,10
|
LOCATE 0,10
|
||||||
COLOR 5
|
COLOR 5
|
||||||
FOR I=0 TO 10
|
FOR I=0 TO 10
|
||||||
?I;\"!\",\"=\",FACT(I)
|
?I;\"!\",\"=\",FACT(I)
|
||||||
NEXT
|
NEXT
|
||||||
DEF FACT(N)
|
DEF FACT(N)
|
||||||
IF N<=1 THEN RETURN 1
|
IF N<=1 THEN RETURN 1
|
||||||
RETURN N*FACT(N-1)
|
RETURN N*FACT(N-1)
|
||||||
END"*/
|
END"*/
|
||||||
/*
|
/*
|
||||||
`CLS : CL=0 : Z=0
|
`CLS : CL=0 : Z=0
|
||||||
WHILE 1
|
WHILE 1
|
||||||
INC Z : IF Z>200 THEN Z=0
|
INC Z : IF Z>200 THEN Z=0
|
||||||
FOR I=0 TO 15
|
FOR I=0 TO 15
|
||||||
LOCATE 9,4+I,Z : COLOR (CL+I) MOD 16
|
LOCATE 9,4+I,Z : COLOR (CL+I) MOD 16
|
||||||
PRINT "★ 梅雨で雨が多い季節ですね ★"
|
PRINT "★ 梅雨で雨が多い季節ですね ★"
|
||||||
NEXT
|
NEXT
|
||||||
CL=(CL+1) MOD 16
|
CL=(CL+1) MOD 16
|
||||||
WEND`*/
|
WEND`*/
|
||||||
/*
|
/*
|
||||||
`CLS : CL=0
|
`CLS : CL=0
|
||||||
WHILE 1
|
WHILE 1
|
||||||
FOR I=0 TO 15
|
FOR I=0 TO 15
|
||||||
LOCATE 9,4+I : COLOR (CL+I) MOD 16
|
LOCATE 9,4+I : COLOR (CL+I) MOD 16
|
||||||
PRINT "Ё プチコン3ゴウ Ж"
|
PRINT "Ё プチコン3ゴウ Ж"
|
||||||
NEXT
|
NEXT
|
||||||
CL=(CL+1) MOD 16 : VSYNC 1
|
CL=(CL+1) MOD 16 : VSYNC 1
|
||||||
WEND`
|
WEND`
|
||||||
/*
|
/*
|
||||||
`CLS : CL=0
|
`CLS : CL=0
|
||||||
@LOOP
|
@LOOP
|
||||||
FOR I=0 TO 15
|
FOR I=0 TO 15
|
||||||
LOCATE 9,4+I : COLOR (CL+I) MOD 16
|
LOCATE 9,4+I : COLOR (CL+I) MOD 16
|
||||||
PRINT "Ё プチコン3ゴウ Ж"
|
PRINT "Ё プチコン3ゴウ Ж"
|
||||||
NEXT
|
NEXT
|
||||||
CL=(CL+1) MOD 16 : VSYNC 1
|
CL=(CL+1) MOD 16 : VSYNC 1
|
||||||
GOTO @LOOP`*/
|
GOTO @LOOP`*/
|
||||||
);
|
);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vm = parser.compile();
|
vm = parser.compile();
|
||||||
@@ -1131,130 +1132,145 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{/*
|
|
||||||
if(!vm)
|
|
||||||
{
|
|
||||||
import otya.smilebasic.vm;
|
|
||||||
vm = new VM();
|
|
||||||
vm.init(this);
|
|
||||||
}
|
|
||||||
auto prg = input("", true);
|
|
||||||
parser = new Parser(prg);
|
|
||||||
vm.code.append(parser.compiler.compileProgram());*/
|
|
||||||
version(none)
|
|
||||||
do
|
|
||||||
{
|
|
||||||
auto file = input("LOAD PROGRAM:", true).to!string;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
parser = new Parser(readText(file).to!wstring);
|
|
||||||
}
|
|
||||||
catch(Throwable t)
|
|
||||||
{
|
|
||||||
writeln(t);
|
|
||||||
printConsole("can't open program \"", file, "\".\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
vm = parser.compile();
|
|
||||||
vm.init(this);
|
|
||||||
running = true;
|
|
||||||
}
|
|
||||||
catch(SmileBasicError sbe)
|
|
||||||
{
|
|
||||||
printConsole(sbe.getErrorMessage, "\n");
|
|
||||||
printConsole(sbe.getErrorMessage2, "\n");
|
|
||||||
//printConsole(sbe.to!string);
|
|
||||||
writeln(sbe.to!string);
|
|
||||||
writeln(sbe.getErrorMessage2);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
catch(Throwable t)
|
|
||||||
{
|
|
||||||
writeln(t);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} while(!quit);
|
|
||||||
}
|
|
||||||
if(quit) return;
|
|
||||||
//vm.dump;
|
|
||||||
this.vm = vm;
|
|
||||||
bg[0].put(0,0,1);
|
|
||||||
//gpset(0, 10, 10, 0xFF00FF00);
|
|
||||||
//gline(0, 0, 0, 399, 239, RGB(0, 255, 0));
|
|
||||||
//gfill(0, 78, 78, 40, 40, RGB(0, 255, 255));
|
|
||||||
//gbox(0, 78, 78, 40, 40, RGB(255, 255, 0));
|
|
||||||
int startcnt = SDL_GetTicks();
|
|
||||||
float frame = 1000f / 60f;
|
|
||||||
typeof(vm.currentLocation()) loc;
|
|
||||||
debug bool trace = false;
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
uint elapse;
|
directMode = true;
|
||||||
startTicks = SDL_GetTicks();
|
/*vm.code.append(parser.compiler.compileProgram());*/
|
||||||
//do
|
version(none)
|
||||||
{
|
do
|
||||||
try
|
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 128 && !vsyncFrame && running; i++)
|
auto file = input("LOAD PROGRAM:", true).to!string;
|
||||||
{
|
|
||||||
//writefln("%04X:%s", vm.pc, vm.getCurrent);
|
|
||||||
running = vm.runStep();
|
|
||||||
debug if(trace && loc.line != vm.currentLocation.line)
|
|
||||||
{
|
|
||||||
loc = vm.currentLocation;
|
|
||||||
printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(SmileBasicError sbe)
|
|
||||||
{
|
|
||||||
running = false;
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
parser = new Parser(readText(file).to!wstring);
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
writeln(t);
|
||||||
|
printConsole("can't open program \"", file, "\".\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vm = parser.compile();
|
||||||
|
vm.init(this);
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
catch(SmileBasicError sbe)
|
||||||
{
|
{
|
||||||
printConsole(sbe.getErrorMessage, "\n");
|
printConsole(sbe.getErrorMessage, "\n");
|
||||||
printConsole(sbe.getErrorMessage2, "\n");
|
printConsole(sbe.getErrorMessage2, "\n");
|
||||||
//printConsole(sbe.to!string);
|
//printConsole(sbe.to!string);
|
||||||
writeln(sbe.to!string);
|
writeln(sbe.to!string);
|
||||||
writeln(sbe.getErrorMessage2);
|
writeln(sbe.getErrorMessage2);
|
||||||
loc = vm.currentLocation;
|
continue;
|
||||||
printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc));
|
|
||||||
}
|
}
|
||||||
catch(Throwable t)
|
catch(Throwable t)
|
||||||
{
|
{
|
||||||
writeln(t);
|
writeln(t);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
} while(!quit);
|
||||||
|
}
|
||||||
|
if(quit) return;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(directMode)
|
||||||
|
{
|
||||||
|
if(!vm)
|
||||||
|
{
|
||||||
|
import otya.smilebasic.vm;
|
||||||
|
vm = (new Parser("")).compile;
|
||||||
|
vm.init(this);
|
||||||
}
|
}
|
||||||
catch(Throwable t)
|
auto prg = input("", true);
|
||||||
|
parser = new Parser(prg);
|
||||||
|
auto cc = parser.compiler;
|
||||||
|
cc.compileDirectMode(vm);
|
||||||
|
vm.dump();
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
//vm.dump;
|
||||||
|
this.vm = vm;
|
||||||
|
bg[0].put(0,0,1);
|
||||||
|
//gpset(0, 10, 10, 0xFF00FF00);
|
||||||
|
//gline(0, 0, 0, 399, 239, RGB(0, 255, 0));
|
||||||
|
//gfill(0, 78, 78, 40, 40, RGB(0, 255, 255));
|
||||||
|
//gbox(0, 78, 78, 40, 40, RGB(255, 255, 0));
|
||||||
|
int startcnt = SDL_GetTicks();
|
||||||
|
float frame = 1000f / 60f;
|
||||||
|
typeof(vm.currentLocation()) loc;
|
||||||
|
debug bool trace = false;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
uint elapse;
|
||||||
|
startTicks = SDL_GetTicks();
|
||||||
|
//do
|
||||||
{
|
{
|
||||||
running = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
printConsole(t.to!string);
|
for(int i = 0; i < 128 && !vsyncFrame && running; i++)
|
||||||
writeln(t);
|
{
|
||||||
printConsole(parser.getLine(vm.currentLocation));
|
//writefln("%04X:%s", vm.pc, vm.getCurrent);
|
||||||
|
running = vm.runStep();
|
||||||
|
debug if(trace && loc.line != vm.currentLocation.line)
|
||||||
|
{
|
||||||
|
loc = vm.currentLocation;
|
||||||
|
printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!running)
|
||||||
|
{
|
||||||
|
if(directMode) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(SmileBasicError sbe)
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
printConsole(sbe.getErrorMessage, "\n");
|
||||||
|
printConsole(sbe.getErrorMessage2, "\n");
|
||||||
|
//printConsole(sbe.to!string);
|
||||||
|
writeln(sbe.to!string);
|
||||||
|
writeln(sbe.getErrorMessage2);
|
||||||
|
loc = vm.currentLocation;
|
||||||
|
printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc));
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
writeln(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Throwable t)
|
catch(Throwable t)
|
||||||
{
|
{
|
||||||
writeln(t);
|
running = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
printConsole(t.to!string);
|
||||||
|
writeln(t);
|
||||||
|
printConsole(parser.getLine(vm.currentLocation));
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
writeln(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//elapse = SDL_GetTicks() - startTicks;
|
||||||
|
} //while(elapse <= 1000 / 60);
|
||||||
|
if(vsyncFrame)
|
||||||
|
{
|
||||||
|
SDL_Delay(cast(uint)(vsyncFrame * frame));
|
||||||
|
vsyncFrame = 0;
|
||||||
|
}
|
||||||
|
maincnt = cast(int)((SDL_GetTicks() - startcnt) / frame);
|
||||||
|
if(quit)
|
||||||
|
{
|
||||||
|
quit = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
//elapse = SDL_GetTicks() - startTicks;
|
|
||||||
} //while(elapse <= 1000 / 60);
|
|
||||||
if(vsyncFrame)
|
|
||||||
{
|
|
||||||
SDL_Delay(cast(uint)(vsyncFrame * frame));
|
|
||||||
vsyncFrame = 0;
|
|
||||||
}
|
}
|
||||||
maincnt = cast(int)((SDL_GetTicks() - startcnt) / frame);
|
} while(directMode);
|
||||||
if(quit)
|
|
||||||
{
|
|
||||||
quit = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scope(exit)
|
scope(exit)
|
||||||
{
|
{
|
||||||
writeln("quit");
|
writeln("quit");
|
||||||
@@ -1306,12 +1322,13 @@ class PetitComputer
|
|||||||
CSRX--;
|
CSRX--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printConsole(key);
|
|
||||||
if(key == '\r')
|
if(key == '\r')
|
||||||
{
|
{
|
||||||
k = key;
|
k = key;
|
||||||
|
printConsole("\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
printConsole(key);
|
||||||
buffer ~= key;
|
buffer ~= key;
|
||||||
}
|
}
|
||||||
clearKeyBuffer();
|
clearKeyBuffer();
|
||||||
|
|||||||
Reference in New Issue
Block a user