diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 3f5d390..d5d18ec 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -443,9 +443,11 @@ class Operate : Code //数値 * 文字列だとエラー case TokenType.Mul: { - wstring delegate(wstring, wstring, int) mul; - mul = (x, y, z) => z > 0 ? x ~ mul(x , y, z - 1) : ""; - vm.push(Value(mul(ls, ls, cast(int)rd))); + //wstring delegate(wstring, wstring, int) mul; + //mul = (x, y, z) => z > 0 ? x ~ mul(x , y, z - 1) : ""; + //vm.push(Value(mul(ls, ls, cast(int)rd))); + import std.array : replicate; + vm.push(Value(replicate(ls, cast(int)rd))); } return; //3.1から?文字列と数値を比較すると3を返す @@ -512,22 +514,22 @@ class Operate : Code vm.push(Value(li ^ ri)); return; case TokenType.Equal: - vm.push(Value(li == ri)); + vm.push(Value(ld == rd)); return; case TokenType.NotEqual: - vm.push(Value(li != ri)); + vm.push(Value(ld != rd)); return; case TokenType.Less: - vm.push(Value(li < ri)); + vm.push(Value(ld < rd)); return; case TokenType.LessEqual: - vm.push(Value(li <= ri)); + vm.push(Value(ld <= rd)); return; case TokenType.Greater: - vm.push(Value(li > ri)); + vm.push(Value(ld > rd)); return; case TokenType.GreaterEqual: - vm.push(Value(li >= ri)); + vm.push(Value(ld >= rd)); return; case TokenType.LeftShift: vm.push(Value(li << ri)); diff --git a/SMILEBASIC/bg.d b/SMILEBASIC/bg.d index ea95182..7248f86 100644 --- a/SMILEBASIC/bg.d +++ b/SMILEBASIC/bg.d @@ -16,6 +16,7 @@ class BG BGChip[16384] chip; int offsetx, offsety, offsetz; int clipx, clipy, clipx2, clipy2; + int homex, homey; int width, height; int rendermax = 899; PetitComputer petitcom; @@ -30,10 +31,11 @@ class BG { disw/=2; dish/=2; - int z = 0; + float z = offsetz / 1025f; glColor3f(1.0, 1.0, 1.0); glLoadIdentity(); - glTranslatef(offsetx / disw, -(offsety / dish), z); + glTranslatef((-offsetx + homex) / disw, -((-offsety + homey) / dish), z); + version(test) glRotatef(45f, 1f, 0f, 0.5f); //viewport //clipx,clipy glBegin(GL_QUADS); @@ -107,4 +109,9 @@ class BG this.clipx2 = 400; this.clipy2 = 240; } + void home(int x, int y) + { + homex = x; + homey = y; + } } diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 9550759..adb5e8d 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -216,6 +216,7 @@ class BuiltinFunction } static void GPRIO(PetitComputer p, int z) { + p.gprio = z; } static void GPAGE(PetitComputer p, int showPage, int usePage) { @@ -380,10 +381,66 @@ class BuiltinFunction formatValue(w, val, f); return cast(immutable)(w.data); } - static void SPSET(PetitComputer p, int id, int defno) + static void SPSET(PetitComputer p, int id, int defno, DefaultValue!(int, false) V, DefaultValue!(int, false) W, DefaultValue!(int, false) H, DefaultValue!(int, false) ATTR) { + if(!V.isDefault && !W.isDefault) + { + int u = defno; + int v = cast(int)V; + int w = 16, h = 16, attr = 1; + if(!ATTR.isDefault) + { + w = cast(int)W; + h = cast(int)H; + attr = cast(int)ATTR; + } + else + { + if(!W.isDefault && !H.isDefault) + { + w = cast(int)W; + h = cast(int)H; + } + if(!W.isDefault && H.isDefault) + { + attr = cast(int)W; + } + } + p.sprite.spset(id, u, v, w, h, cast(SpriteAttr)attr); + return; + } p.sprite.spset(id, defno); } + static void SPCHR(PetitComputer p, int id, int defno, DefaultValue!(int, false) V, DefaultValue!(int, false) W, DefaultValue!(int, false) H, DefaultValue!(int, false) ATTR) + { + if(!V.isDefault && !W.isDefault) + { + int u = defno; + int v = cast(int)V; + int w = 16, h = 16, attr = 1; + if(!ATTR.isDefault) + { + w = cast(int)W; + h = cast(int)H; + attr = cast(int)ATTR; + } + else + { + if(!W.isDefault && !H.isDefault) + { + w = cast(int)W; + h = cast(int)H; + } + if(!W.isDefault && H.isDefault) + { + attr = cast(int)W; + } + } + p.sprite.spchr(id, u, v, w, h, cast(SpriteAttr)attr); + return; + } + p.sprite.spchr(id, defno); + } static void SPHIDE(PetitComputer p, int id) { p.sprite.sphide(id); @@ -394,7 +451,7 @@ class BuiltinFunction } static void SPOFS(PetitComputer p, int id, int x, int y, DefaultValue!(int, false) z) { - p.sprite.spofs(id, x, y); + p.sprite.spofs(id, x, y, cast(int)z); } static void SPANIM(PetitComputer p, Value[] va_args) { @@ -489,10 +546,14 @@ class BuiltinFunction { p.sprite.sphome(i, hx, hy); } - static void SPSCALE(PetitComputer p, int i, int x, int y) + static void SPSCALE(PetitComputer p, int i, double x, double y) { p.sprite.spscale(i, x, y); } + static void SPROT(PetitComputer p, int i, double rot) + { + p.sprite.sprot(i, rot); + } static void BGMSTOP(PetitComputer p) { writeln("NOTIMPL:BGMSTOP"); @@ -535,8 +596,8 @@ class BuiltinFunction if(d != -1) { auto spec = singleSpec(format[i .. d + 1]); - spec.spec = 'x'; - formatValue(w, args[j].castDouble, spec); + spec.spec = cast(char)format[d]; + formatValue(w, args[j].castInteger, spec); j++; i = d; continue; @@ -621,6 +682,10 @@ class BuiltinFunction { p.bg[layer].put(x, y, screendata); } + static void BGHOME(PetitComputer p, int layer, int x, int y) + { + p.bg[layer].home(x, y); + } //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; static BuiltinFunction[wstring] builtinFunctions; static this() diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index fe114b4..a85ca01 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -410,7 +410,6 @@ class Compiler case NodeType.CallFunction: { auto func = cast(CallFunction)exp; - writeln(func.name); auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null); if(bfun) { @@ -433,6 +432,7 @@ class Compiler } else { + writeln(func.name); genCode(new CallFunctionCode(func.name, func.args.length)); } } @@ -801,7 +801,6 @@ class Compiler case NodeType.CallFunctionStatement: { auto func = cast(CallFunctionStatement)i; - writeln(func.name); auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null); if(bfun) { @@ -821,6 +820,7 @@ class Compiler } else { + writeln(func.name); genCode(new CallFunctionCode(func.name, func.args.length, func.outVariable.length)); } //TODO:OUT diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index 3450d74..5e3d9b7 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -45,7 +45,7 @@ class SyntaxError : SmileBasicError this(wstring func) { this(); - this.message2 = "Undefine function (" ~ func.to!string ~ ")"; + this.message2 = "Undefined function (" ~ func.to!string ~ ")"; } } class IllegalFunctionCall : SmileBasicError diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 471f473..aa16c7d 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -52,6 +52,7 @@ class Lexical reserved["FOR"] = TokenType.For; reserved["NEXT"] = TokenType.Next; reserved["MOD"] = TokenType.Mod; + reserved["DIV"] = TokenType.IntDiv; reserved["GOSUB"] = TokenType.Gosub; reserved["RETURN"] = TokenType.Return; reserved["END"] = TokenType.End; @@ -303,13 +304,14 @@ class Lexical } token = Token(table[cast(char)c]); i++; + //CRLFだった if(token.type == TokenType.NewLine) { line++; - if(c == '\n') + if(c == '\r') { //CRLF - if(i < code.length && code[i] == '\r') + if(i < code.length && code[i] == '\n') { i++; } @@ -744,7 +746,6 @@ class Parser { auto token = lex.front(); Statement node = null; - writeln(token.type); switch(token.type) { case TokenType.Print: diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 4844346..a3477c1 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -39,6 +39,27 @@ class GraphicPage this(SDL_Surface* s) { surface = s; + + GLenum texture_format; + GLint nOfColors; + nOfColors = surface.format.BytesPerPixel; + if (nOfColors == 4) // contains an alpha channel + { + if (surface.format.Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + } else if (nOfColors == 3) // no alpha channel + { + if (surface.format.Rmask == 0x000000ff) + texture_format = GL_RGB; + else + texture_format = GL_BGR; + } else { + //printf("warning: the image is not truecolor.. this will probably break\n"); + // this error should not go unhandled + } + textureFormat = texture_format; } GLuint glTexture; GLenum textureFormat; @@ -225,13 +246,23 @@ class PetitComputer } GraphicPage createEmptyPage() { - auto surface = SDL_CreateRGBSurface(0, 512, 512, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0xff); + auto surface = SDL_CreateRGBSurface(0, 512, 512, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); auto pixels = (cast(uint*)surface.pixels); for(int x = 0; x < surface.w; x++) { for(int y = 0; y < surface.h; y++) { - *pixels++ = 0; + ubyte r, g, b, a; + SDL_GetRGBA(*pixels, surface.format, &r, &g, &b, &a); + { + r = 0; + g = 0; + b = 0; + a = 0; + *pixels = 0; + *pixels = SDL_MapRGBA(surface.format, r, g, b, a); + } + pixels++; } } return new GraphicPage(surface); @@ -452,7 +483,10 @@ class PetitComputer glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old); glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[showGRP].buffer); glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); + // + //glAlphaFunc(GL_GEQUAL, 0.0); glViewport(0, 0, 512, 512); for(int i = s; i < len; i++) { @@ -461,7 +495,7 @@ class PetitComputer { case DrawType.PSET: glBegin(GL_POINTS); - glColor3ubv(cast(ubyte*)&dm.color); + glColor4ubv(cast(ubyte*)&dm.color); glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); glEnd(); //draw.gpset(dm.page, dm.x, dm.y ,dm.color); @@ -469,7 +503,7 @@ class PetitComputer case DrawType.LINE: { glBegin(GL_LINES); - glColor3ubv(cast(ubyte*)&dm.color); + glColor4ubv(cast(ubyte*)&dm.color); glVertex2f((dm.x) / 256f - 1, (dm.y) / 256f - 1); glVertex2f((dm.x2) / 256f - 1, (dm.y2) / 256f - 1); //glFlush(); @@ -480,7 +514,7 @@ class PetitComputer case DrawType.FILL: { glBegin(GL_QUADS); - glColor3ubv(cast(ubyte*)&dm.color); + glColor4ubv(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); @@ -492,7 +526,7 @@ class PetitComputer case DrawType.BOX: { glBegin(GL_LINE_LOOP); - glColor3ubv(cast(ubyte*)&dm.color); + glColor4ubv(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); @@ -504,17 +538,19 @@ class PetitComputer default: } } - glFlush(); glBindFramebufferEXT(GL_FRAMEBUFFER, old); glEnable(GL_DEPTH_TEST); drawflag = false; glViewport(0, 0, 400, 240); + glEnable(GL_ALPHA_TEST); } Button[] buttonTable; Sprite sprite; int xscreenmode = 0; void xscreen(int mode, int sprite, int bg) { + this.sprite.spclr(); + //BG int mode2 = mode / 2; if(mode2 == 0) { @@ -583,11 +619,14 @@ class PetitComputer //GRP[0] = GRPF; //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glAlphaFunc(GL_GEQUAL, 0.5); - glEnable(GL_ALPHA_TEST); + //glAlphaFunc(GL_GEQUAL, 0.5); + //glEnable(GL_ALPHA_TEST); draw = new otya.smilebasic.draw.Draw(this); // sprite.spset(0, 0); // sprite.spofs(0, 9, 8); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glAlphaFunc(GL_GEQUAL, 0.5); + glEnable(GL_ALPHA_TEST); while(true) { auto profile = SDL_GetTicks(); @@ -605,20 +644,29 @@ class PetitComputer { glViewport(0, 240, 400, 240); } + glLoadIdentity(); renderGraphic(); + //描画の順位 + //sprite>GRP>console>BG glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - renderGraphicPage(); - renderConsoleGL(); + version(test) glLoadIdentity(); + version(test) glRotatef(45f, 1f, 0f, 0.5f); if(xscreenmode == 1) { glViewport(0, 240, 400, 240); } sprite.render(); + renderGraphicPage(); + renderConsoleGL(); + 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++) { bg[i].render(400f, 240f); } + version(test) glLoadIdentity(); + version(test) glRotatef(45f, 1f, 0f, 0.5f); SDL_GL_SwapWindow(window); auto renderticks = (SDL_GetTicks() - profile); @@ -912,6 +960,7 @@ class PetitComputer { if(format == GL_BGRA) { + //ARGB->BGRA return (petitcolor & 0xFF00FF00) | (petitcolor & 0xFF) << 16 | petitcolor >> 16 & 0xFF; } if(format == GL_RGBA) @@ -1017,9 +1066,10 @@ 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() { - float z = 0.01f; + float z = gprio / 1025f; glColor3f(1.0, 1.0, 1.0); glBindTexture(GL_TEXTURE_2D, GRP[showGRP].glTexture); glEnable(GL_TEXTURE_2D); @@ -1047,10 +1097,10 @@ class PetitComputer { auto back = consoleColorGL[console[y][x].backColor]; glColor4ubv(cast(ubyte*)&back); - glVertex3f((x * 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 0.9f); - glVertex3f((x * 8) / 200f - 1, 1 - (y * 8) / 120f, 0.9f); - glVertex3f((x * 8 + 8) / 200f - 1, 1 - (y * 8) / 120f, 0.9f); - glVertex3f((x * 8 + 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 0.9f); + glVertex3f((x * 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 1f); + glVertex3f((x * 8) / 200f - 1, 1 - (y * 8) / 120f, 1f); + glVertex3f((x * 8 + 8) / 200f - 1, 1 - (y * 8) / 120f, 1f); + glVertex3f((x * 8 + 8) / 200f - 1, 1 - (y * 8 + 8) / 120f, 1f); } if(showCursor && animationCursor) { diff --git a/SMILEBASIC/sprite.d b/SMILEBASIC/sprite.d index c4a96d8..4cddf47 100644 --- a/SMILEBASIC/sprite.d +++ b/SMILEBASIC/sprite.d @@ -74,7 +74,7 @@ struct SpriteAnimData bool interpolation;//線形補完するかどうか SpriteAnimState data; SpriteAnimState old; - int load(int i, ref SpriteData sprite, SpriteAnimTarget target, double[] data) + int load(int i, ref SpriteData sprite, SpriteAnimTarget target, double[] data, SpriteAnimData* old) { this.frame = cast(int)data[i]; if(this.frame < 0) @@ -92,31 +92,32 @@ struct SpriteAnimData case SpriteAnimTarget.XY: this.data.x = cast(int)data[i++]; this.data.y = cast(int)data[i++]; - this.old.x = sprite.x; - this.old.y = sprite.y; + this.old.x = old ? old.data.x : sprite.x; + this.old.y = old ? old.data.y : sprite.y; break; case SpriteAnimTarget.Z: this.data.z = cast(int)data[i++]; - this.old.z = sprite.z; + this.old.z = old ? old.data.z : sprite.z; break; case SpriteAnimTarget.UV: this.data.u = cast(int)data[i++]; this.data.v = cast(int)data[i++]; - this.old.u = sprite.u; - this.old.v = sprite.v; + this.old.u = old ? old.data.u : sprite.u; + this.old.v = old ? old.data.v : sprite.v; break; case SpriteAnimTarget.I: this.data.i = cast(int)data[i++]; - this.old.i = sprite.defno; + this.old.i = old ? old.data.i : sprite.defno; break; case SpriteAnimTarget.R: this.data.r = data[i++]; + this.old.r = old ? old.data.r : sprite.r; break; case SpriteAnimTarget.S: this.data.scalex = data[i++]; this.data.scaley = data[i++]; - this.old.scalex = sprite.scalex; - this.old.scaley = sprite.scaley; + this.old.scalex = old ? old.data.scalex : sprite.scalex; + this.old.scaley = old ? old.data.scaley : sprite.scaley; break; case SpriteAnimTarget.C: this.data.c = cast(uint)data[i++]; @@ -150,6 +151,7 @@ struct SpriteData bool define;//定義されてればtrue double scalex; double scaley; + double r; this(bool flag) { define = false; @@ -158,6 +160,8 @@ struct SpriteData { x = 0; y = 0; + z = 0; + r = 0; this.id = id; this.defno = defno; this.color = -1; @@ -170,6 +174,8 @@ struct SpriteData { x = 0; y = 0; + z = 0; + r = 0; this.id = id; this.u = u; this.v = v; @@ -185,6 +191,8 @@ struct SpriteData { x = 0; y = 0; + z = 0; + r = 0; this.id = id; this.u = spdef.u; this.v = spdef.v; @@ -263,6 +271,11 @@ class Sprite { sprites[i].change(SPDEFTable[d]); } + void spchr(int id, int u, int v, int w, int h, SpriteAttr attr) + { + auto spdef = SpriteDef(u, v, w, h, sprites[id].homex, sprites[id].homey, attr); + sprites[id].change(spdef); + } this(PetitComputer petitcom) { sprites = new SpriteData[512]; @@ -280,41 +293,7 @@ class Sprite SpriteAnimData* data = &d[index]; data.elapse = data.elapse + 1; auto frame = data.elapse; - if(data.interpolation) - { - //線形補完する奴 - switch(target) - { - case SpriteAnimTarget.XY: - sprite.x = data.old.x + ((data.data.x - data.old.x) / data.frame) * frame; - sprite.y = data.old.y + ((data.data.y - data.old.y) / data.frame) * frame; - break; - case SpriteAnimTarget.Z: - sprite.z = data.old.z + ((data.data.z - data.old.z) / data.frame) * frame; - break; - case SpriteAnimTarget.UV: - sprite.u = data.old.u + ((data.data.u - data.old.u) / data.frame) * frame; - sprite.v = data.old.v + ((data.data.v - data.old.v) / data.frame) * frame; - break; - case SpriteAnimTarget.I: - sprite.defno = data.old.i + ((data.data.i - data.old.i) / data.frame) * frame; - spchr(sprite.id, sprite.defno); - break; - case SpriteAnimTarget.R: - break; - case SpriteAnimTarget.S: - sprite.scalex = data.old.scalex + ((data.data.scalex - data.old.scalex) / data.frame) * frame; - sprite.scaley = data.old.scaley + ((data.data.scaley - data.old.scaley) / data.frame) * frame; - break; - case SpriteAnimTarget.C: - break; - case SpriteAnimTarget.V: - break; - default: - break; - } - } - if(frame >= data.frame) + if(frame == 1) { if(!data.interpolation) { @@ -336,6 +315,7 @@ class Sprite spchr(sprite.id, sprite.defno); break; case SpriteAnimTarget.R: + sprite.r = data.data.r; break; case SpriteAnimTarget.S: sprite.scalex = data.data.scalex; @@ -349,6 +329,44 @@ class Sprite break; } } + } + if(data.interpolation) + { + //線形補完する奴 + switch(target) + { + case SpriteAnimTarget.XY: + sprite.x = data.old.x + ((data.data.x - data.old.x) / data.frame) * frame; + sprite.y = data.old.y + ((data.data.y - data.old.y) / data.frame) * frame; + break; + case SpriteAnimTarget.Z: + sprite.z = data.old.z + ((data.data.z - data.old.z) / data.frame) * frame; + break; + case SpriteAnimTarget.UV: + sprite.u = data.old.u + ((data.data.u - data.old.u) / data.frame) * frame; + sprite.v = data.old.v + ((data.data.v - data.old.v) / data.frame) * frame; + break; + case SpriteAnimTarget.I: + sprite.defno = data.old.i + ((data.data.i - data.old.i) / data.frame) * frame; + spchr(sprite.id, sprite.defno); + break; + case SpriteAnimTarget.R: + sprite.r = data.old.r + ((data.data.r - data.old.r) / data.frame) * frame; + break; + case SpriteAnimTarget.S: + sprite.scalex = data.old.scalex + ((data.data.scalex - data.old.scalex) / data.frame) * frame; + sprite.scaley = data.old.scaley + ((data.data.scaley - data.old.scaley) / data.frame) * frame; + break; + case SpriteAnimTarget.C: + break; + case SpriteAnimTarget.V: + break; + default: + break; + } + } + if(frame >= data.frame) + { sprite.animindex[i] = (sprite.animindex[i] + 1) % d.length; data.elapse = 0; if(sprite.animloop[i] == 0) @@ -366,15 +384,17 @@ class Sprite } } bool lll; - double d = 0; import std.algorithm; void render() { auto texture = petitcom.GRP[petitcom.sppage].glTexture; + float aspect = 400f / 240f; float z = -0.01f; glBindTexture(GL_TEXTURE_2D, texture); glEnable(GL_TEXTURE_2D); - // glDisable(GL_TEXTURE_2D); + // glDisable(GL_TEXTURE_2D); + version(test) glLoadIdentity(); + glLoadIdentity(); foreach(i,ref sprite; sprites) { //定義されてたら動かす @@ -384,10 +404,13 @@ class Sprite } if(sprite.attr & SpriteAttr.show) { - int x = cast(int)sprite.x - cast(int)(sprite.homex * sprite.scalex); - int y = cast(int)sprite.y - cast(int)(sprite.homey * sprite.scaley); + 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; int w = sprite.w; int h = sprite.h; + if((sprite.attr & SpriteAttr.rotate90) == SpriteAttr.rotate90) { swap(w, h); @@ -398,47 +421,76 @@ class Sprite int v = cast(int)sprite.v; int u2 = cast(int)sprite.u + sprite.w;//-1 int v2 = cast(int)sprite.v + sprite.h; + z = sprite.z / 1025f; float flipx = cast(float)sprite.scalex, flipy = cast(float)sprite.scaley, flipx2 = x, flipy2 = y; if(sprite.attr & SpriteAttr.hflip) { flipx = -flipx; - flipx2 = x2; + flipx2 = x2 - cast(int)(sprite.homex * sprite.scalex);//sprite.homex * sprite.scalex); } - if(sprite.attr & SpriteAttr.hflip) + if(sprite.attr & SpriteAttr.vflip) { flipy = -flipy; - flipy2 = y2; + flipy2 = y2 - cast(int)(sprite.homey * sprite.scaley); } - glTranslatef((flipx2) / 200f - 1,1 - ((flipy2) / 120f), z); - glScalef(flipx, flipy, 1f); - glRotatef(d, 0.0f, 0.0f, 1.0f ); + version(test) glRotatef(45f, 1f, 0f, 0.5f); + + glTranslatef((flipx2) / 200f - 1, + 1 - ((flipy2) / 120f), 0); + //glTranslatef((flipx2) / 200f - 1,1 - ((flipy2) / 120f), 0); + //glScalef(flipx, flipy, 1f); + //アスペクト比を調節しないといけないらしい + //https://groups.google.com/forum/#!topic/android-group-japan/45mjecPSY4s + //http://www.tnksoft.com/blog/?p=2889 + glScalef(1.0f / aspect, 1.0f, 1.0f); + glRotatef(360 - sprite.r, 0.0f, 0.0f, 1.0f ); + glScalef(flipx * aspect, flipy, 1f); glBegin(GL_QUADS); glColor3f(1.0, 1.0, 1.0); - if(sprite.attr == SpriteAttr.show) + if((sprite.attr& 0b111) == SpriteAttr.show) { //d+=0.01; - glTexCoord2f(u / 512f - 1, v / 512f - 1); + /*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 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); glVertex3f(sprite.w / 200f, -(sprite.h / 120f), z);//3 glTexCoord2f(u2 / 512f - 1, v / 512f - 1); - glVertex3f(sprite.w / 200f, 0, z);//4 + glVertex3f(sprite.w / 200f, 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 + glTexCoord2f(u / 512f - 1 , v2 / 512f - 1); + glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); + glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3//y+--+x--++ + glTexCoord2f(u2 / 512f - 1, v / 512f - 1); + glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 glEnd(); + /* + glDisable(GL_TEXTURE_2D); + glColor3f(1,0,0); + glBegin(GL_POINTS); + glVertex3f(0,0,-0.9); + glColor3f(0,1,0); + glVertex3f(-((sprite.w) / 400f),((sprite.h) / 240f),-0.9); + glEnd(); + glEnable(GL_TEXTURE_2D);*/ glLoadIdentity(); continue; } if((sprite.attr & SpriteAttr.rotate270) == SpriteAttr.rotate270) { glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//3 - glVertex3f(0, 0, z);//1 + glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f(0, -(h / 120f), z);// + glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f(w / 200f, -(h / 120f), z);//3 + glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//4 - glVertex3f(w / 200f, 0, z);//4 + glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 glEnd(); glLoadIdentity(); continue; @@ -446,13 +498,13 @@ class Sprite if((sprite.attr & SpriteAttr.rotate90) == SpriteAttr.rotate90) { glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f(0, 0, z);//1 + glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//3 - glVertex3f(0, -(h / 120f), z);//2 + glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//4 - glVertex3f(w / 200f, -(h / 120f), z);//3 + glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f(w / 200f, 0, z);//4 + glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 glEnd(); glLoadIdentity(); continue; @@ -460,17 +512,25 @@ class Sprite if((sprite.attr & SpriteAttr.rotate180) == SpriteAttr.rotate180) { glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1);//4 - glVertex3f(0, 0, z);//1 + glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 glTexCoord2f(u2 / 512f - 1, v / 512f - 1);//3 - glVertex3f(0, -(h / 120f), z);//2 + glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 glTexCoord2f(u / 512f - 1, v / 512f - 1);//1 - glVertex3f(w / 200f, -(h / 120f), z);//3 + glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 glTexCoord2f(u / 512f - 1 , v2 / 512f - 1);//2 - glVertex3f(w / 200f, 0, z);//4 + glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 glEnd(); glLoadIdentity(); continue; } + glTexCoord2f(u / 512f - 1, v / 512f - 1); + glVertex3f(-((sprite.w) / 400f - homex2), ((sprite.h) / 240f - homey2), z);//1 + glTexCoord2f(u / 512f - 1 , v2 / 512f - 1); + glVertex3f(-((sprite.w) / 400f - homex2), -((sprite.h) / 240f + homey2), z);//2 + glTexCoord2f(u2 / 512f - 1, v2 / 512f - 1); + glVertex3f((sprite.w) / 400f + homex2, -((sprite.h) / 240f + homey2), z);//3 + glTexCoord2f(u2 / 512f - 1, v / 512f - 1); + glVertex3f((sprite.w) / 400f + homex2, ((sprite.h) / 240f - homey2), z);//4 glEnd(); glLoadIdentity(); continue; @@ -481,11 +541,22 @@ class Sprite { sprites[id] = SpriteData(id, SPDEFTable[defno], defno); } + void spset(int id, int u, int v, int w, int h, SpriteAttr attr) + { + auto spdef = SpriteDef(u, v, w, h, 0, 0, attr); + sprites[id] = SpriteData(id, spdef, 0/*要調査*/); + } void spofs(int id, int x, int y) { sprites[id].x = x; sprites[id].y = y; } + void spofs(int id, int x, int y, int z) + { + sprites[id].x = x; + sprites[id].y = y; + sprites[id].z = z; + } void sphide(int id) { sprites[id].attr ^= SpriteAttr.show; @@ -531,9 +602,11 @@ class Sprite SpriteAnimData[] animdata = new SpriteAnimData[animcount]; int j; int loop = 1; + SpriteAnimData* old; for(int i = 0; i < data.length;) { - i = animdata[j++].load(i, sprites[id], target, data); + i = animdata[j].load(i, sprites[id], target, data, old); + old = &animdata[j++]; if(data.length - i == 1) { //loop @@ -559,9 +632,13 @@ class Sprite sprites[i].homex = hx; sprites[i].homey = hy; } - void spscale(int i, int x, int y) + void spscale(int i, double x, double y) { sprites[i].scalex = x; sprites[i].scaley = y; } + void sprot(int i, double rot) + { + sprites[i].r = rot; + } }