diff --git a/etc/com.github.cubitect.cubiomes-viewer.metainfo.xml b/etc/com.github.cubitect.cubiomes-viewer.metainfo.xml index d7dfc0d..4ef1a83 100644 --- a/etc/com.github.cubitect.cubiomes-viewer.metainfo.xml +++ b/etc/com.github.cubitect.cubiomes-viewer.metainfo.xml @@ -13,23 +13,23 @@ - + com.github.cubitect.cubiomes-viewer.desktop - https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.1.1/etc/screenshot_maingui-fs8.png + https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.2.0/etc/screenshot_maingui-fs8.png - https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.1.1/etc/screenshot_biomes-fs8.png + https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.2.0/etc/screenshot_biomes-fs8.png - https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.1.1/etc/screenshot_structures-fs8.png + https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.2.0/etc/screenshot_structures-fs8.png - https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.1.1/etc/screenshot_surface-fs8.png + https://raw.githubusercontent.com/Cubitect/cubiomes-viewer/3.2.0/etc/screenshot_surface-fs8.png diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 0a6909a..fd39263 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -5,8 +5,8 @@ #include #define VERS_MAJOR 3 -#define VERS_MINOR 1 -#define VERS_PATCH 1 // negative patch number designates a development version +#define VERS_MINOR 2 +#define VERS_PATCH 0 // negative patch number designates a development version // returns +1 if newer, -1 if older and 0 if equal inline int cmpVers(int major, int minor, int patch) diff --git a/src/configdialog.cpp b/src/configdialog.cpp index 842abe0..826e127 100644 --- a/src/configdialog.cpp +++ b/src/configdialog.cpp @@ -31,6 +31,7 @@ ConfigDialog::ConfigDialog(QWidget *parent, Config *config) ui->buttonBiomeColor->setFont(*gp_font_mono); ui->lineMatching->setValidator(new QIntValidator(1, 99999999, ui->lineMatching)); + ui->spinThreads->setRange(1, QThread::idealThreadCount()); initSettings(config); visModified = false; @@ -55,6 +56,7 @@ void ConfigDialog::initSettings(Config *config) ui->lineGridSpacing->setText(config->gridSpacing ? QString::number(config->gridSpacing) : ""); ui->comboGridMult->setCurrentText(config->gridMultiplier ? QString::number(config->gridMultiplier) : tr("None")); ui->spinCacheSize->setValue(config->mapCacheSize); + ui->spinThreads->setValue(config->mapThreads ? config->mapThreads : QThread::idealThreadCount()); ui->lineSep->setText(config->separator); int idx = config->quote == "\'" ? 1 : config->quote== "\"" ? 2 : 0; ui->comboQuote->setCurrentIndex(idx); @@ -74,6 +76,7 @@ Config ConfigDialog::getSettings() conf.gridSpacing = ui->lineGridSpacing->text().toInt(); conf.gridMultiplier = ui->comboGridMult->currentText().toInt(); conf.mapCacheSize = ui->spinCacheSize->value(); + conf.mapThreads = ui->spinThreads->value(); conf.separator = ui->lineSep->text(); int idx = ui->comboQuote->currentIndex(); conf.quote = idx == 1 ? "\'" : idx == 2 ? "\"" : ""; diff --git a/src/configdialog.ui b/src/configdialog.ui index e634acb..ee309b4 100644 --- a/src/configdialog.ui +++ b/src/configdialog.ui @@ -342,6 +342,16 @@ + + + + 渲染地图所用线程数: + + + + + + diff --git a/src/exportdialog.cpp b/src/exportdialog.cpp index 46465be..5809d19 100644 --- a/src/exportdialog.cpp +++ b/src/exportdialog.cpp @@ -12,105 +12,78 @@ #include -struct ExportWorker : QRunnable +void ExportWorker::runWorkItem(const ExportWorkItem& work) { - ExportThread *mt; - uint64_t seed; - int tx, tz; - QString fnam; + const ExportDialog *mt = parent; + if (mt->stop) + return; + + Generator g; + setupGenerator(&g, mt->wi.mc, mt->wi.large | FORCE_OCEAN_VARIANTS); + applySeed(&g, mt->dim, work.seed); + Range r = {mt->scale, mt->x, mt->z, mt->w, mt->h, mt->y, 1}; - ExportWorker(ExportThread *master) : mt(master) {} - bool init(uint64_t seed, int tx, int tz) + if (mt->tilesize > 0) { - this->seed = seed; - this->tx = tx; - this->tz = tz; - fnam = mt->pattern; - fnam.replace("%S", QString::number(seed)); - fnam.replace("%x", QString::number(tx)); - fnam.replace("%z", QString::number(tz)); - fnam = mt->dir.filePath(fnam); - return QFileInfo::exists(fnam); + r.x = work.tx * mt->tilesize; + r.z = work.tz * mt->tilesize; + r.sx = r.sz = mt->tilesize; } - void run() - { - Generator g; - setupGenerator(&g, mt->wi.mc, mt->wi.large | FORCE_OCEAN_VARIANTS); - applySeed(&g, mt->dim, seed); - Range r = {mt->scale, mt->x, mt->z, mt->w, mt->h, mt->y, 1}; + int *ids = allocCache(&g, r); + genBiomes(&g, ids, r); - if (mt->tilesize > 0) - { - r.x = tx * mt->tilesize; - r.z = tz * mt->tilesize; - r.sx = r.sz = mt->tilesize; - } + uchar *rgb = new uchar[r.sx * r.sz * 3]; + biomesToImage(rgb, g_biomeColors, ids, r.sx, r.sz, 1, 1); - int *ids = allocCache(&g, r); - genBiomes(&g, ids, r); + if (mt->heightvis >= 0 && mt->dim == DIM_OVERWORLD) + { + SurfaceNoise sn; + initSurfaceNoise(&sn, DIM_OVERWORLD, mt->wi.seed); + int stepbits = mt->scale == 1 ? 2 : 0; + applyHeightShading(rgb, r, &g, &sn, stepbits, mt->heightvis, true, &mt->stop); + } - uchar *rgb = new uchar[r.sx * r.sz * 3]; - biomesToImage(rgb, g_biomeColors, ids, r.sx, r.sz, 1, 1); + QImage img(rgb, r.sx, r.sz, 3*r.sx, QImage::Format_RGB888); - if (mt->heightvis >= 0 && mt->dim == DIM_OVERWORLD) + enum { BG_NONE, BG_TRANSP, BG_BLACK }; + if (mt->tilesize > 0 && mt->bgmode != BG_NONE) + { // TODO: only generate needed sections + QColor bg = QColor(Qt::black); + if (mt->bgmode == BG_TRANSP) { - SurfaceNoise sn; - initSurfaceNoise(&sn, DIM_OVERWORLD, mt->wi.seed); - int stepbits = mt->scale == 1 ? 2 : 0; - applyHeightShading(rgb, r, &g, &sn, stepbits, mt->heightvis, true, &mt->stop); + bg = QColor(Qt::transparent); + img = img.convertToFormat(QImage::Format_RGBA8888, Qt::AutoColor); } - - QImage img(rgb, r.sx, r.sz, 3*r.sx, QImage::Format_RGB888); - - enum { BG_NONE, BG_TRANSP, BG_BLACK }; - if (mt->tilesize > 0 && mt->bgmode != BG_NONE) - { // TODO: only generate needed sections - QColor bg = QColor(Qt::black); - if (mt->bgmode == BG_TRANSP) - { - bg = QColor(Qt::transparent); - img = img.convertToFormat(QImage::Format_RGBA8888, Qt::AutoColor); - } - int zh = mt->z + mt->h; - int xw = mt->x + mt->w; - for (int j = 0; j < r.sz; j++) + int zh = mt->z + mt->h; + int xw = mt->x + mt->w; + for (int j = 0; j < r.sz; j++) + { + for (int i = 0; i < r.sx; i++) { - for (int i = 0; i < r.sx; i++) - { - if (r.z+j < mt->z || r.z+j >= zh || r.x+i < mt->x || r.x+i >= xw) - img.setPixelColor(i, j, bg); - } + if (r.z+j < mt->z || r.z+j >= zh || r.x+i < mt->x || r.x+i >= xw) + img.setPixelColor(i, j, bg); } } - if (!mt->stop) - img.save(fnam); - free(ids); - delete [] rgb; } -}; - -ExportThread::~ExportThread() -{ - for (ExportWorker* worker : qAsConst(workers)) - delete worker; + if (!mt->stop) + { + img.save(work.fnam); + } + free(ids); + delete [] rgb; } -void ExportThread::run() +void ExportWorker::run() { - for (ExportWorker *& worker : workers) + ExportWorkItem work; + while (parent->requestWork(&work)) { - //pool.start(worker); - worker->run(); - emit workerDone(); - if (stop) - break; + runWorkItem(work); + emit workItemDone(); } - //pool.waitForDone(); - deleteLater(); } - static void setCombo(QComboBox *cb, const char *setting) { QSettings settings("cubiomes-viewer", "cubiomes-viewer"); @@ -123,9 +96,30 @@ ExportDialog::ExportDialog(MainWindow *parent) : QDialog(parent) , ui(new Ui::ExportDialog) , mainwindow(parent) + , dir() + , pattern() + , wi() + , dim() + , scale() + , x(), z(), w(), h(), y() + , tilesize() + , bgmode() + , heightvis() + , mutex() + , workitems() + , workers() + , stop() { ui->setupUi(this); + for (int i = 0; i < QThread::idealThreadCount(); i++) + { + ExportWorker *worker = new ExportWorker(this); + connect(worker, &ExportWorker::workItemDone, this, &ExportDialog::workItemDone, Qt::QueuedConnection); + connect(worker, &ExportWorker::finished, this, &ExportDialog::onWorkerFinished, Qt::QueuedConnection); + workers.push_back(worker); + } + QIntValidator *intval = new QIntValidator(this); ui->lineEditX1->setValidator(intval); ui->lineEditZ1->setValidator(intval); @@ -164,9 +158,55 @@ ExportDialog::ExportDialog(MainWindow *parent) ExportDialog::~ExportDialog() { + cancel(); + for (ExportWorker *worker : qAsConst(workers)) + { + worker->wait(); + delete worker; + } delete ui; } +bool ExportDialog::initWork(ExportWorkItem *work, uint64_t seed, int tx, int tz) +{ + work->seed = seed; + work->tx = tx; + work->tz = tz; + work->fnam = pattern; + work->fnam.replace("%S", QString::number(seed)); + work->fnam.replace("%x", QString::number(tx)); + work->fnam.replace("%z", QString::number(tz)); + work->fnam = dir.filePath(work->fnam); + return QFileInfo::exists(work->fnam); +} + +bool ExportDialog::requestWork(ExportWorkItem *work) +{ + QMutexLocker locker(&mutex); + if (workitems.empty()) + return false; + *work = workitems.takeFirst(); + return true; +} + +void ExportDialog::startWorkers() +{ + int threadlimit = mainwindow->config.mapThreads; + int n = (int) workers.size(); + if (threadlimit && threadlimit < n) + n = threadlimit; + for (int i = 0; i < n; i++) + workers[i]->start(); +} + +void ExportDialog::onWorkerFinished() +{ + for (ExportWorker *worker : qAsConst(workers)) + if (worker->isRunning()) + return; + emit exportFinished(); +} + void ExportDialog::update() { int seedcnt = 1; @@ -256,13 +296,16 @@ void ExportDialog::on_buttonDirSelect_clicked() ui->lineDir->setText(dir); } - void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) { QDialogButtonBox::StandardButton b = ui->buttonBox->standardButton(button); if (b == QDialogButtonBox::Ok) { + for (ExportWorker *worker : qAsConst(workers)) + if (worker->isRunning()) + return; + int seedmode = ui->comboSeed->currentIndex(); QString pattern = ui->linePattern->text(); bool tiled = ui->groupTiled->isChecked(); @@ -307,22 +350,19 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) return; } - ExportThread *master = new ExportThread(mainwindow); - master->dir = QDir(ui->lineDir->text()); - master->pattern = pattern; - master->wi = wi; - master->dim = mainwindow->getDim(); - master->scale = 1 << s; - master->x = x0; - master->z = z0; - master->w = x1 - x0; - master->h = z1 - z0; - master->y = y; - master->tilesize = -1; - master->heightvis = ui->comboHeightVis->currentIndex() - 1; - master->bgmode = 0; - - QVector workers; + this->dir = QDir(ui->lineDir->text()); + this->pattern = pattern; + this->wi = wi; + this->dim = mainwindow->getDim(); + this->scale = 1 << s; + this->x = x0; + this->z = z0; + this->w = x1 - x0; + this->h = z1 - z0; + this->y = y; + this->tilesize = -1; + this->heightvis = ui->comboHeightVis->currentIndex() - 1; + this->bgmode = 0; bool existwarn = false; if (tiled) @@ -334,8 +374,8 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) int tx1 = (int) ceil(x1 / (qreal)tilesize); int tz1 = (int) ceil(z1 / (qreal)tilesize); - master->tilesize = tilesize; - master->bgmode = bgmode; + this->tilesize = tilesize; + this->bgmode = bgmode; for (uint64_t seed : qAsConst(seeds)) { @@ -343,9 +383,9 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) { for (int z = tz0; z < tz1; z++) { - ExportWorker *worker = new ExportWorker(master); - existwarn |= worker->init(seed, x, z); - workers.push_back(worker); + ExportWorkItem work; + existwarn |= initWork(&work, seed, x, z); + workitems.push_back(work); } } } @@ -361,16 +401,15 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) QMessageBox::Cancel | QMessageBox::Yes); if (button == QMessageBox::Cancel) { - delete master; return; } } for (uint64_t seed : qAsConst(seeds)) { - ExportWorker *worker = new ExportWorker(master); - existwarn |= worker->init(seed, 0, 0); - workers.push_back(worker); + ExportWorkItem work; + existwarn |= initWork(&work, seed, 0, 0); + workitems.push_back(work); } } @@ -382,10 +421,6 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) QMessageBox::Cancel | QMessageBox::Yes); if (button == QMessageBox::Cancel) { - for (ExportWorker *worker : workers) - delete worker; - workers.clear(); - delete master; return; } } @@ -405,17 +440,17 @@ void ExportDialog::on_buttonBox_clicked(QAbstractButton *button) settings.setValue("export/heightvisIdx", ui->comboHeightVis->currentIndex()); QProgressDialog *progress = new QProgressDialog( - tr("正在导出图片"), tr("中止"), 0, workers.size(), mainwindow); + tr("正在导出图片"), tr("中止"), 0, workitems.size(), mainwindow); progress->setValue(0); + progress->setWindowTitle(tr("Export")); - connect(progress, &QProgressDialog::canceled, master, &ExportThread::cancel); - connect(master, &ExportThread::finished, progress, &QProgressDialog::close); - connect(master, &ExportThread::workerDone, progress, + connect(progress, &QProgressDialog::canceled, this, &ExportDialog::cancel); + connect(this, &ExportDialog::exportFinished, progress, &QProgressDialog::close); + connect(this, &ExportDialog::workItemDone, progress, [=]() { progress->setValue(progress->value() + 1); }, Qt::QueuedConnection); progress->show(); - master->workers = workers; - master->start(); + startWorkers(); } } diff --git a/src/exportdialog.h b/src/exportdialog.h index 361be2b..77c35f2 100644 --- a/src/exportdialog.h +++ b/src/exportdialog.h @@ -4,8 +4,9 @@ #include #include #include -#include +#include #include +#include #include #include "settings.h" @@ -15,40 +16,33 @@ class ExportDialog; } class MainWindow; -struct ExportWorker; -struct ExportThread : public QThread +struct ExportWorkItem { -Q_OBJECT + uint64_t seed; + int tx, tz; + QString fnam; +}; -public: - ExportThread(QObject *parent) : QThread(parent), pool(this), stop() {} - virtual ~ExportThread(); +class ExportDialog; +struct ExportWorker : QThread +{ + Q_OBJECT - void run() override; + public: + ExportWorker(ExportDialog *parent) : parent(parent) {} + virtual ~ExportWorker() {} -signals: - void workerDone(); + void runWorkItem(const ExportWorkItem& work); -public slots: - void cancel() { stop = true; } + virtual void run() override; -public: - QThreadPool pool; - QDir dir; - QString pattern; - WorldInfo wi; - int dim; - int scale; - int x, z, w, h, y; // block area - int tilesize; // tile coordinates - int bgmode; - int heightvis; - QVector workers; +signals: + void workItemDone(); - std::atomic_bool stop; +public: + ExportDialog *parent; }; - class ExportDialog : public QDialog { Q_OBJECT @@ -57,7 +51,19 @@ class ExportDialog : public QDialog explicit ExportDialog(MainWindow *parent); ~ExportDialog(); + bool initWork(ExportWorkItem *work, uint64_t seed, int tx, int tz); + bool requestWork(ExportWorkItem *work); + + void startWorkers(); + +signals: + void exportFinished(); + void workItemDone(); + private slots: + void cancel() { stop = true; } + void onWorkerFinished(); + void update(); void on_buttonFromVisible_clicked(); @@ -65,9 +71,26 @@ private slots: void on_buttonBox_clicked(QAbstractButton *button); + private: Ui::ExportDialog *ui; MainWindow *mainwindow; + +public: + QDir dir; + QString pattern; + WorldInfo wi; + int dim; + int scale; + int x, z, w, h, y; // block area + int tilesize; // tile coordinates + int bgmode; + int heightvis; + QMutex mutex; + QList workitems; + QVector workers; + + std::atomic_bool stop; }; #endif // EXPORTDIALOG_H diff --git a/src/layerdialog.cpp b/src/layerdialog.cpp index 58d0483..ebde5ea 100644 --- a/src/layerdialog.cpp +++ b/src/layerdialog.cpp @@ -130,16 +130,18 @@ LayerDialog::LayerDialog(QWidget *parent, int mc) { ui->setupUi(this); radio[LOPT_BIOMES] = ui->radioBiomes; - radio[LOPT_RIVER_4] = ui->radioRiver; - radio[LOPT_OCEAN_256] = ui->radioOcean; radio[LOPT_NOISE_T_4] = ui->radioNoiseT; radio[LOPT_NOISE_H_4] = ui->radioNoiseH; radio[LOPT_NOISE_C_4] = ui->radioNoiseC; radio[LOPT_NOISE_E_4] = ui->radioNoiseE; radio[LOPT_NOISE_D_4] = ui->radioNoiseD; radio[LOPT_NOISE_W_4] = ui->radioNoiseW; + radio[LOPT_RIVER_4] = ui->radioRiver; + radio[LOPT_OCEAN_256] = ui->radioOcean; + radio[LOPT_NOOCEAN_1] = ui->radioNoOcean; radio[LOPT_HEIGHT_4] = ui->radioHeight; radio[LOPT_STRUCTS] = ui->radioStruct; + combo[LOPT_BIOMES] = ui->comboBiomes; combo[LOPT_NOISE_T_4] = ui->comboNoiseT; combo[LOPT_NOISE_H_4] = ui->comboNoiseH; @@ -183,6 +185,10 @@ LayerDialog::LayerDialog(QWidget *parent, int mc) { radio[i]->setEnabled(mc <= MC_1_17); } + if (i == LOPT_NOOCEAN_1) + { + radio[i]->setEnabled(mc <= MC_B1_7); + } } } diff --git a/src/layerdialog.ui b/src/layerdialog.ui index 0b46587..8387563 100644 --- a/src/layerdialog.ui +++ b/src/layerdialog.ui @@ -2,14 +2,6 @@ LayerDialog - - - 0 - 0 - 474 - 426 - - 图层展示选项 @@ -18,9 +10,33 @@ :/icons/logo.png:/icons/logo.png + + + + + + + 结构潜在生成位置 + + + + + + + 侵蚀度精度: + + + + + + + 河流层 + + + @@ -28,13 +44,10 @@ - - - - - + + - 近似地表高度: + 湿度精度: @@ -45,6 +58,13 @@ + + + + 近似地表高度: + + + @@ -52,18 +72,21 @@ - - + + - - - - 海洋层 + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + @@ -80,15 +103,8 @@ - - - - 湿度精度: - - - - - + + @@ -97,44 +113,27 @@ - - - - 河流层 - - - - - - - 稀有度精度: - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 深度 - - + + - 结构潜在生成位置 + 海洋层 - - + + - 深度 + 不显示beta版本的海洋 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9037003..934247c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -74,16 +74,18 @@ MainWindow::MainWindow(QWidget *parent) laction.resize(LOPT_MAX); laction[LOPT_BIOMES] = ui->actionBiomes; - laction[LOPT_OCEAN_256] = ui->actionOceanTemp; - laction[LOPT_RIVER_4] = ui->actionRiver; laction[LOPT_NOISE_T_4] = ui->actionParaTemperature; laction[LOPT_NOISE_H_4] = ui->actionParaHumidity; laction[LOPT_NOISE_C_4] = ui->actionParaContinentalness; laction[LOPT_NOISE_E_4] = ui->actionParaErosion; laction[LOPT_NOISE_W_4] = ui->actionParaWeirdness; laction[LOPT_NOISE_D_4] = ui->actionParaDepth; + laction[LOPT_RIVER_4] = ui->actionRiver; + laction[LOPT_OCEAN_256] = ui->actionOceanTemp; + laction[LOPT_NOOCEAN_1] = ui->actionNoOceans; laction[LOPT_HEIGHT_4] = ui->actionHeight; laction[LOPT_STRUCTS] = ui->actionStructures; + QActionGroup *grp = new QActionGroup(this); for (int i = 0; i < laction.size(); i++) { @@ -412,6 +414,7 @@ void MainWindow::saveSettings() settings.setValue("config/gridSpacing", config.gridSpacing); settings.setValue("config/gridMultiplier", config.gridMultiplier); settings.setValue("config/mapCacheSize", config.mapCacheSize); + settings.setValue("config/mapThreads", config.mapThreads); settings.setValue("config/biomeColorPath", config.biomeColorPath); settings.setValue("config/separator", config.separator); settings.setValue("config/quote", config.quote); @@ -475,6 +478,7 @@ void MainWindow::loadSettings() config.gridSpacing = settings.value("config/gridSpacing", config.gridSpacing).toInt(); config.gridMultiplier = settings.value("config/gridMultiplier", config.gridMultiplier).toInt(); config.mapCacheSize = settings.value("config/mapCacheSize", config.mapCacheSize).toInt(); + config.mapThreads = settings.value("config/mapThreads", config.mapThreads).toInt(); config.biomeColorPath = settings.value("config/biomeColorPath", config.biomeColorPath).toString(); config.separator = settings.value("config/separator", config.separator).toString(); config.quote = settings.value("config/quote", config.quote).toString(); @@ -761,6 +765,8 @@ void MainWindow::updateMapSeed() setSeed(wi); bool state; + state = (wi.mc <= MC_B1_7); + ui->actionNoOceans->setEnabled(state); state = (wi.mc >= MC_1_13 && wi.mc <= MC_1_17); ui->actionRiver->setEnabled(state); ui->actionOceanTemp->setEnabled(state); @@ -833,7 +839,7 @@ void MainWindow::setMCList(bool experimental) { if (!experimental && mc != wi.mc) { - if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2) + if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2 || mc == MC_1_20) continue; } const char *mcs = mc2str(mc); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4a69201..ebd39a3 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -518,9 +518,6 @@ QToolButton:checked { - - - @@ -528,8 +525,14 @@ QToolButton:checked { + + + + + + @@ -786,6 +789,14 @@ QToolButton:checked { 展示选项 + + + true + + + (Beta 1.7)不展示beta版本的海洋 + + diff --git a/src/mapview.cpp b/src/mapview.cpp index d05c66b..fcdc7c5 100644 --- a/src/mapview.cpp +++ b/src/mapview.cpp @@ -186,6 +186,7 @@ void MapView::settingsToWorld() world->gridspacing = config.gridSpacing; world->gridmultiplier = config.gridMultiplier; world->memlimit = (uint64_t) config.mapCacheSize * 1024 * 1024; + world->threadlimit = config.mapThreads; world->lopt = lopt; } diff --git a/src/search.h b/src/search.h index dc228e8..6855cc6 100644 --- a/src/search.h +++ b/src/search.h @@ -409,7 +409,7 @@ static const struct FilterList "" }; list[F_HEIGHT] = FilterInfo{ - CAT_OTHER, 0, 1, 0, 0, 0, 0, 4, 2, 0, MC_1_0, MC_NEWEST, 0, 0, disp++, + CAT_OTHER, 0, 1, 0, 0, 0, 0, 4, 2, 0, MC_1_1, MC_NEWEST, 0, 0, disp++, ":icons/height.png", _("Surface height"), _("Check the approximate surface height at scale 1:4 at a single coordinate.") diff --git a/src/settings.h b/src/settings.h index 5345b0f..cae3e00 100644 --- a/src/settings.h +++ b/src/settings.h @@ -64,8 +64,6 @@ struct WorldInfo enum { LOPT_BIOMES, - LOPT_RIVER_4, - LOPT_OCEAN_256, LOPT_NOISE_PARA, LOPT_NOISE_T_4 = LOPT_NOISE_PARA, LOPT_NOISE_H_4, @@ -73,6 +71,9 @@ enum { LOPT_NOISE_E_4, LOPT_NOISE_D_4, LOPT_NOISE_W_4, + LOPT_RIVER_4, + LOPT_OCEAN_256, + LOPT_NOOCEAN_1, LOPT_HEIGHT_4, LOPT_STRUCTS, LOPT_MAX, @@ -113,6 +114,7 @@ struct Config int gridSpacing; int gridMultiplier; int mapCacheSize; + int mapThreads; QString biomeColorPath; QString separator; QString quote; @@ -131,6 +133,7 @@ struct Config gridSpacing = 0; gridMultiplier = 0; mapCacheSize = 256; + mapThreads = 0; biomeColorPath = ""; separator = ";"; quote = ""; diff --git a/src/world.cpp b/src/world.cpp index 43ee2c1..f4d8e8a 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -281,7 +281,7 @@ static qreal cubic_hermite(qreal p[4], qreal u) void applyHeightShading(unsigned char *rgb, Range r, const Generator *g, const SurfaceNoise *sn, int stepbits, int mode, - bool bicubic, std::atomic_bool *abort) + bool bicubic, const std::atomic_bool *abort) { int bd = bicubic ? 1 : 0; // sampling border int ps = stepbits; // bits in step size @@ -555,6 +555,10 @@ void Level::init4map(QWorld *w, int pix, int layerscale) setupGenerator(&g, wi.mc, wi.large); g.ls.entry_256 = &g.ls.layers[L_OCEAN_TEMP_256]; } + else if (lopt.mode == LOPT_NOOCEAN_1 && wi.mc <= MC_B1_7) + { + setupGenerator(&g, wi.mc, NO_BETA_OCEAN); + } else { setupGenerator(&g, wi.mc, wi.large | FORCE_OCEAN_VARIANTS); @@ -723,6 +727,8 @@ void MapWorker::run() q->run(); if (q->done) emit quadDone(); + if (q->autoDelete()) + delete q; // manual call to run() so delete manually as well } } @@ -740,6 +746,7 @@ QWorld::QWorld(WorldInfo wi, int dim, LayerOpt lopt) , mutex() , queue() , workers(QThread::idealThreadCount()) + , threadlimit() , showBB() , gridspacing() , gridmultiplier() @@ -929,8 +936,11 @@ void QWorld::clear() void QWorld::startWorkers() { - for (MapWorker& w : workers) - w.start(); + int n = (int) workers.size(); + if (threadlimit && threadlimit < n) + n = threadlimit; + for (int i = 0; i < n; i++) + workers[i].start(); } void QWorld::waitForIdle() @@ -1047,8 +1057,11 @@ struct SpawnStronghold : public Scheduled QWorld *world; WorldInfo wi; - SpawnStronghold(QWorld *world, WorldInfo wi) : - world(world),wi(wi) {} + SpawnStronghold(QWorld *world, WorldInfo wi) + : Scheduled(), world(world),wi(wi) + { + setAutoDelete(true); + } void run() { @@ -1135,7 +1148,10 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, smallfont.setPointSize(8); painter.setFont(smallfont); - int gridpix = painter.fontMetrics().boundingRect("-30000000,-30000000").width(); + int gridpix = 128; + // 128px is approximately the size of: + //gridpix = painter.fontMetrics().boundingRect("-30000000,-30000000").width(); + // and sets the scale changes such that they align with the power of 4 tiles for (int li = activelv+1; li >= activelv; --li) { @@ -1403,7 +1419,8 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, { spawn = (Pos*) -1; mutex.lock(); - add(new SpawnStronghold(this, wi)); + SpawnStronghold *work = new SpawnStronghold(this, wi); + add(work); startWorkers(); mutex.unlock(); } diff --git a/src/world.h b/src/world.h index 946f34b..adf5af7 100644 --- a/src/world.h +++ b/src/world.h @@ -162,7 +162,7 @@ enum { }; void applyHeightShading(unsigned char *rgb, Range r, const Generator *g, const SurfaceNoise *sn, int stepbits, int mode, - bool bicubic, std::atomic_bool *abort); + bool bicubic, const std::atomic_bool *abort); struct Scheduled : public QRunnable { @@ -303,6 +303,7 @@ struct QWorld : public QObject QMutex mutex; Scheduled *queue; std::vector workers; + int threadlimit; bool sshow[STRUCT_NUM]; bool showBB;