diff --git a/README.md b/README.md index 0337a5b..fc8da71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # otyaSMILEBASIC SMILEBASIC 3.x互換BASIC +## 速度 +実行環境によるものの3DSよりは速い。 +SYS/EX8TECDEMOのSPEED TEST括弧は旧3DS +たしざん 732293(153860) +PRINTぶん 351160(34391) +スプライトいどう 623998(67960) +ラインびょうが 394808(17720) ## コンパイルするのに必要なもの + DerelictSDL2 + DerelictGL3 diff --git a/SMILEBASIC/bg.d b/SMILEBASIC/bg.d index 213a1a0..95e025b 100644 --- a/SMILEBASIC/bg.d +++ b/SMILEBASIC/bg.d @@ -66,13 +66,13 @@ class BG int w = 16; int h = 16; glTexCoord2f((u) / 512f - 1 , (v2) / 512f - 1); - glVertex3f((x * w) / 200f - 1, 1 - (y * h + h) / 120f, 0); + glVertex3f((x * w) / disw - 1, 1 - (y * h + h) / dish, 0); glTexCoord2f((u) / 512f - 1, (v) / 512f - 1); - glVertex3f((x * w) / 200f - 1, 1 - (y * h) / 120f, 0); + glVertex3f((x * w) / disw - 1, 1 - (y * h) / dish, 0); glTexCoord2f((u2) / 512f - 1, (v) / 512f - 1); - glVertex3f((x * w + w) / 200f - 1, 1 - (y * h) / 120f, 0); + glVertex3f((x * w + w) / disw - 1, 1 - (y * h) / dish, 0); glTexCoord2f((u2) / 512f - 1, (v2) / 512f - 1); - glVertex3f((x * w + w) / 200f - 1, 1 - (y * h + h) / 120f, 0); + glVertex3f((x * w + w) / disw - 1, 1 - (y * h + h) / dish, 0); rendercount++; if(rendercount >= 899) { diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 0ebd06a..3c538ef 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -178,7 +178,12 @@ class BuiltinFunction static void XSCREEN(PetitComputer p, int mode, DefaultValue!(int, false) a, DefaultValue!(int, false) b) { a.setDefaultValue(512); - b.setDefaultValue(512); + b.setDefaultValue(4); + if(mode == 2 || mode == 3) + { + a.setDefaultValue(256); + b.setDefaultValue(2); + } p.xscreen(mode, cast(int)a, cast(int)b); } static void DISPLAY(PetitComputer p, int display) @@ -648,51 +653,51 @@ class BuiltinFunction { if(layer.isDefault) { - foreach(bg; p.bg) + foreach(bg; p.allBG) { bg.clear; } return; } - p.bg[cast(int)layer].clear; + p.getBG(cast(int)layer).clear; } static void BGSCREEN(PetitComputer p, int layer, int w, int h) { - p.bg[layer].screen(w, h); + p.getBG(layer).screen(w, h); } static void BGOFS(PetitComputer p, int layer, int x, int y, DefaultValue!(int, false) z) { - z.setDefaultValue(p.bg[layer].offsetz); - p.bg[layer].ofs(x, y, cast(int)z); + z.setDefaultValue(p.getBG(layer).offsetz); + p.getBG(layer).ofs(x, y, cast(int)z); } static void BGCLIP(PetitComputer p, int layer, DefaultValue!(int, false) x, DefaultValue!(int, false) y, DefaultValue!(int, false) x2, DefaultValue!(int, false) y2) { if(x.isDefault && y.isDefault && x2.isDefault && y2.isDefault) { - p.bg[layer].clip(); + p.getBG(layer).clip(); } if(x.isDefault || y.isDefault || x2.isDefault || y2.isDefault) { throw new IllegalFunctionCall("BGCLIP"); } - p.bg[layer].clip(cast(int)x, cast(int)y, cast(int)x2, cast(int)y2); + p.getBG(layer).clip(cast(int)x, cast(int)y, cast(int)x2, cast(int)y2); } static void BGPUT(PetitComputer p, int layer, int x, int y, int screendata) { - p.bg[layer].put(x, y, screendata); + p.getBG(layer).put(x, y, screendata); } static void BGHOME(PetitComputer p, int layer, int x, int y) { - p.bg[layer].home(x, y); + p.getBG(layer).home(x, y); } static void BGSCALE(PetitComputer p, int layer, double x, double y) { - p.bg[layer].scale(x, y); + p.getBG(layer).scale(x, y); } static void BGROT(PetitComputer p, int layer, double rot) { - p.bg[layer].rot(rot); + p.getBG(layer).rot(rot); } //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; static BuiltinFunction[wstring] builtinFunctions; diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index e7c3e25..5966bc6 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -194,8 +194,24 @@ class PetitComputer ConsoleCharacter[][] console; ConsoleCharacter[][] consoleDisplay1; bool visibleGRP = true; - int showGRP; - int useGRP; + private int[2] showPage = [0, 1]; + private int[2] usePage = [0, 1]; + @property int useGRP() + { + return usePage[displaynum]; + } + @property int showGRP() + { + return showPage[displaynum]; + } + @property void useGRP(int page) + { + usePage[displaynum] = page; + } + @property void showGRP(int page) + { + showPage[displaynum] = page; + } uint gcolor = -1; GraphicPage[] GRP; GraphicPage GRPF; @@ -423,6 +439,7 @@ class PetitComputer } void display(int number) { + displaynum = number; if(number) { consoleHeightC = consoleHeightDisplay1; @@ -466,7 +483,7 @@ class PetitComputer } Mutex grpmutex; otya.smilebasic.draw.Draw draw; - bool displaynum; + int displaynum; void renderGraphic() { if(!drawMessageLength) return; @@ -481,7 +498,8 @@ class PetitComputer GLint old; auto a = & glBindFramebuffer; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old); - glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[showGRP].buffer); + int oldpage = drawMessageQueue[0].page; + glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer); glDisable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); @@ -491,6 +509,11 @@ class PetitComputer for(int i = s; i < len; i++) { DrawMessage dm = drawMessageQueue[i]; + if(oldpage != dm.page) + { + oldpage = dm.page; + glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer); + } switch(dm.type) { case DrawType.PSET: @@ -547,9 +570,12 @@ class PetitComputer Button[] buttonTable; Sprite sprite; int xscreenmode = 0; + int bgmax; void xscreen(int mode, int sprite, int bg) { this.sprite.spclr(); + this.sprite.spmax = sprite; + this.bgmax = bg; //BG int mode2 = mode / 2; if(mode2 == 0) @@ -566,7 +592,19 @@ class PetitComputer } xscreenmode = mode2; } - BG[4] bg; + BG getBG(int layer) + { + if(displaynum) + { + return bg[layer + bgmax]; + } + return bg[layer]; + } + BG[] allBG() + { + return bg; + } + protected BG[4] bg; void render() { DerelictGL.load(); @@ -640,12 +678,12 @@ class PetitComputer loopcnt = 0; } } + glLoadIdentity(); + renderGraphic(); if(xscreenmode == 1) { glViewport(0, 240, 400, 240); } - glLoadIdentity(); - renderGraphic(); //描画の順位 //sprite>GRP>console>BG glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -656,18 +694,45 @@ class PetitComputer glViewport(0, 240, 400, 240); } sprite.render(); - renderGraphicPage(); + if(xscreenmode == 1) + { + glViewport(0, 240, 400, 240); + } + renderGraphicPage(0, 400, 240); + if(xscreenmode == 1) + { + glViewport(40, 0, 320, 240); + renderGraphicPage(1, 320, 240); + glViewport(0, 240, 400, 240); + } renderConsoleGL(); + if(xscreenmode == 1) + { + glViewport(0, 240, 400, 240); + } version(test) glLoadIdentity(); version(test) glRotatef(45f, 1f, 0f, 0.5f); glBindTexture(GL_TEXTURE_2D, GRP[bgpage].glTexture); - for(int i = 0; i < bg.length; i++) + for(int i = 0; i < bgmax; i++) { bg[i].render(400f, 240f); } + if(xscreenmode == 1) + { + glViewport(40, 0, 320, 240); + for(int i = bgmax; i < bg.length; i++) + { + bg[i].render(320f, 240f); + } + glViewport(0, 240, 400, 240); + } version(test) glLoadIdentity(); version(test) glRotatef(45f, 1f, 0f, 0.5f); + if(xscreenmode == 1) + { + glViewport(0, 240, 400, 240); + } SDL_GL_SwapWindow(window); auto renderticks = (SDL_GetTicks() - profile); if(renderprofile) writeln(renderticks); @@ -1068,21 +1133,21 @@ class PetitComputer sendDrawMessage(DrawType.FILL, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color); } int gprio; - void renderGraphicPage() + void renderGraphicPage(int display, float w, float h) { float z = gprio / 1025f; glColor3f(1.0, 1.0, 1.0); - glBindTexture(GL_TEXTURE_2D, GRP[showGRP].glTexture); + glBindTexture(GL_TEXTURE_2D, GRP[showPage[display]].glTexture); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); - glTexCoord2f(0 / 512f - 1 , 240 / 512f - 1); - glVertex3f(0 / 200f - 1, 1 - 240 / 120f, z); + glTexCoord2f(0 / 512f - 1 , h / 512f - 1); + glVertex3f(-1, -1, z); glTexCoord2f(0 / 512f - 1, 0 / 512f - 1); - glVertex3f(0 / 200f - 1, 1 - 0 / 120f, z); - glTexCoord2f(400 / 512f - 1, 0 / 512f - 1); - glVertex3f(400 / 200f - 1, 1 - 0 / 120f, z); - glTexCoord2f(400 / 512f - 1, 240 / 512f - 1); - glVertex3f(400 / 200f - 1, 1 - 240 / 120f, z); + glVertex3f(-1, 1, z); + glTexCoord2f(w / 512f - 1, 0 / 512f - 1); + glVertex3f(1, 1, z); + glTexCoord2f(w / 512f - 1, h / 512f - 1); + glVertex3f(1, -1, z); glEnd(); //glFlush(); } diff --git a/SMILEBASIC/sprite.d b/SMILEBASIC/sprite.d index 4cddf47..d99ce97 100644 --- a/SMILEBASIC/sprite.d +++ b/SMILEBASIC/sprite.d @@ -244,6 +244,7 @@ class Sprite SpriteData[] sprites; PetitComputer petitcom; string spdefTableFile = "spdef.csv"; + int spmax = 512; void initUVTable() { SPDEFTable = new SpriteDef[4096]; @@ -269,10 +270,12 @@ class Sprite } void spchr(int i, int d) { + i = spid(i); sprites[i].change(SPDEFTable[d]); } void spchr(int id, int u, int v, int w, int h, SpriteAttr attr) { + id = spid(id); auto spdef = SpriteDef(u, v, w, h, sprites[id].homex, sprites[id].homey, attr); sprites[id].change(spdef); } @@ -387,9 +390,11 @@ class Sprite import std.algorithm; void render() { + float disw = 200f, dish = 120f, disw2 = 400f, dish2 = 240f; auto texture = petitcom.GRP[petitcom.sppage].glTexture; - float aspect = 400f / 240f; + float aspect = disw2 / dish2; float z = -0.01f; + int spmax = petitcom.xscreenmode == 1 ? this.spmax : -1;//XSCREENが2,3じゃないと下画面は描画しない glBindTexture(GL_TEXTURE_2D, texture); glEnable(GL_TEXTURE_2D); // glDisable(GL_TEXTURE_2D); @@ -397,6 +402,13 @@ class Sprite glLoadIdentity(); foreach(i,ref sprite; sprites) { + if(i == spmax) + { + disw = 160f; + disw2 = 320f; + glViewport(40, 0, 320, 240); + aspect = disw2 / dish2; + } //定義されてたら動かす if(sprite.define) { @@ -406,8 +418,8 @@ class Sprite { int x = cast(int)sprite.x;// - cast(int)(sprite.homex * sprite.scalex); int y = cast(int)sprite.y;// - cast(int)(sprite.homey * sprite.scaley); - auto homex2 = ((sprite.w / 2 ) - sprite.homex) / 200f; - auto homey2 = ((sprite.h / 2 ) - sprite.homey) / 120f; + auto homex2 = ((sprite.w / 2 ) - sprite.homex) / dish; + auto homey2 = ((sprite.h / 2 ) - sprite.homey) / dish; int w = sprite.w; int h = sprite.h; @@ -435,9 +447,9 @@ class Sprite } version(test) glRotatef(45f, 1f, 0f, 0.5f); - glTranslatef((flipx2) / 200f - 1, - 1 - ((flipy2) / 120f), 0); - //glTranslatef((flipx2) / 200f - 1,1 - ((flipy2) / 120f), 0); + glTranslatef((flipx2) / disw - 1, + 1 - ((flipy2) / dish), 0); + //glTranslatef((flipx2) / dish - 1,1 - ((flipy2) / dish), 0); //glScalef(flipx, flipy, 1f); //アスペクト比を調節しないといけないらしい //https://groups.google.com/forum/#!topic/android-group-japan/45mjecPSY4s @@ -453,21 +465,21 @@ class Sprite /*glTexCoord2f(u / 512f - 1, v / 512f - 1); glVertex3f(0, 0, z);//1 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1); - glVertex3f(0, -(sprite.h / 120f), z);//2 + glVertex3f(0, -(sprite.h / dish), z);//2 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); - glVertex3f(sprite.w / 200f, -(sprite.h / 120f), z);//3 + glVertex3f(sprite.w / dish, -(sprite.h / dish), z);//3 glTexCoord2f(u2 / 512f - 1, v / 512f - 1); - glVertex3f(sprite.w / 200f, 0, z);//4*/ + glVertex3f(sprite.w / dish, 0, z);//4*/ //glColor3f(0,1,0); glTexCoord2f(u / 512f - 1, v / 512f - 1); - glVertex3f(-((sprite.w) / 400f - homex2) , ((sprite.h) / 240f - homey2), z);//1 + glVertex3f(-((sprite.w) / disw2 - homex2) , ((sprite.h) / dish2 - homey2), z);//1 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1); - glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glVertex3f(-((sprite.w) / disw2 - homex2), -((sprite.h) / dish2 + homey2), z);//2 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); - glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3//y+--+x--++ + glVertex3f((sprite.w) / disw2 + homex2, -((sprite.h) / dish2 + homey2), z);//3//y+--+x--++ glTexCoord2f(u2 / 512f - 1, v / 512f - 1); - glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 + glVertex3f((sprite.w) / disw2 + homex2, ((sprite.h) / dish2 - homey2), z);//4 glEnd(); /* glDisable(GL_TEXTURE_2D); @@ -475,7 +487,7 @@ class Sprite glBegin(GL_POINTS); glVertex3f(0,0,-0.9); glColor3f(0,1,0); - glVertex3f(-((sprite.w) / 400f),((sprite.h) / 240f),-0.9); + glVertex3f(-((sprite.w) / dish2),((sprite.h) / dish2),-0.9); glEnd(); glEnable(GL_TEXTURE_2D);*/ glLoadIdentity(); @@ -484,13 +496,13 @@ class Sprite if((sprite.attr & SpriteAttr.rotate270) == SpriteAttr.rotate270) { glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//3 - glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 + glVertex3f(-((sprite.w) / disw2 - homex2), ((sprite.h) / dish2 - homey2), z);//1 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glVertex3f(-((sprite.w) / disw2 - homex2), -((sprite.h) / dish2 + homey2), z);//2 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 + glVertex3f((sprite.w) / disw2 + homex2, -((sprite.h) / dish2 + homey2), z);//3 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//4 - glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 + glVertex3f((sprite.w) / disw2 + homex2, ((sprite.h) / dish2 - homey2), z);//4 glEnd(); glLoadIdentity(); continue; @@ -498,13 +510,13 @@ class Sprite if((sprite.attr & SpriteAttr.rotate90) == SpriteAttr.rotate90) { glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 + glVertex3f(-((sprite.w) / disw2 - homex2), ((sprite.h) / dish2 - homey2), z);//1 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//3 - glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glVertex3f(-((sprite.w) / disw2 - homex2), -((sprite.h) / dish2 + homey2), z);//2 glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//4 - glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 + glVertex3f((sprite.w) / disw2 + homex2, -((sprite.h) / dish2 + homey2), z);//3 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 + glVertex3f((sprite.w) / disw2 + homex2, ((sprite.h) / dish2 - homey2), z);//4 glEnd(); glLoadIdentity(); continue; @@ -512,57 +524,71 @@ class Sprite if((sprite.attr & SpriteAttr.rotate180) == SpriteAttr.rotate180) { glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//4 - glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 + glVertex3f(-((sprite.w) / disw2 - homex2), ((sprite.h) / dish2 - homey2), z);//1 glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//3 - glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glVertex3f(-((sprite.w) / disw2 - homex2), -((sprite.h) / dish2 + homey2), z);//2 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 + glVertex3f((sprite.w) / disw2 + homex2, -((sprite.h) / dish2 + homey2), z);//3 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 + glVertex3f((sprite.w) / disw2 + homex2, ((sprite.h) / dish2 - homey2), z);//4 glEnd(); glLoadIdentity(); continue; } glTexCoord2f(u / 512f - 1, v / 512f - 1); - glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 + glVertex3f(-((sprite.w) / disw2 - homex2), ((sprite.h) / dish2 - homey2), z);//1 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1); - glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glVertex3f(-((sprite.w) / disw2 - homex2), -((sprite.h) / dish2 + homey2), z);//2 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); - glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 + glVertex3f((sprite.w) / disw2 + homex2, -((sprite.h) / dish2 + homey2), z);//3 glTexCoord2f(u2 / 512f - 1, v / 512f - 1); - glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 + glVertex3f((sprite.w) / disw2 + homex2, ((sprite.h) / dish2 - homey2), z);//4 glEnd(); glLoadIdentity(); continue; } } } + int spid(int id) + { + if(petitcom.displaynum == 1) + { + return id + this.spmax; + } + return id; + } void spset(int id, int defno) { + id = spid(id); sprites[id] = SpriteData(id, SPDEFTable[defno], defno); } void spset(int id, int u, int v, int w, int h, SpriteAttr attr) { + id = spid(id); auto spdef = SpriteDef(u, v, w, h, 0, 0, attr); sprites[id] = SpriteData(id, spdef, 0/*要調査*/); } void spofs(int id, int x, int y) { + id = spid(id); sprites[id].x = x; sprites[id].y = y; } void spofs(int id, int x, int y, int z) { + id = spid(id); sprites[id].x = x; sprites[id].y = y; sprites[id].z = z; } void sphide(int id) { + id = spid(id); sprites[id].attr ^= SpriteAttr.show; } void spshow(int id) { + id = spid(id); sprites[id].attr |= SpriteAttr.show; } void spanim(int id, wstring target, double[] data) @@ -592,6 +618,7 @@ class Sprite } void spanim(int id, SpriteAnimTarget target, double[] data) { + id = spid(id); bool relative; if(SpriteAnimTarget.relative & target) { @@ -618,27 +645,31 @@ class Sprite } void spclr(int id) { + id = spid(id); sprites[id].clear; } void spclr() { for(int i = 0; i < sprites.length; i++) { - spclr(i); + sprites[i].clear; } } void sphome(int i, int hx, int hy) { + i = spid(i); sprites[i].homex = hx; sprites[i].homey = hy; } void spscale(int i, double x, double y) { + i = spid(i); sprites[i].scalex = x; sprites[i].scaley = y; } void sprot(int i, double rot) { + i = spid(i); sprites[i].r = rot; } }