1
0

Implement GCLIP function

This commit is contained in:
otya128
2016-12-04 21:57:07 +09:00
parent 3b1193ee80
commit 460787c33d
4 changed files with 171 additions and 41 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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){}
dm.color = petitcom.toGLColor(this.GRP[0].textureFormat, dm.color & 0xFFF8F8F8); if (dm.type != DrawType.CLIPWRITE)
{
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);
}
}
} }

View File

@@ -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)
{ {