From 0a52b513719efca66592b8b94b4ae051e9b9ed25 Mon Sep 17 00:00:00 2001 From: otya128 Date: Sun, 23 Aug 2015 20:37:56 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B0=E3=83=A9=E3=83=95=E3=82=A3=E3=83=83?= =?UTF-8?q?=E3=82=AF=E7=B3=BB=E3=82=92=E5=A4=A7=E5=B9=85=E3=81=AB=E9=AB=98?= =?UTF-8?q?=E9=80=9F=E5=8C=96,16,2=E9=80=B2=E6=95=B0=E3=83=AA=E3=83=86?= =?UTF-8?q?=E3=83=A9=E3=83=AB=E3=81=AE=E5=AE=9F=EF=BF=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SMILEBASIC/VM.d | 2 +- SMILEBASIC/builtinfunctions.d | 7 +- SMILEBASIC/compiler.d | 8 +++ SMILEBASIC/draw.d | 5 +- SMILEBASIC/parser.d | 45 ++++++++++-- SMILEBASIC/petitcomputer.d | 127 +++++++++++++++++++++++++--------- SMILEBASIC/systemvariable.d | 39 ++++++++++- 7 files changed, 185 insertions(+), 48 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 80b7064..3f5d390 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -1339,7 +1339,7 @@ class PushSystemVariable : Code } override void execute(VM vm) { - vm.push(var.value); + vm.push(var.value(vm)); } override string toString(VM vm) { diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 5a73266..9550759 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -368,18 +368,13 @@ class BuiltinFunction static wstring HEX(int val, DefaultValue!(int, false) digits) { import std.format; - if(digits.isDefault) - { - //ひどい - return val.to!string(16).to!wstring; - } if(digits > 8) { throw new OutOfRange(); } FormatSpec!char f; f.spec = 'X'; - f.flZero = true; + f.flZero = !digits.isDefault; f.width = cast(int)digits; auto w = appender!wstring(); formatValue(w, val, f); diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index c354756..fe114b4 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -160,6 +160,14 @@ class Compiler sysVariable["DATE$"] = new Date(); global["TIME$"] = VMVariable(-1); sysVariable["TIME$"] = new Time(); + global["MAINCNT"] = VMVariable(-1); + sysVariable["MAINCNT"] = new Maincnt(); + global["CSRX"] = VMVariable(-1); + sysVariable["CSRX"] = new CSRX(); + global["CSRY"] = VMVariable(-1); + sysVariable["CSRY"] = new CSRY(); + global["CSRZ"] = VMVariable(-1); + sysVariable["CSRZ"] = new CSRZ(); } SystemVariable[wstring] sysVariable; diff --git a/SMILEBASIC/draw.d b/SMILEBASIC/draw.d index 1c7190e..c00ce62 100644 --- a/SMILEBASIC/draw.d +++ b/SMILEBASIC/draw.d @@ -18,6 +18,9 @@ class Draw void gline(int page, int x, int y, int x2, int y2, uint color) { import std.math; + color = PetitComputer.toGLColor(petitcom.GRP[page].textureFormat, color); + glBindTexture(GL_TEXTURE_2D, petitcom.GRP[page].glTexture); + auto tf = petitcom.GRP[page].textureFormat; int dx = abs(x2 - x); int dy = abs(y2 - y); int sx, sy; @@ -27,7 +30,7 @@ class Draw while(true) { if(x < 0 || y < 0 || x >= 512 || y >= 512) break; - gpset(page, x, y, color); + glTexSubImage2D(GL_TEXTURE_2D , 0, x, y, 1, 1, tf, GL_UNSIGNED_BYTE, &color); if(x == x2 && y == y2) break; int e2 = 2*err; if(e2 > -dy) diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 0a0cf64..471f473 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -248,11 +248,48 @@ class Lexical i += 2; break; } - if(c == '&' && i + 1 < code.length && code[i + 1] == '&') + if(c == '&' && i + 1 < code.length) { - token = Token(TokenType.LogicalAnd); - i += 2; - break; + if(code[i + 1].toUpper == 'H') + { + i += 2; + int start = i; + for(;i < code.length;i++) + { + c = cast(wchar)(code[i].toUpper); + if(!c.isDigit() && (c < 'A' || c > 'F')) + { + break; + } + } + wstring numstr = code[start..i]; + int num = numstr.to!int(16); + token = Token(TokenType.Integer, Value(num)); + break; + } + if(code[i + 1].toUpper == 'B') + { + i += 2; + int start = i; + for(;i < code.length;i++) + { + c = code[i]; + if(c != '1' && c != '0') + { + break; + } + } + wstring numstr = code[start..i]; + int num = numstr.to!int(2); + token = Token(TokenType.Integer, Value(num)); + break; + } + if(code[i + 1] == '&') + { + token = Token(TokenType.LogicalAnd); + i += 2; + break; + } } if(c == '|' && i + 1 < code.length && code[i + 1] == '|') { diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 83159a1..4844346 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -2,6 +2,7 @@ module otya.smilebasic.petitcomputer; import derelict.sdl2.sdl; import derelict.sdl2.image; import derelict.opengl3.gl; +import derelict.opengl3.gl3; import std.net.curl; import std.file; import std.stdio; @@ -77,6 +78,27 @@ class GraphicPage texture_format, GL_UNSIGNED_BYTE, surface.pixels ); textureFormat = texture_format; } + GLuint render; + GLuint buffer; + void createBuffer() + { + GLint old; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old); + glBindTexture(GL_TEXTURE_2D, glTexture); + glGenRenderbuffersEXT(1, &render); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 512, 512); + glGenFramebuffersEXT(1, &buffer); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, glTexture, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + writeln("!?"); + } + glBindFramebufferEXT(GL_FRAMEBUFFER, old); + } } version(Windows) @@ -272,7 +294,7 @@ class PetitComputer { DerelictSDL2.load(); DerelictSDL2Image.load(); - DerelictGL.load(); + // DerelictGL.load(); for(int i = 0; i < consoleColor.length; i++) consoleColorGL[i] = toGLColor(consoleColor[i]); if(!exists(resourcePath)) @@ -416,6 +438,7 @@ class PetitComputer bool displaynum; void renderGraphic() { + if(!drawMessageLength) return; //grpmutex.lock(); //scope(exit) // grpmutex.unlock(); @@ -423,28 +446,69 @@ class PetitComputer //betuni kouzoutai demo sonnnani sokudo kawaranasasou auto len = drawMessageLength; drawMessageLength = 0; - for(int i = 0; i < len; i++) + int s = 0; + GLint old; + auto a = & glBindFramebuffer; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old); + glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[showGRP].buffer); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glViewport(0, 0, 512, 512); + for(int i = s; i < len; i++) { DrawMessage dm = drawMessageQueue[i]; switch(dm.type) { case DrawType.PSET: - draw.gpset(dm.page, dm.x, dm.y ,dm.color); + glBegin(GL_POINTS); + glColor3ubv(cast(ubyte*)&dm.color); + glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); + glEnd(); + //draw.gpset(dm.page, dm.x, dm.y ,dm.color); break; case DrawType.LINE: - draw.gline(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); + { + glBegin(GL_LINES); + glColor3ubv(cast(ubyte*)&dm.color); + glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); + glVertex2f((dm.x2) / 256f - 1, (dm.y2) / 256f - 1); + //glFlush(); + glEnd(); + } + //draw.gline(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); break; case DrawType.FILL: - draw.gfill(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); + { + glBegin(GL_QUADS); + glColor3ubv(cast(ubyte*)&dm.color); + glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); + glVertex2f((dm.x) / 256f - 1, (dm.y2 + 1) / 256f - 1); + glVertex2f((dm.x2 + 1) / 256f - 1, (dm.y2 + 1) / 256f - 1); + glVertex2f((dm.x2 + 1) / 256f - 1, (dm.y) / 256f - 1); + glEnd(); + } + //draw.gfill(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); break; case DrawType.BOX: - draw.gbox(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); + { + glBegin(GL_LINE_LOOP); + glColor3ubv(cast(ubyte*)&dm.color); + glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); + glVertex2f((dm.x) / 256f - 1, (dm.y2) / 256f - 1); + glVertex2f((dm.x2) / 256f - 1, (dm.y2) / 256f - 1); + glVertex2f((dm.x2) / 256f - 1, (dm.y) / 256f - 1); + glEnd(); + } + //draw.gbox(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color); break; default: } } + glFlush(); + glBindFramebufferEXT(GL_FRAMEBUFFER, old); + glEnable(GL_DEPTH_TEST); drawflag = false; - + glViewport(0, 0, 400, 240); } Button[] buttonTable; Sprite sprite; @@ -469,13 +533,15 @@ class PetitComputer BG[4] bg; void render() { + 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 = true; + bool renderprofile;// = true; try { version(Windows) @@ -508,9 +574,11 @@ class PetitComputer } } int loopcnt; + DerelictGL3.reload(); foreach(g; GRP) { g.createTexture(renderer); + g.createBuffer(); } //GRP[0] = GRPF; //glEnable(GL_BLEND); @@ -551,15 +619,6 @@ class PetitComputer { bg[i].render(400f, 240f); } -/* if(this.sprite.sprites[0].define) - if(this.sprite.sprites[0].u == 0) - { - writeln("WHATW"); - } - else - { - writeln(this.sprite.sprites[0].u); - }*/ SDL_GL_SwapWindow(window); auto renderticks = (SDL_GetTicks() - profile); @@ -609,6 +668,10 @@ class PetitComputer break; } } + if(drawMessageLength) + { + //renderGraphic; + } while(true) { long delay = (1000/60) - (cast(long)SDL_GetTicks() - profile); @@ -630,6 +693,7 @@ class PetitComputer } SDL_Window* window; otya.smilebasic.vm.VM vm; + int maincnt; void run() { init(); @@ -710,6 +774,7 @@ class PetitComputer //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(); while (true) { uint elapse; @@ -718,7 +783,7 @@ class PetitComputer { try { - if(!vsyncFrame && running) + for(int i = 0; i < 128 && !vsyncFrame && running; i++) { //writefln("%04X:%s", vm.pc, vm.getCurrent); running = vm.runStep(); @@ -751,16 +816,8 @@ class PetitComputer } } elapse = SDL_GetTicks() - startTicks; - /*if(this.sprite.sprites[0].define) - if(this.sprite.sprites[0].u == 0) - { - writeln("WHATW"); - } - else - { - writeln(this.sprite.sprites[0].u); - }*/ } while(elapse <= 1000 / 60); + maincnt = (SDL_GetTicks() - startcnt) / (1000 / 60); vsyncCount++; if(vsyncFrame <= vsyncCount) vsyncFrame = 0; } @@ -855,7 +912,7 @@ class PetitComputer { if(format == GL_BGRA) { - return petitcolor; + return (petitcolor & 0xFF00FF00) | (petitcolor & 0xFF) << 16 | petitcolor >> 16 & 0xFF; } if(format == GL_RGBA) { @@ -922,21 +979,25 @@ class PetitComputer drawMessageQueue[drawMessageLength].page = page; drawMessageQueue[drawMessageLength].x = x; drawMessageQueue[drawMessageLength].y = y; - drawMessageQueue[drawMessageLength].color = color; + drawMessageQueue[drawMessageLength].color = toGLColor(this.GRP[0].textureFormat, color); drawMessageLength++; } void sendDrawMessage(DrawType type, byte page, short x, short y, short x2, short y2, uint color) { - grpmutex.lock(); - scope(exit) - grpmutex.unlock(); + if(drawMessageLength >= dmqqueuelen) + { + while(drawMessageLength) + { + SDL_Delay(1); + } + } drawMessageQueue[drawMessageLength].type = type; drawMessageQueue[drawMessageLength].page = page; drawMessageQueue[drawMessageLength].x = x; drawMessageQueue[drawMessageLength].y = y; drawMessageQueue[drawMessageLength].x2 = x2; drawMessageQueue[drawMessageLength].y2 = y2; - drawMessageQueue[drawMessageLength].color = color; + drawMessageQueue[drawMessageLength].color = toGLColor(this.GRP[0].textureFormat, color); drawMessageLength++; } //TODO:範囲チェック diff --git a/SMILEBASIC/systemvariable.d b/SMILEBASIC/systemvariable.d index b35d3e3..3916032 100644 --- a/SMILEBASIC/systemvariable.d +++ b/SMILEBASIC/systemvariable.d @@ -1,10 +1,11 @@ module otya.smilebasic.systemvariable; import otya.smilebasic.type; import otya.smilebasic.error; +import otya.smilebasic.vm; class SystemVariable { @property - abstract Value value(); + abstract Value value(VM vm); @property void value(Value value) { @@ -17,7 +18,7 @@ import std.conv; class Date : SystemVariable { @property - override Value value() + override Value value(VM vm) { auto currentTime = Clock.currTime(); wstring timeString = format("%04d/%02d/%02d", currentTime.year, currentTime.month, currentTime.day).to!wstring; @@ -27,11 +28,43 @@ class Date : SystemVariable class Time : SystemVariable { @property - override Value value() + override Value value(VM vm) { auto currentTime = Clock.currTime(); wstring timeString = format("%02d:%02d:%02d", currentTime.hour, currentTime.minute, currentTime.second).to!wstring; return Value(timeString); } } +class Maincnt : SystemVariable +{ + @property + override Value value(VM vm) + { + return Value(vm.petitcomputer.maincnt); + } +} +class CSRX : SystemVariable +{ + @property + override Value value(VM vm) + { + return Value(vm.petitcomputer.CSRX); + } +} +class CSRY : SystemVariable +{ + @property + override Value value(VM vm) + { + return Value(vm.petitcomputer.CSRY); + } +} +class CSRZ : SystemVariable +{ + @property + override Value value(VM vm) + { + return Value(vm.petitcomputer.CSRZ); + } +}