summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/shape.h29
-rw-r--r--lib/shape.cc133
2 files changed, 150 insertions, 12 deletions
diff --git a/include/shape.h b/include/shape.h
index b2e218d..756f7d0 100644
--- a/include/shape.h
+++ b/include/shape.h
@@ -1,6 +1,7 @@
#ifndef __SHAPE_H__
#define __SHAPE_H__
+#include <vector>
#include <Exceptions.h>
#include <BString.h>
#include <mcolor.h>
@@ -18,11 +19,18 @@ namespace mogltk {
virtual ~fillwalker();
virtual void step(int x, int y);
};
+ class segwalker : public Base {
+ public:
+ segwalker();
+ virtual ~segwalker();
+ virtual void step(int x1, int y1, int x2, int y2);
+ };
class fill : public Base {
public:
fill();
virtual ~fill();
void walk(fillwalker *);
+ void swalk(segwalker *);
void insert(int, int, int, int);
int GetMinX() const;
int GetMinY() const;
@@ -30,9 +38,14 @@ namespace mogltk {
int GetMaxY() const;
texture * GetTexture();
texture * Talloc();
+ texture * GetSTexture();
+ texture * STalloc();
Color last;
private:
void insert(int, int);
+ struct segment {
+ int x1, y1, x2, y2;
+ };
class sline : public Base {
public:
sline(int, fill *);
@@ -64,17 +77,21 @@ namespace mogltk {
};
int minX, minY, maxX, maxY;
texture * cached;
+ texture * scached;
+ std::vector<segment> segments;
protected:
sline * header;
friend class sline;
};
class shape : public Base {
public:
+ shape(SDL_Surface * = 0);
virtual void pixel(int x, int y, ColorP = WHITE);
virtual void circle(int x, int y, int r, ColorP = WHITE);
virtual void pcircle(int x, int y, int r, ColorP = WHITE);
virtual fill * fcircle(int x, int y, int r);
virtual void fdraw(fill *, ColorP = WHITE, int sx = 0, int sy = 0);
+ virtual void sdraw(fill *, ColorP = WHITE, int sx = 0, int sy = 0);
virtual void arc(int x, int y, int r, double a1, double a2, ColorP = DOS_WHITE);
virtual void arc(int x, int y, int r, int x1, int y1, int x2, int y2, ColorP = DOS_WHITE);
virtual void box(int x1, int y1, int x2, int y2, ColorP = DOS_WHITE);
@@ -119,6 +136,7 @@ namespace mogltk {
ColorP textcolor = DOS_BLACK,
ColorP tshade1 = DOS_HIGH_WHITE,
ColorP tshade2 = DOS_GRAY);
+ SDL_Surface * GetSurf();
private:
void bsubline_1(int x1, int y1, int x2, int y2, ColorP = WHITE);
void bsubline_2(int x1, int y1, int x2, int y2, ColorP = WHITE);
@@ -126,6 +144,7 @@ namespace mogltk {
void bsubline_4(int x1, int y1, int x2, int y2, ColorP = WHITE);
virtual bool Enter();
virtual void Leave(bool);
+ SDL_Surface * surf;
};
class filldrawer : public fillwalker {
@@ -139,6 +158,16 @@ namespace mogltk {
ColorP c;
int oldx, oldy;
};
+ class segdrawer : public segwalker {
+ public:
+ segdrawer(fill *, texture *, ColorP = DOS_WHITE);
+ virtual ~segdrawer();
+ virtual void step(int x1, int y1, int x2, int y2);
+ private:
+ fill * f;
+ texture * t;
+ ColorP c;
+ };
};
#endif
diff --git a/lib/shape.cc b/lib/shape.cc
index 84e89fd..de2a498 100644
--- a/lib/shape.cc
+++ b/lib/shape.cc
@@ -21,7 +21,16 @@ mogltk::fillwalker::~fillwalker() {
void mogltk::fillwalker::step(int x, int y) {
}
-mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), header(0) {
+mogltk::segwalker::segwalker() {
+}
+
+mogltk::segwalker::~segwalker() {
+}
+
+mogltk::segwalker::setup(int x1, int y1, int x2, int y2) {
+}
+
+mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), scached(0), header(0) {
}
mogltk::fill::~fill() {
@@ -30,19 +39,34 @@ mogltk::fill::~fill() {
if (cached)
delete cached;
+
+ if (scached)
+ delete scached;
}
void mogltk::fill::walk(fillwalker * w) {
header->walk(w);
}
+void mogltk::fill::swalk(segwalker * s) {
+ std::vector<struct segment>::iterator i;
+
+ for (i = segments.begin(); i != segments.end(); i++) {
+ s->setup(i->x1, i->y1, i->x2, i->y2);
+ }
+}
+
void mogltk::fill::insert(int x, int y) {
- printm(M_INFO, "Inserting %i %i\n", x, y);
if (cached) {
delete cached;
cached = 0;
}
+ if (scached) {
+ delete scached;
+ scached = 0;
+ }
+
if (!header) {
new sline(y, this);
}
@@ -65,7 +89,12 @@ void mogltk::fill::insert(int x1, int y1, int x2, int y2) {
int dx, dy, y;
double x, i, i2;
- printm(M_INFO, "Adding line (%i, %i)-(%i, %i)\n", x1, y1, x2, y2);
+ struct segment s;
+ s.x1 = x1;
+ s.y1 = y2;
+ s.x2 = x2;
+ s.y2 = y2;
+ segments.push_back(s);
if (y1 == y2)
return;
@@ -105,6 +134,10 @@ mogltk::texture * mogltk::fill::GetTexture() {
return cached;
}
+mogltk::texture * mogltk::fill::GetSTexture() {
+ return scached;
+}
+
mogltk::texture * mogltk::fill::Talloc() {
if (cached)
return cached;
@@ -118,6 +151,19 @@ mogltk::texture * mogltk::fill::Talloc() {
return cached;
}
+mogltk::texture * mogltk::fill::STalloc() {
+ if (scached)
+ return scached;
+
+ int x; int y;
+
+ for (x = 1; x < (maxX - minX); x <<= 1);
+ for (y = 1; y < (maxY - minY); y <<= 1);
+
+ scached = new texture(x, y, true);
+ return scached;
+}
+
mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) {
if (!header->header) {
header->header = this;
@@ -244,13 +290,22 @@ mogltk::fill::sline * mogltk::fill::sline::look(int _y) {
return next->look(_y);
}
+mogltk::shape(SDL_Surface * _surf) : surf(_surf) {
+ if (!tex)
+ tex = mogltk::engine::base_o->GetSurface();
+}
+
+SDL_Surface * mogltk::GetSurf() {
+ return Surf;
+}
+
void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) {
ENTER;
SDL_Rect rect;
rect.x = x1; rect.y = y1; rect.w = x2 - x1 + 1; rect.h = y2 - y1 + 1;
- SDL_FillRect(mogltk::engine::base_o->getsurface(), &rect, c.toSDL());
+ SDL_FillRect(Surf, &rect, c.toSDL(Surf));
LEAVE;
}
@@ -412,10 +467,9 @@ void mogltk::shape::line(int x1, int y1, int x2, int y2, ColorP c) {
void mogltk::shape::pixel(int x, int y, ColorP c) {
ENTER;
- SDL_Surface * surface = mogltk::engine::base_o->getsurface();
int bpp = surface->format->BytesPerPixel;
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
- Uint32 pixel = c.toSDL();
+ Uint8 *p = (Uint8 *)Surf->pixels + y * Surf->pitch + x * bpp;
+ Uint32 pixel = c.toSDL(Surf);
switch(bpp) {
case 1:
@@ -487,7 +541,7 @@ mogltk::fill * mogltk::shape::fcircle(int x0, int y0, int r) {
int rI = 6;
mogltk::fill * f = new fill();
bool t = false;
- int ox, oy;
+ int ox = 0, oy = 0;
while (x <= y) {
/*
@@ -585,7 +639,62 @@ void mogltk::shape::fdraw(fill * f, ColorP c, int sx, int sy) {
SDL_Rect r;
r.x = f->GetMinX() + sx;
r.y = f->GetMinY() + sy;
- SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, mogltk::engine::base_o->getsurface(), &r);
+ SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, Surf, &r);
+
+ f->last = c.c;
+ LEAVE;
+}
+
+mogltk::segdrawer::segdrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c) {
+}
+
+mogltk::segdrawer::~segdrawer() {
+}
+
+void mogltk::segdrawer::step(int x1, int y1, int x2, int y2) {
+ if (oldy != y) {
+ oldx = -1;
+ }
+ if (oldx == -1) {
+ oldx = x;
+ } else {
+// s->hline(oldx, x, y, c);
+ Uint32 * p = t->GetPixels();
+ int i,
+ first = t->GetWidth() * (y - f->GetMinY()) + oldx - f->GetMinX(),
+ last = first - oldx + x;
+ SDL_PixelFormat * format = t->GetFormat();
+
+ for (i = first; i <= last; i++) {
+ p[i] = c.toSDL(format);
+ }
+
+ oldx = -1;
+ }
+ oldy = y;
+}
+
+void mogltk::shape::sdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTER;
+ if (!f->GetSTexture()) {
+ segdrawer * w = new segdrawer(f, f->STalloc(), c);
+ f->swalk(w);
+ delete w;
+ f->last = c.c;
+ }
+ SDL_PixelFormat * format = f->GetSTexture()->GetFormat();
+
+ if (f->last == c.c) {
+ Uint32 * p = f->GetSTexture()->GetPixels();
+ int i, n = f->GetSTexture()->GetWidth() * f->GetSTexture()->GetHeight();
+ for (i = 0; i < n; i++)
+ if (p[i] & 0xff000000)
+ p[i] = c.toSDL(format);
+ }
+ SDL_Rect r;
+ r.x = f->GetMinX() + sx;
+ r.y = f->GetMinY() + sy;
+ SDL_BlitSurface(f->GetSTexture()->GetSurface(), 0, Surf, &r);
f->last = c.c;
LEAVE;
@@ -745,8 +854,8 @@ void mogltk::shape::button(int x1, int y1, int x2, int y2,
}
bool mogltk::shape::Enter() {
- if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) {
- SDL_LockSurface(mogltk::engine::base_o->getsurface());
+ if (SDL_MUSTLOCK(Surf)) {
+ SDL_LockSurface(Surf);
return true;
} else {
return false;
@@ -755,7 +864,7 @@ bool mogltk::shape::Enter() {
void mogltk::shape::Leave(bool locked) {
if (locked)
- SDL_UnlockSurface(mogltk::engine::base_o->getsurface());
+ SDL_UnlockSurface(Surf);
}
void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {