wxMemoryDC* GameSprite::getDC(SpriteSize size) { ASSERT(size == SPRITE_SIZE_16x16 || size == SPRITE_SIZE_32x32); if(!dc[size]) { ASSERT(width >= 1 && height >= 1); const int bgshade = g_settings.getInteger(Config::ICON_BACKGROUND); int image_size = std::max<int>(width, height) * SPRITE_PIXELS; wxImage image(image_size, image_size); image.Clear(bgshade); for(uint8_t l = 0; l < layers; l++) { for(uint8_t w = 0; w < width; w++) { for(uint8_t h = 0; h < height; h++) { const int i = getIndex(w, h, l, 0, 0, 0, 0); uint8_t* data = spriteList[i]->getRGBData(); if(data) { wxImage img(SPRITE_PIXELS, SPRITE_PIXELS, data); img.SetMaskColour(0xFF, 0x00, 0xFF); image.Paste(img, (width - w - 1) * SPRITE_PIXELS, (height - h - 1) * SPRITE_PIXELS); img.Destroy(); } } } } // Now comes the resizing / antialiasing if(size == SPRITE_SIZE_16x16 || image.GetWidth() > SPRITE_PIXELS || image.GetHeight() > SPRITE_PIXELS) { int new_size = SPRITE_SIZE_16x16 ? 16 : 32; image.Rescale(new_size, new_size); } wxBitmap bmp(image); dc[size] = newd wxMemoryDC(bmp); g_gui.gfx.addSpriteToCleanup(this); image.Destroy(); } return dc[size]; }
wxMemoryDC* GameSprite::getDC(SpriteSize sz) { if(!dc[sz]) { const int bgshade = settings.getInteger(Config::ICON_BACKGROUND); uint8_t* rgb = nullptr; uint32_t ht, wt; if(width == 2 && height == 2) { wt = 2, ht = 2; rgb = newd uint8_t[2*2*32*32*3]; memset(rgb, bgshade, 2*2*32*32*3); for(int cf = 0; cf != layers; ++cf) { uint8_t* rgb32x32[2][2] = { {spriteList[(cf*2+1)*2+1]->getRGBData(),spriteList[(cf*2+1)*2]->getRGBData()}, {spriteList[cf*4+1]->getRGBData(),spriteList[cf*4]->getRGBData()} }; for(int cy = 0; cy < 64; ++cy) { for(int cx = 0; cx < 64; ++cx) { int cw = cx/32; int ch = cy/32; if(!rgb32x32[ch][cw]) continue; int rx = cx%32; int ry = cy%32; uint8_t r = rgb32x32[ch][cw][32*3*ry + 3*rx + 0]; uint8_t g = rgb32x32[ch][cw][32*3*ry + 3*rx + 1]; uint8_t b = rgb32x32[ch][cw][32*3*ry + 3*rx + 2]; if(r == 0xFF && g == 0x00 && b == 0xFF) { // Transparent.. let it pass } else { rgb[64*3*cy + 3*cx + 0] = r; rgb[64*3*cy + 3*cx + 1] = g; rgb[64*3*cy + 3*cx + 2] = b; } } } delete[] rgb32x32[0][0]; delete[] rgb32x32[0][1]; delete[] rgb32x32[1][0]; delete[] rgb32x32[1][1]; } // (cf*2+ch)*2+cw } else if(width == 2 && height == 1) { wt = 2, ht = 2; rgb = newd uint8_t[2*2*32*32*3]; memset(rgb, bgshade, 2*2*32*32*3); for(int cf = 0; cf != layers; ++cf) { uint8_t* rgb32x32[2] = { spriteList[cf*2+1]->getRGBData(), spriteList[cf*2+0]->getRGBData() }; for(int cy = 16; cy < 48; ++cy) { for(int cx = 0; cx < 64; ++cx) { int cw = cx/32; int rx = cx%32; int ry = cy-16; if(!rgb32x32[cw]) continue; uint8_t r = rgb32x32[cw][32*3*ry + 3*rx + 0]; uint8_t g = rgb32x32[cw][32*3*ry + 3*rx + 1]; uint8_t b = rgb32x32[cw][32*3*ry + 3*rx + 2]; if(r == 0xFF && g == 0x00 && b == 0xFF) { // Transparent.. let it pass } else { rgb[64*3*cy + 3*cx + 0] = r; rgb[64*3*cy + 3*cx + 1] = g; rgb[64*3*cy + 3*cx + 2] = b; } } } delete[] rgb32x32[0]; delete[] rgb32x32[1]; } } else if(width == 1 && height == 2) { wt = 2, ht = 2; rgb = newd uint8_t[2*2*32*32*3]; memset(rgb, bgshade, 2*2*32*32*3); for(int cf = 0; cf != layers; ++cf) { uint8_t* rgb32x32[2] = { spriteList[cf*2+1]->getRGBData(), spriteList[cf*2+0]->getRGBData() }; for(int cy = 0; cy < 64; ++cy) { for(int cx = 16; cx < 48; ++cx) { int ch = cy/32; int rx = cx-16; int ry = cy%32; if(!rgb32x32[ch]) continue; uint8_t r = rgb32x32[ch][32*3*ry + 3*rx + 0]; uint8_t g = rgb32x32[ch][32*3*ry + 3*rx + 1]; uint8_t b = rgb32x32[ch][32*3*ry + 3*rx + 2]; if(r == 0xFF && g == 0x00 && b == 0xFF) { // Transparent.. let it pass } else { rgb[64*3*cy + 3*cx + 0] = r; rgb[64*3*cy + 3*cx + 1] = g; rgb[64*3*cy + 3*cx + 2] = b; } } } delete[] rgb32x32[0]; delete[] rgb32x32[1]; } } else if(width == 1 && height == 1) { wt = 1, ht = 1; rgb = newd uint8_t[32*32*3]; memset(rgb, bgshade, 32*32*3); for(int cf = 0; cf != layers; ++cf) { uint8_t* rgb32x32 = spriteList[cf]->getRGBData(); if(!rgb32x32) continue; for(int cy = 0; cy < 32; ++cy) { for(int cx = 0; cx < 32; ++cx) { uint8_t r = rgb32x32[32*3*cy + 3*cx + 0]; uint8_t g = rgb32x32[32*3*cy + 3*cx + 1]; uint8_t b = rgb32x32[32*3*cy + 3*cx + 2]; if(r == 0xFF && g == 0x00 && b == 0xFF) { // Transparent.. let it pass } else { rgb[32*3*cy + 3*cx + 0] = r; rgb[32*3*cy + 3*cx + 1] = g; rgb[32*3*cy + 3*cx + 2] = b; } } } delete[] rgb32x32; } } else { return nullptr; } // Now comes the resizing / antialiasing if(sz == SPRITE_SIZE_16x16) { uint8_t* rgb16x16 = reinterpret_cast<uint8_t*>(malloc(16*16*3)); uint32_t pixels_per_line = 32*wt; uint32_t pixels_per_pixel = 2*wt; uint32_t bytes_per_line = 3*pixels_per_line; uint32_t bytes_per_pixel = 3*pixels_per_pixel; for(uint32_t y = 0; y < 16; ++y) { for(uint32_t x = 0; x < 16; ++x) { uint32_t r = 0, g = 0, b = 0, c = 0; for(uint32_t u = 0; u < 2; ++u) { for(uint32_t v = 0; v < 2; ++v) { r += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 0]; g += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 1]; b += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 2]; //r += rgb[96 * (2*y + u) + (6*x + v*3) + 0]; //g += rgb[96 * (2*y + u) + (6*x + v*3) + 1]; //b += rgb[96 * (2*y + u) + (6*x + v*3) + 2]; ++c; } } ASSERT(c); rgb16x16[48*y+x*3+0] = r/c; rgb16x16[48*y+x*3+1] = g/c; rgb16x16[48*y+x*3+2] = b/c; } } wxImage img(16,16, rgb16x16); wxBitmap bmp(img); dc[sz] = newd wxMemoryDC(bmp); delete[] rgb; gui.gfx.addSpriteToCleanup(this); } else if(sz == SPRITE_SIZE_32x32) { uint8_t* rgb32x32 = reinterpret_cast<uint8_t*>(malloc(32*32*3)); uint32_t pixels_per_line = 32*wt; uint32_t pixels_per_pixel = wt; uint32_t bytes_per_line = 3*pixels_per_line; uint32_t bytes_per_pixel = 3*pixels_per_pixel; for(uint32_t y = 0; y < 32; ++y) { for(uint32_t x = 0; x < 32; ++x) { uint32_t r = 0, g = 0, b = 0, c = 0; for(uint32_t u = 0; u < ht; ++u) { for(uint32_t v = 0; v < wt; ++v) { r += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 0]; g += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 1]; b += rgb[bytes_per_line * (pixels_per_pixel*y + u) + (bytes_per_pixel*x + 3*v) + 2]; ++c; } } ASSERT(c); rgb32x32[96*y+x*3+0] = r/c; rgb32x32[96*y+x*3+1] = g/c; rgb32x32[96*y+x*3+2] = b/c; } } wxImage img(32,32, rgb32x32); wxBitmap bmp(img); dc[sz] = newd wxMemoryDC(bmp); delete[] rgb; gui.gfx.addSpriteToCleanup(this); } else { ASSERT(sz == 0); } } return dc[sz]; }