Add clip rect feature to Graphics and gfx.setClipRect
Also retire the separate VideoBuffer in Panel and hiding ToolButtons in the GameView ToolButton panel in favour of clip rects.
This commit is contained in:
parent
f18bd6553f
commit
715333295b
@ -1081,3 +1081,23 @@ VideoBuffer Graphics::DumpFrame()
|
||||
std::copy(vid, vid+(WINDOWW*WINDOWH), newBuffer.Buffer);
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
void Graphics::SetClipRect(int &x, int &y, int &w, int &h)
|
||||
{
|
||||
int newX = x;
|
||||
int newY = y;
|
||||
int newW = w;
|
||||
int newH = h;
|
||||
if (newX < 0) newX = 0;
|
||||
if (newY < 0) newY = 0;
|
||||
if (newW > WINDOWW - newX) newW = WINDOWW - newX;
|
||||
if (newH > WINDOWH - newY) newH = WINDOWH - newY;
|
||||
x = clipx1;
|
||||
y = clipy1;
|
||||
w = clipx2 - clipx1;
|
||||
h = clipy2 - clipy1;
|
||||
clipx1 = newX;
|
||||
clipy1 = newY;
|
||||
clipx2 = newX + newW;
|
||||
clipy2 = newY + newH;
|
||||
}
|
||||
|
@ -70,6 +70,11 @@ public:
|
||||
|
||||
class Graphics
|
||||
{
|
||||
int clipx1 = 0;
|
||||
int clipy1 = 0;
|
||||
int clipx2 = WINDOWW;
|
||||
int clipy2 = WINDOWH;
|
||||
|
||||
public:
|
||||
pixel *vid;
|
||||
int sdl_scale;
|
||||
@ -122,13 +127,14 @@ public:
|
||||
void clearrect(int x, int y, int width, int height);
|
||||
void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2);
|
||||
|
||||
void draw_image(pixel *img, int x, int y, int w, int h, int a);
|
||||
void draw_image(const VideoBuffer & vidBuf, int x, int y, int a);
|
||||
void draw_image(VideoBuffer * vidBuf, int x, int y, int a);
|
||||
void draw_image(const pixel *img, int x, int y, int w, int h, int a);
|
||||
void draw_image(const VideoBuffer * vidBuf, int x, int y, int a);
|
||||
void draw_rgba_image(const unsigned char *data, int x, int y, float alpha);
|
||||
|
||||
Graphics();
|
||||
~Graphics();
|
||||
|
||||
void SetClipRect(int &x, int &y, int &w, int &h);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -104,7 +104,11 @@ int PIXELMETHODS_CLASS::addchar(int x, int y, String::value_type c, int r, int g
|
||||
TPT_INLINE void PIXELMETHODS_CLASS::xor_pixel(int x, int y)
|
||||
{
|
||||
int c;
|
||||
if (x<0 || y<0 || x>=XRES || y>=YRES)
|
||||
#ifdef DO_CLIPCHECK
|
||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
||||
#else
|
||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
||||
#endif
|
||||
return;
|
||||
c = vid[y*(VIDXRES)+x];
|
||||
c = PIXB(c) + 3*PIXG(c) + 2*PIXR(c);
|
||||
@ -117,7 +121,11 @@ TPT_INLINE void PIXELMETHODS_CLASS::xor_pixel(int x, int y)
|
||||
void PIXELMETHODS_CLASS::blendpixel(int x, int y, int r, int g, int b, int a)
|
||||
{
|
||||
pixel t;
|
||||
#ifdef DO_CLIPCHECK
|
||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
||||
#else
|
||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
||||
#endif
|
||||
return;
|
||||
if (a!=255)
|
||||
{
|
||||
@ -132,7 +140,11 @@ void PIXELMETHODS_CLASS::blendpixel(int x, int y, int r, int g, int b, int a)
|
||||
void PIXELMETHODS_CLASS::addpixel(int x, int y, int r, int g, int b, int a)
|
||||
{
|
||||
pixel t;
|
||||
#ifdef DO_CLIPCHECK
|
||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
||||
#else
|
||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
||||
#endif
|
||||
return;
|
||||
t = vid[y*(VIDXRES)+x];
|
||||
r = (a*r + 255*PIXR(t)) >> 8;
|
||||
@ -376,6 +388,20 @@ void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
|
||||
w -= 1;
|
||||
h -= 1;
|
||||
|
||||
#ifdef DO_CLIPCHECK
|
||||
if (x+w > clipx2) w = clipx2-x;
|
||||
if (y+h > clipy2) h = clipy2-y;
|
||||
if (x<clipx1)
|
||||
{
|
||||
w += x - clipx1;
|
||||
x = clipx1;
|
||||
}
|
||||
if (y<clipy1)
|
||||
{
|
||||
h += y - clipy1;
|
||||
y = clipy1;
|
||||
}
|
||||
#else
|
||||
if (x+w > VIDXRES) w = VIDXRES-x;
|
||||
if (y+h > VIDYRES) h = VIDYRES-y;
|
||||
if (x<0)
|
||||
@ -388,6 +414,7 @@ void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
#endif
|
||||
if (w<0 || h<0)
|
||||
return;
|
||||
|
||||
@ -395,7 +422,7 @@ void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
|
||||
memset(vid+(x+(VIDXRES)*(y+i)), 0, PIXELSIZE*w);
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::draw_image(pixel *img, int x, int y, int w, int h, int a)
|
||||
void PIXELMETHODS_CLASS::draw_image(const pixel *img, int x, int y, int w, int h, int a)
|
||||
{
|
||||
int startX = 0;
|
||||
if (!img)
|
||||
@ -428,6 +455,9 @@ void PIXELMETHODS_CLASS::draw_image(pixel *img, int x, int y, int w, int h, int
|
||||
img += startX;
|
||||
for (int i = startX; i < w; i++)
|
||||
{
|
||||
#ifdef DO_CLIPCHECK
|
||||
if (!(x+i<clipx1 || y+j<clipy1 || x+i>=clipx2 || y+j>=clipy2))
|
||||
#endif
|
||||
vid[(y+j)*(VIDXRES)+(x+i)] = *img;
|
||||
img++;
|
||||
}
|
||||
@ -450,12 +480,7 @@ void PIXELMETHODS_CLASS::draw_image(pixel *img, int x, int y, int w, int h, int
|
||||
}
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::draw_image(const VideoBuffer & vidBuf, int x, int y, int a)
|
||||
{
|
||||
draw_image(vidBuf.Buffer, x, y, vidBuf.Width, vidBuf.Height, a);
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::draw_image(VideoBuffer * vidBuf, int x, int y, int a)
|
||||
void PIXELMETHODS_CLASS::draw_image(const VideoBuffer * vidBuf, int x, int y, int a)
|
||||
{
|
||||
draw_image(vidBuf->Buffer, x, y, vidBuf->Width, vidBuf->Height, a);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ void Graphics::Finalise()
|
||||
#define VIDXRES WINDOWW
|
||||
#define VIDYRES WINDOWH
|
||||
#define PIXELMETHODS_CLASS Graphics
|
||||
#define DO_CLIPCHECK
|
||||
#include "RasterDrawMethods.inl"
|
||||
#undef VIDYRES
|
||||
#undef VIDXRES
|
||||
|
@ -120,9 +120,8 @@ public:
|
||||
void clearrect(int x, int y, int width, int height);
|
||||
void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2);
|
||||
|
||||
void draw_image(pixel *img, int x, int y, int w, int h, int a);
|
||||
void draw_image(const VideoBuffer & vidBuf, int w, int h, int a);
|
||||
void draw_image(VideoBuffer * vidBuf, int w, int h, int a);
|
||||
void draw_image(const pixel *img, int x, int y, int w, int h, int a);
|
||||
void draw_image(const VideoBuffer * vidBuf, int w, int h, int a);
|
||||
|
||||
VideoBuffer DumpFrame();
|
||||
|
||||
|
@ -576,6 +576,11 @@ void GameView::NotifyToolListChanged(GameModel * sender)
|
||||
else
|
||||
tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), tool->GetName(), tool->GetIdentifier(), tool->GetDescription());
|
||||
|
||||
tempButton->clipRectX = 1;
|
||||
tempButton->clipRectY = YRES + 1;
|
||||
tempButton->clipRectW = XRES - 1;
|
||||
tempButton->clipRectH = 18;
|
||||
|
||||
//currentY -= 17;
|
||||
currentX -= 31;
|
||||
tempButton->tool = tool;
|
||||
@ -1014,10 +1019,6 @@ void GameView::updateToolButtonScroll()
|
||||
for (auto *button : toolButtons)
|
||||
{
|
||||
button->Position.X -= offsetDelta;
|
||||
if (button->Position.X + button->Size.X <= 0 || (button->Position.X + button->Size.X) > XRES - 2)
|
||||
button->Visible = false;
|
||||
else
|
||||
button->Visible = true;
|
||||
}
|
||||
|
||||
// Ensure that mouseLeave events are make their way to the buttons should they move from underneath the mouse pointer
|
||||
@ -1803,7 +1804,24 @@ void GameView::DoExit()
|
||||
void GameView::DoDraw()
|
||||
{
|
||||
Window::DoDraw();
|
||||
constexpr std::array<int, 9> fadeout = { { // * Gamma-corrected.
|
||||
255, 195, 145, 103, 69, 42, 23, 10, 3
|
||||
} };
|
||||
auto *g = GetGraphics();
|
||||
for (auto x = 0U; x < fadeout.size(); ++x)
|
||||
{
|
||||
g->draw_line(x, YRES + 1, x, YRES + 18, 0, 0, 0, fadeout[x]);
|
||||
g->draw_line(XRES - x, YRES + 1, XRES - x, YRES + 18, 0, 0, 0, fadeout[x]);
|
||||
}
|
||||
|
||||
c->Tick();
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w = WINDOWW;
|
||||
int h = WINDOWH;
|
||||
g->SetClipRect(x, y, w, h); // reset any nonsense cliprect Lua left configured
|
||||
}
|
||||
}
|
||||
|
||||
void GameView::NotifyNotificationsChanged(GameModel * sender)
|
||||
|
@ -49,6 +49,14 @@ void ToolButton::OnMouseUp(int x, int y, unsigned int button)
|
||||
void ToolButton::Draw(const ui::Point& screenPos)
|
||||
{
|
||||
Graphics * g = GetGraphics();
|
||||
int x = clipRectX;
|
||||
int y = clipRectY;
|
||||
int w = clipRectW;
|
||||
int h = clipRectH;
|
||||
if (clipRectW && clipRectH)
|
||||
{
|
||||
g->SetClipRect(x, y, w, h); // old cliprect is now in x, y, w, h
|
||||
}
|
||||
int totalColour = Appearance.BackgroundInactive.Blue + (3*Appearance.BackgroundInactive.Green) + (2*Appearance.BackgroundInactive.Red);
|
||||
|
||||
if (Appearance.GetTexture())
|
||||
@ -81,6 +89,10 @@ void ToolButton::Draw(const ui::Point& screenPos)
|
||||
{
|
||||
g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, buttonDisplayText, 0, 0, 0, 255);
|
||||
}
|
||||
if (clipRectW && clipRectH)
|
||||
{
|
||||
g->SetClipRect(x, y, w, h); // apply old clip rect
|
||||
}
|
||||
}
|
||||
|
||||
void ToolButton::SetSelectionState(int state)
|
||||
|
@ -18,6 +18,10 @@ public:
|
||||
void SetSelectionState(int state);
|
||||
int GetSelectionState();
|
||||
Tool *tool;
|
||||
int clipRectX = 0;
|
||||
int clipRectY = 0;
|
||||
int clipRectW = 0;
|
||||
int clipRectH = 0;
|
||||
};
|
||||
|
||||
#endif /* TOOLBUTTON_H_ */
|
||||
|
@ -13,7 +13,6 @@ Panel::Panel(Point position, Point size):
|
||||
ViewportPosition(0, 0),
|
||||
mouseInside(false)
|
||||
{
|
||||
myVid = new pixel[WINDOWW*WINDOWH];
|
||||
}
|
||||
|
||||
Panel::~Panel()
|
||||
@ -22,7 +21,6 @@ Panel::~Panel()
|
||||
{
|
||||
delete children[i];
|
||||
}
|
||||
delete[] myVid;
|
||||
}
|
||||
|
||||
void Panel::AddChild(Component* c)
|
||||
@ -66,12 +64,14 @@ void Panel::RemoveChild(unsigned idx, bool freeMem)
|
||||
|
||||
void Panel::Draw(const Point& screenPos)
|
||||
{
|
||||
|
||||
// draw ourself first
|
||||
XDraw(screenPos);
|
||||
pixel * lastVid = ui::Engine::Ref().g->vid;
|
||||
ui::Engine::Ref().g->vid = myVid;
|
||||
std::fill(myVid, myVid+(WINDOWW*WINDOWH), 0);
|
||||
|
||||
int x = screenPos.X;
|
||||
int y = screenPos.Y;
|
||||
int w = Size.X;
|
||||
int h = Size.Y;
|
||||
ui::Engine::Ref().g->SetClipRect(x, y, w, h); // old cliprect is now in x, y, w, h
|
||||
|
||||
// attempt to draw all children
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
@ -85,19 +85,13 @@ void Panel::Draw(const Point& screenPos)
|
||||
children[i]->Position.X + ViewportPosition.X < ui::Engine::Ref().GetWidth() &&
|
||||
children[i]->Position.Y + ViewportPosition.Y < ui::Engine::Ref().GetHeight() )
|
||||
{
|
||||
Point scrpos = /*screenPos + */children[i]->Position + ViewportPosition;
|
||||
Point scrpos = screenPos + children[i]->Position + ViewportPosition;
|
||||
children[i]->Draw(scrpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui::Engine::Ref().g->vid = lastVid;
|
||||
|
||||
//dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
|
||||
for (int row = 0; row < Size.Y; row++)
|
||||
{
|
||||
std::copy(myVid+(row*WINDOWW), myVid+(row*WINDOWW)+Size.X, lastVid+((screenPos.Y+row)*WINDOWW)+screenPos.X);
|
||||
}
|
||||
ui::Engine::Ref().g->SetClipRect(x, y, w, h); // apply old cliprect
|
||||
}
|
||||
|
||||
void Panel::Tick(float dt)
|
||||
|
@ -22,7 +22,6 @@ class Component;
|
||||
public:
|
||||
friend class Component;
|
||||
|
||||
pixel * myVid;
|
||||
ui::Point InnerSize;
|
||||
ui::Point ViewportPosition;
|
||||
|
||||
|
@ -3579,6 +3579,7 @@ void LuaScriptInterface::initGraphicsAPI()
|
||||
{"fillCircle", graphics_fillCircle},
|
||||
{"getColors", graphics_getColors},
|
||||
{"getHexColor", graphics_getHexColor},
|
||||
{"setClipRect", graphics_setClipRect},
|
||||
{NULL, NULL}
|
||||
};
|
||||
luaL_register(l, "graphics", graphicsAPIMethods);
|
||||
@ -3775,6 +3776,20 @@ int LuaScriptInterface::graphics_getHexColor(lua_State * l)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::graphics_setClipRect(lua_State * l)
|
||||
{
|
||||
int x = luaL_optinteger(l, 1, 0);
|
||||
int y = luaL_optinteger(l, 2, 0);
|
||||
int w = luaL_optinteger(l, 3, WINDOWW);
|
||||
int h = luaL_optinteger(l, 4, WINDOWH);
|
||||
luacon_g->SetClipRect(x, y, w, h);
|
||||
lua_pushinteger(l, x);
|
||||
lua_pushinteger(l, y);
|
||||
lua_pushinteger(l, w);
|
||||
lua_pushinteger(l, h);
|
||||
return 4;
|
||||
}
|
||||
|
||||
void LuaScriptInterface::initFileSystemAPI()
|
||||
{
|
||||
//Methods
|
||||
|
@ -167,6 +167,7 @@ class LuaScriptInterface: public CommandInterface
|
||||
static int graphics_fillCircle(lua_State * l);
|
||||
static int graphics_getColors(lua_State * l);
|
||||
static int graphics_getHexColor(lua_State * l);
|
||||
static int graphics_setClipRect(lua_State * l);
|
||||
|
||||
void initFileSystemAPI();
|
||||
static int fileSystem_list(lua_State * l);
|
||||
|
Loading…
Reference in New Issue
Block a user