Extract graphic class
This commit is contained in:
@@ -299,58 +299,58 @@ class BuiltinFunction
|
|||||||
static void GCLS(PetitComputer p, DefaultValue!(int, false) color)
|
static void GCLS(PetitComputer p, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(0);
|
color.setDefaultValue(0);
|
||||||
p.gfill(p.useGRP, 0, 0, 511, 511, cast(int)color);
|
p.graphic.gfill(p.graphic.useGRP, 0, 0, 511, 511, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GPSET(PetitComputer p, int x, int y, DefaultValue!(int, false) color)
|
static void GPSET(PetitComputer p, int x, int y, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gpset(p.useGRP, x, y, cast(int)color);
|
p.graphic.gpset(p.graphic.useGRP, x, y, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GLINE(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
static void GLINE(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gline(p.useGRP, x, y, x2, y2, cast(int)color);
|
p.graphic.gline(p.graphic.useGRP, x, y, x2, y2, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GBOX(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
static void GBOX(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gbox(p.useGRP, x, y, x2, y2, cast(int)color);
|
p.graphic.gbox(p.graphic.useGRP, x, y, x2, y2, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GFILL(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
static void GFILL(PetitComputer p, int x, int y, int x2, int y2, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gfill(p.useGRP, x, y, x2, y2, cast(int)color);
|
p.graphic.gfill(p.graphic.useGRP, x, y, x2, y2, cast(int)color);
|
||||||
}
|
}
|
||||||
//X,Y,R[,COLOR]
|
//X,Y,R[,COLOR]
|
||||||
//X,Y,R,SR,ER[,COLOR]
|
//X,Y,R,SR,ER[,COLOR]
|
||||||
static void GCIRCLE(PetitComputer p, int x, int y, int r, DefaultValue!(int, false) color)
|
static void GCIRCLE(PetitComputer p, int x, int y, int r, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gcircle(p.useGRP, x, y, r, 0, 360, 0, cast(int)color);
|
p.graphic.gcircle(p.graphic.useGRP, x, y, r, 0, 360, 0, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GCIRCLE(PetitComputer p, int x, int y, int r, int sr, int er, DefaultValue!(int, false) flag, DefaultValue!(int, false) color)
|
static void GCIRCLE(PetitComputer p, int x, int y, int r, int sr, int er, DefaultValue!(int, false) flag, DefaultValue!(int, false) color)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
flag.setDefaultValue(0);
|
flag.setDefaultValue(0);
|
||||||
p.gcircle(p.useGRP, x, y, r, sr, er, cast(int)flag, cast(int)color);
|
p.graphic.gcircle(p.graphic.useGRP, x, y, r, sr, er, cast(int)flag, cast(int)color);
|
||||||
}
|
}
|
||||||
static void GCOLOR(PetitComputer p, int color)
|
static void GCOLOR(PetitComputer p, int color)
|
||||||
{
|
{
|
||||||
p.gcolor = color;
|
p.graphic.gcolor = color;
|
||||||
}
|
}
|
||||||
static void GPRIO(PetitComputer p, int z)
|
static void GPRIO(PetitComputer p, int z)
|
||||||
{
|
{
|
||||||
p.gprio = z;
|
p.graphic.gprio = z;
|
||||||
}
|
}
|
||||||
static void GPAGE(PetitComputer p, int showPage, int usePage)
|
static void GPAGE(PetitComputer p, int showPage, int usePage)
|
||||||
{
|
{
|
||||||
p.showGRP = showPage;
|
p.graphic.showGRP = showPage;
|
||||||
p.useGRP = usePage;
|
p.graphic.useGRP = usePage;
|
||||||
}
|
}
|
||||||
static void GPAINT(PetitComputer p, int x, int y, DefaultValue!(int, false) color, DefaultValue!(int, false) color2)
|
static void GPAINT(PetitComputer p, int x, int y, DefaultValue!(int, false) color, DefaultValue!(int, false) color2)
|
||||||
{
|
{
|
||||||
color.setDefaultValue(p.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
p.gpaint(p.useGRP, x, y, cast(int)color);
|
p.graphic.gpaint(p.graphic.useGRP, x, y, cast(int)color);
|
||||||
}
|
}
|
||||||
static void BGMPLAY(PetitComputer p, int music)
|
static void BGMPLAY(PetitComputer p, int music)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
module otya.smilebasic.draw;
|
|
||||||
import otya.smilebasic.petitcomputer;
|
|
||||||
import derelict.opengl3.gl;
|
|
||||||
class Draw
|
|
||||||
{
|
|
||||||
PetitComputer petitcom;
|
|
||||||
this(PetitComputer petitcom)
|
|
||||||
{
|
|
||||||
this.petitcom = petitcom;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpset(int page, int x, int y, uint color)
|
|
||||||
{
|
|
||||||
color = PetitComputer.toGLColor(petitcom.GRP[page].textureFormat, color);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, petitcom.GRP[page].glTexture);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x, y, 1, 1, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, &color);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
if(x < x2) sx = 1; else sx = -1;
|
|
||||||
if(y < y2) sy = 1; else sy = -1;
|
|
||||||
int err = dx - dy;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if(x < 0 || y < 0 || x >= 512 || y >= 512) break;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
err = err - dy;
|
|
||||||
x = x + sx;
|
|
||||||
}
|
|
||||||
if(e2 < dx)
|
|
||||||
{
|
|
||||||
err = err + dx;
|
|
||||||
y = y + sy ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint[] graphicBuffer = new uint[512 * 512];
|
|
||||||
void gfill(int page, int x, int y, int x2, int y2, uint color)
|
|
||||||
{
|
|
||||||
import std.algorithm;
|
|
||||||
import std.math;
|
|
||||||
if(x < 0 && x2 < 0 || y < 0 && y2 < 0) return;
|
|
||||||
if(x > 511 && x2 > 511 || y > 511 && y2 > 511) return;
|
|
||||||
//0<=x<512
|
|
||||||
x = min(max(x, 0), 511);
|
|
||||||
y = min(max(y, 0), 511);
|
|
||||||
x2 = min(max(x2, 0), 511);
|
|
||||||
y2 = min(max(y2, 0), 511);
|
|
||||||
if(x2 < x) swap(x, x2);
|
|
||||||
if(y2 < y) swap(y, y2);
|
|
||||||
auto w = abs(x2 - x) + 1;//abs
|
|
||||||
auto h = abs(y2 - y) + 1;
|
|
||||||
auto size = w * h;
|
|
||||||
uint* pixels = graphicBuffer.ptr;
|
|
||||||
color = PetitComputer.toGLColor(petitcom.GRP[page].textureFormat, color);
|
|
||||||
for(int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
pixels[i] = color;
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, petitcom.GRP[page].glTexture);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x, y, w, h, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gbox(int page, int x, int y, int x2, int y2, uint color)
|
|
||||||
{
|
|
||||||
import std.algorithm;
|
|
||||||
import std.math;
|
|
||||||
if(x < 0 && x2 < 0 || y < 0 && y2 < 0) return;
|
|
||||||
if(x > 511 && x2 > 511 || y > 511 && y2 > 511) return;
|
|
||||||
//0<=x<512
|
|
||||||
x = min(max(x, 0), 511);
|
|
||||||
y = min(max(y, 0), 511);
|
|
||||||
x2 = min(max(x2, 0), 511);
|
|
||||||
y2 = min(max(y2, 0), 511);
|
|
||||||
if(x2 < x) swap(x, x2);
|
|
||||||
if(y2 < y) swap(y, y2);
|
|
||||||
auto w = abs(x2 - x) + 1;//abs
|
|
||||||
auto h = abs(y2 - y) + 1;
|
|
||||||
auto size = max(w, h);
|
|
||||||
uint* pixels = graphicBuffer.ptr;
|
|
||||||
color = PetitComputer.toGLColor(petitcom.GRP[page].textureFormat, color);
|
|
||||||
for(int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
pixels[i] = color;
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, petitcom.GRP[page].glTexture);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x, y, w, 1, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x, y2, w, 1, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x, y, 1, h, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, x2, y, 1, h, petitcom.GRP[page].textureFormat, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
442
SMILEBASIC/graphic.d
Normal file
442
SMILEBASIC/graphic.d
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
module otya.smilebasic.graphic;
|
||||||
|
import derelict.sdl2.sdl;
|
||||||
|
import derelict.sdl2.image;
|
||||||
|
import derelict.opengl3.gl;
|
||||||
|
import derelict.opengl3.gl3;
|
||||||
|
import otya.smilebasic.petitcomputer;
|
||||||
|
|
||||||
|
class Graphic
|
||||||
|
{
|
||||||
|
PetitComputer petitcom;
|
||||||
|
this(PetitComputer p)
|
||||||
|
{
|
||||||
|
petitcom = p;
|
||||||
|
//nnnue
|
||||||
|
paint.buffer = new uint[512 * 512];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visibleGRP = true;
|
||||||
|
private int[2] showPage = [0, 1];
|
||||||
|
private int[2] usePage = [0, 1];
|
||||||
|
@property int useGRP()
|
||||||
|
{
|
||||||
|
return usePage[petitcom.displaynum];
|
||||||
|
}
|
||||||
|
@property int showGRP()
|
||||||
|
{
|
||||||
|
return showPage[petitcom.displaynum];
|
||||||
|
}
|
||||||
|
@property void useGRP(int page)
|
||||||
|
{
|
||||||
|
usePage[petitcom.displaynum] = page;
|
||||||
|
}
|
||||||
|
@property void showGRP(int page)
|
||||||
|
{
|
||||||
|
showPage[petitcom.displaynum] = page;
|
||||||
|
}
|
||||||
|
uint gcolor = -1;
|
||||||
|
GraphicPage[] GRP;
|
||||||
|
struct Paint
|
||||||
|
{
|
||||||
|
uint[] buffer;
|
||||||
|
static const MAXSIZE = 1024; /* バッファサイズ */
|
||||||
|
|
||||||
|
/* 画面サイズは 1024 X 1024 とする */
|
||||||
|
static const MINX = 0;
|
||||||
|
static const MINY = 0;
|
||||||
|
static const MAXX = 511;
|
||||||
|
static const MAXY = 511;
|
||||||
|
|
||||||
|
struct BufStr {
|
||||||
|
int lx; /* 領域右端のX座標 */
|
||||||
|
int rx; /* 領域右端のX座標 */
|
||||||
|
int y; /* 領域のY座標 */
|
||||||
|
int oy; /* 親ラインのY座標 */
|
||||||
|
};
|
||||||
|
BufStr buff[MAXSIZE]; /* シード登録用バッファ */
|
||||||
|
BufStr* sIdx, eIdx; /* buffの先頭・末尾ポインタ */
|
||||||
|
uint point(int x, int y)
|
||||||
|
{
|
||||||
|
return buffer.ptr[x + y * 512];
|
||||||
|
}
|
||||||
|
void pset(int x, int y, uint col)
|
||||||
|
{
|
||||||
|
buffer.ptr[x + y * 512] = col;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
scanLine : 線分からシードを探索してバッファに登録する
|
||||||
|
|
||||||
|
int lx, rx : 線分のX座標の範囲
|
||||||
|
int y : 線分のY座標
|
||||||
|
int oy : 親ラインのY座標
|
||||||
|
unsigned int col : 領域色
|
||||||
|
*/
|
||||||
|
void scanLine( int lx, int rx, int y, int oy, uint col )
|
||||||
|
{
|
||||||
|
while ( lx <= rx ) {
|
||||||
|
|
||||||
|
/* 非領域色を飛ばす */
|
||||||
|
for ( ; lx < rx ; lx++ )
|
||||||
|
if ( point( lx, y ) == col ) break;
|
||||||
|
if ( point( lx, y ) != col ) break;
|
||||||
|
|
||||||
|
eIdx.lx = lx;
|
||||||
|
|
||||||
|
/* 領域色を飛ばす */
|
||||||
|
for ( ; lx <= rx ; lx++ )
|
||||||
|
if ( point( lx, y ) != col ) break;
|
||||||
|
|
||||||
|
eIdx.rx = lx - 1;
|
||||||
|
eIdx.y = y;
|
||||||
|
eIdx.oy = oy;
|
||||||
|
|
||||||
|
if ( ++eIdx == &buff.ptr[MAXSIZE] )
|
||||||
|
eIdx = buff.ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
paint : 塗り潰し処理(高速版)
|
||||||
|
|
||||||
|
int x, y : 開始座標
|
||||||
|
unsigned int paintCol : 塗り潰す時の色(描画色)
|
||||||
|
*/
|
||||||
|
void paint( int x, int y, uint paintCol , out int dx, out int dy, out int dx2, out int dy2)
|
||||||
|
{
|
||||||
|
int lx, rx; /* 塗り潰す線分の両端のX座標 */
|
||||||
|
int ly; /* 塗り潰す線分のY座標 */
|
||||||
|
int oy; /* 親ラインのY座標 */
|
||||||
|
int i;
|
||||||
|
uint col = point( x, y ); /* 閉領域の色(領域色) */
|
||||||
|
dx = int.max, dy = int.max, dx2 = int.min, dy2 = int.min;
|
||||||
|
if ( col == paintCol ) return; /* 領域色と描画色が等しければ処理不要 */
|
||||||
|
sIdx = buff.ptr;
|
||||||
|
eIdx = buff.ptr + 1;
|
||||||
|
sIdx.lx = sIdx.rx = x;
|
||||||
|
sIdx.y = sIdx.oy = y;
|
||||||
|
|
||||||
|
do {
|
||||||
|
lx = sIdx.lx;
|
||||||
|
rx = sIdx.rx;
|
||||||
|
ly = sIdx.y;
|
||||||
|
oy = sIdx.oy;
|
||||||
|
|
||||||
|
int lxsav = lx - 1;
|
||||||
|
int rxsav = rx + 1;
|
||||||
|
|
||||||
|
if ( ++sIdx == &buff.ptr[MAXSIZE] ) sIdx = buff.ptr;
|
||||||
|
|
||||||
|
/* 処理済のシードなら無視 */
|
||||||
|
if ( point( lx, ly ) != col )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* 右方向の境界を探す */
|
||||||
|
while ( rx < MAXX ) {
|
||||||
|
if ( point( rx + 1, ly ) != col ) break;
|
||||||
|
rx++;
|
||||||
|
}
|
||||||
|
/* 左方向の境界を探す */
|
||||||
|
while ( lx > MINX ) {
|
||||||
|
if ( point( lx - 1, ly ) != col ) break;
|
||||||
|
lx--;
|
||||||
|
}
|
||||||
|
import std.algorithm;
|
||||||
|
dy = min(dy, ly);
|
||||||
|
dy2 = max(dy2, ly);
|
||||||
|
dx = min(dx, lx);
|
||||||
|
dx2 = max(dx2, rx);
|
||||||
|
//
|
||||||
|
/* lx-rxの線分を描画 */
|
||||||
|
for ( i = lx; i <= rx; i++ ) pset( i, ly, paintCol );
|
||||||
|
|
||||||
|
/* 真上のスキャンラインを走査する */
|
||||||
|
if ( ly - 1 >= MINY ) {
|
||||||
|
if ( ly - 1 == oy ) {
|
||||||
|
scanLine( lx, lxsav, ly - 1, ly, col );
|
||||||
|
scanLine( rxsav, rx, ly - 1, ly, col );
|
||||||
|
} else {
|
||||||
|
scanLine( lx, rx, ly - 1, ly, col );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 真下のスキャンラインを走査する */
|
||||||
|
if ( ly + 1 <= MAXY ) {
|
||||||
|
if ( ly + 1 == oy ) {
|
||||||
|
scanLine( lx, lxsav, ly + 1, ly, col );
|
||||||
|
scanLine( rxsav, rx, ly + 1, ly, col );
|
||||||
|
} else {
|
||||||
|
scanLine( lx, rx, ly + 1, ly, col );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ( sIdx != eIdx );
|
||||||
|
}
|
||||||
|
void gpaintBuffer(uint* pixels, int x, int y, uint color, GLenum tf)
|
||||||
|
{
|
||||||
|
int dx, dy, dx2, dy2;
|
||||||
|
paint(x, y, color, dx, dy, dx2, dy2);
|
||||||
|
if(dx == int.max) return;
|
||||||
|
int h = dy2 - dy;
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D , 0, 0, dy, 512, h, tf, GL_UNSIGNED_BYTE, pixels + (dy * 512));
|
||||||
|
// glDrawPixels(512, dy2, tf, GL_UNSIGNED_BYTE, buffer.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Paint paint;
|
||||||
|
void drawCircle(int x, int y, int r, int startr, int endr, int flag)
|
||||||
|
{
|
||||||
|
import std.math : sin, cos, PI;
|
||||||
|
int count = r;
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
for (int i = 0; i <= r; i++)
|
||||||
|
{
|
||||||
|
//float a = i * (360f / r);
|
||||||
|
glVertex2f(sin(cast(float)i / count * 2f * PI) * r + x, cos(cast(float)i / count * 2f * PI) * r + y);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
void draw()
|
||||||
|
{
|
||||||
|
if(!drawMessageLength) return;
|
||||||
|
drawflag = true;
|
||||||
|
//betuni kouzoutai demo sonnnani sokudo kawaranasasou
|
||||||
|
auto len = drawMessageLength;
|
||||||
|
int s = petitcom.renderstartpos;
|
||||||
|
GLint old;
|
||||||
|
auto a = &glBindFramebuffer;
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old);
|
||||||
|
int oldpage = drawMessageQueue[0].page;
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
//glAlphaFunc(GL_GEQUAL, 0.0);
|
||||||
|
void chScreen(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
glViewport(x, y, w, h);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, w, 0, h, -256, 1024);//wakaranai
|
||||||
|
}
|
||||||
|
chScreen(0, 0, 511, 511);
|
||||||
|
DrawType dt;
|
||||||
|
auto start = SDL_GetTicks();
|
||||||
|
int i = s;
|
||||||
|
static const size = 255.5f;
|
||||||
|
for(; 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:
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
|
glVertex2f(dm.x, dm.y);
|
||||||
|
glEnd();
|
||||||
|
break;
|
||||||
|
case DrawType.LINE:
|
||||||
|
{
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
|
glVertex2f(dm.x, dm.y);
|
||||||
|
glVertex2f(dm.x2, dm.y2);
|
||||||
|
//glFlush();
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DrawType.FILL:
|
||||||
|
{
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
|
glVertex2f(dm.x, dm.y);
|
||||||
|
glVertex2f(dm.x, dm.y2);
|
||||||
|
glVertex2f(dm.x2, dm.y2);
|
||||||
|
glVertex2f(dm.x2, dm.y);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DrawType.BOX:
|
||||||
|
{
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
|
glVertex2f(dm.x, dm.y);
|
||||||
|
glVertex2f(dm.x, dm.y2);
|
||||||
|
glVertex2f(dm.x2, dm.y2);
|
||||||
|
glVertex2f(dm.x2, dm.y);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DrawType.PAINT:
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, GRP[oldpage].glTexture);
|
||||||
|
if(dt != DrawType.PAINT)
|
||||||
|
{
|
||||||
|
glFinish();
|
||||||
|
//glGetTexImage(GL_TEXTURE_2D,0,GRP[oldpage].textureFormat,GL_UNSIGNED_BYTE,buffer.ptr);
|
||||||
|
glReadPixels(0, 0, 512, 512, GRP[oldpage].textureFormat, GL_UNSIGNED_BYTE, paint.buffer.ptr);
|
||||||
|
}
|
||||||
|
paint.gpaintBuffer(paint.buffer.ptr, dm.x, dm.y, dm.color, GRP[oldpage].textureFormat);
|
||||||
|
//gpaintBufferExW(oldpage, dm.x, dm.y, dm.color);
|
||||||
|
if(SDL_GetTicks() - start >= 16 && i != len - 1)
|
||||||
|
{
|
||||||
|
s = i + 1;
|
||||||
|
goto brk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DrawType.CIRCLE:
|
||||||
|
{
|
||||||
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
|
drawCircle(dm.x, dm.y, dm.circle.r, dm.circle.startr, dm.circle.endr, dm.circle.flag);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
dt = dm.type;
|
||||||
|
}
|
||||||
|
brk:
|
||||||
|
if(i == len)
|
||||||
|
{
|
||||||
|
petitcom.renderstartpos = 0;
|
||||||
|
drawMessageLength = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
petitcom.renderstartpos = s;
|
||||||
|
}
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER, old);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
drawflag = false;
|
||||||
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
}
|
||||||
|
enum DrawType
|
||||||
|
{
|
||||||
|
CLEAR,
|
||||||
|
PSET,
|
||||||
|
LINE,
|
||||||
|
FILL,
|
||||||
|
BOX,
|
||||||
|
CIRCLE,
|
||||||
|
TRI,
|
||||||
|
PAINT,
|
||||||
|
}
|
||||||
|
struct Circle
|
||||||
|
{
|
||||||
|
short r, startr, endr;
|
||||||
|
short flag;
|
||||||
|
}
|
||||||
|
struct DrawMessage
|
||||||
|
{
|
||||||
|
DrawType type;
|
||||||
|
byte page;
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
uint color;
|
||||||
|
short x2;
|
||||||
|
short y2;
|
||||||
|
Circle circle;
|
||||||
|
//
|
||||||
|
}
|
||||||
|
static const int dmqqueuelen = 8192;
|
||||||
|
DrawMessage[] drawMessageQueue = new DrawMessage[dmqqueuelen];
|
||||||
|
int drawMessageLength;
|
||||||
|
bool drawflag;
|
||||||
|
void sendDrawMessage(DrawMessage dm)
|
||||||
|
{
|
||||||
|
//grpmutex.lock();
|
||||||
|
//scope(exit)
|
||||||
|
// grpmutex.unlock();
|
||||||
|
if(drawMessageLength >= dmqqueuelen)
|
||||||
|
{
|
||||||
|
while(drawMessageLength)
|
||||||
|
{
|
||||||
|
SDL_Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(drawflag){}
|
||||||
|
dm.color = petitcom.toGLColor(this.GRP[0].textureFormat, dm.color & 0xFFF8F8F8);
|
||||||
|
drawMessageQueue[drawMessageLength] = dm;
|
||||||
|
drawMessageLength++;
|
||||||
|
}
|
||||||
|
void sendDrawMessage(DrawType type, byte page, short x, short y, uint color)
|
||||||
|
{
|
||||||
|
DrawMessage dm;
|
||||||
|
dm.type = type;
|
||||||
|
dm.page = page;
|
||||||
|
dm.x = x;
|
||||||
|
dm.y = y;
|
||||||
|
dm.color = color;
|
||||||
|
sendDrawMessage(dm);
|
||||||
|
}
|
||||||
|
void sendDrawMessage(DrawType type, byte page, short x, short y, short x2, short y2, uint color)
|
||||||
|
{
|
||||||
|
DrawMessage dm;
|
||||||
|
dm.type = type;
|
||||||
|
dm.page = page;
|
||||||
|
dm.x = x;
|
||||||
|
dm.y = y;
|
||||||
|
dm.x2 = x2;
|
||||||
|
dm.y2 = y2;
|
||||||
|
dm.color = color;
|
||||||
|
sendDrawMessage(dm);
|
||||||
|
}
|
||||||
|
//TODO:範囲チェック
|
||||||
|
void gpset(int page, int x, int y, uint color)
|
||||||
|
{
|
||||||
|
sendDrawMessage(DrawType.PSET, cast(byte)page, cast(short)x, cast(short)y, color);
|
||||||
|
}
|
||||||
|
void gline(int page, int x, int y, int x2, int y2, uint color)
|
||||||
|
{
|
||||||
|
sendDrawMessage(DrawType.LINE, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
||||||
|
}
|
||||||
|
void gbox(int page, int x, int y, int x2, int y2, uint color)
|
||||||
|
{
|
||||||
|
sendDrawMessage(DrawType.BOX, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
||||||
|
}
|
||||||
|
void gfill(int page, int x, int y, int x2, int y2, uint color)
|
||||||
|
{
|
||||||
|
sendDrawMessage(DrawType.FILL, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
||||||
|
}
|
||||||
|
void gpaint(int page, int x, int y, uint color)
|
||||||
|
{
|
||||||
|
sendDrawMessage(DrawType.PAINT, cast(byte)page, cast(short)x, cast(short)y, color);
|
||||||
|
}
|
||||||
|
void gcircle(int page, int x, int y, int r, int startr, int endr, int flag, uint color)
|
||||||
|
{
|
||||||
|
DrawMessage dm;
|
||||||
|
dm.page = cast(byte)page;
|
||||||
|
dm.x = cast(short)x;
|
||||||
|
dm.y = cast(short)y;
|
||||||
|
dm.circle.r = cast(short)r;
|
||||||
|
dm.circle.startr = cast(short)startr;
|
||||||
|
dm.circle.endr = cast(short)endr;
|
||||||
|
dm.circle.flag = cast(short)flag;
|
||||||
|
dm.color = color;
|
||||||
|
dm.type = DrawType.CIRCLE;
|
||||||
|
sendDrawMessage(dm);
|
||||||
|
}
|
||||||
|
int gprio;
|
||||||
|
void render(int display, float w, float h)
|
||||||
|
{
|
||||||
|
float z = gprio;
|
||||||
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, GRP[showPage[display]].glTexture);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(0 / 512f - 1 , h / 512f - 1);
|
||||||
|
glVertex3f(0, h, z);
|
||||||
|
glTexCoord2f(0 / 512f - 1, 0 / 512f - 1);
|
||||||
|
glVertex3f(0, 0, z);
|
||||||
|
glTexCoord2f(w / 512f - 1, 0 / 512f - 1);
|
||||||
|
glVertex3f(w, 0, z);
|
||||||
|
glTexCoord2f(w / 512f - 1, h / 512f - 1);
|
||||||
|
glVertex3f(w, h, z);
|
||||||
|
glEnd();
|
||||||
|
//glFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import otya.smilebasic.bg;
|
|||||||
import otya.smilebasic.parser;
|
import otya.smilebasic.parser;
|
||||||
import otya.smilebasic.project;
|
import otya.smilebasic.project;
|
||||||
import otya.smilebasic.console;
|
import otya.smilebasic.console;
|
||||||
|
import otya.smilebasic.graphic;
|
||||||
const static rot_test_deg = 45f;
|
const static rot_test_deg = 45f;
|
||||||
const static rot_test_x = 0f;
|
const static rot_test_x = 0f;
|
||||||
const static rot_test_y = 1f;
|
const static rot_test_y = 1f;
|
||||||
@@ -185,27 +186,6 @@ class PetitComputer
|
|||||||
return SDL_Color(r >> 5 << 5, g >> 5 << 5, b >> 5 << 5, a == 255 ? 255 : 0);
|
return SDL_Color(r >> 5 << 5, g >> 5 << 5, b >> 5 << 5, a == 255 ? 255 : 0);
|
||||||
}
|
}
|
||||||
Button button;
|
Button button;
|
||||||
bool visibleGRP = true;
|
|
||||||
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 createGRPF(string file)
|
GraphicPage createGRPF(string file)
|
||||||
{
|
{
|
||||||
SDL_RWops* stream = SDL_RWFromFile(toStringz(file), toStringz("rb"));
|
SDL_RWops* stream = SDL_RWFromFile(toStringz(file), toStringz("rb"));
|
||||||
@@ -345,6 +325,7 @@ class PetitComputer
|
|||||||
vsyncCount = 0;
|
vsyncCount = 0;
|
||||||
vsyncFrame = f;
|
vsyncFrame = f;
|
||||||
}
|
}
|
||||||
|
Graphic graphic;
|
||||||
Mutex keybuffermutex;
|
Mutex keybuffermutex;
|
||||||
int keybufferpos;
|
int keybufferpos;
|
||||||
int keybufferlen;
|
int keybufferlen;
|
||||||
@@ -386,152 +367,6 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
Mutex grpmutex;
|
Mutex grpmutex;
|
||||||
int displaynum;
|
int displaynum;
|
||||||
struct Paint
|
|
||||||
{
|
|
||||||
uint[] buffer;
|
|
||||||
static const MAXSIZE = 1024; /* バッファサイズ */
|
|
||||||
|
|
||||||
/* 画面サイズは 1024 X 1024 とする */
|
|
||||||
static const MINX = 0;
|
|
||||||
static const MINY = 0;
|
|
||||||
static const MAXX = 511;
|
|
||||||
static const MAXY = 511;
|
|
||||||
|
|
||||||
struct BufStr {
|
|
||||||
int lx; /* 領域右端のX座標 */
|
|
||||||
int rx; /* 領域右端のX座標 */
|
|
||||||
int y; /* 領域のY座標 */
|
|
||||||
int oy; /* 親ラインのY座標 */
|
|
||||||
};
|
|
||||||
BufStr buff[MAXSIZE]; /* シード登録用バッファ */
|
|
||||||
BufStr* sIdx, eIdx; /* buffの先頭・末尾ポインタ */
|
|
||||||
uint point(int x, int y)
|
|
||||||
{
|
|
||||||
return buffer.ptr[x + y * 512];
|
|
||||||
}
|
|
||||||
void pset(int x, int y, uint col)
|
|
||||||
{
|
|
||||||
buffer.ptr[x + y * 512] = col;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
scanLine : 線分からシードを探索してバッファに登録する
|
|
||||||
|
|
||||||
int lx, rx : 線分のX座標の範囲
|
|
||||||
int y : 線分のY座標
|
|
||||||
int oy : 親ラインのY座標
|
|
||||||
unsigned int col : 領域色
|
|
||||||
*/
|
|
||||||
void scanLine( int lx, int rx, int y, int oy, uint col )
|
|
||||||
{
|
|
||||||
while ( lx <= rx ) {
|
|
||||||
|
|
||||||
/* 非領域色を飛ばす */
|
|
||||||
for ( ; lx < rx ; lx++ )
|
|
||||||
if ( point( lx, y ) == col ) break;
|
|
||||||
if ( point( lx, y ) != col ) break;
|
|
||||||
|
|
||||||
eIdx.lx = lx;
|
|
||||||
|
|
||||||
/* 領域色を飛ばす */
|
|
||||||
for ( ; lx <= rx ; lx++ )
|
|
||||||
if ( point( lx, y ) != col ) break;
|
|
||||||
|
|
||||||
eIdx.rx = lx - 1;
|
|
||||||
eIdx.y = y;
|
|
||||||
eIdx.oy = oy;
|
|
||||||
|
|
||||||
if ( ++eIdx == &buff.ptr[MAXSIZE] )
|
|
||||||
eIdx = buff.ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
paint : 塗り潰し処理(高速版)
|
|
||||||
|
|
||||||
int x, y : 開始座標
|
|
||||||
unsigned int paintCol : 塗り潰す時の色(描画色)
|
|
||||||
*/
|
|
||||||
void paint( int x, int y, uint paintCol , out int dx, out int dy, out int dx2, out int dy2)
|
|
||||||
{
|
|
||||||
int lx, rx; /* 塗り潰す線分の両端のX座標 */
|
|
||||||
int ly; /* 塗り潰す線分のY座標 */
|
|
||||||
int oy; /* 親ラインのY座標 */
|
|
||||||
int i;
|
|
||||||
uint col = point( x, y ); /* 閉領域の色(領域色) */
|
|
||||||
dx = int.max, dy = int.max, dx2 = int.min, dy2 = int.min;
|
|
||||||
if ( col == paintCol ) return; /* 領域色と描画色が等しければ処理不要 */
|
|
||||||
sIdx = buff.ptr;
|
|
||||||
eIdx = buff.ptr + 1;
|
|
||||||
sIdx.lx = sIdx.rx = x;
|
|
||||||
sIdx.y = sIdx.oy = y;
|
|
||||||
|
|
||||||
do {
|
|
||||||
lx = sIdx.lx;
|
|
||||||
rx = sIdx.rx;
|
|
||||||
ly = sIdx.y;
|
|
||||||
oy = sIdx.oy;
|
|
||||||
|
|
||||||
int lxsav = lx - 1;
|
|
||||||
int rxsav = rx + 1;
|
|
||||||
|
|
||||||
if ( ++sIdx == &buff.ptr[MAXSIZE] ) sIdx = buff.ptr;
|
|
||||||
|
|
||||||
/* 処理済のシードなら無視 */
|
|
||||||
if ( point( lx, ly ) != col )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* 右方向の境界を探す */
|
|
||||||
while ( rx < MAXX ) {
|
|
||||||
if ( point( rx + 1, ly ) != col ) break;
|
|
||||||
rx++;
|
|
||||||
}
|
|
||||||
/* 左方向の境界を探す */
|
|
||||||
while ( lx > MINX ) {
|
|
||||||
if ( point( lx - 1, ly ) != col ) break;
|
|
||||||
lx--;
|
|
||||||
}
|
|
||||||
import std.algorithm;
|
|
||||||
dy = min(dy, ly);
|
|
||||||
dy2 = max(dy2, ly);
|
|
||||||
dx = min(dx, lx);
|
|
||||||
dx2 = max(dx2, rx);
|
|
||||||
//
|
|
||||||
/* lx-rxの線分を描画 */
|
|
||||||
for ( i = lx; i <= rx; i++ ) pset( i, ly, paintCol );
|
|
||||||
|
|
||||||
/* 真上のスキャンラインを走査する */
|
|
||||||
if ( ly - 1 >= MINY ) {
|
|
||||||
if ( ly - 1 == oy ) {
|
|
||||||
scanLine( lx, lxsav, ly - 1, ly, col );
|
|
||||||
scanLine( rxsav, rx, ly - 1, ly, col );
|
|
||||||
} else {
|
|
||||||
scanLine( lx, rx, ly - 1, ly, col );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 真下のスキャンラインを走査する */
|
|
||||||
if ( ly + 1 <= MAXY ) {
|
|
||||||
if ( ly + 1 == oy ) {
|
|
||||||
scanLine( lx, lxsav, ly + 1, ly, col );
|
|
||||||
scanLine( rxsav, rx, ly + 1, ly, col );
|
|
||||||
} else {
|
|
||||||
scanLine( lx, rx, ly + 1, ly, col );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} while ( sIdx != eIdx );
|
|
||||||
}
|
|
||||||
void gpaintBuffer(uint* pixels, int x, int y, uint color, GLenum tf)
|
|
||||||
{
|
|
||||||
int dx, dy, dx2, dy2;
|
|
||||||
paint(x, y, color, dx, dy, dx2, dy2);
|
|
||||||
if(dx == int.max) return;
|
|
||||||
int h = dy2 - dy;
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D , 0, 0, dy, 512, h, tf, GL_UNSIGNED_BYTE, pixels + (dy * 512));
|
|
||||||
// glDrawPixels(512, dy2, tf, GL_UNSIGNED_BYTE, buffer.ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Paint paint;
|
|
||||||
int renderstartpos;
|
int renderstartpos;
|
||||||
void chScreen(int x, int y, int w, int h)
|
void chScreen(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
@@ -540,142 +375,6 @@ class PetitComputer
|
|||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0, w, h, 0, 1024, -2048);
|
glOrtho(0, w, h, 0, 1024, -2048);
|
||||||
}
|
}
|
||||||
void drawCircle(int x, int y, int r, int startr, int endr, int flag)
|
|
||||||
{
|
|
||||||
import std.math : sin, cos, PI;
|
|
||||||
int count = r;
|
|
||||||
glBegin(GL_LINE_LOOP);
|
|
||||||
for (int i = 0; i <= r; i++)
|
|
||||||
{
|
|
||||||
//float a = i * (360f / r);
|
|
||||||
glVertex2f(sin(cast(float)i / count * 2f * PI) * r + x, cos(cast(float)i / count * 2f * PI) * r + y);
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
void renderGraphic()
|
|
||||||
{
|
|
||||||
if(!drawMessageLength) return;
|
|
||||||
drawflag = true;
|
|
||||||
//betuni kouzoutai demo sonnnani sokudo kawaranasasou
|
|
||||||
auto len = drawMessageLength;
|
|
||||||
int s = renderstartpos;
|
|
||||||
GLint old;
|
|
||||||
auto a = & glBindFramebuffer;
|
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old);
|
|
||||||
int oldpage = drawMessageQueue[0].page;
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
//glAlphaFunc(GL_GEQUAL, 0.0);
|
|
||||||
void chScreen(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
glViewport(x, y, w, h);
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0, w, 0, h, -256, 1024);//wakaranai
|
|
||||||
}
|
|
||||||
chScreen(0, 0, 511, 511);
|
|
||||||
DrawType dt;
|
|
||||||
auto start = SDL_GetTicks();
|
|
||||||
int i = s;
|
|
||||||
static const size = 255.5f;
|
|
||||||
for(; 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:
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
|
||||||
glVertex2f(dm.x, dm.y);
|
|
||||||
glEnd();
|
|
||||||
//draw.gpset(dm.page, dm.x, dm.y ,dm.color);
|
|
||||||
break;
|
|
||||||
case DrawType.LINE:
|
|
||||||
{
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
|
||||||
glVertex2f(dm.x, dm.y);
|
|
||||||
glVertex2f(dm.x2, dm.y2);
|
|
||||||
//glFlush();
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
//draw.gline(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color);
|
|
||||||
break;
|
|
||||||
case DrawType.FILL:
|
|
||||||
{
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
|
||||||
glVertex2f(dm.x, dm.y);
|
|
||||||
glVertex2f(dm.x, dm.y2);
|
|
||||||
glVertex2f(dm.x2, dm.y2);
|
|
||||||
glVertex2f(dm.x2, dm.y);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
//draw.gfill(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color);
|
|
||||||
break;
|
|
||||||
case DrawType.BOX:
|
|
||||||
{
|
|
||||||
glBegin(GL_LINE_LOOP);
|
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
|
||||||
glVertex2f(dm.x, dm.y);
|
|
||||||
glVertex2f(dm.x, dm.y2);
|
|
||||||
glVertex2f(dm.x2, dm.y2);
|
|
||||||
glVertex2f(dm.x2, dm.y);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
//draw.gbox(dm.page, dm.x, dm.y ,dm.x2, dm.y2, dm.color);
|
|
||||||
break;
|
|
||||||
case DrawType.PAINT:
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, GRP[oldpage].glTexture);
|
|
||||||
if(dt != DrawType.PAINT)
|
|
||||||
{
|
|
||||||
glFinish();
|
|
||||||
//glGetTexImage(GL_TEXTURE_2D,0,GRP[oldpage].textureFormat,GL_UNSIGNED_BYTE,buffer.ptr);
|
|
||||||
glReadPixels(0, 0, 512, 512, GRP[oldpage].textureFormat, GL_UNSIGNED_BYTE, paint.buffer.ptr);
|
|
||||||
}
|
|
||||||
paint.gpaintBuffer(paint.buffer.ptr, dm.x, dm.y, dm.color, GRP[oldpage].textureFormat);
|
|
||||||
//gpaintBufferExW(oldpage, dm.x, dm.y, dm.color);
|
|
||||||
if(SDL_GetTicks() - start >= 16 && i != len - 1)
|
|
||||||
{
|
|
||||||
s = i + 1;
|
|
||||||
goto brk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DrawType.CIRCLE:
|
|
||||||
{
|
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
|
||||||
drawCircle(dm.x, dm.y, dm.circle.r, dm.circle.startr, dm.circle.endr, dm.circle.flag);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
dt = dm.type;
|
|
||||||
}
|
|
||||||
brk:
|
|
||||||
if(i == len)
|
|
||||||
{
|
|
||||||
renderstartpos = 0;
|
|
||||||
drawMessageLength = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
renderstartpos = s;
|
|
||||||
}
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER, old);
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
drawflag = false;
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
|
||||||
}
|
|
||||||
Button[] buttonTable;
|
Button[] buttonTable;
|
||||||
Sprite sprite;
|
Sprite sprite;
|
||||||
int xscreenmode = 0;
|
int xscreenmode = 0;
|
||||||
@@ -721,19 +420,18 @@ class PetitComputer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
paint.buffer = new uint[512 * 512];
|
|
||||||
DerelictSDL2.load();
|
DerelictSDL2.load();
|
||||||
DerelictSDL2Image.load();
|
DerelictSDL2Image.load();
|
||||||
console.GRPF = createGRPF(fontFile);
|
console.GRPF = createGRPF(fontFile);
|
||||||
GRP = new GraphicPage[6];
|
graphic.GRP = new GraphicPage[6];
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
GRP[i] = createEmptyPage();
|
graphic.GRP[i] = createEmptyPage();
|
||||||
}
|
}
|
||||||
sppage = 4;
|
sppage = 4;
|
||||||
GRP[4] = createGRPF(spriteFile);
|
graphic.GRP[4] = createGRPF(spriteFile);
|
||||||
bgpage = 5;
|
bgpage = 5;
|
||||||
GRP[5] = createGRPF(BGFile);
|
graphic.GRP[5] = createGRPF(BGFile);
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
DerelictGL.load();
|
DerelictGL.load();
|
||||||
@@ -809,7 +507,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
int loopcnt;
|
int loopcnt;
|
||||||
DerelictGL3.reload();
|
DerelictGL3.reload();
|
||||||
foreach(g; GRP)
|
foreach(g; graphic.GRP)
|
||||||
{
|
{
|
||||||
g.createTexture(renderer);
|
g.createTexture(renderer);
|
||||||
g.createBuffer();
|
g.createBuffer();
|
||||||
@@ -842,7 +540,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
renderGraphic();
|
graphic.draw();
|
||||||
chScreen(0, 0, 400, 240);
|
chScreen(0, 0, 400, 240);
|
||||||
if(xscreenmode == 1)
|
if(xscreenmode == 1)
|
||||||
{
|
{
|
||||||
@@ -865,16 +563,16 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
if(xscreenmode == 2)
|
if(xscreenmode == 2)
|
||||||
{
|
{
|
||||||
renderGraphicPage(0, 320, 480);
|
graphic.render(0, 320, 480);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderGraphicPage(0, 400, 240);
|
graphic.render(0, 400, 240);
|
||||||
}
|
}
|
||||||
if(xscreenmode == 1)
|
if(xscreenmode == 1)
|
||||||
{
|
{
|
||||||
chScreen(40, 0, 320, 240);
|
chScreen(40, 0, 320, 240);
|
||||||
renderGraphicPage(1, 320, 240);
|
graphic.render(1, 320, 240);
|
||||||
chScreen(0, 240, 400, 240);
|
chScreen(0, 240, 400, 240);
|
||||||
}
|
}
|
||||||
if(xscreenmode == 2)
|
if(xscreenmode == 2)
|
||||||
@@ -887,7 +585,7 @@ class PetitComputer
|
|||||||
}
|
}
|
||||||
version(test) glLoadIdentity();
|
version(test) glLoadIdentity();
|
||||||
version(test) glRotatef(rot_test_deg, rot_test_x, rot_test_y, rot_test_z);
|
version(test) glRotatef(rot_test_deg, rot_test_x, rot_test_y, rot_test_z);
|
||||||
glBindTexture(GL_TEXTURE_2D, GRP[bgpage].glTexture);
|
glBindTexture(GL_TEXTURE_2D, graphic.GRP[bgpage].glTexture);
|
||||||
if(xscreenmode == 2)
|
if(xscreenmode == 2)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < bgmax; i++)
|
for(int i = 0; i < bgmax; i++)
|
||||||
@@ -1030,6 +728,7 @@ class PetitComputer
|
|||||||
slot = new Slot[5];
|
slot = new Slot[5];
|
||||||
keybuffer = new Key[128];
|
keybuffer = new Key[128];
|
||||||
init();
|
init();
|
||||||
|
graphic = new Graphic(this);
|
||||||
consolem = new Mutex();
|
consolem = new Mutex();
|
||||||
keybuffermutex = new Mutex();
|
keybuffermutex = new Mutex();
|
||||||
grpmutex = new Mutex();
|
grpmutex = new Mutex();
|
||||||
@@ -1490,129 +1189,4 @@ class PetitComputer
|
|||||||
{
|
{
|
||||||
return a << 24 | r << 16 | g << 8 | b;
|
return a << 24 | r << 16 | g << 8 | b;
|
||||||
}
|
}
|
||||||
enum DrawType
|
|
||||||
{
|
|
||||||
CLEAR,
|
|
||||||
PSET,
|
|
||||||
LINE,
|
|
||||||
FILL,
|
|
||||||
BOX,
|
|
||||||
CIRCLE,
|
|
||||||
TRI,
|
|
||||||
PAINT,
|
|
||||||
}
|
|
||||||
struct Circle
|
|
||||||
{
|
|
||||||
short r, startr, endr;
|
|
||||||
short flag;
|
|
||||||
}
|
|
||||||
struct DrawMessage
|
|
||||||
{
|
|
||||||
DrawType type;
|
|
||||||
byte page;
|
|
||||||
short x;
|
|
||||||
short y;
|
|
||||||
uint color;
|
|
||||||
short x2;
|
|
||||||
short y2;
|
|
||||||
Circle circle;
|
|
||||||
//
|
|
||||||
}
|
|
||||||
static const int dmqqueuelen = 8192;
|
|
||||||
DrawMessage[] drawMessageQueue = new DrawMessage[dmqqueuelen];
|
|
||||||
int drawMessageLength;
|
|
||||||
bool drawflag;
|
|
||||||
void sendDrawMessage(DrawMessage dm)
|
|
||||||
{
|
|
||||||
//grpmutex.lock();
|
|
||||||
//scope(exit)
|
|
||||||
// grpmutex.unlock();
|
|
||||||
if(drawMessageLength >= dmqqueuelen)
|
|
||||||
{
|
|
||||||
while(drawMessageLength)
|
|
||||||
{
|
|
||||||
SDL_Delay(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(drawflag){}
|
|
||||||
dm.color = toGLColor(this.GRP[0].textureFormat, dm.color & 0xFFF8F8F8);
|
|
||||||
drawMessageQueue[drawMessageLength] = dm;
|
|
||||||
drawMessageLength++;
|
|
||||||
}
|
|
||||||
void sendDrawMessage(DrawType type, byte page, short x, short y, uint color)
|
|
||||||
{
|
|
||||||
DrawMessage dm;
|
|
||||||
dm.type = type;
|
|
||||||
dm.page = page;
|
|
||||||
dm.x = x;
|
|
||||||
dm.y = y;
|
|
||||||
dm.color = color;
|
|
||||||
sendDrawMessage(dm);
|
|
||||||
}
|
|
||||||
void sendDrawMessage(DrawType type, byte page, short x, short y, short x2, short y2, uint color)
|
|
||||||
{
|
|
||||||
DrawMessage dm;
|
|
||||||
dm.type = type;
|
|
||||||
dm.page = page;
|
|
||||||
dm.x = x;
|
|
||||||
dm.y = y;
|
|
||||||
dm.x2 = x2;
|
|
||||||
dm.y2 = y2;
|
|
||||||
dm.color = color;
|
|
||||||
sendDrawMessage(dm);
|
|
||||||
}
|
|
||||||
//TODO:範囲チェック
|
|
||||||
void gpset(int page, int x, int y, uint color)
|
|
||||||
{
|
|
||||||
sendDrawMessage(DrawType.PSET, cast(byte)page, cast(short)x, cast(short)y, color);
|
|
||||||
}
|
|
||||||
void gline(int page, int x, int y, int x2, int y2, uint color)
|
|
||||||
{
|
|
||||||
sendDrawMessage(DrawType.LINE, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
|
||||||
}
|
|
||||||
void gbox(int page, int x, int y, int x2, int y2, uint color)
|
|
||||||
{
|
|
||||||
sendDrawMessage(DrawType.BOX, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
|
||||||
}
|
|
||||||
void gfill(int page, int x, int y, int x2, int y2, uint color)
|
|
||||||
{
|
|
||||||
sendDrawMessage(DrawType.FILL, cast(byte)page, cast(short)x, cast(short)y, cast(short)x2, cast(short)y2, color);
|
|
||||||
}
|
|
||||||
void gpaint(int page, int x, int y, uint color)
|
|
||||||
{
|
|
||||||
sendDrawMessage(DrawType.PAINT, cast(byte)page, cast(short)x, cast(short)y, color);
|
|
||||||
}
|
|
||||||
void gcircle(int page, int x, int y, int r, int startr, int endr, int flag, uint color)
|
|
||||||
{
|
|
||||||
DrawMessage dm;
|
|
||||||
dm.page = cast(byte)page;
|
|
||||||
dm.x = cast(short)x;
|
|
||||||
dm.y = cast(short)y;
|
|
||||||
dm.circle.r = cast(short)r;
|
|
||||||
dm.circle.startr = cast(short)startr;
|
|
||||||
dm.circle.endr = cast(short)endr;
|
|
||||||
dm.circle.flag = cast(short)flag;
|
|
||||||
dm.color = color;
|
|
||||||
dm.type = DrawType.CIRCLE;
|
|
||||||
sendDrawMessage(dm);
|
|
||||||
}
|
|
||||||
int gprio;
|
|
||||||
void renderGraphicPage(int display, float w, float h)
|
|
||||||
{
|
|
||||||
float z = gprio;
|
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, GRP[showPage[display]].glTexture);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glTexCoord2f(0 / 512f - 1 , h / 512f - 1);
|
|
||||||
glVertex3f(0, h, z);
|
|
||||||
glTexCoord2f(0 / 512f - 1, 0 / 512f - 1);
|
|
||||||
glVertex3f(0, 0, z);
|
|
||||||
glTexCoord2f(w / 512f - 1, 0 / 512f - 1);
|
|
||||||
glVertex3f(w, 0, z);
|
|
||||||
glTexCoord2f(w / 512f - 1, h / 512f - 1);
|
|
||||||
glVertex3f(w, h, z);
|
|
||||||
glEnd();
|
|
||||||
//glFlush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -625,7 +625,7 @@ class Sprite
|
|||||||
dish2 = 480f;
|
dish2 = 480f;
|
||||||
dis = -1;
|
dis = -1;
|
||||||
}
|
}
|
||||||
auto texture = petitcom.GRP[petitcom.sppage].glTexture;
|
auto texture = petitcom.graphic.GRP[petitcom.sppage].glTexture;
|
||||||
float aspect = disw2 / dish2;
|
float aspect = disw2 / dish2;
|
||||||
float z = -0.01f;
|
float z = -0.01f;
|
||||||
int spmax = petitcom.xscreenmode == 1 ? this.spmax : 512;//XSCREENが2,3じゃないと下画面は描画しない
|
int spmax = petitcom.xscreenmode == 1 ? this.spmax : 512;//XSCREENが2,3じゃないと下画面は描画しない
|
||||||
|
|||||||
Reference in New Issue
Block a user