Commit 20680fe3 authored by mercury233's avatar mercury233

add pic scaling

parent 3a577c93
......@@ -905,6 +905,8 @@ void Game::LoadConfig() {
char strbuf[32];
char valbuf[256];
wchar_t wstr[256];
gameConf.use_d3d = 0;
gameConf.use_image_scale = 1;
gameConf.antialias = 0;
gameConf.serverport = 7911;
gameConf.textfontsize = 12;
......@@ -937,6 +939,8 @@ void Game::LoadConfig() {
gameConf.antialias = atoi(valbuf);
} else if(!strcmp(strbuf, "use_d3d")) {
gameConf.use_d3d = atoi(valbuf) > 0;
} else if(!strcmp(strbuf, "use_image_scale")) {
gameConf.use_image_scale = atoi(valbuf) > 0;
} else if(!strcmp(strbuf, "errorlog")) {
enable_log = atoi(valbuf);
} else if(!strcmp(strbuf, "textfont")) {
......@@ -1009,6 +1013,7 @@ void Game::SaveConfig() {
fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n");
char linebuf[256];
fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
fprintf(fp, "use_image_scale = %d\n", gameConf.use_image_scale ? 1 : 0);
fprintf(fp, "antialias = %d\n", gameConf.antialias);
fprintf(fp, "errorlog = %d\n", enable_log);
BufferIO::CopyWStr(ebNickName->getText(), gameConf.nickname, 20);
......
......@@ -13,6 +13,7 @@ namespace ygo {
struct Config {
bool use_d3d;
bool use_image_scale;
unsigned short antialias;
unsigned short serverport;
unsigned char textfontsize;
......
#include "image_manager.h"
#include "game.h"
namespace ygo {
......@@ -63,6 +64,100 @@ void ImageManager::RemoveTexture(int code) {
tMap.erase(tit);
}
}
// function by Warr1024, from https://github.com/minetest/minetest/issues/2419 , modified
void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest)
{
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
u32 dy, dx;
irr::video::SColor pxl;
// Cache rectsngle boundaries.
double sw = src->getDimension().Width * 1.0;
double sh = src->getDimension().Height * 1.0;
// Walk each destination image pixel.
// Note: loop y around x for better cache locality.
irr::core::dimension2d<u32> dim = dest->getDimension();
for(dy = 0; dy < dim.Height; dy++)
for(dx = 0; dx < dim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
minsx = dx * sw / dim.Width;
maxsx = minsx + sw / dim.Width;
minsy = dy * sh / dim.Height;
maxsy = minsy + sh / dim.Height;
// Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops.
area = 0;
ra = 0;
ga = 0;
ba = 0;
aa = 0;
// Loop over the integral pixel positions described by those bounds.
for(sy = floor(minsy); sy < maxsy; sy++)
for(sx = floor(minsx); sx < maxsx; sx++) {
// Calculate width, height, then area of dest pixel
// that's covered by this source pixel.
pw = 1;
if(minsx > sx)
pw += sx - minsx;
if(maxsx < (sx + 1))
pw += maxsx - sx - 1;
ph = 1;
if(minsy > sy)
ph += sy - minsy;
if(maxsy < (sy + 1))
ph += maxsy - sy - 1;
pa = pw * ph;
// Get source pixel and add it to totals, weighted
// by covered area and alpha.
pxl = src->getPixel((u32)sx, (u32)sy);
area += pa;
ra += pa * pxl.getRed();
ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
// Set the destination image pixel to the average color.
if(area > 0) {
pxl.setRed(ra / area + 0.5);
pxl.setGreen(ga / area + 0.5);
pxl.setBlue(ba / area + 0.5);
pxl.setAlpha(aa / area + 0.5);
} else {
pxl.setRed(0);
pxl.setGreen(0);
pxl.setBlue(0);
pxl.setAlpha(0);
}
dest->setPixel(dx, dy, pxl);
}
}
irr::video::ITexture* ImageManager::GetTextureFromFile(char* file, s32 width, s32 height) {
if(mainGame->gameConf.use_image_scale) {
irr::video::ITexture* texture;
irr::video::IImage* srcimg = driver->createImageFromFile(file);
if(srcimg == NULL)
return NULL;
if(srcimg->getDimension() == irr::core::dimension2d<u32>(width, height)) {
texture = driver->addTexture(file, srcimg);
} else {
video::IImage *destimg = driver->createImage(srcimg->getColorFormat(), irr::core::dimension2d<u32>(width, height));
imageScaleNNAA(srcimg, destimg);
texture = driver->addTexture(file, destimg);
destimg->drop();
}
srcimg->drop();
return texture;
} else {
return driver->getTexture(file);
}
}
irr::video::ITexture* ImageManager::GetTexture(int code) {
if(code == 0)
return tUnknown;
......@@ -70,12 +165,12 @@ irr::video::ITexture* ImageManager::GetTexture(int code) {
if(tit == tMap.end()) {
char file[256];
sprintf(file, "expansions/pics/%d.jpg", code);
irr::video::ITexture* img = driver->getTexture(file);
irr::video::ITexture* img = GetTextureFromFile(file, CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
if(img == NULL) {
sprintf(file, "pics/%d.jpg", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
}
if(img == NULL) {
if(img == NULL && !mainGame->gameConf.use_image_scale) {
tMap[code] = NULL;
return GetTextureThumb(code);
} else {
......@@ -86,7 +181,7 @@ irr::video::ITexture* ImageManager::GetTexture(int code) {
if(tit->second)
return tit->second;
else
return GetTextureThumb(code);
return mainGame->gameConf.use_image_scale ? tUnknown : GetTextureThumb(code);
}
irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0)
......@@ -94,11 +189,15 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
char file[256];
sprintf(file, "expansions/pics/thumbnail/%d.jpg", code);
irr::video::ITexture* img = driver->getTexture(file);
if(img == NULL) {
char exfile[256];
if(mainGame->gameConf.use_image_scale)
sprintf(file, "pics/%d.jpg", code);
else
sprintf(file, "pics/thumbnail/%d.jpg", code);
img = driver->getTexture(file);
sprintf(exfile, "expansions/%s", file);
irr::video::ITexture* img = GetTextureFromFile(exfile, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
if(img == NULL) {
img = GetTextureFromFile(file, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
}
if(img == NULL) {
tThumb[code] = NULL;
......
......@@ -13,6 +13,7 @@ public:
void SetDevice(irr::IrrlichtDevice* dev);
void ClearTexture();
void RemoveTexture(int code);
irr::video::ITexture* GetTextureFromFile(char* file, s32 width, s32 height);
irr::video::ITexture* GetTexture(int code);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment