diff options
| author | xolatile | 2025-08-06 22:54:55 +0200 |
|---|---|---|
| committer | xolatile | 2025-08-06 22:54:55 +0200 |
| commit | 0a1172b75f571685c264a8b9d8ee224bbf11381f (patch) | |
| tree | d041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/texture.cpp | |
| parent | affde05dc07a94643f1fd2751b2b441f57f73d7d (diff) | |
| download | xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst | |
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/texture.cpp')
| -rw-r--r-- | src/engine/texture.cpp | 1123 |
1 files changed, 375 insertions, 748 deletions
diff --git a/src/engine/texture.cpp b/src/engine/texture.cpp index 7f391a9..0f7a5df 100644 --- a/src/engine/texture.cpp +++ b/src/engine/texture.cpp @@ -8,33 +8,26 @@ (SDL_VERSIONNUM(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL) >= SDL_VERSIONNUM(X, Y, Z)) #endif -template<int BPP> static void halvetexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst) -{ - for(uchar *yend = &src[sh*stride]; src < yend;) - { - for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += 2*BPP, dst += BPP) - { +template<int BPP> static void halvetexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst) { + for(uchar *yend = &src[sh*stride]; src < yend;) { + for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += 2*BPP, dst += BPP) { loopi(BPP) dst[i] = (uint(xsrc[i]) + uint(xsrc[i+BPP]) + uint(xsrc[stride+i]) + uint(xsrc[stride+i+BPP]))>>2; } src += 2*stride; } } -template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) -{ +template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) { uint wfrac = sw/dw, hfrac = sh/dh, wshift = 0, hshift = 0; while(dw<<wshift < sw) wshift++; while(dh<<hshift < sh) hshift++; uint tshift = wshift + hshift; - for(uchar *yend = &src[sh*stride]; src < yend;) - { - for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += wfrac*BPP, dst += BPP) - { + for(uchar *yend = &src[sh*stride]; src < yend;) { + for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += wfrac*BPP, dst += BPP) { uint t[BPP] = {0}; for(uchar *ycur = xsrc, *xend = &ycur[wfrac*BPP], *yend = &src[hfrac*stride]; ycur < yend; - ycur += stride, xend += stride) - { + ycur += stride, xend += stride) { for(uchar *xcur = ycur; xcur < xend; xcur += BPP) loopi(BPP) t[i] += xcur[i]; } @@ -44,8 +37,7 @@ template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint s } } -template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) -{ +template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) { uint wfrac = (sw<<12)/dw, hfrac = (sh<<12)/dh, darea = dw*dh, sarea = sw*sh; int over, under; for(over = 0; (darea>>over) > sarea; over++); @@ -56,24 +48,20 @@ template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint s area = ((ullong)darea<<ascale)/sarea; dw *= wfrac; dh *= hfrac; - for(uint y = 0; y < dh; y += hfrac) - { + for(uint y = 0; y < dh; y += hfrac) { const uint yn = y + hfrac - 1, yi = y>>12, h = (yn>>12) - yi, ylow = ((yn|(-int(h)>>24))&0xFFFU) + 1 - (y&0xFFFU), yhigh = (yn&0xFFFU) + 1; const uchar *ysrc = &src[yi*stride]; - for(uint x = 0; x < dw; x += wfrac, dst += BPP) - { + for(uint x = 0; x < dw; x += wfrac, dst += BPP) { const uint xn = x + wfrac - 1, xi = x>>12, w = (xn>>12) - xi, xlow = ((w+0xFFFU)&0x1000U) - (x&0xFFFU), xhigh = (xn&0xFFFU) + 1; const uchar *xsrc = &ysrc[xi*BPP], *xend = &xsrc[w*BPP]; uint t[BPP] = {0}; for(const uchar *xcur = &xsrc[BPP]; xcur < xend; xcur += BPP) loopi(BPP) t[i] += xcur[i]; loopi(BPP) t[i] = (ylow*(t[i] + ((xsrc[i]*xlow + xend[i]*xhigh)>>12)))>>cscale; - if(h) - { + if(h) { xsrc += stride; xend += stride; - for(uint hcur = h; --hcur; xsrc += stride, xend += stride) - { + for(uint hcur = h; --hcur; xsrc += stride, xend += stride) { uint c[BPP] = {0}; for(const uchar *xcur = &xsrc[BPP]; xcur < xend; xcur += BPP) loopi(BPP) c[i] += xcur[i]; @@ -89,32 +77,25 @@ template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint s } } -static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint pitch, uchar * RESTRICT dst, uint dw, uint dh) -{ - if(sw == dw*2 && sh == dh*2) - { - switch(bpp) - { +static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint pitch, uchar * RESTRICT dst, uint dw, uint dh) { + if(sw == dw*2 && sh == dh*2) { + switch(bpp) { case 1: return halvetexture<1>(src, sw, sh, pitch, dst); case 2: return halvetexture<2>(src, sw, sh, pitch, dst); case 3: return halvetexture<3>(src, sw, sh, pitch, dst); case 4: return halvetexture<4>(src, sw, sh, pitch, dst); } } - else if(sw < dw || sh < dh || sw&(sw-1) || sh&(sh-1) || dw&(dw-1) || dh&(dh-1)) - { - switch(bpp) - { + else if(sw < dw || sh < dh || sw&(sw-1) || sh&(sh-1) || dw&(dw-1) || dh&(dh-1)) { + switch(bpp) { case 1: return scaletexture<1>(src, sw, sh, pitch, dst, dw, dh); case 2: return scaletexture<2>(src, sw, sh, pitch, dst, dw, dh); case 3: return scaletexture<3>(src, sw, sh, pitch, dst, dw, dh); case 4: return scaletexture<4>(src, sw, sh, pitch, dst, dw, dh); } } - else - { - switch(bpp) - { + else { + switch(bpp) { case 1: return shifttexture<1>(src, sw, sh, pitch, dst, dw, dh); case 2: return shifttexture<2>(src, sw, sh, pitch, dst, dw, dh); case 3: return shifttexture<3>(src, sw, sh, pitch, dst, dw, dh); @@ -123,17 +104,14 @@ static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint } } -static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) -{ +static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) { int stridex = bpp, stridey = bpp; if(swapxy) stridex *= sh; else stridey *= sw; if(flipx) { dst += (sw-1)*stridex; stridex = -stridex; } if(flipy) { dst += (sh-1)*stridey; stridey = -stridey; } uchar *srcrow = src; - loopi(sh) - { - for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*bpp]; src < end;) - { + loopi(sh) { + for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*bpp]; src < end;) { uchar nx = *src++, ny = *src++; if(flipx) nx = 255-nx; if(flipy) ny = 255-ny; @@ -150,17 +128,14 @@ static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int s } template<int BPP> -static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) -{ +static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) { int stridex = BPP, stridey = BPP; if(swapxy) stridex *= sh; else stridey *= sw; if(flipx) { dst += (sw-1)*stridex; stridex = -stridex; } if(flipy) { dst += (sh-1)*stridey; stridey = -stridey; } uchar *srcrow = src; - loopi(sh) - { - for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*BPP]; src < end;) - { + loopi(sh) { + for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*BPP]; src < end;) { loopk(BPP) curdst[k] = *src++; curdst += stridex; } @@ -169,10 +144,8 @@ static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int str } } -static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) -{ - switch(bpp) - { +static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) { + switch(bpp) { case 1: return reorienttexture<1>(src, sw, sh, stride, dst, flipx, flipy, swapxy); case 2: return reorienttexture<2>(src, sw, sh, stride, dst, flipx, flipy, swapxy); case 3: return reorienttexture<3>(src, sw, sh, stride, dst, flipx, flipy, swapxy); @@ -180,23 +153,18 @@ static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int s } } -static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy, bool normals = false) -{ +static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy, bool normals = false) { int bx1 = 0, by1 = 0, bx2 = min(w, 4), by2 = min(h, 4), bw = (w+3)/4, bh = (h+3)/4, stridex = blocksize, stridey = blocksize; if(swapxy) stridex *= bw; else stridey *= bh; if(flipx) { dst += (bw-1)*stridex; stridex = -stridex; bx1 += 4-bx2; bx2 = 4; } if(flipy) { dst += (bh-1)*stridey; stridey = -stridey; by1 += 4-by2; by2 = 4; } - loopi(bh) - { - for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; src += blocksize, curdst += stridex) - { - if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) - { + loopi(bh) { + for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; src += blocksize, curdst += stridex) { + if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) { ullong salpha = lilswap(*(const ullong *)src), dalpha = 0; uint xmask = flipx ? 15 : 0, ymask = flipy ? 15 : 0, xshift = 2, yshift = 4; if(swapxy) swap(xshift, yshift); - for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) - { + for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) { dalpha |= ((salpha&15) << (((xmask^x)<<xshift) + ((ymask^y)<<yshift))); salpha >>= 4; } @@ -204,14 +172,12 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, src += 8; curdst += 8; } - else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) - { + else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) { uchar alpha1 = src[0], alpha2 = src[1]; ullong salpha = lilswap(*(const ushort *)&src[2]) + ((ullong)lilswap(*(const uint *)&src[4]) << 16), dalpha = 0; uint xmask = flipx ? 7 : 0, ymask = flipy ? 7 : 0, xshift = 0, yshift = 2; if(swapxy) swap(xshift, yshift); - for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) - { + for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) { dalpha |= ((salpha&7) << (3*((xmask^x)<<xshift) + ((ymask^y)<<yshift))); salpha >>= 3; } @@ -223,24 +189,19 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, src += 8; curdst += 8; } - ushort color1 = lilswap(*(const ushort *)src), color2 = lilswap(*(const ushort *)&src[2]); uint sbits = lilswap(*(const uint *)&src[4]); - if(normals) - { + if(normals) { ushort ncolor1 = color1, ncolor2 = color2; - if(flipx) - { + if(flipx) { ncolor1 = (ncolor1 & ~0xF800) | (0xF800 - (ncolor1 & 0xF800)); ncolor2 = (ncolor2 & ~0xF800) | (0xF800 - (ncolor2 & 0xF800)); } - if(flipy) - { + if(flipy) { ncolor1 = (ncolor1 & ~0x7E0) | (0x7E0 - (ncolor1 & 0x7E0)); ncolor2 = (ncolor2 & ~0x7E0) | (0x7E0 - (ncolor2 & 0x7E0)); } - if(swapxy) - { + if(swapxy) { ncolor1 = (ncolor1 & 0x1F) | (((((ncolor1 >> 11) & 0x1F) * 0x3F) / 0x1F) << 5) | (((((ncolor1 >> 5) & 0x3F) * 0x1F) / 0x3F) << 11); ncolor2 = (ncolor2 & 0x1F) | (((((ncolor2 >> 11) & 0x1F) * 0x3F) / 0x1F) << 5) | (((((ncolor2 >> 5) & 0x3F) * 0x1F) / 0x3F) << 11); } @@ -249,40 +210,33 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, } uint dbits = 0, xmask = flipx ? 3 : 0, ymask = flipy ? 3 : 0, xshift = 1, yshift = 3; if(swapxy) swap(xshift, yshift); - for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) - { + for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) { dbits |= ((sbits&3) << (((xmask^x)<<xshift) + ((ymask^y)<<yshift))); sbits >>= 2; } *(ushort *)curdst = lilswap(color1); *(ushort *)&curdst[2] = lilswap(color2); *(uint *)&curdst[4] = lilswap(dbits); - if(blocksize > 8) { src -= 8; curdst -= 8; } } dst += stridey; } } -static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy) -{ +static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy) { int bx1 = 0, by1 = 0, bx2 = min(w, 4), by2 = min(h, 4), bw = (w+3)/4, bh = (h+3)/4, stridex = blocksize, stridey = blocksize; if(swapxy) stridex *= bw; else stridey *= bh; if(flipx) { dst += (bw-1)*stridex; stridex = -stridex; bx1 += 4-bx2; bx2 = 4; } if(flipy) { dst += (bh-1)*stridey; stridey = -stridey; by1 += 4-by2; by2 = 4; } stridex -= blocksize; - loopi(bh) - { - for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; curdst += stridex) - { - loopj(blocksize/8) - { + loopi(bh) { + for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; curdst += stridex) { + loopj(blocksize/8) { uchar val1 = src[0], val2 = src[1]; ullong sval = lilswap(*(const ushort *)&src[2]) + ((ullong)lilswap(*(const uint *)&src[4] )<< 16), dval = 0; uint xmask = flipx ? 7 : 0, ymask = flipy ? 7 : 0, xshift = 0, yshift = 2; if(swapxy) swap(xshift, yshift); - for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) - { + for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) { dval |= ((sval&7) << (3*((xmask^x)<<xshift) + ((ymask^y)<<yshift))); sval >>= 3; } @@ -299,26 +253,26 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, } } -#define writetex(t, body) do \ - { \ +#define writetex(t, body) do { \ + \ uchar *dstrow = t.data; \ - loop(y, t.h) \ - { \ - for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp]; dst < end; dst += t.bpp) \ - { \ + loop(y, t.h) { \ + \ + for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp]; dst < end; dst += t.bpp) { \ + \ body; \ } \ dstrow += t.pitch; \ } \ } while(0) -#define readwritetex(t, s, body) do \ - { \ +#define readwritetex(t, s, body) do { \ + \ uchar *dstrow = t.data, *srcrow = s.data; \ - loop(y, t.h) \ - { \ - for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[s.w*s.bpp]; src < end; dst += t.bpp, src += s.bpp) \ - { \ + loop(y, t.h) { \ + \ + for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[s.w*s.bpp]; src < end; dst += t.bpp, src += s.bpp) { \ + \ body; \ } \ dstrow += t.pitch; \ @@ -326,13 +280,13 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, } \ } while(0) -#define read2writetex(t, s1, src1, s2, src2, body) do \ - { \ +#define read2writetex(t, s1, src1, s2, src2, body) do { \ + \ uchar *dstrow = t.data, *src1row = s1.data, *src2row = s2.data; \ - loop(y, t.h) \ - { \ - for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp], *src1 = src1row, *src2 = src2row; dst < end; dst += t.bpp, src1 += s1.bpp, src2 += s2.bpp) \ - { \ + loop(y, t.h) { \ + \ + for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp], *src1 = src1row, *src2 = src2row; dst < end; dst += t.bpp, src1 += s1.bpp, src2 += s2.bpp) { \ + \ body; \ } \ dstrow += t.pitch; \ @@ -341,30 +295,29 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, } \ } while(0) -#define readwritergbtex(t, s, body) \ - { \ +#define readwritergbtex(t, s, body) { \ + \ if(t.bpp >= 3) readwritetex(t, s, body); \ - else \ - { \ + else { \ + \ ImageData rgb(t.w, t.h, 3); \ read2writetex(rgb, t, orig, s, src, { dst[0] = dst[1] = dst[2] = orig[0]; body; }); \ t.replace(rgb); \ } \ } -void forcergbimage(ImageData &s) -{ +void forcergbimage(ImageData &s) { if(s.bpp >= 3) return; ImageData d(s.w, s.h, 3); readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; }); s.replace(d); } -#define readwritergbatex(t, s, body) \ - { \ +#define readwritergbatex(t, s, body) { \ + \ if(t.bpp >= 4) { readwritetex(t, s, body); } \ - else \ - { \ + else { \ + \ ImageData rgba(t.w, t.h, 4); \ if(t.bpp==3) read2writetex(rgba, t, orig, s, src, { dst[0] = orig[0]; dst[1] = orig[1]; dst[2] = orig[2]; body; }); \ else read2writetex(rgba, t, orig, s, src, { dst[0] = dst[1] = dst[2] = orig[0]; body; }); \ @@ -372,8 +325,7 @@ void forcergbimage(ImageData &s) } \ } -void forcergbaimage(ImageData &s) -{ +void forcergbaimage(ImageData &s) { if(s.bpp >= 4) return; ImageData d(s.w, s.h, 4); if(s.bpp==3) readwritetex(d, s, { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; }); @@ -381,38 +333,31 @@ void forcergbaimage(ImageData &s) s.replace(d); } -void swizzleimage(ImageData &s) -{ - if(s.bpp==2) - { +void swizzleimage(ImageData &s) { + if(s.bpp==2) { ImageData d(s.w, s.h, 4); readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; dst[3] = src[1]; }); s.replace(d); } - else if(s.bpp==1) - { + else if(s.bpp==1) { ImageData d(s.w, s.h, 3); readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; }); s.replace(d); } } -void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = TEX_DIFFUSE) -{ +void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = TEX_DIFFUSE) { ImageData d(swapxy ? s.h : s.w, swapxy ? s.w : s.h, s.bpp, s.levels, s.align, s.compressed); - switch(s.compressed) - { + switch(s.compressed) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: [[fallthrough]]; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: [[fallthrough]]; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: [[fallthrough]]; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - { + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { uchar *dst = d.data, *src = s.data; - loopi(s.levels) - { + loopi(s.levels) { reorients3tc(s.compressed, s.bpp, max(s.w>>i, 1), max(s.h>>i, 1), src, dst, flipx, flipy, swapxy, type==TEX_NORMAL); src += s.calclevelsize(i); dst += d.calclevelsize(i); @@ -425,11 +370,9 @@ void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = T [[fallthrough]]; case GL_COMPRESSED_LUMINANCE_LATC1_EXT: [[fallthrough]]; - case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: - { + case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: { uchar *dst = d.data, *src = s.data; - loopi(s.levels) - { + loopi(s.levels) { reorientrgtc(s.compressed, s.bpp, max(s.w>>i, 1), max(s.h>>i, 1), src, dst, flipx, flipy, swapxy); src += s.calclevelsize(i); dst += d.calclevelsize(i); @@ -444,29 +387,25 @@ void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = T s.replace(d); } -extern const texrotation texrotations[8] = -{ - { false, false, false }, // 0: default - { false, true, true }, // 1: 90 degrees - { true, true, false }, // 2: 180 degrees - { true, false, true }, // 3: 270 degrees - { true, false, false }, // 4: flip X - { false, true, false }, // 5: flip Y - { false, false, true }, // 6: transpose +extern const texrotation texrotations[8] = { + { false, false, false }, // 0: default { + { false, true, true }, // 1: 90 degrees { + { true, true, false }, // 2: 180 degrees { + { true, false, true }, // 3: 270 degrees { + { true, false, false }, // 4: flip X { + { false, true, false }, // 5: flip Y { + { false, false, true }, // 6: transpose { { true, true, true }, // 7: flipped transpose }; -void texrotate(ImageData &s, int numrots, int type = TEX_DIFFUSE) -{ - if(numrots>=1 && numrots<=7) - { +void texrotate(ImageData &s, int numrots, int type = TEX_DIFFUSE) { + if(numrots>=1 && numrots<=7) { const texrotation &r = texrotations[numrots]; texreorient(s, r.flipx, r.flipy, r.swapxy, type); } } -void texoffset(ImageData &s, int xoffset, int yoffset) -{ +void texoffset(ImageData &s, int xoffset, int yoffset) { xoffset = max(xoffset, 0); xoffset %= s.w; yoffset = max(yoffset, 0); @@ -474,8 +413,7 @@ void texoffset(ImageData &s, int xoffset, int yoffset) if(!xoffset && !yoffset) return; ImageData d(s.w, s.h, s.bpp); uchar *src = s.data; - loop(y, s.h) - { + loop(y, s.h) { uchar *dst = (uchar *)d.data+((y+yoffset)%d.h)*d.pitch; memcpy(dst+xoffset*s.bpp, src, (s.w-xoffset)*s.bpp); memcpy(dst, src+(s.w-xoffset)*s.bpp, xoffset*s.bpp); @@ -484,8 +422,7 @@ void texoffset(ImageData &s, int xoffset, int yoffset) s.replace(d); } -void texmad(ImageData &s, const vec &mul, const vec &add) -{ +void texmad(ImageData &s, const vec &mul, const vec &add) { if(s.bpp < 3 && (mul.x != mul.y || mul.y != mul.z || add.x != add.y || add.y != add.z)) swizzleimage(s); int maxk = min(int(s.bpp), 3); @@ -494,8 +431,7 @@ void texmad(ImageData &s, const vec &mul, const vec &add) ); } -void texcolorify(ImageData &s, const vec &color, vec weights) -{ +void texcolorify(ImageData &s, const vec &color, vec weights) { if(s.bpp < 3) return; if(weights.iszero()) weights = vec(0.21f, 0.72f, 0.07f); writetex(s, @@ -504,8 +440,7 @@ void texcolorify(ImageData &s, const vec &color, vec weights) ); } -void texcolormask(ImageData &s, const vec &color1, const vec &color2) -{ +void texcolormask(ImageData &s, const vec &color1, const vec &color2) { if(s.bpp < 4) return; ImageData d(s.w, s.h, 3); readwritetex(d, s, @@ -516,20 +451,17 @@ void texcolormask(ImageData &s, const vec &color1, const vec &color2) s.replace(d); } -void texdup(ImageData &s, int srcchan, int dstchan) -{ +void texdup(ImageData &s, int srcchan, int dstchan) { if(srcchan==dstchan || max(srcchan, dstchan) >= s.bpp) return; writetex(s, dst[dstchan] = dst[srcchan]); } -void texmix(ImageData &s, int c1, int c2, int c3, int c4) -{ +void texmix(ImageData &s, int c1, int c2, int c3, int c4) { int numchans = c1 < 0 ? 0 : (c2 < 0 ? 1 : (c3 < 0 ? 2 : (c4 < 0 ? 3 : 4))); if(numchans <= 0) return; ImageData d(s.w, s.h, numchans); readwritetex(d, s, - switch(numchans) - { + switch(numchans) { case 4: dst[3] = src[c4]; [[fallthrough]]; case 3: dst[2] = src[c3]; @@ -543,28 +475,23 @@ void texmix(ImageData &s, int c1, int c2, int c3, int c4) s.replace(d); } -void texgrey(ImageData &s) -{ +void texgrey(ImageData &s) { if(s.bpp <= 2) return; ImageData d(s.w, s.h, s.bpp >= 4 ? 2 : 1); - if(s.bpp >= 4) - { + if(s.bpp >= 4) { readwritetex(d, s, dst[0] = src[0]; dst[1] = src[3]; ); } - else - { + else { readwritetex(d, s, dst[0] = src[0]); } s.replace(d); } -void texpremul(ImageData &s) -{ - switch(s.bpp) - { +void texpremul(ImageData &s) { + switch(s.bpp) { case 2: writetex(s, dst[0] = uchar((uint(dst[0])*uint(dst[1]))/255); @@ -581,30 +508,25 @@ void texpremul(ImageData &s) } } -void texagrad(ImageData &s, float x2, float y2, float x1, float y1) -{ +void texagrad(ImageData &s, float x2, float y2, float x1, float y1) { if(s.bpp != 2 && s.bpp != 4) return; y1 = 1 - y1; y2 = 1 - y2; float minx = 1, miny = 1, maxx = 1, maxy = 1; - if(x1 != x2) - { + if(x1 != x2) { minx = (0 - x1) / (x2 - x1); maxx = (1 - x1) / (x2 - x1); } - if(y1 != y2) - { + if(y1 != y2) { miny = (0 - y1) / (y2 - y1); maxy = (1 - y1) / (y2 - y1); } float dx = (maxx - minx)/max(s.w-1, 1), dy = (maxy - miny)/max(s.h-1, 1), cury = miny; - for(uchar *dstrow = s.data + s.bpp - 1, *endrow = dstrow + s.h*s.pitch; dstrow < endrow; dstrow += s.pitch) - { + for(uchar *dstrow = s.data + s.bpp - 1, *endrow = dstrow + s.h*s.pitch; dstrow < endrow; dstrow += s.pitch) { float curx = minx; - for(uchar *dst = dstrow, *end = &dstrow[s.w*s.bpp]; dst < end; dst += s.bpp) - { + for(uchar *dst = dstrow, *end = &dstrow[s.w*s.bpp]; dst < end; dst += s.bpp) { dst[0] = uchar(dst[0]*clamp(curx, 0.0f, 1.0f)*clamp(cury, 0.0f, 1.0f)); curx += dx; } @@ -626,23 +548,18 @@ VARFP(aniso, 0, 0, 16, initwarning("texture filtering", INIT_LOAD)); extern int usetexcompress; -void setuptexcompress() -{ +void setuptexcompress() { if(!usetexcompress) return; - GLenum hint = GL_DONT_CARE; - switch(texcompressquality) - { + switch(texcompressquality) { case 1: hint = GL_NICEST; break; case 0: hint = GL_FASTEST; break; } glHint(GL_TEXTURE_COMPRESSION_HINT, hint); } -GLenum compressedformat(GLenum format, int w, int h, int force = 0) -{ - if(usetexcompress && texcompress && force >= 0 && (force || max(w, h) >= texcompress)) switch(format) - { +GLenum compressedformat(GLenum format, int w, int h, int force = 0) { + if(usetexcompress && texcompress && force >= 0 && (force || max(w, h) >= texcompress)) switch(format) { case GL_RGB5: case GL_RGB8: case GL_RGB: return usetexcompress > 1 ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB; @@ -660,10 +577,8 @@ GLenum compressedformat(GLenum format, int w, int h, int force = 0) return format; } -GLenum uncompressedformat(GLenum format) -{ - switch(format) - { +GLenum uncompressedformat(GLenum format) { + switch(format) { case GL_COMPRESSED_ALPHA: return GL_ALPHA; case GL_COMPRESSED_LUMINANCE: @@ -690,10 +605,8 @@ GLenum uncompressedformat(GLenum format) return GL_FALSE; } -int formatsize(GLenum format) -{ - switch(format) - { +int formatsize(GLenum format) { + switch(format) { case GL_RED: case GL_LUMINANCE: case GL_ALPHA: return 1; @@ -707,61 +620,51 @@ int formatsize(GLenum format) VARFP(usenp2, 0, 0, 1, initwarning("texture quality", INIT_LOAD)); -void resizetexture(int w, int h, bool mipmap, bool canreduce, GLenum target, int compress, int &tw, int &th) -{ +void resizetexture(int w, int h, bool mipmap, bool canreduce, GLenum target, int compress, int &tw, int &th) { int hwlimit = target==GL_TEXTURE_CUBE_MAP ? hwcubetexsize : hwtexsize, sizelimit = mipmap && maxtexsize ? min(maxtexsize, hwlimit) : hwlimit; - if(compress > 0 && !usetexcompress) - { + if(compress > 0 && !usetexcompress) { w = max(w/compress, 1); h = max(h/compress, 1); } - if(canreduce && texreduce) - { + if(canreduce && texreduce) { w = max(w>>texreduce, 1); h = max(h>>texreduce, 1); } w = min(w, sizelimit); h = min(h, sizelimit); - if(!usenp2 && (w&(w-1) || h&(h-1))) - { + if(!usenp2 && (w&(w-1) || h&(h-1))) { tw = th = 1; while(tw < w) tw *= 2; while(th < h) th *= 2; if(w < tw - tw/4) tw /= 2; if(h < th - th/4) th /= 2; } - else - { + else { tw = w; th = h; } } -void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLenum format, GLenum type, void *pixels, int pw, int ph, int pitch, bool mipmap) -{ +void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLenum format, GLenum type, void *pixels, int pw, int ph, int pitch, bool mipmap) { int bpp = formatsize(format), row = 0, rowalign = 0; if(!pitch) pitch = pw*bpp; uchar *buf = NULL; - if(pw!=tw || ph!=th) - { + if(pw!=tw || ph!=th) { buf = new uchar[tw*th*bpp]; scaletexture((uchar *)pixels, pw, ph, bpp, pitch, buf, tw, th); } - else if(tw*bpp != pitch) - { + else if(tw*bpp != pitch) { row = pitch/bpp; rowalign = texalign(pixels, pitch, 1); while(rowalign > 0 && ((row*bpp + rowalign - 1)/rowalign)*rowalign != pitch) rowalign >>= 1; - if(!rowalign) - { + if(!rowalign) { row = 0; buf = new uchar[tw*th*bpp]; loopi(th) memcpy(&buf[i*tw*bpp], &((uchar *)pixels)[i*pitch], tw*bpp); } } - for(int level = 0, align = 0, mw = tw, mh = th;; level++) - { + for(int level = 0, align = 0, mw = tw, mh = th;; level++) { uchar *src = buf ? buf : (uchar *)pixels; if(buf) pitch = mw*bpp; int srcalign = row > 0 ? rowalign : texalign(src, pitch, 1); @@ -773,8 +676,7 @@ void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLe int srcw = mw, srch = mh; if(mw > 1) mw /= 2; if(mh > 1) mh /= 2; - if(src) - { + if(src) { if(!buf) buf = new uchar[mw*mh*bpp]; scaletexture(src, srcw, srch, bpp, pitch, buf, mw, mh); } @@ -782,16 +684,13 @@ void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLe if(buf) delete[] buf; } -void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int w, int h, uchar *data, int align, int blocksize, int levels, bool mipmap) -{ +void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int w, int h, uchar *data, int align, int blocksize, int levels, bool mipmap) { int hwlimit = target==GL_TEXTURE_CUBE_MAP ? hwcubetexsize : hwtexsize, sizelimit = levels > 1 && maxtexsize ? min(maxtexsize, hwlimit) : hwlimit; int level = 0; - loopi(levels) - { + loopi(levels) { int size = ((w + align-1)/align) * ((h + align-1)/align) * blocksize; - if(w <= sizelimit && h <= sizelimit) - { + if(w <= sizelimit && h <= sizelimit) { glCompressedTexImage2D_(subtarget, level, format, w, h, 0, size, data); level++; if(!mipmap) break; @@ -803,10 +702,8 @@ void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int } } -GLenum textarget(GLenum subtarget) -{ - switch(subtarget) - { +GLenum textarget(GLenum subtarget) { + switch(subtarget) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -818,20 +715,17 @@ GLenum textarget(GLenum subtarget) return subtarget; } -const GLint *swizzlemask(GLenum format) -{ +const GLint *swizzlemask(GLenum format) { static const GLint luminance[4] = { GL_RED, GL_RED, GL_RED, GL_ONE }; static const GLint luminancealpha[4] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; - switch(format) - { + switch(format) { case GL_RED: return luminance; case GL_RG: return luminancealpha; } return NULL; } -void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum format, GLenum target, bool swizzle) -{ +void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum format, GLenum target, bool swizzle) { glBindTexture(target, tnum); glTexParameteri(target, GL_TEXTURE_WRAP_S, clamp&1 ? GL_CLAMP_TO_EDGE : (clamp&0x100 ? GL_MIRRORED_REPEAT : GL_REPEAT)); glTexParameteri(target, GL_TEXTURE_WRAP_T, clamp&2 ? GL_CLAMP_TO_EDGE : (clamp&0x200 ? GL_MIRRORED_REPEAT : GL_REPEAT)); @@ -843,48 +737,40 @@ void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum fo (bilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR) : (bilinear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST)) : (filter && bilinear ? GL_LINEAR : GL_NEAREST)); - if(swizzle && hasTRG && hasTSW) - { + if(swizzle && hasTRG && hasTSW) { const GLint *mask = swizzlemask(format); if(mask) glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, mask); } } -static GLenum textype(GLenum &component, GLenum &format) -{ +static GLenum textype(GLenum &component, GLenum &format) { GLenum type = GL_UNSIGNED_BYTE; - switch(component) - { + switch(component) { case GL_R16F: case GL_R32F: if(!format) format = GL_RED; type = GL_FLOAT; break; - case GL_RG16F: case GL_RG32F: if(!format) format = GL_RG; type = GL_FLOAT; break; - case GL_RGB16F: case GL_RGB32F: if(!format) format = GL_RGB; type = GL_FLOAT; break; - case GL_RGBA16F: case GL_RGBA32F: if(!format) format = GL_RGBA; type = GL_FLOAT; break; - case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: if(!format) format = GL_DEPTH_COMPONENT; break; - case GL_RGB5: case GL_RGB8: case GL_RGB10: @@ -893,7 +779,6 @@ static GLenum textype(GLenum &component, GLenum &format) case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: if(!format) format = GL_RGB; break; - case GL_RGB5_A1: case GL_RGBA8: case GL_RGB10_A2: @@ -904,41 +789,35 @@ static GLenum textype(GLenum &component, GLenum &format) case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: if(!format) format = GL_RGBA; break; - case GL_DEPTH_STENCIL: case GL_DEPTH24_STENCIL8: if(!format) format = GL_DEPTH_STENCIL; type = GL_UNSIGNED_INT_24_8; break; - case GL_R8: case GL_R16: case GL_COMPRESSED_RED: case GL_COMPRESSED_RED_RGTC1: if(!format) format = GL_RED; break; - case GL_RG8: case GL_RG16: case GL_COMPRESSED_RG: case GL_COMPRESSED_RG_RGTC2: if(!format) format = GL_RG; break; - case GL_LUMINANCE8: case GL_LUMINANCE16: case GL_COMPRESSED_LUMINANCE: case GL_COMPRESSED_LUMINANCE_LATC1_EXT: if(!format) format = GL_LUMINANCE; break; - case GL_LUMINANCE8_ALPHA8: case GL_LUMINANCE16_ALPHA16: case GL_COMPRESSED_LUMINANCE_ALPHA: case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: if(!format) format = GL_LUMINANCE_ALPHA; break; - case GL_ALPHA8: case GL_ALPHA16: case GL_COMPRESSED_ALPHA: @@ -949,24 +828,21 @@ static GLenum textype(GLenum &component, GLenum &format) return type; } -void createtexture(int tnum, int w, int h, void *pixels, int clamp, int filter, GLenum component, GLenum subtarget, int pw, int ph, int pitch, bool resize, GLenum format, bool swizzle) -{ +void createtexture(int tnum, int w, int h, void *pixels, int clamp, int filter, GLenum component, GLenum subtarget, int pw, int ph, int pitch, bool resize, GLenum format, bool swizzle) { GLenum target = textarget(subtarget), type = textype(component, format); if(filter >= 0 && clamp >= 0) setuptexparameters(tnum, pixels, clamp, filter, format, target, swizzle); if(!pw) pw = w; if(!ph) ph = h; int tw = w, th = h; bool mipmap = filter > 1 && pixels; - if(resize && pixels) - { + if(resize && pixels) { resizetexture(w, h, mipmap, false, target, 0, tw, th); if(mipmap) component = compressedformat(component, tw, th); } uploadtexture(tnum, subtarget, component, tw, th, format, type, pixels, pw, ph, pitch, mipmap); } -void createcompressedtexture(int tnum, int w, int h, uchar *data, int align, int blocksize, int levels, int clamp, int filter, GLenum format, GLenum subtarget, bool swizzle = false) -{ +void createcompressedtexture(int tnum, int w, int h, uchar *data, int align, int blocksize, int levels, int clamp, int filter, GLenum format, GLenum subtarget, bool swizzle = false) { GLenum target = textarget(subtarget); if(filter >= 0 && clamp >= 0) setuptexparameters(tnum, data, clamp, filter, format, target); uploadcompressedtexture(target, subtarget, format, w, h, data, align, blocksize, levels, filter > 1); @@ -976,10 +852,8 @@ hashnameset<Texture> textures; Texture *notexture = NULL; // used as default, ensured to be loaded -static GLenum texformat(int bpp, bool swizzle = false) -{ - switch(bpp) - { +static GLenum texformat(int bpp, bool swizzle = false) { + switch(bpp) { case 1: return hasTRG && (hasTSW || !glcompat || !swizzle) ? GL_RED : GL_LUMINANCE; case 2: return hasTRG && (hasTSW || !glcompat || !swizzle) ? GL_RG : GL_LUMINANCE_ALPHA; case 3: return GL_RGB; @@ -988,10 +862,8 @@ static GLenum texformat(int bpp, bool swizzle = false) } } -static bool alphaformat(GLenum format) -{ - switch(format) - { +static bool alphaformat(GLenum format) { + switch(format) { case GL_ALPHA: case GL_LUMINANCE_ALPHA: case GL_RG: @@ -1002,49 +874,40 @@ static bool alphaformat(GLenum format) } } -int texalign(const void *data, int w, int bpp) -{ +int texalign(const void *data, int w, int bpp) { int stride = w*bpp; if(stride&1) return 1; if(stride&2) return 2; return 4; } -static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clamp = 0, bool mipit = true, bool canreduce = false, bool transient = false, int compress = 0) -{ - if(!t) - { +static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clamp = 0, bool mipit = true, bool canreduce = false, bool transient = false, int compress = 0) { + if(!t) { char *key = newstring(rname); t = &textures[key]; t->name = key; } - t->clamp = clamp; t->mipmap = mipit; t->type = Texture::IMAGE; if(transient) t->type |= Texture::TRANSIENT; if(clamp&0x300) t->type |= Texture::MIRROR; - if(!s.data) - { + if(!s.data) { t->type |= Texture::STUB; t->w = t->h = t->xs = t->ys = t->bpp = 0; return t; } - bool swizzle = !(clamp&0x10000); GLenum format; - if(s.compressed) - { + if(s.compressed) { format = uncompressedformat(s.compressed); t->bpp = formatsize(format); t->type |= Texture::COMPRESSED; } - else - { + else { format = texformat(s.bpp, swizzle); t->bpp = s.bpp; - if(swizzle && hasTRG && !hasTSW && swizzlemask(format)) - { + if(swizzle && hasTRG && !hasTSW && swizzlemask(format)) { swizzleimage(s); format = texformat(s.bpp, swizzle); t->bpp = s.bpp; @@ -1053,23 +916,19 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam if(alphaformat(format)) t->type |= Texture::ALPHA; t->w = t->xs = s.w; t->h = t->ys = s.h; - int filter = !canreduce || reducefilter ? (mipit ? 2 : 1) : 0; glGenTextures(1, &t->id); - if(s.compressed) - { + if(s.compressed) { uchar *data = s.data; int levels = s.levels, level = 0; - if(canreduce && texreduce) loopi(min(texreduce, s.levels-1)) - { + if(canreduce && texreduce) loopi(min(texreduce, s.levels-1)) { data += s.calclevelsize(level++); levels--; if(t->w > 1) t->w /= 2; if(t->h > 1) t->h /= 2; } int sizelimit = mipit && maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize; - while(t->w > sizelimit || t->h > sizelimit) - { + while(t->w > sizelimit || t->h > sizelimit) { data += s.calclevelsize(level++); levels--; if(t->w > 1) t->w /= 2; @@ -1077,8 +936,7 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam } createcompressedtexture(t->id, t->w, t->h, data, s.align, s.bpp, levels, clamp, filter, s.compressed, GL_TEXTURE_2D, swizzle); } - else - { + else { resizetexture(t->w, t->h, mipit, canreduce, GL_TEXTURE_2D, compress, t->w, t->h); GLenum component = compressedformat(format, t->w, t->h, compress); createtexture(t->id, t->w, t->h, s.data, clamp, filter, component, GL_TEXTURE_2D, t->xs, t->ys, s.pitch, false, format, swizzle); @@ -1094,29 +952,24 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam #define RGBMASKS 0x0000ff, 0x00ff00, 0xff0000, 0 #endif -SDL_Surface *wrapsurface(void *data, int width, int height, int bpp) -{ - switch(bpp) - { +SDL_Surface *wrapsurface(void *data, int width, int height, int bpp) { + switch(bpp) { case 3: return SDL_CreateRGBSurfaceFrom(data, width, height, 8*bpp, bpp*width, RGBMASKS); case 4: return SDL_CreateRGBSurfaceFrom(data, width, height, 8*bpp, bpp*width, RGBAMASKS); } return NULL; } -SDL_Surface *creatergbsurface(SDL_Surface *os) -{ +SDL_Surface *creatergbsurface(SDL_Surface *os) { SDL_Surface *ns = SDL_CreateRGBSurface(SDL_SWSURFACE, os->w, os->h, 24, RGBMASKS); if(ns) SDL_BlitSurface(os, NULL, ns, NULL); SDL_FreeSurface(os); return ns; } -SDL_Surface *creatergbasurface(SDL_Surface *os) -{ +SDL_Surface *creatergbasurface(SDL_Surface *os) { SDL_Surface *ns = SDL_CreateRGBSurface(SDL_SWSURFACE, os->w, os->h, 32, RGBAMASKS); - if(ns) - { + if(ns) { SDL_SetSurfaceBlendMode(os, SDL_BLENDMODE_NONE); SDL_BlitSurface(os, NULL, ns, NULL); } @@ -1124,11 +977,9 @@ SDL_Surface *creatergbasurface(SDL_Surface *os) return ns; } -bool checkgrayscale(SDL_Surface *s) -{ +bool checkgrayscale(SDL_Surface *s) { // gray scale images have 256 levels, no colorkey, and the palette is a ramp - if(s->format->palette) - { + if(s->format->palette) { if(s->format->palette->ncolors != 256 || SDL_GetColorKey(s, NULL) >= 0) return false; const SDL_Color *colors = s->format->palette->colors; loopi(256) if(colors[i].r != i || colors[i].g != i || colors[i].b != i) return false; @@ -1136,17 +987,14 @@ bool checkgrayscale(SDL_Surface *s) return true; } -SDL_Surface *fixsurfaceformat(SDL_Surface *s) -{ +SDL_Surface *fixsurfaceformat(SDL_Surface *s) { if(!s) return NULL; - if(!s->pixels || min(s->w, s->h) <= 0 || s->format->BytesPerPixel <= 0) - { + if(!s->pixels || min(s->w, s->h) <= 0 || s->format->BytesPerPixel <= 0) { SDL_FreeSurface(s); return NULL; } static const uint rgbmasks[] = { RGBMASKS }, rgbamasks[] = { RGBAMASKS }; - switch(s->format->BytesPerPixel) - { + switch(s->format->BytesPerPixel) { case 1: if(!checkgrayscale(s)) return SDL_GetColorKey(s, NULL) >= 0 ? creatergbasurface(s) : creatergbsurface(s); break; @@ -1162,12 +1010,10 @@ SDL_Surface *fixsurfaceformat(SDL_Surface *s) return s; } -void texflip(ImageData &s) -{ +void texflip(ImageData &s) { ImageData d(s.w, s.h, s.bpp); uchar *dst = d.data, *src = &s.data[s.pitch*s.h]; - loopi(s.h) - { + loopi(s.h) { src -= s.pitch; memcpy(dst, src, s.bpp*s.w); dst += d.pitch; @@ -1175,12 +1021,10 @@ void texflip(ImageData &s) s.replace(d); } -void texnormal(ImageData &s, int emphasis) -{ +void texnormal(ImageData &s, int emphasis) { ImageData d(s.w, s.h, 3); uchar *src = s.data, *dst = d.data; - loop(y, s.h) loop(x, s.w) - { + loop(y, s.h) loop(x, s.w) { vec normal(0.0f, 0.0f, 255.0f/emphasis); normal.x += src[y*s.pitch + ((x+s.w-1)%s.w)*s.bpp]; normal.x -= src[y*s.pitch + ((x+1)%s.w)*s.bpp]; @@ -1195,16 +1039,13 @@ void texnormal(ImageData &s, int emphasis) } template<int n, int bpp, bool normals> -static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) -{ - static const int weights3x3[9] = - { +static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) { + static const int weights3x3[9] = { 0x10, 0x20, 0x10, 0x20, 0x40, 0x20, 0x10, 0x20, 0x10 }; - static const int weights5x5[25] = - { + static const int weights5x5[25] = { 0x05, 0x05, 0x09, 0x05, 0x05, 0x05, 0x0A, 0x14, 0x0A, 0x05, 0x09, 0x14, 0x28, 0x14, 0x09, @@ -1219,15 +1060,12 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) nextoffset1 = stride + mstride*bpp, nextoffset2 = stride - mstride*bpp; src += margin*(stride + bpp); - for(int y = margin; y < h-margin; y++) - { - for(int x = margin; x < w-margin; x++) - { + for(int y = margin; y < h-margin; y++) { + for(int x = margin; x < w-margin; x++) { int dr = 0, dg = 0, db = 0; const uchar *p = src - startoffset; const int *m = mat + mstartoffset; - for(int t = y; t >= y-n; t--, p -= nextoffset1, m -= mstride) - { + for(int t = y; t >= y-n; t--, p -= nextoffset1, m -= mstride) { if(t < 0) p += stride; int a = 0; if(n > 1) { a += m[-2]; if(x >= 2) { dr += p[0] * a; dg += p[1] * a; db += p[2] * a; a = 0; } p += bpp; } @@ -1238,8 +1076,7 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) } p = src - startoffset + stride; m = mat + mstartoffset + mstride; - for(int t = y+1; t <= y+n; t++, p += nextoffset2, m += mstride) - { + for(int t = y+1; t <= y+n; t++, p += nextoffset2, m += mstride) { if(t >= h) p -= stride; int a = 0; if(n > 1) { a += m[-2]; if(x >= 2) { dr += p[0] * a; dg += p[1] * a; db += p[2] * a; a = 0; } p += bpp; } @@ -1248,16 +1085,14 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) if(x+1 < w) { cr = p[0]; cg = p[1]; cb = p[2]; } dr += cr * m[1]; dg += cg * m[1]; db += cb * m[1]; p += bpp; if(n > 1) { if(x+2 < w) { cr = p[0]; cg = p[1]; cb = p[2]; } dr += cr * m[2]; dg += cg * m[2]; db += cb * m[2]; p += bpp; } } - if(normals) - { + if(normals) { vec v(dr-0x7F80, dg-0x7F80, db-0x7F80); float mag = 127.5f/v.magnitude(); dst[0] = uchar(v.x*mag + 127.5f); dst[1] = uchar(v.y*mag + 127.5f); dst[2] = uchar(v.z*mag + 127.5f); } - else - { + else { dst[0] = dr>>8; dst[1] = dg>>8; dst[2] = db>>8; @@ -1270,10 +1105,8 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) } } -void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int margin) -{ - switch((clamp(n, 1, 2)<<4) | bpp) - { +void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int margin) { + switch((clamp(n, 1, 2)<<4) | bpp) { case 0x13: blurtexture<1, 3, false>(w, h, dst, src, margin); break; case 0x23: blurtexture<2, 3, false>(w, h, dst, src, margin); break; case 0x14: blurtexture<1, 4, false>(w, h, dst, src, margin); break; @@ -1281,50 +1114,41 @@ void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int } } -void blurnormals(int n, int w, int h, bvec *dst, const bvec *src, int margin) -{ - switch(clamp(n, 1, 2)) - { +void blurnormals(int n, int w, int h, bvec *dst, const bvec *src, int margin) { + switch(clamp(n, 1, 2)) { case 1: blurtexture<1, 3, true>(w, h, dst->v, src->v, margin); break; case 2: blurtexture<2, 3, true>(w, h, dst->v, src->v, margin); break; } } -void texblur(ImageData &s, int n, int r) -{ +void texblur(ImageData &s, int n, int r) { if(s.bpp < 3) return; - loopi(r) - { + loopi(r) { ImageData d(s.w, s.h, s.bpp); blurtexture(n, s.bpp, s.w, s.h, d.data, s.data); s.replace(d); } } -void scaleimage(ImageData &s, int w, int h) -{ +void scaleimage(ImageData &s, int w, int h) { ImageData d(w, h, s.bpp); scaletexture(s.data, s.w, s.h, s.bpp, s.pitch, d.data, w, h); s.replace(d); } -bool canloadsurface(const char *name) -{ +bool canloadsurface(const char *name) { stream *f = openfile(name, "rb"); if(!f) return false; delete f; return true; } -SDL_Surface *loadsurface(const char *name) -{ +SDL_Surface *loadsurface(const char *name) { SDL_Surface *s = NULL; stream *z = openzipfile(name, "rb"); - if(z) - { + if(z) { SDL_RWops *rw = z->rwops(); - if(rw) - { + if(rw) { char *ext = (char *)strrchr(name, '.'); if(ext) ++ext; s = IMG_LoadTyped_RW(rw, 0, ext); @@ -1336,12 +1160,10 @@ SDL_Surface *loadsurface(const char *name) return fixsurfaceformat(s); } -static vec parsevec(const char *arg) -{ +static vec parsevec(const char *arg) { vec v(0, 0, 0); int i = 0; - for(; arg[0] && (!i || arg[0]=='/') && i<3; arg += strcspn(arg, "/,><"), i++) - { + for(; arg[0] && (!i || arg[0]=='/') && i<3; arg += strcspn(arg, "/,><"), i++) { if(i) arg++; v[i] = atof(arg); } @@ -1349,38 +1171,30 @@ static vec parsevec(const char *arg) return v; } -static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, bool msg = true, int *compress = NULL, int *wrap = NULL) -{ +static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, bool msg = true, int *compress = NULL, int *wrap = NULL) { const char *cmds = NULL, *file = tname; - - if(!tname) - { + if(!tname) { if(!tex) return false; - if(tex->name[0]=='<') - { + if(tex->name[0]=='<') { cmds = tex->name; file = strrchr(tex->name, '>'); if(!file) { if(msg) conoutf(CON_ERROR, "could not load texture packages/%s", tex->name); return false; } file++; } else file = tex->name; - static string pname; formatstring(pname, "packages/%s", file); file = path(pname); } - else if(tname[0]=='<') - { + else if(tname[0]=='<') { cmds = tname; file = strrchr(tname, '>'); if(!file) { if(msg) conoutf(CON_ERROR, "could not load texture %s", tname); return false; } file++; } - int flen = strlen(file); - bool raw = !compress, guess = false; - for(const char *pcmds = cmds; pcmds;) - { + bool guess = false; + for(const char *pcmds = cmds; pcmds;) { #define PARSETEXCOMMANDS(cmds) \ const char *cmd = NULL, *end = NULL, *arg[4] = { NULL, NULL, NULL, NULL }; \ cmd = &cmds[1]; \ @@ -1388,32 +1202,25 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, if(!end) break; \ cmds = strchr(cmd, '<'); \ size_t len = strcspn(cmd, ":,><"); \ - loopi(4) \ - { \ + loopi(4) { \ + \ arg[i] = strchr(i ? arg[i-1] : cmd, i ? ',' : ':'); \ if(!arg[i] || arg[i] >= end) arg[i] = ""; \ else arg[i]++; \ } PARSETEXCOMMANDS(pcmds); - if(matchstring(cmd, len, "thumbnail")) - { - raw = true; + if(matchstring(cmd, len, "thumbnail")) { guess = flen >= 4 && !strchr(file+flen-4, '.'); } else if(matchstring(cmd, len, "stub")) return canloadsurface(file); } - if(msg) renderprogress(loadprogress, file); - - if(!d.data) - { + if(!d.data) { SDL_Surface *s = NULL; - if(guess) - { + if(guess) { static const char *exts[] = {".jpg", ".png"}; string ext; - loopi(sizeof(exts)/sizeof(exts[0])) - { + loopi(sizeof(exts)/sizeof(exts[0])) { copystring(ext, file); concatstring(ext, exts[i]); s = loadsurface(ext); @@ -1427,16 +1234,13 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, if(max(s->w, s->h) > (1<<12)) { SDL_FreeSurface(s); conoutf(CON_ERROR, "texture size exceeded %dx%d pixels: %s", 1<<12, 1<<12, file); return false; } d.wrap(s); } - - while(cmds) - { + while(cmds) { PARSETEXCOMMANDS(cmds); if(d.compressed) goto compressed; if(matchstring(cmd, len, "mad")) texmad(d, parsevec(arg[0]), parsevec(arg[1])); else if(matchstring(cmd, len, "colorify")) texcolorify(d, parsevec(arg[0]), parsevec(arg[1])); else if(matchstring(cmd, len, "colormask")) texcolormask(d, parsevec(arg[0]), *arg[1] ? parsevec(arg[1]) : vec(1, 1, 1)); - else if(matchstring(cmd, len, "normal")) - { + else if(matchstring(cmd, len, "normal")) { int emphasis = atoi(arg[0]); texnormal(d, emphasis > 0 ? emphasis : 3); } @@ -1446,25 +1250,21 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, else if(matchstring(cmd, len, "reorient")) texreorient(d, atoi(arg[0])>0, atoi(arg[1])>0, atoi(arg[2])>0, tex ? tex->type : TEX_DIFFUSE); else if(matchstring(cmd, len, "mix")) texmix(d, *arg[0] ? atoi(arg[0]) : -1, *arg[1] ? atoi(arg[1]) : -1, *arg[2] ? atoi(arg[2]) : -1, *arg[3] ? atoi(arg[3]) : -1); else if(matchstring(cmd, len, "grey")) texgrey(d); - else if(matchstring(cmd, len, "blur")) - { + else if(matchstring(cmd, len, "blur")) { int emphasis = atoi(arg[0]), repeat = atoi(arg[1]); texblur(d, emphasis > 0 ? clamp(emphasis, 1, 2) : 1, repeat > 0 ? repeat : 1); } else if(matchstring(cmd, len, "premul")) texpremul(d); else if(matchstring(cmd, len, "agrad")) texagrad(d, atof(arg[0]), atof(arg[1]), atof(arg[2]), atof(arg[3])); - else if(matchstring(cmd, len, "compress")) - { + else if(matchstring(cmd, len, "compress")) { int scale = atoi(arg[0]); if(scale <= 0) scale = 2; if(compress) *compress = scale; } - else if(matchstring(cmd, len, "nocompress")) - { + else if(matchstring(cmd, len, "nocompress")) { if(compress) *compress = -1; } - else if(matchstring(cmd, len, "thumbnail")) - { + else if(matchstring(cmd, len, "thumbnail")) { int w = atoi(arg[0]), h = atoi(arg[1]); if(w <= 0 || w > (1<<12)) w = 64; if(h <= 0 || h > (1<<12)) h = w; @@ -1472,32 +1272,26 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, } else compressed: - if(matchstring(cmd, len, "mirror")) - { + if(matchstring(cmd, len, "mirror")) { if(wrap) *wrap |= 0x300; } - else if(matchstring(cmd, len, "noswizzle")) - { + else if(matchstring(cmd, len, "noswizzle")) { if(wrap) *wrap |= 0x10000; } } - return true; } -uchar *loadalphamask(Texture *t) -{ +uchar *loadalphamask(Texture *t) { if(t->alphamask) return t->alphamask; if(!(t->type&Texture::ALPHA)) return NULL; ImageData s; if(!texturedata(s, t->name, NULL, false) || !s.data || s.compressed) return NULL; t->alphamask = new uchar[s.h * ((s.w+7)/8)]; uchar *srcrow = s.data, *dst = t->alphamask-1; - loop(y, s.h) - { + loop(y, s.h) { uchar *src = srcrow+s.bpp-1; - loop(x, s.w) - { + loop(x, s.w) { int offset = x%8; if(!offset) *++dst = 0; if(*src) *dst |= 1<<offset; @@ -1508,8 +1302,7 @@ uchar *loadalphamask(Texture *t) return t->alphamask; } -Texture *textureload(const char *name, int clamp, bool mipit, bool msg) -{ +Texture *textureload(const char *name, int clamp, bool mipit, bool msg) { string tname; copystring(tname, name); Texture *t = textures.access(path(tname)); @@ -1520,8 +1313,7 @@ Texture *textureload(const char *name, int clamp, bool mipit, bool msg) return notexture; } -bool settexture(const char *name, int clamp) -{ +bool settexture(const char *name, int clamp) { Texture *t = textureload(name, clamp, true, false); glBindTexture(GL_TEXTURE_2D, t->id); return t != notexture; @@ -1532,20 +1324,17 @@ vector<Slot *> slots; Slot dummyslot; VSlot dummyvslot(&dummyslot); -void texturereset(int *n) -{ +void texturereset(int *n) { if(!(identflags&IDF_OVERRIDDEN) && !game::allowedittoggle()) return; resetslotshader(); int limit = clamp(*n, 0, slots.length()); - for(int i = limit; i < slots.length(); i++) - { + for(int i = limit; i < slots.length(); i++) { Slot *s = slots[i]; for(VSlot *vs = s->variants; vs; vs = vs->next) vs->slot = &dummyslot; delete s; } slots.setsize(limit); - while(vslots.length()) - { + while(vslots.length()) { VSlot *vs = vslots.last(); if(vs->slot != &dummyslot || vs->changed) break; delete vslots.pop(); @@ -1557,8 +1346,7 @@ COMMAND(texturereset, "i"); static int compactedvslots = 0, compactvslotsprogress = 0, clonedvslots = 0; static bool markingvslots = false; -void clearslots() -{ +void clearslots() { resetslotshader(); slots.deletecontents(); vslots.deletecontents(); @@ -1567,44 +1355,35 @@ void clearslots() static void assignvslot(VSlot &vs); -static inline void assignvslotlayer(VSlot &vs) -{ - if(vs.layer && vslots.inrange(vs.layer)) - { +static inline void assignvslotlayer(VSlot &vs) { + if(vs.layer && vslots.inrange(vs.layer)) { VSlot &layer = *vslots[vs.layer]; if(layer.index < 0) assignvslot(layer); } } -static void assignvslot(VSlot &vs) -{ +static void assignvslot(VSlot &vs) { vs.index = compactedvslots++; assignvslotlayer(vs); } -void compactvslot(int &index) -{ - if(vslots.inrange(index)) - { +void compactvslot(int &index) { + if(vslots.inrange(index)) { VSlot &vs = *vslots[index]; if(vs.index < 0) assignvslot(vs); if(!markingvslots) index = vs.index; } } -void compactvslot(VSlot &vs) -{ +void compactvslot(VSlot &vs) { if(vs.index < 0) assignvslot(vs); } -void compactvslots(cube *c, int n) -{ +void compactvslots(cube *c, int n) { if((compactvslotsprogress++&0xFFF)==0) renderprogress(min(float(compactvslotsprogress)/allocnodes, 1.0f), markingvslots ? "marking slots..." : "compacting slots..."); - loopi(n) - { + loopi(n) { if(c[i].children) compactvslots(c[i].children); - else loopj(6) if(vslots.inrange(c[i].texture[j])) - { + else loopj(6) if(vslots.inrange(c[i].texture[j])) { VSlot &vs = *vslots[c[i].texture[j]]; if(vs.index < 0) assignvslot(vs); if(!markingvslots) c[i].texture[j] = vs.index; @@ -1612,8 +1391,7 @@ void compactvslots(cube *c, int n) } } -int compactvslots() -{ +int compactvslots() { clonedvslots = 0; markingvslots = false; compactedvslots = 0; @@ -1621,38 +1399,31 @@ int compactvslots() loopv(vslots) vslots[i]->index = -1; loopv(slots) slots[i]->variants->index = compactedvslots++; loopv(slots) assignvslotlayer(*slots[i]->variants); - loopv(vslots) - { + loopv(vslots) { VSlot &vs = *vslots[i]; if(!vs.changed && vs.index < 0) { markingvslots = true; break; } } compactvslots(worldroot); int total = compactedvslots; compacteditvslots(); - loopv(vslots) - { + loopv(vslots) { VSlot *vs = vslots[i]; if(vs->changed) continue; - while(vs->next) - { + while(vs->next) { if(vs->next->index < 0) vs->next = vs->next->next; else vs = vs->next; } } - if(markingvslots) - { + if(markingvslots) { markingvslots = false; compactedvslots = 0; compactvslotsprogress = 0; int lastdiscard = 0; - loopv(vslots) - { + loopv(vslots) { VSlot &vs = *vslots[i]; if(vs.changed || (vs.index < 0 && !vs.next)) vs.index = -1; - else - { - while(lastdiscard < i) - { + else { + while(lastdiscard < i) { VSlot &ds = *vslots[lastdiscard++]; if(!ds.changed && ds.index < 0) ds.index = compactedvslots++; } @@ -1664,13 +1435,11 @@ int compactvslots() compacteditvslots(); } compactmruvslots(); - loopv(vslots) - { + loopv(vslots) { VSlot &vs = *vslots[i]; if(vs.index >= 0 && vs.layer && vslots.inrange(vs.layer)) vs.layer = vslots[vs.layer]->index; } - loopv(vslots) - { + loopv(vslots) { while(vslots[i]->index >= 0 && vslots[i]->index != i) swap(vslots[i], vslots[vslots[i]->index]); } @@ -1679,8 +1448,7 @@ int compactvslots() return total; } -ICOMMAND(compactvslots, "", (), -{ +ICOMMAND(compactvslots, "", (), { extern int nompedit; if(nompedit && multiplayer()) return; compactvslots(); @@ -1689,11 +1457,9 @@ ICOMMAND(compactvslots, "", (), static Slot &loadslot(Slot &s, bool forceload); -static void clampvslotoffset(VSlot &dst, Slot *slot = NULL) -{ +static void clampvslotoffset(VSlot &dst, Slot *slot = NULL) { if(!slot) slot = dst.slot; - if(slot && slot->sts.inrange(0)) - { + if(slot && slot->sts.inrange(0)) { if(!slot->loaded) loadslot(*slot, false); Texture *t = slot->sts[0].t; int xs = t->xs, ys = t->ys; @@ -1705,49 +1471,39 @@ static void clampvslotoffset(VSlot &dst, Slot *slot = NULL) else dst.offset.max(0); } -static void propagatevslot(VSlot &dst, const VSlot &src, int diff, bool edit = false) -{ +static void propagatevslot(VSlot &dst, const VSlot &src, int diff, bool edit = false) { if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params) dst.params.add(src.params[i]); if(diff & (1<<VSLOT_SCALE)) dst.scale = src.scale; - if(diff & (1<<VSLOT_ROTATION)) - { + if(diff & (1<<VSLOT_ROTATION)) { dst.rotation = src.rotation; if(edit && !dst.offset.iszero()) clampvslotoffset(dst); } - if(diff & (1<<VSLOT_OFFSET)) - { + if(diff & (1<<VSLOT_OFFSET)) { dst.offset = src.offset; if(edit) clampvslotoffset(dst); } if(diff & (1<<VSLOT_SCROLL)) dst.scroll = src.scroll; if(diff & (1<<VSLOT_LAYER)) dst.layer = src.layer; - if(diff & (1<<VSLOT_ALPHA)) - { + if(diff & (1<<VSLOT_ALPHA)) { dst.alphafront = src.alphafront; dst.alphaback = src.alphaback; } if(diff & (1<<VSLOT_COLOR)) dst.colorscale = src.colorscale; } -static void propagatevslot(VSlot *root, int changed) -{ - for(VSlot *vs = root->next; vs; vs = vs->next) - { +static void propagatevslot(VSlot *root, int changed) { + for(VSlot *vs = root->next; vs; vs = vs->next) { int diff = changed & ~vs->changed; if(diff) propagatevslot(*vs, *root, diff); } } -static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL) -{ - if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params) - { +static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL) { + if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params) { const SlotShaderParam &sp = src.params[i]; - loopvj(dst.params) - { + loopvj(dst.params) { SlotShaderParam &dp = dst.params[j]; - if(sp.name == dp.name) - { + if(sp.name == dp.name) { memcpy(dp.val, sp.val, sizeof(dp.val)); goto nextparam; } @@ -1755,42 +1511,35 @@ static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL dst.params.add(sp); nextparam:; } - if(diff & (1<<VSLOT_SCALE)) - { + if(diff & (1<<VSLOT_SCALE)) { dst.scale = clamp(dst.scale*src.scale, 1/8.0f, 8.0f); } - if(diff & (1<<VSLOT_ROTATION)) - { + if(diff & (1<<VSLOT_ROTATION)) { dst.rotation = clamp(dst.rotation + src.rotation, 0, 7); if(!dst.offset.iszero()) clampvslotoffset(dst, slot); } - if(diff & (1<<VSLOT_OFFSET)) - { + if(diff & (1<<VSLOT_OFFSET)) { dst.offset.add(src.offset); clampvslotoffset(dst, slot); } if(diff & (1<<VSLOT_SCROLL)) dst.scroll.add(src.scroll); if(diff & (1<<VSLOT_LAYER)) dst.layer = src.layer; - if(diff & (1<<VSLOT_ALPHA)) - { + if(diff & (1<<VSLOT_ALPHA)) { dst.alphafront = src.alphafront; dst.alphaback = src.alphaback; } if(diff & (1<<VSLOT_COLOR)) dst.colorscale.mul(src.colorscale); } -void mergevslot(VSlot &dst, const VSlot &src, const VSlot &delta) -{ +void mergevslot(VSlot &dst, const VSlot &src, const VSlot &delta) { dst.changed = src.changed | delta.changed; propagatevslot(dst, src, (1<<VSLOT_NUM)-1); mergevslot(dst, delta, delta.changed, src.slot); } -static VSlot *reassignvslot(Slot &owner, VSlot *vs) -{ +static VSlot *reassignvslot(Slot &owner, VSlot *vs) { owner.variants = vs; - while(vs) - { + while(vs) { vs->slot = &owner; vs->linked = false; vs = vs->next; @@ -1798,21 +1547,17 @@ static VSlot *reassignvslot(Slot &owner, VSlot *vs) return owner.variants; } -static VSlot *emptyvslot(Slot &owner) -{ +static VSlot *emptyvslot(Slot &owner) { int offset = 0; loopvrev(slots) if(slots[i]->variants) { offset = slots[i]->variants->index + 1; break; } for(int i = offset; i < vslots.length(); i++) if(!vslots[i]->changed) return reassignvslot(owner, vslots[i]); return vslots.add(new VSlot(&owner, vslots.length())); } -static bool comparevslot(const VSlot &dst, const VSlot &src, int diff) -{ - if(diff & (1<<VSLOT_SHPARAM)) - { +static bool comparevslot(const VSlot &dst, const VSlot &src, int diff) { + if(diff & (1<<VSLOT_SHPARAM)) { if(src.params.length() != dst.params.length()) return false; - loopv(src.params) - { + loopv(src.params) { const SlotShaderParam &sp = src.params[i], &dp = dst.params[i]; if(sp.name != dp.name || memcmp(sp.val, dp.val, sizeof(sp.val))) return false; } @@ -1827,53 +1572,43 @@ static bool comparevslot(const VSlot &dst, const VSlot &src, int diff) return true; } -void packvslot(vector<uchar> &buf, const VSlot &src) -{ - if(src.changed & (1<<VSLOT_SHPARAM)) - { - loopv(src.params) - { +void packvslot(vector<uchar> &buf, const VSlot &src) { + if(src.changed & (1<<VSLOT_SHPARAM)) { + loopv(src.params) { const SlotShaderParam &p = src.params[i]; buf.put(VSLOT_SHPARAM); sendstring(p.name, buf); loopj(4) putfloat(buf, p.val[j]); } } - if(src.changed & (1<<VSLOT_SCALE)) - { + if(src.changed & (1<<VSLOT_SCALE)) { buf.put(VSLOT_SCALE); putfloat(buf, src.scale); } - if(src.changed & (1<<VSLOT_ROTATION)) - { + if(src.changed & (1<<VSLOT_ROTATION)) { buf.put(VSLOT_ROTATION); putint(buf, src.rotation); } - if(src.changed & (1<<VSLOT_OFFSET)) - { + if(src.changed & (1<<VSLOT_OFFSET)) { buf.put(VSLOT_OFFSET); putint(buf, src.offset.x); putint(buf, src.offset.y); } - if(src.changed & (1<<VSLOT_SCROLL)) - { + if(src.changed & (1<<VSLOT_SCROLL)) { buf.put(VSLOT_SCROLL); putfloat(buf, src.scroll.x); putfloat(buf, src.scroll.y); } - if(src.changed & (1<<VSLOT_LAYER)) - { + if(src.changed & (1<<VSLOT_LAYER)) { buf.put(VSLOT_LAYER); putuint(buf, vslots.inrange(src.layer) && !vslots[src.layer]->changed ? src.layer : 0); } - if(src.changed & (1<<VSLOT_ALPHA)) - { + if(src.changed & (1<<VSLOT_ALPHA)) { buf.put(VSLOT_ALPHA); putfloat(buf, src.alphafront); putfloat(buf, src.alphaback); } - if(src.changed & (1<<VSLOT_COLOR)) - { + if(src.changed & (1<<VSLOT_COLOR)) { buf.put(VSLOT_COLOR); putfloat(buf, src.colorscale.r); putfloat(buf, src.colorscale.g); @@ -1882,28 +1617,22 @@ void packvslot(vector<uchar> &buf, const VSlot &src) buf.put(0xFF); } -void packvslot(vector<uchar> &buf, int index) -{ +void packvslot(vector<uchar> &buf, int index) { if(vslots.inrange(index)) packvslot(buf, *vslots[index]); else buf.put(0xFF); } -void packvslot(vector<uchar> &buf, const VSlot *vs) -{ +void packvslot(vector<uchar> &buf, const VSlot *vs) { if(vs) packvslot(buf, *vs); else buf.put(0xFF); } -bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta) -{ - while(buf.remaining()) - { +bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta) { + while(buf.remaining()) { int changed = buf.get(); if(changed >= 0x80) break; - switch(changed) - { - case VSLOT_SHPARAM: - { + switch(changed) { + case VSLOT_SHPARAM: { string name; getstring(name, buf); SlotShaderParam p = { name[0] ? getshaderparamname(name) : NULL, -1, { 0, 0, 0, 0 } }; @@ -1929,8 +1658,7 @@ bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta) dst.scroll.x = getfloat(buf); dst.scroll.y = getfloat(buf); break; - case VSLOT_LAYER: - { + case VSLOT_LAYER: { int tex = getuint(buf); dst.layer = vslots.inrange(tex) ? tex : 0; break; @@ -1953,10 +1681,8 @@ bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta) return true; } -VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta) -{ - for(VSlot *dst = slot.variants; dst; dst = dst->next) - { +VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta) { + for(VSlot *dst = slot.variants; dst; dst = dst->next) { if((!dst->changed || dst->changed == (src.changed | delta.changed)) && comparevslot(*dst, src, src.changed & ~delta.changed) && comparevslot(*dst, delta, delta.changed)) @@ -1965,8 +1691,7 @@ VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta) return NULL; } -static VSlot *clonevslot(const VSlot &src, const VSlot &delta) -{ +static VSlot *clonevslot(const VSlot &src, const VSlot &delta) { VSlot *dst = vslots.add(new VSlot(src.slot, vslots.length())); dst->changed = src.changed | delta.changed; propagatevslot(*dst, src, ((1<<VSLOT_NUM)-1) & ~delta.changed); @@ -1976,28 +1701,23 @@ static VSlot *clonevslot(const VSlot &src, const VSlot &delta) VARP(autocompactvslots, 0, 256, 0x10000); -VSlot *editvslot(const VSlot &src, const VSlot &delta) -{ +VSlot *editvslot(const VSlot &src, const VSlot &delta) { VSlot *exists = findvslot(*src.slot, src, delta); if(exists) return exists; - if(vslots.length()>=0x10000) - { + if(vslots.length()>=0x10000) { compactvslots(); allchanged(); if(vslots.length()>=0x10000) return NULL; } - if(autocompactvslots && ++clonedvslots >= autocompactvslots) - { + if(autocompactvslots && ++clonedvslots >= autocompactvslots) { compactvslots(); allchanged(); } return clonevslot(src, delta); } -static void fixinsidefaces(cube *c, const ivec &o, int size, int tex) -{ - loopi(8) - { +static void fixinsidefaces(cube *c, const ivec &o, int size, int tex) { + loopi(8) { ivec co(i, o, size); if(c[i].children) fixinsidefaces(c[i].children, co, size>>1, tex); else loopj(6) if(!visibletris(c[i], j, co, size)) @@ -2005,40 +1725,35 @@ static void fixinsidefaces(cube *c, const ivec &o, int size, int tex) } } -ICOMMAND(fixinsidefaces, "i", (int *tex), -{ +ICOMMAND(fixinsidefaces, "i", (int *tex), { extern int nompedit; if(noedit(true) || (nompedit && multiplayer())) return; fixinsidefaces(worldroot, ivec(0, 0, 0), worldsize>>1, *tex && vslots.inrange(*tex) ? *tex : DEFAULT_GEOM); allchanged(); }); -const struct slottex -{ +const struct slottex { const char *name; int id; -} slottexs[] = -{ - {"c", TEX_DIFFUSE}, - {"u", TEX_UNKNOWN}, - {"d", TEX_DECAL}, - {"n", TEX_NORMAL}, - {"s", TEX_SPEC}, - {"z", TEX_DEPTH}, - {"a", TEX_ALPHA} +} slottexs[] = { + { + "c", TEX_DIFFUSE}, { + "u", TEX_UNKNOWN}, { + "d", TEX_DECAL}, { + "n", TEX_NORMAL}, { + "s", TEX_SPEC}, { + "z", TEX_DEPTH}, { + "a", TEX_ALPHA} }; -int findslottex(const char *name) -{ - loopi(sizeof(slottexs)/sizeof(slottex)) - { +int findslottex(const char *name) { + loopi(sizeof(slottexs)/sizeof(slottex)) { if(!strcmp(slottexs[i].name, name)) return slottexs[i].id; } return -1; } -void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float *scale) -{ +void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float *scale) { if(slots.length()>=0x10000) return; int tnum = findslottex(type); if(tnum<0) tnum = atoi(type); @@ -2052,8 +1767,7 @@ void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float st.t = NULL; copystring(st.name, name); path(st.name); - if(tnum==TEX_DIFFUSE) - { + if(tnum==TEX_DIFFUSE) { setslotshader(s); VSlot &vs = *emptyvslot(s); vs.reset(); @@ -2066,8 +1780,7 @@ void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float COMMAND(texture, "ssiiif"); -void texscroll(float *scrollS, float *scrollT) -{ +void texscroll(float *scrollS, float *scrollT) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->scroll = vec2(*scrollS, *scrollT).div(1000.0f); @@ -2075,8 +1788,7 @@ void texscroll(float *scrollS, float *scrollT) } COMMAND(texscroll, "ff"); -void texoffset_(int *xoffset, int *yoffset) -{ +void texoffset_(int *xoffset, int *yoffset) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->offset = ivec2(*xoffset, *yoffset).max(0); @@ -2084,8 +1796,7 @@ void texoffset_(int *xoffset, int *yoffset) } COMMANDN(texoffset, texoffset_, "ii"); -void texrotate_(int *rot) -{ +void texrotate_(int *rot) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->rotation = clamp(*rot, 0, 7); @@ -2093,8 +1804,7 @@ void texrotate_(int *rot) } COMMANDN(texrotate, texrotate_, "i"); -void texscale(float *scale) -{ +void texscale(float *scale) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->scale = *scale <= 0 ? 1 : *scale; @@ -2102,8 +1812,7 @@ void texscale(float *scale) } COMMAND(texscale, "f"); -void texlayer(int *layer, char *name, int *mode, float *scale) -{ +void texlayer(int *layer, char *name, int *mode, float *scale) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->layer = *layer < 0 ? max(slots.length()-1+*layer, 0) : *layer; @@ -2114,8 +1823,7 @@ void texlayer(int *layer, char *name, int *mode, float *scale) } COMMAND(texlayer, "isif"); -void texalpha(float *front, float *back) -{ +void texalpha(float *front, float *back) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->alphafront = clamp(*front, 0.0f, 1.0f); @@ -2124,8 +1832,7 @@ void texalpha(float *front, float *back) } COMMAND(texalpha, "ff"); -void texcolor(float *r, float *g, float *b) -{ +void texcolor(float *r, float *g, float *b) { if(slots.empty()) return; Slot &s = *slots.last(); s.variants->colorscale = vec(clamp(*r, 0.0f, 1.0f), clamp(*g, 0.0f, 1.0f), clamp(*b, 0.0f, 1.0f)); @@ -2133,48 +1840,40 @@ void texcolor(float *r, float *g, float *b) } COMMAND(texcolor, "fff"); -static int findtextype(Slot &s, int type, int last = -1) -{ +static int findtextype(Slot &s, int type, int last = -1) { for(int i = last+1; i<s.sts.length(); i++) if((type&(1<<s.sts[i].type)) && s.sts[i].combined<0) return i; return -1; } -static void mergespec(ImageData &c, ImageData &s) -{ +static void mergespec(ImageData &c, ImageData &s) { if(s.bpp < 3) { readwritergbatex(c, s, dst[3] = src[0]; ); } else { readwritergbatex(c, s, dst[3] = (int(src[0]) + int(src[1]) + int(src[2]))/3; ); } } -static void mergedepth(ImageData &c, ImageData &z) -{ +static void mergedepth(ImageData &c, ImageData &z) { readwritergbatex(c, z, dst[3] = src[0]; ); } -static void mergealpha(ImageData &c, ImageData &s) -{ +static void mergealpha(ImageData &c, ImageData &s) { if(s.bpp < 3) { readwritergbatex(c, s, dst[3] = src[0]; ); } else if(s.bpp == 3) { readwritergbatex(c, s, dst[3] = (int(src[0]) + int(src[1]) + int(src[2]))/3; ); } else { readwritergbatex(c, s, dst[3] = src[3]; ); } } -static void addname(vector<char> &key, Slot &slot, Slot::Tex &t, bool combined = false, const char *prefix = NULL) -{ +static void addname(vector<char> &key, Slot &slot, Slot::Tex &t, bool combined = false, const char *prefix = NULL) { if(combined) key.add('&'); if(prefix) { while(*prefix) key.add(*prefix++); } defformatstring(tname, "packages/%s", t.name); for(const char *s = path(tname); *s; key.add(*s++)); } -static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) -{ +static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) { vector<char> key; addname(key, s, t); int texmask = 0; - if(!forceload) switch(t.type) - { + if(!forceload) switch(t.type) { case TEX_DIFFUSE: - case TEX_NORMAL: - { + case TEX_NORMAL: { int i = findtextype(s, t.type==TEX_DIFFUSE ? (s.texmask&(1<<TEX_SPEC) ? 1<<TEX_SPEC : 1<<TEX_ALPHA) : (s.texmask&(1<<TEX_DEPTH) ? 1<<TEX_DEPTH : 1<<TEX_ALPHA)); if(i<0) break; texmask |= 1<<s.sts[i].type; @@ -2189,20 +1888,17 @@ static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) int compress = 0, wrap = 0; ImageData ts; if(!texturedata(ts, NULL, &t, true, &compress, &wrap)) { t.t = notexture; return; } - if(!ts.compressed) switch(t.type) - { + if(!ts.compressed) switch(t.type) { case TEX_DIFFUSE: case TEX_NORMAL: - loopv(s.sts) - { + loopv(s.sts) { Slot::Tex &a = s.sts[i]; if(a.combined!=index) continue; ImageData as; if(!texturedata(as, NULL, &a)) continue; //if(ts.bpp!=4) forcergbaimage(ts); if(as.w!=ts.w || as.h!=ts.h) scaleimage(as, ts.w, ts.h); - switch(a.type) - { + switch(a.type) { case TEX_SPEC: mergespec(ts, as); break; case TEX_DEPTH: mergedepth(ts, as); break; case TEX_ALPHA: mergealpha(ts, as); break; @@ -2214,15 +1910,12 @@ static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) t.t = newtexture(NULL, key.getbuf(), ts, wrap, true, true, true, compress); } -static Slot &loadslot(Slot &s, bool forceload) -{ +static Slot &loadslot(Slot &s, bool forceload) { linkslotshader(s); - loopv(s.sts) - { + loopv(s.sts) { Slot::Tex &t = s.sts[i]; if(t.combined >= 0) continue; - switch(t.type) - { + switch(t.type) { default: texcombine(s, i, t, forceload); break; @@ -2232,17 +1925,14 @@ static Slot &loadslot(Slot &s, bool forceload) return s; } -Slot &lookupslot(int index, bool load) -{ +Slot &lookupslot(int index, bool load) { Slot &s = slots.inrange(index) ? *slots[index] : (slots.inrange(DEFAULT_GEOM) ? *slots[DEFAULT_GEOM] : dummyslot); return s.loaded || !load ? s : loadslot(s, false); } -VSlot &lookupvslot(int index, bool load) -{ +VSlot &lookupvslot(int index, bool load) { VSlot &s = vslots.inrange(index) && vslots[index]->slot ? *vslots[index] : (slots.inrange(DEFAULT_GEOM) && slots[DEFAULT_GEOM]->variants ? *slots[DEFAULT_GEOM]->variants : dummyvslot); - if(load && !s.linked) - { + if(load && !s.linked) { if(!s.slot->loaded) loadslot(*s.slot, false); linkvslotshader(s); s.linked = true; @@ -2250,17 +1940,14 @@ VSlot &lookupvslot(int index, bool load) return s; } -void linkslotshaders() -{ +void linkslotshaders() { loopv(slots) if(slots[i]->loaded) linkslotshader(*slots[i]); loopv(vslots) if(vslots[i]->linked) linkvslotshader(*vslots[i]); } -Texture *loadthumbnail(Slot &slot) -{ +Texture *loadthumbnail(Slot &slot) { if(slot.thumbnail) return slot.thumbnail; - if(!slot.variants) - { + if(!slot.variants) { slot.thumbnail = notexture; return slot.thumbnail; } @@ -2269,17 +1956,14 @@ Texture *loadthumbnail(Slot &slot) linkvslotshader(vslot, false); vector<char> name; if(vslot.colorscale == vec(1, 1, 1)) addname(name, slot, slot.sts[0], false, "<thumbnail>"); - else - { + else { defformatstring(prefix, "<thumbnail:%.2f/%.2f/%.2f>", vslot.colorscale.x, vslot.colorscale.y, vslot.colorscale.z); addname(name, slot, slot.sts[0], false, prefix); } VSlot *layer = vslot.layer ? &lookupvslot(vslot.layer, false) : NULL; - if(layer) - { + if(layer) { if(layer->colorscale == vec(1, 1, 1)) addname(name, *layer->slot, layer->slot->sts[0], true, "<layer>"); - else - { + else { defformatstring(prefix, "<layer:%.2f/%.2f/%.2f>", vslot.colorscale.x, vslot.colorscale.y, vslot.colorscale.z); addname(name, *layer->slot, layer->slot->sts[0], true, prefix); } @@ -2287,30 +1971,25 @@ Texture *loadthumbnail(Slot &slot) name.add('\0'); Texture *t = textures.access(path(name.getbuf())); if(t) slot.thumbnail = t; - else - { + else { ImageData s, g, l; texturedata(s, NULL, &slot.sts[0], false); if(layer) texturedata(l, NULL, &layer->slot->sts[0], false); if(!s.data) t = slot.thumbnail = notexture; - else - { + else { if(vslot.colorscale != vec(1, 1, 1)) texmad(s, vslot.colorscale, vec(0, 0, 0)); int xs = s.w, ys = s.h; if(s.w > 64 || s.h > 64) scaleimage(s, min(s.w, 64), min(s.h, 64)); - if(g.data) - { + if(g.data) { if(g.w != s.w || g.h != s.h) scaleimage(g, s.w, s.h); } - if(l.data) - { + if(l.data) { if(layer->colorscale != vec(1, 1, 1)) texmad(l, layer->colorscale, vec(0, 0, 0)); if(l.w != s.w/2 || l.h != s.h/2) scaleimage(l, s.w/2, s.h/2); forcergbimage(s); forcergbimage(l); uchar *dstrow = &s.data[s.pitch*l.h + s.bpp*l.w], *srcrow = l.data; - loop(y, l.h) - { + loop(y, l.h) { for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[l.w*l.bpp]; src < end; dst += s.bpp, src += l.bpp) loopk(3) dst[k] = src[k]; dstrow += s.pitch; @@ -2327,13 +2006,10 @@ Texture *loadthumbnail(Slot &slot) return t; } -void loadlayermasks() -{ - loopv(slots) - { +void loadlayermasks() { + loopv(slots) { Slot &slot = *slots[i]; - if(slot.loaded && slot.layermaskname && !slot.layermask) - { + if(slot.loaded && slot.layermaskname && !slot.layermask) { slot.layermask = new ImageData; texturedata(*slot.layermask, slot.layermaskname); if(!slot.layermask->data) DELETEP(slot.layermask); @@ -2341,34 +2017,28 @@ void loadlayermasks() } } -void cleanuptexture(Texture *t) -{ +void cleanuptexture(Texture *t) { DELETEA(t->alphamask); if(t->id) { glDeleteTextures(1, &t->id); t->id = 0; } if(t->type&Texture::TRANSIENT) textures.remove(t->name); } -void cleanuptextures() -{ +void cleanuptextures() { loopv(slots) slots[i]->cleanup(); loopv(vslots) vslots[i]->cleanup(); enumerate(textures, Texture, tex, cleanuptexture(&tex)); } -bool reloadtexture(const char *name) -{ +bool reloadtexture(const char *name) { Texture *t = textures.access(path(name, true)); if(t) return reloadtexture(*t); return true; } -bool reloadtexture(Texture &tex) -{ +bool reloadtexture(Texture &tex) { if(tex.id) return true; - switch(tex.type&Texture::TYPE) - { - case Texture::IMAGE: - { + switch(tex.type&Texture::TYPE) { + case Texture::IMAGE: { int compress = 0; ImageData s; if(!texturedata(s, tex.name, NULL, true, &compress) || !newtexture(&tex, NULL, s, tex.clamp, tex.mipmap, false, false, compress)) return false; @@ -2378,16 +2048,14 @@ bool reloadtexture(Texture &tex) return true; } -void reloadtex(char *name) -{ +void reloadtex(char *name) { Texture *t = textures.access(path(name, true)); if(!t) { conoutf(CON_ERROR, "texture %s is not loaded", name); return; } if(t->type&Texture::TRANSIENT) { conoutf(CON_ERROR, "can't reload transient texture %s", name); return; } DELETEA(t->alphamask); Texture oldtex = *t; t->id = 0; - if(!reloadtexture(*t)) - { + if(!reloadtexture(*t)) { if(t->id) glDeleteTextures(1, &t->id); *t = oldtex; conoutf(CON_ERROR, "failed to reload texture %s", name); @@ -2396,23 +2064,19 @@ void reloadtex(char *name) COMMAND(reloadtex, "s"); -void reloadtextures() -{ +void reloadtextures() { int reloaded = 0; - enumerate(textures, Texture, tex, - { + enumerate(textures, Texture, tex, { loadprogress = float(++reloaded)/textures.numelems; reloadtexture(tex); }); loadprogress = 0; } -void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0) -{ +void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0) { f->putbig<uint>(len); f->write(type, 4); f->write(data, len); - uint crc = crc32(0, Z_NULL, 0); crc = crc32(crc, (const Bytef *)type, 4); if(data) crc = crc32(crc, data, len); @@ -2421,11 +2085,9 @@ void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0 VARP(compresspng, 0, 9, 9); -void savepng(const char *filename, ImageData &image, bool flip) -{ +void savepng(const char *filename, ImageData &image, bool flip) { uchar ctype = 0; - switch(image.bpp) - { + switch(image.bpp) { case 1: ctype = 0; break; case 2: ctype = 4; break; case 3: ctype = 2; break; @@ -2434,44 +2096,33 @@ void savepng(const char *filename, ImageData &image, bool flip) } stream *f = openfile(filename, "wb"); if(!f) { conoutf(CON_ERROR, "could not write to %s", filename); return; } - uchar signature[] = { 137, 80, 78, 71, 13, 10, 26, 10 }; f->write(signature, sizeof(signature)); - - struct pngihdr - { + struct pngihdr { uint width, height; uchar bitdepth, colortype, compress, filter, interlace; } ihdr = { bigswap<uint>(image.w), bigswap<uint>(image.h), 8, ctype, 0, 0, 0 }; writepngchunk(f, "IHDR", (uchar *)&ihdr, 13); - stream::offset idat = f->tell(); uint len = 0; f->write("\0\0\0\0IDAT", 8); uint crc = crc32(0, Z_NULL, 0); crc = crc32(crc, (const Bytef *)"IDAT", 4); - z_stream z; z.zalloc = NULL; z.zfree = NULL; z.opaque = NULL; - if(deflateInit(&z, compresspng) != Z_OK) goto error; - uchar buf[1<<12]; z.next_out = (Bytef *)buf; z.avail_out = sizeof(buf); - - loopi(image.h) - { + loopi(image.h) { uchar filter = 0; - loopj(2) - { + loopj(2) { z.next_in = j ? (Bytef *)image.data + (flip ? image.h-i-1 : i)*image.pitch : (Bytef *)&filter; z.avail_in = j ? image.w*image.bpp : 1; - while(z.avail_in > 0) - { + while(z.avail_in > 0) { if(deflate(&z, Z_NO_FLUSH) != Z_OK) goto cleanuperror; #define FLUSHZ do { \ int flush = sizeof(buf) - z.avail_out; \ @@ -2485,24 +2136,18 @@ void savepng(const char *filename, ImageData &image, bool flip) } } } - - for(;;) - { + for(;;) { int err = deflate(&z, Z_FINISH); if(err != Z_OK && err != Z_STREAM_END) goto cleanuperror; FLUSHZ; if(err == Z_STREAM_END) break; } - deflateEnd(&z); - f->seek(idat, SEEK_SET); f->putbig<uint>(len); f->seek(0, SEEK_END); f->putbig<uint>(crc); - writepngchunk(f, "IEND"); - delete f; return; @@ -2511,7 +2156,6 @@ cleanuperror: error: delete f; - conoutf(CON_ERROR, "failed saving png to %s", filename); } @@ -2522,31 +2166,25 @@ VARP(screenshotformat, 0, IMG_PNG, NUMIMG-1); const char *imageexts[NUMIMG] = { ".bmp", ".png", ".jpg" }; -int guessimageformat(const char *filename, int format = IMG_BMP) -{ +int guessimageformat(const char *filename, int format = IMG_BMP) { int len = strlen(filename); - loopi(NUMIMG) - { + loopi(NUMIMG) { int extlen = strlen(imageexts[i]); if(len >= extlen && !strcasecmp(&filename[len-extlen], imageexts[i])) return i; } return format; } -void saveimage(const char *filename, int format, ImageData &image, bool flip = false) -{ - switch(format) - { +void saveimage(const char *filename, int format, ImageData &image, bool flip = false) { + switch(format) { case IMG_PNG: savepng(filename, image, flip); break; - default: - { + default: { ImageData flipped(image.w, image.h, image.bpp, image.data); if(flip) texflip(flipped); SDL_Surface *s = wrapsurface(flipped.data, flipped.w, flipped.h, flipped.bpp); if(!s) break; stream *f = openfile(filename, "wb"); - if(f) - { + if(f) { switch(format) { case IMG_JPG: #if SDL_IMAGE_VERSION_ATLEAST(2, 0, 2) @@ -2565,8 +2203,7 @@ void saveimage(const char *filename, int format, ImageData &image, bool flip = f } } -bool loadimage(const char *filename, ImageData &image) -{ +bool loadimage(const char *filename, ImageData &image) { SDL_Surface *s = loadsurface(path(filename, true)); if(!s) return false; image.wrap(s); @@ -2575,51 +2212,41 @@ bool loadimage(const char *filename, ImageData &image) SVARP(screenshotdir, "screenshot"); -void screenshot(char *filename) -{ +void screenshot(char *filename) { static string buf; int format = -1, dirlen = 0; copystring(buf, screenshotdir); - if(screenshotdir[0]) - { + if(screenshotdir[0]) { dirlen = strlen(buf); if(buf[dirlen] != '/' && buf[dirlen] != '\\' && dirlen+1 < (int)sizeof(buf)) { buf[dirlen++] = '/'; buf[dirlen] = '\0'; } const char *dir = findfile(buf, "w"); if(!fileexists(dir, "w")) createdir(dir); } - if(filename[0]) - { + if(filename[0]) { concatstring(buf, filename); format = guessimageformat(buf, -1); } - else - { + else { string sstime; time_t t = time(NULL); size_t len = strftime(sstime, sizeof(sstime), "%Y-%m-%d_%H.%M.%S", localtime(&t)); sstime[min(len, sizeof(sstime)-1)] = '\0'; concatstring(buf, sstime); - const char *map = game::getclientmap(), *ssinfo = game::getscreenshotinfo(); - if(map && map[0]) - { + if(map && map[0]) { concatstring(buf, "_"); concatstring(buf, map); } - if(ssinfo && ssinfo[0]) - { + if(ssinfo && ssinfo[0]) { concatstring(buf, "_"); concatstring(buf, ssinfo); } - for(char *s = &buf[dirlen]; *s; s++) if(iscubespace(*s) || *s == '/' || *s == '\\') *s = '-'; } - if(format < 0) - { + if(format < 0) { format = screenshotformat; concatstring(buf, imageexts[format]); } - ImageData image(screenw, screenh, 3); glPixelStorei(GL_PACK_ALIGNMENT, texalign(image.data, screenw, 3)); glReadPixels(0, 0, screenw, screenh, GL_RGB, GL_UNSIGNED_BYTE, image.data); |
