Implement GCLIP function
This commit is contained in:
@@ -362,6 +362,34 @@ class BuiltinFunction
|
|||||||
p.graphic.showGRP = showPage;
|
p.graphic.showGRP = showPage;
|
||||||
p.graphic.useGRP = usePage;
|
p.graphic.useGRP = usePage;
|
||||||
}
|
}
|
||||||
|
static void GCLIP(PetitComputer p, int clipmode)
|
||||||
|
{
|
||||||
|
p.graphic.clip(cast(bool)clipmode/*not checked*/);
|
||||||
|
}
|
||||||
|
static void GCLIP(PetitComputer p, int clipmode, int sx, int sy, int ex, int ey)
|
||||||
|
{
|
||||||
|
import std.algorithm : swap;
|
||||||
|
if (sx < 0 || sy < 0 || ex < 0 || ey < 0)
|
||||||
|
throw new OutOfRange("GCLIP");
|
||||||
|
if (clipmode)
|
||||||
|
{
|
||||||
|
if (sx >= 512 || sy >= 512 || ex >= 512 || ey >= 512)
|
||||||
|
throw new OutOfRange("GCLIP");
|
||||||
|
}
|
||||||
|
if (sx > ex)
|
||||||
|
{
|
||||||
|
swap(sx, ex);
|
||||||
|
}
|
||||||
|
if (sy > ey)
|
||||||
|
{
|
||||||
|
swap(sy, ey);
|
||||||
|
}
|
||||||
|
int x = sx;
|
||||||
|
int y = sy;
|
||||||
|
int w = ex - sx + 1;
|
||||||
|
int h = ey - sy + 1;
|
||||||
|
p.graphic.clip(cast(bool)clipmode/*not checked*/, x, y, w, h);
|
||||||
|
}
|
||||||
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.graphic.gcolor);
|
color.setDefaultValue(p.graphic.gcolor);
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ class OutOfRange : SmileBasicError
|
|||||||
this.errnum = 10;
|
this.errnum = 10;
|
||||||
super("Out of range");
|
super("Out of range");
|
||||||
}
|
}
|
||||||
|
this(string func)
|
||||||
|
{
|
||||||
|
this.errnum = 10;
|
||||||
|
super("Out of range(" ~ func ~ ")");
|
||||||
|
}
|
||||||
this(string func, int arg)
|
this(string func, int arg)
|
||||||
{
|
{
|
||||||
this.errnum = 10;
|
this.errnum = 10;
|
||||||
|
|||||||
@@ -5,6 +5,45 @@ import derelict.opengl3.gl;
|
|||||||
import derelict.opengl3.gl3;
|
import derelict.opengl3.gl3;
|
||||||
import otya.smilebasic.petitcomputer;
|
import otya.smilebasic.petitcomputer;
|
||||||
|
|
||||||
|
enum DrawType
|
||||||
|
{
|
||||||
|
CLEAR,
|
||||||
|
PSET,
|
||||||
|
LINE,
|
||||||
|
FILL,
|
||||||
|
BOX,
|
||||||
|
CIRCLE1,
|
||||||
|
CIRCLE2,//startangle, endangle
|
||||||
|
TRI,
|
||||||
|
PAINT,
|
||||||
|
CLIPWRITE,
|
||||||
|
}
|
||||||
|
struct Circle
|
||||||
|
{
|
||||||
|
short r, startr, endr;
|
||||||
|
short flag;
|
||||||
|
}
|
||||||
|
struct DrawMessage
|
||||||
|
{
|
||||||
|
DrawType type;
|
||||||
|
byte page;
|
||||||
|
byte display;
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
short x2;
|
||||||
|
short w;
|
||||||
|
}
|
||||||
|
union
|
||||||
|
{
|
||||||
|
short y2;
|
||||||
|
short h;
|
||||||
|
}
|
||||||
|
uint color;
|
||||||
|
Circle circle;
|
||||||
|
//
|
||||||
|
}
|
||||||
class Graphic
|
class Graphic
|
||||||
{
|
{
|
||||||
PetitComputer petitcom;
|
PetitComputer petitcom;
|
||||||
@@ -254,13 +293,14 @@ class Graphic
|
|||||||
glViewport(x, y, w, h);
|
glViewport(x, y, w, h);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0, w, 0, h, -256, 1024);//wakaranai
|
glOrtho(x, x + w - 1, y, y + h - 1, -256, 1024);//wakaranai
|
||||||
}
|
}
|
||||||
chScreen(0, 0, 511, 511);
|
chScreen(0, 0, 511, 511);
|
||||||
DrawType dt;
|
DrawType dt;
|
||||||
auto start = SDL_GetTicks();
|
auto start = SDL_GetTicks();
|
||||||
int i = s;
|
int i = s;
|
||||||
static const size = 255.5f;
|
static const size = 255.5f;
|
||||||
|
int display = -1;
|
||||||
for(; i < len; i++)
|
for(; i < len; i++)
|
||||||
{
|
{
|
||||||
DrawMessage dm = drawMessageQueue[i];
|
DrawMessage dm = drawMessageQueue[i];
|
||||||
@@ -269,8 +309,20 @@ class Graphic
|
|||||||
oldpage = dm.page;
|
oldpage = dm.page;
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER, this.GRP[oldpage].buffer);
|
||||||
}
|
}
|
||||||
|
if (display != dm.display)
|
||||||
|
{
|
||||||
|
display = dm.display;
|
||||||
|
chScreen(writeArea[display].x, writeArea[display].y, writeArea[display].w, writeArea[display].h);
|
||||||
|
}
|
||||||
switch(dm.type)
|
switch(dm.type)
|
||||||
{
|
{
|
||||||
|
case DrawType.CLIPWRITE:
|
||||||
|
writeArea[display].x = dm.x;
|
||||||
|
writeArea[display].y = dm.y;
|
||||||
|
writeArea[display].w = dm.w;
|
||||||
|
writeArea[display].h = dm.h;
|
||||||
|
chScreen(writeArea[display].x, writeArea[display].y, writeArea[display].w, writeArea[display].h);
|
||||||
|
break;
|
||||||
case DrawType.PSET:
|
case DrawType.PSET:
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
glColor4ubv(cast(ubyte*)&dm.color);
|
glColor4ubv(cast(ubyte*)&dm.color);
|
||||||
@@ -358,35 +410,6 @@ class Graphic
|
|||||||
drawflag = false;
|
drawflag = false;
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
enum DrawType
|
|
||||||
{
|
|
||||||
CLEAR,
|
|
||||||
PSET,
|
|
||||||
LINE,
|
|
||||||
FILL,
|
|
||||||
BOX,
|
|
||||||
CIRCLE1,
|
|
||||||
CIRCLE2,//startangle, endangle
|
|
||||||
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;
|
static const int dmqqueuelen = 8192;
|
||||||
DrawMessage[] drawMessageQueue = new DrawMessage[dmqqueuelen];
|
DrawMessage[] drawMessageQueue = new DrawMessage[dmqqueuelen];
|
||||||
int drawMessageLength;
|
int drawMessageLength;
|
||||||
@@ -404,7 +427,10 @@ class Graphic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(drawflag){}
|
while(drawflag){}
|
||||||
|
if (dm.type != DrawType.CLIPWRITE)
|
||||||
|
{
|
||||||
dm.color = petitcom.toGLColor(this.GRP[0].textureFormat, dm.color & 0xFFF8F8F8);
|
dm.color = petitcom.toGLColor(this.GRP[0].textureFormat, dm.color & 0xFFF8F8F8);
|
||||||
|
}
|
||||||
drawMessageQueue[drawMessageLength] = dm;
|
drawMessageQueue[drawMessageLength] = dm;
|
||||||
drawMessageLength++;
|
drawMessageLength++;
|
||||||
}
|
}
|
||||||
@@ -416,6 +442,7 @@ class Graphic
|
|||||||
dm.x = x;
|
dm.x = x;
|
||||||
dm.y = y;
|
dm.y = y;
|
||||||
dm.color = color;
|
dm.color = color;
|
||||||
|
dm.display = cast(byte)petitcom.displaynum;
|
||||||
sendDrawMessage(dm);
|
sendDrawMessage(dm);
|
||||||
}
|
}
|
||||||
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)
|
||||||
@@ -428,6 +455,7 @@ class Graphic
|
|||||||
dm.x2 = x2;
|
dm.x2 = x2;
|
||||||
dm.y2 = y2;
|
dm.y2 = y2;
|
||||||
dm.color = color;
|
dm.color = color;
|
||||||
|
dm.display = cast(byte)petitcom.displaynum;
|
||||||
sendDrawMessage(dm);
|
sendDrawMessage(dm);
|
||||||
}
|
}
|
||||||
//TODO:範囲チェック
|
//TODO:範囲チェック
|
||||||
@@ -460,6 +488,7 @@ class Graphic
|
|||||||
dm.circle.r = cast(short)r;
|
dm.circle.r = cast(short)r;
|
||||||
dm.color = color;
|
dm.color = color;
|
||||||
dm.type = DrawType.CIRCLE1;
|
dm.type = DrawType.CIRCLE1;
|
||||||
|
dm.display = cast(byte)petitcom.displaynum;
|
||||||
sendDrawMessage(dm);
|
sendDrawMessage(dm);
|
||||||
}
|
}
|
||||||
void gcircle(int page, int x, int y, int r, int startr, int endr, int flag, uint color)
|
void gcircle(int page, int x, int y, int r, int startr, int endr, int flag, uint color)
|
||||||
@@ -474,10 +503,11 @@ class Graphic
|
|||||||
dm.circle.flag = cast(short)flag;
|
dm.circle.flag = cast(short)flag;
|
||||||
dm.color = color;
|
dm.color = color;
|
||||||
dm.type = DrawType.CIRCLE2;
|
dm.type = DrawType.CIRCLE2;
|
||||||
|
dm.display = cast(byte)petitcom.displaynum;
|
||||||
sendDrawMessage(dm);
|
sendDrawMessage(dm);
|
||||||
}
|
}
|
||||||
int gprio;
|
int gprio;
|
||||||
void render(int display, float w, float h)
|
void render(int display, int w, int h)
|
||||||
{
|
{
|
||||||
if (!visibles[display])
|
if (!visibles[display])
|
||||||
return;
|
return;
|
||||||
@@ -486,15 +516,54 @@ class Graphic
|
|||||||
glBindTexture(GL_TEXTURE_2D, GRP[showPage[display]].glTexture);
|
glBindTexture(GL_TEXTURE_2D, GRP[showPage[display]].glTexture);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0 / 512f - 1 , h / 512f - 1);
|
int x1 = displayArea[display].x;
|
||||||
glVertex3f(0, h, z);
|
int y1 = displayArea[display].y;
|
||||||
glTexCoord2f(0 / 512f - 1, 0 / 512f - 1);
|
int x2 = x1 + displayArea[display].w;
|
||||||
glVertex3f(0, 0, z);
|
int y2 = y1 + displayArea[display].h;
|
||||||
glTexCoord2f(w / 512f - 1, 0 / 512f - 1);
|
glTexCoord2f(x1 / 512f - 1 , y2 / 512f - 1);
|
||||||
glVertex3f(w, 0, z);
|
glVertex3f(x1, y2, z);
|
||||||
glTexCoord2f(w / 512f - 1, h / 512f - 1);
|
glTexCoord2f(x1 / 512f - 1, y1 / 512f - 1);
|
||||||
glVertex3f(w, h, z);
|
glVertex3f(x1, y1, z);
|
||||||
|
glTexCoord2f(x2 / 512f - 1, y1 / 512f - 1);
|
||||||
|
glVertex3f(x2, y1, z);
|
||||||
|
glTexCoord2f(x2 / 512f - 1, y2 / 512f - 1);
|
||||||
|
glVertex3f(x2, y2, z);
|
||||||
glEnd();
|
glEnd();
|
||||||
//glFlush();
|
//glFlush();
|
||||||
}
|
}
|
||||||
|
bool writeClip;
|
||||||
|
SDL_Rect[2] writeArea;
|
||||||
|
bool displayClip;
|
||||||
|
SDL_Rect[2] displayArea;
|
||||||
|
void clip(bool clipmode)
|
||||||
|
{
|
||||||
|
if (clipmode)
|
||||||
|
{
|
||||||
|
clip(clipmode, 0, 0, 512, 512);
|
||||||
|
//displayArea = SDL_Rect(0, 0, 511, 511);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clip(clipmode, 0, 0, petitcom.currentScreenWidth, petitcom.currentScreenHeight);
|
||||||
|
//displayArea = SDL_Rect(0, 0, petitcom.currentScreenWidth - 1, petitcom.currentScreenHeight - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clip(bool clipmode, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (clipmode)
|
||||||
|
{
|
||||||
|
DrawMessage dm;
|
||||||
|
dm.display = cast(byte)petitcom.displaynum;
|
||||||
|
dm.x = cast(short)x;
|
||||||
|
dm.y = cast(short)y;
|
||||||
|
dm.w = cast(short)w;
|
||||||
|
dm.h = cast(short)h;
|
||||||
|
dm.type = DrawType.CLIPWRITE;
|
||||||
|
sendDrawMessage(dm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
displayArea[petitcom.displaynum] = SDL_Rect(x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -312,9 +312,32 @@ class PetitComputer
|
|||||||
display(0);
|
display(0);
|
||||||
writeln("OK");
|
writeln("OK");
|
||||||
}
|
}
|
||||||
|
int currentScreenWidth;
|
||||||
|
int currentScreenHeight;
|
||||||
void display(int number)
|
void display(int number)
|
||||||
{
|
{
|
||||||
|
import std.exception : enforce;
|
||||||
|
enforce(number >= 0);
|
||||||
|
if(xscreenmode == 0)
|
||||||
|
{
|
||||||
|
enforce(number == 0);
|
||||||
|
currentScreenWidth = screenWidth;
|
||||||
|
currentScreenHeight = screenHeight;
|
||||||
|
}
|
||||||
|
else if(xscreenmode == 1)
|
||||||
|
{
|
||||||
|
enforce(number == 0 || number == 1);
|
||||||
|
currentScreenWidth = screenWidthDisplay1;
|
||||||
|
currentScreenHeight = screenHeightDisplay1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enforce(number == 0);
|
||||||
|
currentScreenWidth = screenWidthDisplay1;
|
||||||
|
currentScreenHeight = screenHeightDisplay1 * 2;
|
||||||
|
}
|
||||||
displaynum = number;
|
displaynum = number;
|
||||||
|
|
||||||
console.display(number);
|
console.display(number);
|
||||||
}
|
}
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
@@ -394,12 +417,17 @@ class PetitComputer
|
|||||||
if(mode2 == 1)
|
if(mode2 == 1)
|
||||||
{
|
{
|
||||||
SDL_SetWindowSize(window, 400, 480);
|
SDL_SetWindowSize(window, 400, 480);
|
||||||
|
display(1);
|
||||||
|
graphic.clip(false);
|
||||||
|
graphic.clip(true);
|
||||||
}
|
}
|
||||||
if(mode == 4)
|
if(mode == 4)
|
||||||
{
|
{
|
||||||
SDL_SetWindowSize(window, 320, 240 * 2);
|
SDL_SetWindowSize(window, 320, 240 * 2);
|
||||||
display(0);
|
|
||||||
}
|
}
|
||||||
|
display(0);
|
||||||
|
graphic.clip(false);
|
||||||
|
graphic.clip(true);
|
||||||
}
|
}
|
||||||
BG getBG(int layer)
|
BG getBG(int layer)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user