diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 43a6af6..fbb9ca7 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -591,6 +591,79 @@ class BuiltinFunction throw new TypeMismatch("GSAVE", 1); GSAVE(p, p.graphic.useGRP, ary, flag); } + static void GLOAD(PetitComputer p, int x, int y, int w, int h, Value ary, Value flagOrPalette, int copymode) + { + if (!ary.isNumberArray) + { + throw new TypeMismatch("GLOAD", 5); + } + if (w < 0) + throw new OutOfRange("GLOAD", 3); + if (h < 0) + throw new OutOfRange("GLOAD", 4); + if (w * h > ary.length) + { + throw new SubscriptOutOfRange("GLOAD", 5); + } + if (flagOrPalette.isNumber) + { + int colorflag = flagOrPalette.castInteger; + if (ary.type == ValueType.IntegerArray) + { + p.graphic.gload(x, y, w, h, ary.integerArray.array, colorflag, copymode); + } + if (ary.type == ValueType.DoubleArray) + { + p.graphic.gload(x, y, w, h, ary.doubleArray.array, colorflag, copymode); + } + } + else if (flagOrPalette.isNumberArray) + { + if (ary.type == ValueType.IntegerArray) + { + if (flagOrPalette.type == ValueType.IntegerArray) + { + p.graphic.gloadPalette(x, y, w, h, ary.integerArray.array, flagOrPalette.integerArray.array, copymode); + } + if (flagOrPalette.type == ValueType.DoubleArray) + { + p.graphic.gloadPalette(x, y, w, h, ary.integerArray.array, flagOrPalette.doubleArray.array, copymode); + } + } + if (ary.type == ValueType.DoubleArray) + { + if (flagOrPalette.type == ValueType.IntegerArray) + { + p.graphic.gloadPalette(x, y, w, h, ary.doubleArray.array, flagOrPalette.integerArray.array, copymode); + } + if (flagOrPalette.type == ValueType.DoubleArray) + { + p.graphic.gloadPalette(x, y, w, h, ary.doubleArray.array, flagOrPalette.doubleArray.array, copymode); + } + } + } + else + { + throw new TypeMismatch("GLOAD", 6); + } + } + static void GLOAD(PetitComputer p, Value ary, Value flagOrPalette, int copymode) + { + if (!ary.isNumberArray) + { + throw new TypeMismatch("GLOAD", 1); + } + auto writeArea = p.graphic.writeArea[p.displaynum]; + if (writeArea.w * writeArea.h > ary.length) + { + throw new SubscriptOutOfRange("GLOAD", 1); + } + if (!flagOrPalette.isNumber && !flagOrPalette.isNumberArray) + { + throw new TypeMismatch("GLOAD", 2); + } + GLOAD(p, writeArea.x, writeArea.y, writeArea.w, writeArea.h, ary, flagOrPalette, copymode); + } static void BGMPLAY(PetitComputer p, int music) { } diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index cb9fad5..e93587c 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -164,6 +164,16 @@ class SubscriptOutOfRange : SmileBasicError this.errnum = 31; super("Subscript out of range"); } + this(string func) + { + this.errnum = 31; + super("Subscript out of range(" ~ func ~ ")"); + } + this(string func, int arg) + { + this.errnum = 31; + super("Subscript out of range(" ~ func ~ ":" ~ arg.to!string ~ ")"); + } } class StringTooLong : SmileBasicError { diff --git a/SMILEBASIC/graphic.d b/SMILEBASIC/graphic.d index f7a067a..3691ecb 100644 --- a/SMILEBASIC/graphic.d +++ b/SMILEBASIC/graphic.d @@ -590,14 +590,63 @@ class Graphic //ARRRRRGGGGGBBBBB for (int i = 0; i < array.length; i++) { - auto a = (array[i] & 0xFF000000) >> 24; - auto r = (array[i] & 0x00FF0000) >> 16; - auto g = (array[i] & 0x0000FF00) >> 8; - auto b = (array[i] & 0x000000FF); - array[i] = (a == 255) | r >> 3 << 11 | g >> 3 << 6 | b >> 3 << 1; + array[i] = ARGB32ToRGBA16Color(array[i]); } } } + int ARGB32ToRGBA16Color(int argb32) + { + auto a = (argb32 & 0xFF000000) >> 24; + auto r = (argb32 & 0x00FF0000) >> 16; + auto g = (argb32 & 0x0000FF00) >> 8; + auto b = (argb32 & 0x000000FF); + return (a == 255) | r >> 3 << 11 | g >> 3 << 6 | b >> 3 << 1; + } + void gload(int x, int y, int w, int h, int[] array, int flag, int copymode) + { + if (w * h > array.length) + return; + if (!copymode) + { + glEnable(GL_ALPHA_TEST); + } + glRasterPos2i(x, y); + //convertColor + if (flag) + { + //ARRRRRGGGGGBBBBB + for (int i = 0; i < array.length; i++) + { + paint.buffer[i] = ARGB32ToRGBA16Color(array[i]); + } + glDrawPixels(w , h , GL_BGRA , GL_UNSIGNED_BYTE , paint.buffer.ptr); + } + else + { + glDrawPixels(w , h , GL_BGRA , GL_UNSIGNED_BYTE , array.ptr); + } + if (!copymode) + { + glDisable(GL_ALPHA_TEST); + } + } + void gload(int x, int y, int w, int h, double[] array, int flag, int copymode) + { + for (int i = 0; i < array.length; i++) + { + paint.buffer[i] = cast(int)array[i]; + } + gload(x, y, w, h, cast(int[])paint.buffer, flag, copymode); + } + void gloadPalette(T, T2)(int x, int y, int w, int h, T[] array, T2[] palette, int copymode) + if ((is(T == int) || is(T == double)) && (is(T2 == int) || is(T2 == double))) + { + for (int i = 0; i < array.length; i++) + { + paint.buffer[i] = cast(int)palette[cast(int)array[i]]; + } + gload(x, y, w, h, cast(int[])paint.buffer, 0, copymode); + } int gprio; void render() {