1
0

グラフィック系を大幅に高速化,16,2進数リテラルの実�

This commit is contained in:
otya128
2015-08-23 20:37:56 +09:00
parent e57782ea3d
commit 0a52b51371
7 changed files with 185 additions and 48 deletions

View File

@@ -1339,7 +1339,7 @@ class PushSystemVariable : Code
} }
override void execute(VM vm) override void execute(VM vm)
{ {
vm.push(var.value); vm.push(var.value(vm));
} }
override string toString(VM vm) override string toString(VM vm)
{ {

View File

@@ -368,18 +368,13 @@ class BuiltinFunction
static wstring HEX(int val, DefaultValue!(int, false) digits) static wstring HEX(int val, DefaultValue!(int, false) digits)
{ {
import std.format; import std.format;
if(digits.isDefault)
{
//ひどい
return val.to!string(16).to!wstring;
}
if(digits > 8) if(digits > 8)
{ {
throw new OutOfRange(); throw new OutOfRange();
} }
FormatSpec!char f; FormatSpec!char f;
f.spec = 'X'; f.spec = 'X';
f.flZero = true; f.flZero = !digits.isDefault;
f.width = cast(int)digits; f.width = cast(int)digits;
auto w = appender!wstring(); auto w = appender!wstring();
formatValue(w, val, f); formatValue(w, val, f);

View File

@@ -160,6 +160,14 @@ class Compiler
sysVariable["DATE$"] = new Date(); sysVariable["DATE$"] = new Date();
global["TIME$"] = VMVariable(-1); global["TIME$"] = VMVariable(-1);
sysVariable["TIME$"] = new Time(); 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; SystemVariable[wstring] sysVariable;

View File

@@ -18,6 +18,9 @@ class Draw
void gline(int page, int x, int y, int x2, int y2, uint color) void gline(int page, int x, int y, int x2, int y2, uint color)
{ {
import std.math; 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 dx = abs(x2 - x);
int dy = abs(y2 - y); int dy = abs(y2 - y);
int sx, sy; int sx, sy;
@@ -27,7 +30,7 @@ class Draw
while(true) while(true)
{ {
if(x < 0 || y < 0 || x >= 512 || y >= 512) break; 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; if(x == x2 && y == y2) break;
int e2 = 2*err; int e2 = 2*err;
if(e2 > -dy) if(e2 > -dy)

View File

@@ -248,12 +248,49 @@ class Lexical
i += 2; i += 2;
break; break;
} }
if(c == '&' && i + 1 < code.length && code[i + 1] == '&') if(c == '&' && i + 1 < code.length)
{
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); token = Token(TokenType.LogicalAnd);
i += 2; i += 2;
break; break;
} }
}
if(c == '|' && i + 1 < code.length && code[i + 1] == '|') if(c == '|' && i + 1 < code.length && code[i + 1] == '|')
{ {
token = Token(TokenType.LogicalOr); token = Token(TokenType.LogicalOr);

View File

@@ -2,6 +2,7 @@ module otya.smilebasic.petitcomputer;
import derelict.sdl2.sdl; import derelict.sdl2.sdl;
import derelict.sdl2.image; import derelict.sdl2.image;
import derelict.opengl3.gl; import derelict.opengl3.gl;
import derelict.opengl3.gl3;
import std.net.curl; import std.net.curl;
import std.file; import std.file;
import std.stdio; import std.stdio;
@@ -77,6 +78,27 @@ class GraphicPage
texture_format, GL_UNSIGNED_BYTE, surface.pixels ); texture_format, GL_UNSIGNED_BYTE, surface.pixels );
textureFormat = texture_format; 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) version(Windows)
@@ -272,7 +294,7 @@ class PetitComputer
{ {
DerelictSDL2.load(); DerelictSDL2.load();
DerelictSDL2Image.load(); DerelictSDL2Image.load();
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))
@@ -416,6 +438,7 @@ class PetitComputer
bool displaynum; bool displaynum;
void renderGraphic() void renderGraphic()
{ {
if(!drawMessageLength) return;
//grpmutex.lock(); //grpmutex.lock();
//scope(exit) //scope(exit)
// grpmutex.unlock(); // grpmutex.unlock();
@@ -423,28 +446,69 @@ class PetitComputer
//betuni kouzoutai demo sonnnani sokudo kawaranasasou //betuni kouzoutai demo sonnnani sokudo kawaranasasou
auto len = drawMessageLength; auto len = drawMessageLength;
drawMessageLength = 0; 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]; DrawMessage dm = drawMessageQueue[i];
switch(dm.type) switch(dm.type)
{ {
case DrawType.PSET: 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; break;
case DrawType.LINE: 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; break;
case DrawType.FILL: 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; break;
case DrawType.BOX: 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; break;
default: default:
} }
} }
glFlush();
glBindFramebufferEXT(GL_FRAMEBUFFER, old);
glEnable(GL_DEPTH_TEST);
drawflag = false; drawflag = false;
glViewport(0, 0, 400, 240);
} }
Button[] buttonTable; Button[] buttonTable;
Sprite sprite; Sprite sprite;
@@ -469,13 +533,15 @@ class PetitComputer
BG[4] bg; BG[4] bg;
void render() void render()
{ {
DerelictGL.load();
DerelictGL3.load();
buttonTable = new Button[SDL_SCANCODE_SLEEP + 1]; buttonTable = new Button[SDL_SCANCODE_SLEEP + 1];
buttonTable[SDL_SCANCODE_UP] = Button.UP; buttonTable[SDL_SCANCODE_UP] = Button.UP;
buttonTable[SDL_SCANCODE_DOWN] = Button.DOWN; buttonTable[SDL_SCANCODE_DOWN] = Button.DOWN;
buttonTable[SDL_SCANCODE_LEFT] = Button.LEFT; buttonTable[SDL_SCANCODE_LEFT] = Button.LEFT;
buttonTable[SDL_SCANCODE_RIGHT] = Button.RIGHT; buttonTable[SDL_SCANCODE_RIGHT] = Button.RIGHT;
buttonTable[SDL_SCANCODE_SPACE] = Button.A; buttonTable[SDL_SCANCODE_SPACE] = Button.A;
bool renderprofile = true; bool renderprofile;// = true;
try try
{ {
version(Windows) version(Windows)
@@ -508,9 +574,11 @@ class PetitComputer
} }
} }
int loopcnt; int loopcnt;
DerelictGL3.reload();
foreach(g; GRP) foreach(g; GRP)
{ {
g.createTexture(renderer); g.createTexture(renderer);
g.createBuffer();
} }
//GRP[0] = GRPF; //GRP[0] = GRPF;
//glEnable(GL_BLEND); //glEnable(GL_BLEND);
@@ -551,15 +619,6 @@ class PetitComputer
{ {
bg[i].render(400f, 240f); 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); SDL_GL_SwapWindow(window);
auto renderticks = (SDL_GetTicks() - profile); auto renderticks = (SDL_GetTicks() - profile);
@@ -609,6 +668,10 @@ class PetitComputer
break; break;
} }
} }
if(drawMessageLength)
{
//renderGraphic;
}
while(true) while(true)
{ {
long delay = (1000/60) - (cast(long)SDL_GetTicks() - profile); long delay = (1000/60) - (cast(long)SDL_GetTicks() - profile);
@@ -630,6 +693,7 @@ class PetitComputer
} }
SDL_Window* window; SDL_Window* window;
otya.smilebasic.vm.VM vm; otya.smilebasic.vm.VM vm;
int maincnt;
void run() void run()
{ {
init(); init();
@@ -710,6 +774,7 @@ class PetitComputer
//gline(0, 0, 0, 399, 239, RGB(0, 255, 0)); //gline(0, 0, 0, 399, 239, RGB(0, 255, 0));
//gfill(0, 78, 78, 40, 40, RGB(0, 255, 255)); //gfill(0, 78, 78, 40, 40, RGB(0, 255, 255));
//gbox(0, 78, 78, 40, 40, RGB(255, 255, 0)); //gbox(0, 78, 78, 40, 40, RGB(255, 255, 0));
int startcnt = SDL_GetTicks();
while (true) while (true)
{ {
uint elapse; uint elapse;
@@ -718,7 +783,7 @@ class PetitComputer
{ {
try try
{ {
if(!vsyncFrame && running) for(int i = 0; i < 128 && !vsyncFrame && running; i++)
{ {
//writefln("%04X:%s", vm.pc, vm.getCurrent); //writefln("%04X:%s", vm.pc, vm.getCurrent);
running = vm.runStep(); running = vm.runStep();
@@ -751,16 +816,8 @@ class PetitComputer
} }
} }
elapse = SDL_GetTicks() - startTicks; 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); } while(elapse <= 1000 / 60);
maincnt = (SDL_GetTicks() - startcnt) / (1000 / 60);
vsyncCount++; vsyncCount++;
if(vsyncFrame <= vsyncCount) vsyncFrame = 0; if(vsyncFrame <= vsyncCount) vsyncFrame = 0;
} }
@@ -855,7 +912,7 @@ class PetitComputer
{ {
if(format == GL_BGRA) if(format == GL_BGRA)
{ {
return petitcolor; return (petitcolor & 0xFF00FF00) | (petitcolor & 0xFF) << 16 | petitcolor >> 16 & 0xFF;
} }
if(format == GL_RGBA) if(format == GL_RGBA)
{ {
@@ -922,21 +979,25 @@ class PetitComputer
drawMessageQueue[drawMessageLength].page = page; drawMessageQueue[drawMessageLength].page = page;
drawMessageQueue[drawMessageLength].x = x; drawMessageQueue[drawMessageLength].x = x;
drawMessageQueue[drawMessageLength].y = y; drawMessageQueue[drawMessageLength].y = y;
drawMessageQueue[drawMessageLength].color = color; drawMessageQueue[drawMessageLength].color = toGLColor(this.GRP[0].textureFormat, color);
drawMessageLength++; drawMessageLength++;
} }
void sendDrawMessage(DrawType type, byte page, short x, short y, short x2, short y2, uint color) void sendDrawMessage(DrawType type, byte page, short x, short y, short x2, short y2, uint color)
{ {
grpmutex.lock(); if(drawMessageLength >= dmqqueuelen)
scope(exit) {
grpmutex.unlock(); while(drawMessageLength)
{
SDL_Delay(1);
}
}
drawMessageQueue[drawMessageLength].type = type; drawMessageQueue[drawMessageLength].type = type;
drawMessageQueue[drawMessageLength].page = page; drawMessageQueue[drawMessageLength].page = page;
drawMessageQueue[drawMessageLength].x = x; drawMessageQueue[drawMessageLength].x = x;
drawMessageQueue[drawMessageLength].y = y; drawMessageQueue[drawMessageLength].y = y;
drawMessageQueue[drawMessageLength].x2 = x2; drawMessageQueue[drawMessageLength].x2 = x2;
drawMessageQueue[drawMessageLength].y2 = y2; drawMessageQueue[drawMessageLength].y2 = y2;
drawMessageQueue[drawMessageLength].color = color; drawMessageQueue[drawMessageLength].color = toGLColor(this.GRP[0].textureFormat, color);
drawMessageLength++; drawMessageLength++;
} }
//TODO:範囲チェック //TODO:範囲チェック

View File

@@ -1,10 +1,11 @@
module otya.smilebasic.systemvariable; module otya.smilebasic.systemvariable;
import otya.smilebasic.type; import otya.smilebasic.type;
import otya.smilebasic.error; import otya.smilebasic.error;
import otya.smilebasic.vm;
class SystemVariable class SystemVariable
{ {
@property @property
abstract Value value(); abstract Value value(VM vm);
@property @property
void value(Value value) void value(Value value)
{ {
@@ -17,7 +18,7 @@ import std.conv;
class Date : SystemVariable class Date : SystemVariable
{ {
@property @property
override Value value() override Value value(VM vm)
{ {
auto currentTime = Clock.currTime(); auto currentTime = Clock.currTime();
wstring timeString = format("%04d/%02d/%02d", currentTime.year, currentTime.month, currentTime.day).to!wstring; wstring timeString = format("%04d/%02d/%02d", currentTime.year, currentTime.month, currentTime.day).to!wstring;
@@ -27,11 +28,43 @@ class Date : SystemVariable
class Time : SystemVariable class Time : SystemVariable
{ {
@property @property
override Value value() override Value value(VM vm)
{ {
auto currentTime = Clock.currTime(); auto currentTime = Clock.currTime();
wstring timeString = format("%02d:%02d:%02d", currentTime.hour, currentTime.minute, currentTime.second).to!wstring; wstring timeString = format("%02d:%02d:%02d", currentTime.hour, currentTime.minute, currentTime.second).to!wstring;
return Value(timeString); 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);
}
}