From 900bae57d6f8bdc959373527a384c96d6da24340 Mon Sep 17 00:00:00 2001 From: ketmar Date: Sun, 18 Mar 2012 18:51:27 +0200 Subject: [PATCH] polymod is working --- src/awish.c | 2 +- src/game.c | 32 +++++++- src/polymod.c | 237 +++++++++++++++++++--------------------------------------- src/polymod.h | 2 + src/video.h | 153 ++++++++++++++++--------------------- 5 files changed, 176 insertions(+), 250 deletions(-) diff --git a/src/awish.c b/src/awish.c index 49d27ad..f167bdf 100644 --- a/src/awish.c +++ b/src/awish.c @@ -366,7 +366,7 @@ int main (int argc, char *argv[]) { SurfaceLock lock; // lockSurface(&lock, screen); - drawString(screen, "loading...", 2, 200-9, 1); + drawString(screen, "loading...", 2, 200-10, 1); unlockSurface(&lock); SDL_Flip(screen); } diff --git a/src/game.c b/src/game.c index 9263cbf..81d7ffb 100644 --- a/src/game.c +++ b/src/game.c @@ -877,11 +877,13 @@ static void frmGameDraw (SDL_Surface *frame) { } // #if 1 - static angle = 0; + static int angle = 0; // if (!fkeys[9]) { angle = (angle+1)%360; //fprintf(stderr, "a=%d\n", angle); + } else { + polyDump = fkeys[8]; } polymodStart(320/2, 200/2, 1*POLYFIX_BASE, angle); // @@ -923,9 +925,35 @@ static void frmGameDraw (SDL_Surface *frame) { polymodAddPoint(31, -18); polymodAddPoint(46, -12); #endif +#if 0 + polymodAddPoint(42, 0); + polymodAddPoint(40, 10); + polymodAddPoint(36, 20); + polymodAddPoint(29, 29); + polymodAddPoint(21, 36); + polymodAddPoint(10, 40); + polymodAddPoint(0, 42); + polymodAddPoint(-10, 40); + polymodAddPoint(-20, 36); + polymodAddPoint(-29, 29); + polymodAddPoint(-36, 20); + polymodAddPoint(-40, 10); + polymodAddPoint(-42, 0); + polymodAddPoint(-40, -10); + polymodAddPoint(-36, -21); + polymodAddPoint(-29, -29); + polymodAddPoint(-21, -36); + polymodAddPoint(-10, -40); + polymodAddPoint(0, -42); + polymodAddPoint(10, -40); + polymodAddPoint(21, -36); + polymodAddPoint(29, -29); + polymodAddPoint(36, -21); + polymodAddPoint(40, -10); +#endif // polymodEnd(); - polymodFill(frame, 3, 50); + polymodFill(frame, 3, 100); #endif // if (goobers) { diff --git a/src/polymod.c b/src/polymod.c index 2f49d07..6660550 100644 --- a/src/polymod.c +++ b/src/polymod.c @@ -16,27 +16,19 @@ #include -#ifdef TEST -# include -# include -# include -#else -# include "video.h" -# include "gameglobals.h" -#endif +#include "video.h" +#include "gameglobals.h" #include "sincostab.c" -#ifdef TEST -static void fatal (const char *msg) { - printf("FATAL: %s\n", msg); - abort(); -} -#endif +int polyDump = 0; +static FILE *fdump = NULL; typedef struct PolyPoint { + int vertexnum; + int dy; int next; // -1: none int x; } PolyPoint; @@ -48,12 +40,10 @@ static PolyPoint *polyPointPool = NULL; static int polyScans[200]; // index of the first point of each scan; -1: none static int firstX, firstY; static int lastX, lastY; -static int firstPoint; -static int lastDY; -static int minY, maxY; static int pofsx, pofsy; static int pscale; static int pangle; +static int vertexnum; void polymodInitialize (void) { @@ -61,7 +51,7 @@ void polymodInitialize (void) { polyPointPool = NULL; polyPointPoolSize = 0; polyPointPoolPos = 0; - firstPoint = 1; + vertexnum = 0; } @@ -70,11 +60,11 @@ void polymodDeinitialize (void) { polyPointPool = NULL; polyPointPoolSize = 0; polyPointPoolPos = 0; - firstPoint = 1; + vertexnum = 0; } -static inline int allocPolyPoint (int x, int next) { +static inline int allocPolyPoint (int x, int next, int dy) { if (polyPointPoolPos+1 > polyPointPoolSize) { int newsz = polyPointPoolSize+8192; PolyPoint *nn = realloc(polyPointPool, sizeof(PolyPoint)*newsz); @@ -85,11 +75,13 @@ static inline int allocPolyPoint (int x, int next) { } polyPointPool[polyPointPoolPos].x = x; polyPointPool[polyPointPoolPos].next = next; + polyPointPool[polyPointPoolPos].dy = dy; + polyPointPool[polyPointPoolPos].vertexnum = vertexnum; return polyPointPoolPos++; } -static inline void insertPoint (int x, int y) { +static inline void insertPoint (int x, int y, int dy) { if (y >= 0 && y < 200) { int n; // @@ -99,40 +91,48 @@ static inline void insertPoint (int x, int y) { for (p = -1; n != -1 && x > polyPointPool[n].x; p = n, n = polyPointPool[n].next) ; if (p == -1) { // this is new first point - polyScans[y] = allocPolyPoint(x, n); + polyScans[y] = allocPolyPoint(x, n, dy); } else { // insert new point after p; n is the next point - polyPointPool[p].next = allocPolyPoint(x, n); + polyPointPool[p].next = allocPolyPoint(x, n, dy); } } else { // first - polyScans[y] = allocPolyPoint(x, -1); + polyScans[y] = allocPolyPoint(x, -1, dy); } } } +/* static inline void rotate (int *x, int *y) { int64_t tx = (int64_t)(*x)*pscale/POLYFIX_BASE; int64_t ty = (int64_t)(*y)*pscale/POLYFIX_BASE; *x = (tx*costab[pangle]-ty*sintab[pangle])/POLYFIX_BASE+pofsx; *y = (tx*sintab[pangle]+ty*costab[pangle])/POLYFIX_BASE+pofsy; } +*/ +#define rotate(x, y) do { \ + int64_t tx = (int64_t)(x)*pscale/POLYFIX_BASE; \ + int64_t ty = (int64_t)(y)*pscale/POLYFIX_BASE; \ + (x) = (tx*costab[pangle]-ty*sintab[pangle])/POLYFIX_BASE+pofsx; \ + (y) = (tx*sintab[pangle]+ty*costab[pangle])/POLYFIX_BASE+pofsy; \ +} while (0) static void lineDDA (int x0, int y0, int x1, int y1) { - int dy; double x, dx; // - if (y0 == y1) { - // horizontal line - if (y0 >= 0 && y0 <= 199 && lastDY != 0) insertPoint(x0, y0); - lastDY = 0; - return; - } - // + /* rotate(&x0, &y0); rotate(&x1, &y1); + */ + rotate(x0, y0); + rotate(x1, y1); + // + if (fdump) fprintf(fdump, "%d: (%d,%d)-(%d,%d)\n", vertexnum, x0, y0, x1, y1); + // + if (y0 == y1) return; // horizontal line // //fprintf(stderr, "*(%d,%d)-(%d,%d)\n", x0, y0, x1, y1); if ((y0 < 0 && y1 < 0) || (y0 > 199 && y1 > 199)) return; // out-of-screen lines aren't interesting @@ -140,43 +140,20 @@ static void lineDDA (int x0, int y0, int x1, int y1) { if (x0 == x1) { // straight vertical line if (y0 < y1) { - if (y0 < 0) y0 = 0; - if (y1 > 199) y1 = 199; - if (y0 < minY) minY = y0; - if (y1 > maxY) maxY = y1; - if (lastDY == -11) insertPoint(x0, y0); - lastDY = 1; - for (; y0 < y1; ++y0) insertPoint(x0, y0); + for (; y0 < y1; ++y0) insertPoint(x0, y0, 1); } else { - if (y1 < 0) y1 = 0; - if (y0 > 199) y0 = 199; - if (y1 < minY) minY = y1; - if (y0 > maxY) maxY = y0; - if (lastDY == 1) insertPoint(x0, y0); - lastDY = -1; - for (; y0 > y1; --y0) insertPoint(x0, y0); + for (--y0; y0 >= y1; --y0) insertPoint(x0, y0, -1); } } else { // draw sloped x = x0; if (y0 < y1) { dx = (double)(x1-x0)/(double)(y1-y0); - dy = 1; - if (y0 < 0) { x += dx*(0-y0); y0 = 0; } - if (y1 > 199) y1 = 199; - if (y0 < minY) minY = y0; - if (y1 > maxY) maxY = y1; + for (; y0 < y1; ++y0) { insertPoint(x+0.5, y0, 1); x += dx; } } else { dx = (double)(x1-x0)/(double)(y0-y1); - dy = -1; - if (y1 < 0) y1 = 0; - if (y0 > 199) { x += dy*(y0-199); y0 = 199; } - if (y1 < minY) minY = y1; - if (y0 > maxY) maxY = y0; + for (--y0; y0 >= y1; --y0) { insertPoint(x+0.5, y0, -1); x += dx; } } - if (lastDY == -dy) insertPoint(x0, y0); - lastDY = dy; - for (; y0 != y1; y0 += dy) { insertPoint(x+0.5, y0); x += dx; } } } @@ -184,23 +161,23 @@ static void lineDDA (int x0, int y0, int x1, int y1) { void polymodStart (int ofsx, int ofsy, int scale, int angle) { for (int f = 0; f < 200; ++f) polyScans[f] = -1; polyPointPoolPos = 0; - lastDY = 0; - firstPoint = 1; - minY = 200; - maxY = -1; pofsx = ofsx; pofsy = ofsy; pscale = scale; while (angle < 0) angle += 360; // hehe pangle = angle%360; + if (polyDump) { + fdump = fopen("zdump.txt", "w"); + } + vertexnum = -1; } void polymodAddPoint (int x, int y) { - if (!firstPoint) { + ++vertexnum; + if (vertexnum > 0) { lineDDA(lastX, lastY, x, y); } else { - firstPoint = 0; firstX = x; firstY = y; } @@ -210,111 +187,53 @@ void polymodAddPoint (int x, int y) { void polymodEnd (void) { - if (!firstPoint) { + if (vertexnum >= 3) { + ++vertexnum; lineDDA(lastX, lastY, firstX, firstY); - insertPoint(firstX, firstY); + } else { + for (int f = 0; f < 200; ++f) polyScans[f] = -1; } } void polymodFill (SDL_Surface *frame, Uint8 color, Uint8 alpha) { - for (int y = minY; y <= maxY; ++y) { - int p = polyScans[y]; - // - if (p >= 0) { -#ifdef TEST - printf("y: %d\n", y); + if (fdump) { + fprintf(fdump, "=========================\n"); + for (int y = 0; y < 200; ++y) { + int p = polyScans[y], cnt = 0; + // + if (p < 0) continue; + fprintf(fdump, "y: %d\n", y); while (p >= 0) { - printf(" x: %d\n", polyPointPool[p].x); + fprintf(fdump, " x: %d (%d) [%d]\n", polyPointPool[p].x, polyPointPool[p].dy, polyPointPool[p].vertexnum); p = polyPointPool[p].next; + ++cnt; } -#else - for (;;) { - int n = polyPointPool[p].next; + if (cnt%2) fprintf(fdump, " ***\n"); + } + } + for (int y = 0; y < 200; ++y) { + int p = polyScans[y]; + // + if (p >= 0) { + int wind = polyPointPool[p].dy, x = polyPointPool[p].x; + // + for (p = polyPointPool[p].next; p != -1; p = polyPointPool[p].next) { + int ex = polyPointPool[p].x; // - if (n < 0) break; - //fprintf(stderr, "y: %d; x0: %d; x1: %d\n", y, polyPointPool[p].x, polyPointPool[n].x); - //ex = polyPointPool[n].x; - //for (int x = polyPointPool[p].x; x <= ex; ++x) putPixelA2x(frame, x, y, color, alpha); - hline2x(frame, polyPointPool[p].x, y, polyPointPool[n].x-polyPointPool[p].x+1, color); - p = polyPointPool[n].next; - if (p < 0) break; + if (wind != 0) { + while (x++ < ex) putPixelA2x(frame, x, y, color, alpha); + } else { + x = ex; + } + if (polyPointPool[p].dy < 0) putPixelA2x(frame, x, y, color, alpha); + wind += polyPointPool[p].dy; } -#endif } } + if (polyDump) { + if (fdump != NULL) fclose(fdump); + fdump = NULL; + polyDump = 0; + } } - - -#ifdef TEST -int main () { - polymodStart(); - // - /* - polymodAddPoint(50, 50); - polymodAddPoint(90, 50); - polymodAddPoint(90, 90); - polymodAddPoint(50, 90); - */ - /* - polymodAddPoint(10, 200-10); - polymodAddPoint(320-10, 200-10); - polymodAddPoint(10, 10); - polymodAddPoint(320-10, 10); - */ - /* - polymodAddPoint(202, 100); - polymodAddPoint(200, 110); - polymodAddPoint(196, 120); - polymodAddPoint(189, 129); - polymodAddPoint(181, 136); - polymodAddPoint(170, 140); - polymodAddPoint(160, 142); - polymodAddPoint(150, 140); - polymodAddPoint(140, 136); - polymodAddPoint(131, 129); - polymodAddPoint(124, 120); - polymodAddPoint(120, 110); - polymodAddPoint(118, 100); - polymodAddPoint(120, 90); - polymodAddPoint(124, 79); - polymodAddPoint(131, 71); - polymodAddPoint(139, 64); - polymodAddPoint(150, 60); - polymodAddPoint(160, 58); - polymodAddPoint(170, 60); - polymodAddPoint(181, 64); - polymodAddPoint(189, 71); - polymodAddPoint(196, 79); - polymodAddPoint(200, 90); - */ - polymodAddPoint(196, 100); - polymodAddPoint(206, 112); - polymodAddPoint(191, 117); - polymodAddPoint(193, 133); - polymodAddPoint(178, 131); - polymodAddPoint(172, 146); - polymodAddPoint(160, 136); - polymodAddPoint(148, 146); - polymodAddPoint(143, 131); - polymodAddPoint(127, 133); - polymodAddPoint(129, 117); - polymodAddPoint(114, 112); - polymodAddPoint(124, 100); - polymodAddPoint(114, 88); - polymodAddPoint(129, 82); - polymodAddPoint(127, 67); - polymodAddPoint(142, 69); - polymodAddPoint(148, 54); - polymodAddPoint(160, 64); - polymodAddPoint(172, 54); - polymodAddPoint(178, 69); - polymodAddPoint(193, 67); - polymodAddPoint(191, 82); - polymodAddPoint(206, 88); - // - polymodEnd(); - polymodFill(NULL, 3, 50); - return 0; -} -#endif diff --git a/src/polymod.h b/src/polymod.h index 25d8cc5..7ffb039 100644 --- a/src/polymod.h +++ b/src/polymod.h @@ -21,6 +21,8 @@ #define POLYFIX_BASE (0x4000) +extern int polyDump; + extern void polymodInitialize (void); extern void polymodDeinitialize (void); diff --git a/src/video.h b/src/video.h index c013715..0f54f03 100644 --- a/src/video.h +++ b/src/video.h @@ -43,50 +43,84 @@ extern SDL_Surface *createSurface (int w, int h); // NO LOCKING! static inline void putPixelC32 (SDL_Surface *s, int x, int y, Uint32 col) { if (s && x >= s->clip_rect.x && y >= s->clip_rect.y && x < s->clip_rect.x+s->clip_rect.w && y < s->clip_rect.y+s->clip_rect.h) { - Uint8 bpp = s->format->BytesPerPixel; - Uint8 *bits = ((Uint8 *)s->pixels)+(y*s->pitch)+(x*bpp); + *(Uint32 *)(((Uint8 *)s->pixels)+(y*s->pitch)+(x*s->format->BytesPerPixel)) = col; + } +} + + +static inline void putPixel2xC32 (SDL_Surface *s, int x, int y, Uint32 col) { + x *= 2; y *= 2; + if (s && x >= s->clip_rect.x && y >= s->clip_rect.y && x+1 < s->clip_rect.x+s->clip_rect.w && y+1 < s->clip_rect.y+s->clip_rect.h) { + Uint32 *bits = (Uint32 *)(((Uint8 *)s->pixels)+(y*s->pitch)+(x*s->format->BytesPerPixel)); // - switch (bpp) { -/* - case 1: - *((Uint8 *)(bits)) = (Uint8)col; - break; - case 2: - *((Uint16 *)(bits)) = (Uint16)col; - break; - case 3: - *((bits)+s->format->Rshift/8) = (col>>s->format->Rshift)&0xFF; - *((bits)+s->format->Gshift/8) = (col>>s->format->Gshift)&0xFF; - *((bits)+s->format->Bshift/8) = (col>>s->format->Bshift)&0xFF; - break; -*/ - case 4: - *((Uint32 *)(bits)) = col; - break; - } + bits[0] = col; + bits[1] = col; + bits = (Uint32 *)((Uint8 *)bits+s->pitch); + bits[0] = col; + bits[1] = col; } } -static inline void putPixel2x (SDL_Surface *s, int x, int y, Uint8 col) { - x *= 2; - y *= 2; +#define _INTERNAL_VIDEO_ABLEND_MACRO_(n) \ + SDL_GetRGB(bits[n], s->format, &r, &g, &b); \ + r = (((pr-r)*alpha)>>8)+r; \ + g = (((pg-g)*alpha)>>8)+g; \ + b = (((pb-b)*alpha)>>8)+b; \ + bits[n] = SDL_MapRGB(s->format, r, g, b); \ + + +static inline void putPixelA32 (SDL_Surface *s, int x, int y, Uint32 col, Uint8 alpha) { if (s && x >= s->clip_rect.x && y >= s->clip_rect.y && x < s->clip_rect.x+s->clip_rect.w && y < s->clip_rect.y+s->clip_rect.h) { Uint8 bpp = s->format->BytesPerPixel; Uint32 *bits = (Uint32 *)(((Uint8 *)s->pixels)+(y*s->pitch)+(x*bpp)); - Uint32 pix = palette[col]; + unsigned char r, pr, g, pg, b, pb; // - *bits = pix; - if (x+1 < s->clip_rect.x+s->clip_rect.w) bits[1] = pix; - if (y+1 < s->clip_rect.y+s->clip_rect.h) { - bits = (Uint32 *)((Uint8 *)bits+s->pitch); - *bits = pix; - if (x+1 < s->clip_rect.x+s->clip_rect.w) bits[1] = pix; + SDL_GetRGB(col, s->format, &pr, &pg, &pb); + _INTERNAL_VIDEO_ABLEND_MACRO_(0) + } +} + + +static inline void putPixel2xA32 (SDL_Surface *s, int x, int y, Uint32 col, Uint8 alpha) { + x *= 2; + y *= 2; + if (s && x >= s->clip_rect.x && y >= s->clip_rect.y && x+1 < s->clip_rect.x+s->clip_rect.w && y+1 < s->clip_rect.y+s->clip_rect.h) { + Uint32 *bits = (Uint32 *)(((Uint8 *)s->pixels)+(y*s->pitch)+(x*s->format->BytesPerPixel)); + unsigned char r, pr, g, pg, b, pb; + // + SDL_GetRGB(col, s->format, &pr, &pg, &pb); + _INTERNAL_VIDEO_ABLEND_MACRO_(0) + _INTERNAL_VIDEO_ABLEND_MACRO_(1) + bits = (Uint32 *)((Uint8 *)bits+s->pitch); + _INTERNAL_VIDEO_ABLEND_MACRO_(0) + _INTERNAL_VIDEO_ABLEND_MACRO_(1) + } +} + + +static inline void putPixel2x (SDL_Surface *s, int x, int y, Uint8 col) { + putPixel2xC32(s, x, y, palette[col]); +} + + +static inline void putPixelA2x (SDL_Surface *s, int x, int y, Uint8 clr, Uint8 alpha) { + if (alpha != 0) { + if (alpha != 255) { + putPixel2xA32(s, x, y, palette[clr], alpha); + } else { + putPixel2x(s, x, y, palette[clr]); } } } +static inline void putPixel (SDL_Surface *s, int x, int y, Uint8 clr) { + putPixelC32(s, x, y, palette[clr]); +} + + +/* static inline void hlineC32 (SDL_Surface *s, int x, int y, int len, Uint32 col) { if (s && y >= s->clip_rect.y && x < s->clip_rect.x+s->clip_rect.w && y < s->clip_rect.y+s->clip_rect.h) { if (x < s->clip_rect.x) { @@ -111,64 +145,7 @@ static inline void hline2x (SDL_Surface *s, int x, int y, int len, Uint8 col) { hlineC32(s, x, y, len, palette[col]); hlineC32(s, x, y+1, len, palette[col]); } - - -static inline void putPixelA32 (SDL_Surface *s, int x, int y, Uint32 col, Uint8 alpha) { - if (s && x >= s->clip_rect.x && y >= s->clip_rect.y && x < s->clip_rect.x+s->clip_rect.w && y < s->clip_rect.y+s->clip_rect.h) { - Uint8 bpp = s->format->BytesPerPixel; - Uint8 *bits = ((Uint8 *)s->pixels)+(y*s->pitch)+(x*bpp); - Uint32 pixel = 0; - unsigned char r, pr, g, pg, b, pb; - // - SDL_GetRGB(col, s->format, &pr, &pg, &pb); - pixel = *((Uint32 *)(bits)); - // get RGB values from pixel - r = (((pixel&s->format->Rmask)>>s->format->Rshift)<format->Rloss); - g = (((pixel&s->format->Gmask)>>s->format->Gshift)<format->Gloss); - b = (((pixel&s->format->Bmask)>>s->format->Bshift)<format->Bloss); - // blend with alpha - r = (((pr-r)*alpha)>>8)+r; - g = (((pg-g)*alpha)>>8)+g; - b = (((pb-b)*alpha)>>8)+b; - // set - pixel = SDL_MapRGB(s->format, r, g, b); - *((Uint32 *)(bits)) = pixel; - } -} - - -static inline void putPixelA2x (SDL_Surface *s, int x, int y, Uint8 clr, Uint8 alpha) { - if (clr != 0) { - if (clr != 255) { - x *= 2; - y *= 2; - putPixelA32(s, x+0, y+0, palette[clr], alpha); - putPixelA32(s, x+1, y+0, palette[clr], alpha); - ++y; - putPixelA32(s, x+0, y+1, palette[clr], alpha); - putPixelA32(s, x+1, y+1, palette[clr], alpha); - } else { - putPixel2x(s, x, y, clr); - } - } -} - - -// NO LOCKING! -static inline void putPixel2xC32 (SDL_Surface *s, int x, int y, Uint32 clr) { - x *= 2; - y *= 2; - putPixelC32(s, x+0, y+0, clr); - putPixelC32(s, x+1, y+0, clr); - ++y; - putPixelC32(s, x+0, y, clr); - putPixelC32(s, x+1, y, clr); -} - - -static inline void putPixel (SDL_Surface *s, int x, int y, Uint8 clr) { - putPixelC32(s, x, y, palette[clr]); -} +*/ //////////////////////////////////////////////////////////////////////////////// -- 2.11.4.GIT