diff --git a/include/draw.h b/include/draw.h index d485eb4..5f6fbc8 100644 --- a/include/draw.h +++ b/include/draw.h @@ -43,17 +43,24 @@ typedef struct _jlColorS { jbyte b; } jlColorT; +typedef struct { + jbyte l : 4; + jbyte r : 4; +} jlPixelPairT; + typedef struct _jlContextS { - jbyte *_pixels; - jbyte _jlDrawColor; - jbyte _jlDrawFillColor; - jlStackT *_jlFillStackTop; - jlColorT _jlPalette[16]; + jbyte *_trueColorPixels; + jbyte _jlDrawColor; + jbyte _jlDrawFillColor; + jlStackT *_jlFillStackTop; + jlColorT _jlPalette[16]; + jlPixelPairT _pixels[32000]; // 320x200, 4 bits per pixel } jlContextT; -jlContextT *jlContextNew(jbyte *pixels); void jlContextDel(jlContextT **context); +void jlContextFlush(jlContextT *c); +jlContextT *jlContextNew(jbyte *pixels); void jlDrawBox(jlContextT *c, jint16 x1, jint16 y1, jint16 x2, jint16 y2); void jlDrawBoxFilled(jlContextT *c, jint16 x1, jint16 y1, jint16 x2, jint16 y2); @@ -70,6 +77,7 @@ void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y); void jlPaletteDefault(jlContextT *c); void jlPaletteGet(jlContextT *c, jbyte index, jbyte *r, jbyte *g, jbyte *b); // This is not a standard JoeyLib API. void jlPaletteSet(jlContextT *c, jbyte index, jbyte r, jbyte g, jbyte b); +#define jlUtilIsOdd(x) (((x & 1) == 1) ? jtrue : jfalse) int16_t jlUtilRandom(void); int jlUtilRandomSeedGet(void); void jlUtilRandomSeedSet(int seed); diff --git a/src/draw.c b/src/draw.c index 212698d..1d8fcf5 100644 --- a/src/draw.c +++ b/src/draw.c @@ -52,6 +52,36 @@ static void _jlDrawFillAddLine(jlContextT *c, jint16 startX, jint16 end static _jlScanDataT *_jlDrawFillNewSegment(jlContextT *c, jint16 startX, jint16 endX, jint16 y, signed char dir, jbool scanLeft, jbool scanRight); +void jlContextDel(jlContextT **context) { + jlContextT *c = (jlContextT *)*context; + DEL(c); +} + + +void jlContextFlush(jlContextT *c) { + int x; + int y; + int p; + unsigned int offset = 0; + + // This converts the 4 bit image to true color using the current palette + // assignments. This reflects how the image would appear if the palette + // is changed after drawing which doesn't happen without this extra step. + + for (y=0; y<200; y++) { + for (x=0; x<320; x++) { + p = jlDrawPixelGet(c, x, y); + c->_trueColorPixels[offset] = c->_jlPalette[p].b * 16; + c->_trueColorPixels[offset + 1] = c->_jlPalette[p].g * 16; + c->_trueColorPixels[offset + 2] = c->_jlPalette[p].r * 16; + // We're using CAIRO_FORMAT_RGB24 so the upper 8 bits are not used. + c->_trueColorPixels[offset + 3] = 255; // This is alpha in CAIRO_FORMAT_ARGB32 mode. + offset += 4; + } + } +} + + jlContextT *jlContextNew(jbyte *pixels) { jlContextT *c = NEW(jlContextT); @@ -60,16 +90,13 @@ jlContextT *jlContextNew(jbyte *pixels) { c->_jlDrawColor = 15; c->_jlDrawFillColor = 0; c->_jlFillStackTop = NULL; - c->_pixels = pixels; + c->_trueColorPixels = pixels; jlPaletteDefault(c); - return c; -} + memset(c->_pixels, 0, 32000); -void jlContextDel(jlContextT **context) { - jlContextT *c = (jlContextT *)*context; - DEL(c); + return c; } @@ -320,12 +347,7 @@ void jlDrawLine(jlContextT *c, jint16 x1, jint16 y1, jint16 x2, jint16 y2) { jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) { - unsigned int offset = (x + y * 320) * 4; - int r = c->_pixels[offset + 2]; - int g = c->_pixels[offset + 1]; - int b = c->_pixels[offset]; - int index = 0; - int i; + int p = x / 2 + y * 160; // Clip at edge. We can do this on modern machines! if (x < 0) return 0; @@ -333,20 +355,11 @@ jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) { if (y < 0) return 0; if (y > 199) return 0; - // Find the palette index for this color. - for (i=0; i<16; i++) { - if (r == c->_jlPalette[i].r && g == c->_jlPalette[i].g && b == c->_jlPalette[i].b) { - index = i; - break; - } - } - - return index; + return (jlUtilIsOdd(x) ? c->_pixels[p].l : c->_pixels[p].r); } void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y) { - unsigned int offset = (x + y * 320) * 4; // Clip at edge. We can do this on modern machines! if (x < 0) return; @@ -354,11 +367,12 @@ void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y) { if (y < 0) return; if (y > 199) return; - c->_pixels[offset] = c->_jlPalette[c->_jlDrawColor].b * 16; - c->_pixels[offset + 1] = c->_jlPalette[c->_jlDrawColor].g * 16; - c->_pixels[offset + 2] = c->_jlPalette[c->_jlDrawColor].r * 16; - // We're using CAIRO_FORMAT_RGB24 so the upper 8 bits are not used. - c->_pixels[offset + 3] = 255; // This is alpha in CAIRO_FORMAT_ARGB32 mode. + jlPixelPairT *pixelPair = c->_pixels + (y * 160) + (x / 2); + if (jlUtilIsOdd(x)) { + pixelPair->l = c->_jlDrawColor; + } else { + pixelPair->r = c->_jlDrawColor; + } } diff --git a/src/vector.c b/src/vector.c index f0f9993..29d88e4 100644 --- a/src/vector.c +++ b/src/vector.c @@ -301,6 +301,7 @@ EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer user (void)userData; // Copy JoeyLib output to a surface scaled to match the preview. + jlContextFlush(self->jlc); cairo_surface_mark_dirty(self->surface); myCr = cairo_create(self->scaled); cairo_scale(myCr, (double)((double)PREVIEW_WIDTH / (double)width), (double)((double)PREVIEW_HEIGHT / (double)height));